diff --git a/_quarto.yml b/_quarto.yml index df582038..60270e98 100644 --- a/_quarto.yml +++ b/_quarto.yml @@ -142,6 +142,7 @@ website: - components/inputs/action-link/index.qmd - components/inputs/checkbox/index.qmd - components/inputs/checkbox-group/index.qmd + - components/inputs/dark-mode/index.qmd - components/inputs/date-range-selector/index.qmd - components/inputs/date-selector/index.qmd - components/inputs/file/index.qmd diff --git a/components/_partials/components-detail-kitchen-sink.ejs b/components/_partials/components-detail-kitchen-sink.ejs new file mode 100644 index 00000000..1b940168 --- /dev/null +++ b/components/_partials/components-detail-kitchen-sink.ejs @@ -0,0 +1,23 @@ +::: {.kitchensink} + +<% for (const item of items) { %> + +## Variation Showcase + +A live kitchen sink of all possible parameters for the <%= item.title %> in [Shiny Core](<%= item.core %>){target="_blank"} and [Shiny Express](<%= item.express%>){target="_blank"}. + +![](<%= item.image %>){.border .my-4 style="border-radius: .5em;"} + +::::{.grid} +:::{.g-col-sm-6 .g-col-12} +

[ Live Core App](<%= item.core %>){.btn .btn-primary .w-100 .m-1 target="_blank"}

+::: + +:::{.g-col-sm-6 .g-col-12} +

[ Live Express App](<%= item.express %>){.btn .btn-primary .w-100 .m-1 target="_blank"}

+::: +:::: + +<% } %> + +::: diff --git a/components/_partials/components.css b/components/_partials/components.css index 4337146e..5a054042 100644 --- a/components/_partials/components.css +++ b/components/_partials/components.css @@ -19,13 +19,13 @@ The article pages (/components/_____/index.qmd) get styling from here. /* Add rule and spacing between sections */ -section.level2:not(:first-child) h2 { +section.level2:not(:first-child) h2, section.level3:not(:first-child) h2 { border-top: 1px solid var(--bs-primary); padding-top: 5rem !important; margin-top: 5rem !important; } -section.level2:not(:first-child) > :last-child { +section.level2:not(:first-child) > :last-child, section.level3:not(:first-child) > :last-child { margin-bottom: 0; } diff --git a/components/inputs/action-button/app-kitchensink-core.py b/components/inputs/action-button/app-kitchensink-core.py new file mode 100644 index 00000000..61ffaea1 --- /dev/null +++ b/components/inputs/action-button/app-kitchensink-core.py @@ -0,0 +1,59 @@ +from shiny import App, reactive, render, ui + +# Create the UI +app_ui = ui.page_fluid( + # Add Font Awesome CSS in the head + ui.tags.head( + ui.tags.link( + rel="stylesheet", + href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css", + ) + ), + # Main layout + ui.layout_column_wrap( + ui.card( + ui.card_header("Action Button Examples"), + # Basic button with width parameter + ui.input_action_button(id="btn1", label="Basic Button", width="200px"), + ui.output_text("click_count_btn1"), + ui.br(), # Add spacing + # Button with icon and disabled state + ui.input_action_button( + id="btn2", + label="Disabled Button with Icon", + icon=ui.tags.i(class_="fa-solid fa-shield-halved"), + disabled=True, + ), + ui.output_text("click_count_btn2"), + ui.br(), # Add spacing + # Button with custom class and style attributes + ui.input_action_button( + id="btn3", + label="Styled Button", + class_="btn-success", + style="margin-top: 20px;", + ), + ui.output_text("click_count_btn3"), + ), + width="100%", + ), +) + + +# Define the server +def server(input, output, session): + @render.text + def click_count_btn1(): + return f"Button 1 clicks: {input.btn1() or 0}" + + @render.text + def click_count_btn2(): + return f"Button 2 clicks: {input.btn2() or 0}" + + @render.text + def click_count_btn3(): + return f"Button 3 clicks: {input.btn3() or 0}" + + +# Create and return the app +app = App(app_ui, server) diff --git a/components/inputs/action-button/app-kitchensink-express.py b/components/inputs/action-button/app-kitchensink-express.py new file mode 100644 index 00000000..1ea5ed42 --- /dev/null +++ b/components/inputs/action-button/app-kitchensink-express.py @@ -0,0 +1,51 @@ +from shiny import reactive +from shiny.express import input, ui, render + +ui.page_opts(full_width=True) + +# Add Font Awesome CSS for icons +ui.head_content( + ui.HTML( + '' + ) +) + +# Create a layout with some spacing +with ui.layout_column_wrap(width="100%"): + with ui.card(): + ui.card_header("Action Button Examples") + + # Basic button with width parameter + ui.input_action_button(id="btn1", label="Basic Button", width="200px") + + @render.text + def click_count_btn1(): + return f"Button 1 clicks: {input.btn1() or 0}" + + ui.br() # Add some spacing + + # Button with icon and disabled state + ui.input_action_button( + id="btn2", + label="Disabled Button with Icon", + icon=ui.tags.i(class_="fa-solid fa-shield-halved"), + disabled=True, + ) + + @render.text + def click_count_btn2(): + return f"Button 2 clicks: {input.btn2() or 0}" + + ui.br() # Add some spacing + + # Button with custom class and style attributes + ui.input_action_button( + id="btn3", + label="Styled Button", + class_="btn-success", + style="margin-top: 20px;", + ) + + @render.text + def click_count_btn3(): + return f"Button 3 clicks: {input.btn3() or 0}" diff --git a/components/inputs/action-button/index.qmd b/components/inputs/action-button/index.qmd index f7d7cc29..ecd819c8 100644 --- a/components/inputs/action-button/index.qmd +++ b/components/inputs/action-button/index.qmd @@ -28,6 +28,13 @@ listing: - title: reactive.event href: https://shiny.posit.co/py/api/reactive.event.html signature: reactive.event(*args, ignore_none=True, ignore_init=False) +- id: kitchen-sink + template: ../../_partials/components-detail-kitchen-sink.ejs + contents: + - title: Action Button + core: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbJjmVYnTJMAgujxM6cKITIcAbnAlSIAEzh0JAVw4AdCPoDETAMJSoFJmTZwmAVQCS+tKgD6OpgF4mOrFADmcK40ADY6qgAU+kwxTMYiqqpMAGKkwiIA7nAsjLYmAMr5vBBWNkw2UKrRsb5kASwYFZHVsTUcGHX+DSFcANZRJa1DMVIhnrpgLGTYIdk2cGQTeC3DsWxSNONgbGRkqCyIAPSHhKoQAFYNhCHEWqqhUFIYJDCHUOdQAB6HPQBGLIcaGkALRQLI5eCHABsGAA7BgAEwnFgAqAhEIYGBcZ4opYrVoAShWBOWgxixgAslAuEwQlBsLdFmSfO06QytGRXCQwjAIK4MnQ0ANVizno9msyRb5COLXE0NFEwCJZBxSEwAEIcshqgCin1gqFmLAmJPxq2M6qgLA4hCYvy1aoyHGsTCdqhdqEesAWGjNw18XFQHNcMjkpFc9t2pAiHFUW1+ZAgAEYlrSoL84GMJpbrbbNVGDPhXbHrFsEQAGcuoT4m0ki1q+RlBzkUT5kRXXG29Lm3cgRxMpsCmyWrXy-OgREnk0SJViewhcfx+oYWh0lJ0um1qqBqJiqDgsdOzJJTCxwZcN9qB4Oh1V8yPaiDC+vDWPxxMIvEjl90jNZsAACIHkecBJPmj7Fi6DgkIWdYvkMW4QJ4tT1BgHARNcVosK4Ww0FAwI5D0SR4QRnCZqowJsGiihVEOcHwbE+6Hr8x6eAAKnQWhKBesTDgxjYcs2ritu2EydoQ3YkFofYJhAn50TxMRjhOU5xDOJ7zouilqeBjrOmwTCEFoUyMIZdIokwO4ntMsyWbsdAcJG2TaQGEBCbe4YPtG2mtG+EyyQAzF+DGtL+mZbPkNmgRqa7BSFMSYSiOH+YmBFaIQhDZMa+A+bEUwzHAWwwI8-hcMC2qoIgTAVtWADccUvnx8ECXswYiR2PQST20mcoFtbLk1wxuqWExJpWACkDVMMORIGHNxgAXANBcLY1i2CwGiKHQ+jqDQrCbQq15kBITYchIG0oneBKICsAACKjqHQHRwG2Ky7WZXbdTJA6Tjd36SAsWh0CUNDZmuTBJh9EkHEwIBHRgslJpOTCCEw5YAL4TPod0PRoz2vcy73iZJva9R+v3LlIZBAyDYMFtVUO9DDcNuRyCPkwSKN0GjmNgNjzL3ZQj340yrRE51JM9f2EABRT-1UzTTCg2AuklAFjPM-DgXI6jGNY3NRimOYlhWQD1PA6UtguM46BeKI6ARC47gcOdB10LNYDowAukAA + express: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbJjmVYnTJM6cKITIcAbnAA6Eeo1aduGOAA9Uoli179BwrqgCuZPE2MdzoiABM4defMtYoAczgB9YqjIsAFDTGADbBngDuHLZkbAC8ACp0xnAAlE4QAMRMAIK2tkwAYqTC2eFwLIxwTADCAMq1TDSCvCQQLM4cGGxitp6tFOT+8kwjFp0AEvEAsgAyQxCji0wA5AA8wVwA1iJwwbGyYCxk2MHl3XBkB0xsojT7YGxkZKgsiAD0b4S2EABWLBiEYLEYy2GjBKCiAGMN5QH5QdRvDYAIxYbya5AAtFAyhV4G8AGwYADsGAATJ8dDDQhgYFwAToDgA+ZbDUZpCDs+RZaqiKAUJhQJjg7DA4SRGKsSqsVDiLhueTithjDDC0V9YjBYwwCAROhofyRaJxA4ARgADGaAKQHFKIVkjRXKwgQ2z+W32pYuZ10XrdKD2OhDMDZCQcUhMABCpjI4YAoupYKhTu0wJyFksRlkI1AWBxCEwkdHw47DRKZXr4BRHOmMy4jKZPOJJKRPIWnqR-FF7kiyBATQdzOCkbt7tnc-mo+2IAOmKXjWBSRbUOobekMyMAAI2AMYCjqS41pb2GhMQF5zbq4zkVu9k1uu2H9c7MjGOgLGgHScxhYm08bQibK8TAgPWZAYD2fZukwzRmgAvgca7ri4SKBikmY5HkkrwNKsoQPK06PqMWZFgsjp5uGUB2EwtgcCwUBIqc+RHHyciESMdYQCYZCNqGLZtt+8xPosXYHBBpIDh6T5DiOBwACK0fRjGRiRs4cBKACSrQSWxSzkRAsQuGQ7j-Bw-iAjmLCePcNBQBiFQbPkNl2Zwuy2BibBQMEMi2DaeCSeuNF0QxcC2AkSRwH5Olpk+W6UDue4Hk+x5-uel7XmJ97+Rmogvm+jSfippIpQBQEgZxpjgb2pJQTB8FgIhtadChUFMFkuRMVKLAyoQcoNUsxFTqpEqEMYRxKOZOgClRRwnFUfJkHQHBtuUWXKqBPHNjq-EdqtwmhaJvYAMzaUJozSXsBy1McSlfqQJ2nX+FlWQdEB2cYhCEOUKaRQ9rDXXA9wwBCbhcBiMaoIgTCLsuADc90ZtF66xXYDi7hoiUBXAJ5ngBaXcRBh2ZTpiw5a+74FYNh3FYBkNlVxlUQITaG1QhEBgLBAC6QA + image: thumbnail.png --- :::{#example} diff --git a/components/inputs/action-button/thumbnail.png b/components/inputs/action-button/thumbnail.png new file mode 100644 index 00000000..d1d0d967 Binary files /dev/null and b/components/inputs/action-button/thumbnail.png differ diff --git a/components/inputs/action-link/app-kitchensink-core.py b/components/inputs/action-link/app-kitchensink-core.py new file mode 100644 index 00000000..8aa0c0b2 --- /dev/null +++ b/components/inputs/action-link/app-kitchensink-core.py @@ -0,0 +1,38 @@ +from shiny import App, reactive, render, ui + +# Define the UI +app_ui = ui.page_fillable( + # Add Font Awesome CSS in the head section + ui.tags.head( + ui.tags.link( + rel="stylesheet", + href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css", + ) + ), + + # First card + ui.card( + ui.card_header("Action Link Demo"), + # Create an action link with an icon + ui.input_action_link( + id="demo_link", + label="Click Me!", + icon=ui.tags.i(class_="fa-solid fa-shield-halved"), + ), + ui.output_text("link_clicks"), + full_screen=True, + height="300px", + id="card1", + ), +) + + +# Define the server +def server(input, output, session): + @render.text + def link_clicks(): + count = input.demo_link() or 0 + return f"The link has been clicked {count} times" + +# Create and return the app +app = App(app_ui, server) diff --git a/components/inputs/action-link/app-kitchensink-express.py b/components/inputs/action-link/app-kitchensink-express.py new file mode 100644 index 00000000..3c2351f9 --- /dev/null +++ b/components/inputs/action-link/app-kitchensink-express.py @@ -0,0 +1,30 @@ +from shiny import reactive +from shiny.express import input, render, ui + +# Add Font Awesome CSS in the head section +ui.head_content( + ui.HTML( + '' + ) +) + +# Set page title +ui.page_opts(fillable=True) + + +# Create a card to hold the action link +with ui.card(full_screen=True, height="300px", id="card1"): + ui.card_header("Action Link Demo") + + # Create an action link with an icon + ui.input_action_link( + id="demo_link", + label="Click Me!", + icon=ui.tags.i(class_="fa-solid fa-shield-halved"), + ) + + # Display the click count + @render.text + def link_clicks(): + count = input.demo_link() or 0 + return f"The link has been clicked {count} times" diff --git a/components/inputs/action-link/index.qmd b/components/inputs/action-link/index.qmd index 5dd6e803..b376f6ca 100644 --- a/components/inputs/action-link/index.qmd +++ b/components/inputs/action-link/index.qmd @@ -28,6 +28,13 @@ listing: - title: reactive.event href: https://shiny.posit.co/py/api/reactive.event.html signature: reactive.event(*args, ignore_none=True, ignore_init=False) +- id: kitchen-sink + template: ../../_partials/components-detail-kitchen-sink.ejs + contents: + - title: Action Link + core: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbJjmVYnTJMAgujxM6cKITIcAbnAlSIAEzh0JAVw4AdCPoDETACJwaXOEzJsrAVQCS+tKgD6OpgF4mOrFADmcK4WADYhUABGIXAAFPpMCUzGIqqqTABipMIiAO5wLIxWAMIAyiW8ENa2TLZQaSxwshyk8Ym+ZAEsGLWqcZWJA+2dGCFcANZ9A1OJUiGeumAsZNjR7HBwZAt4rdMDbFI082BsZGSoLIgA9JeEqhAAVl2EIcRaqjThUhgkMJdQ91AAB6XUYRFiXGhZAC0UDyBXglwAbBgAOwYABMNxY4KgYQwMC432xWx2UwAlKSydsDP0EsZ0hw6EsmIQoHRVKTfKz2ZNdly2apXD0NHEwCImqQmAAZcamOAwYgLKmkgbGIpSKAUJhQSoyOSS0YQMZMHIcGzayocEg03Y+DgYLioLRkVx65oQVyGiYq3YcVRHdQKz3jEm021McIROBzBZFUaEY0AWTgAEJQ+HElbSJ4hv4uhwYs8oNjXEcaFAoQVRmly5XONHVFC2LjFBywMqwwMO7bfK8zs7XBRAWRRV7XM8rWMWErqbaaFowq4WIQpJRPAAVOhaJQ+hK2Dj+E5HADMAAZT6hAenff6FtzVABGa8JDsUmlGOUWCBWGxWBp0RQ6H0dQaFYDRAJiR1nQkPsnTICQGmxd0yUQUkAAEVHUOgMCHTYwxAiNxnHeMpxiFDdxZV5yC8Co4IwQNiGDI0yKYQQmFPCipDILQ6EqGgFnXaovRqYsmCjSgWRIuA0hAEgtHIABfaw+HyBZ9A-dVpC1HU0i4njKl-bV0GcdAaLEVAYhcdwOAQ8CNDfMAFIAXSAA + express: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbJjmVYnTJM6cKITIcAbnAA6Eeo1aduGOAA9Uoli179BwrqgCuZPCMoATOHXPGO8+QGImAQUuWmAMVLDXAdzgWRjgmAGEAZQjeCCYyNlCEqE8WOAkOUnl7DCTLAH0SckoyAAp5JgqmbIAJABUAWQAZMtjKtoByAB4AGy4AawtugF5ZMBYybG6ghLgyUaY2URoRsDYyMlQWRAB6bcJLCAArFgxCbuJjSxpuqFFTxm2oQ6h1bd6AIxZtml8AWihAsF4NsAGwYADsGAATHsdI9ut0MDAuKcdKMAHztcqVACU8jxEGcTAisyYqCgAHNQpIyFMshwsJS4HliKgyCwSjQOAioO8pkNanRjHACY4IC4wqIoBQmFAmIRbp4yMQFsRukqErL0qQmL0IH15P4OPEqgyFXRLJzjAi8ixCKJKAKhXBzAkOBS1isAMwABh9qHUo3MHEsK3NlgAjKMcYhsRVsuG8rkbGUwK5tbFGv0mAAROAwYjRsVtCVSmVQWLiSQ6vUDI0miu8Qpx00YIymPJVjIQPK1lptNohlbWAu9-pBlttG7vODDUZhXqEAb1OAAQgnrQHTdIQ2yZEpJw4JTOUB0eRWNCgv2CvU8l+vnFnll+bCg3RklmjeBbos3TBcOYcCwqA3Dw8ShGcHBLvKFzkC2AACogQNYdAYBQ6hzH+1g0Lq-QFIufQcjGk6VCQxjkEwQwxCYZAYCOxBjvqJQ4kwghMD6JEVKIZDGHQsQ0KMtSarWCynkwM6UPKBFwJ4IBkeQAC+cR8EEozyGACkALpAA + image: thumbnail.png --- :::{#example} diff --git a/components/inputs/action-link/thumbnail.png b/components/inputs/action-link/thumbnail.png new file mode 100644 index 00000000..b719f98b Binary files /dev/null and b/components/inputs/action-link/thumbnail.png differ diff --git a/components/inputs/checkbox-group/app-kitchensink-core.py b/components/inputs/checkbox-group/app-kitchensink-core.py new file mode 100644 index 00000000..3754ca7e --- /dev/null +++ b/components/inputs/checkbox-group/app-kitchensink-core.py @@ -0,0 +1,38 @@ +from shiny import App, reactive, render, ui + +# Create sample choices with HTML formatting for demonstration +choices = { + "red": ui.span("Red", style="color: #FF0000;"), + "green": ui.span("Green", style="color: #00AA00;"), + "blue": ui.span("Blue", style="color: #0000AA;"), +} + +app_ui = ui.page_fluid( + ui.card( + ui.card_header("Color Selection Demo"), + # Using input_checkbox_group with all its parameters + ui.input_checkbox_group( + id="colors", # Required: unique identifier + label="Choose colors", # Required: label text + choices=choices, # Required: choices as dict with HTML formatting + selected=["red", "blue"], # Optional: pre-selected values + inline=True, # Optional: display choices inline + width="300px", # Optional: CSS width + ), + # Add some spacing + ui.hr(), + # Output for selected values + ui.output_text("selected_colors"), + ) +) + + +def server(input, output, session): + @render.text + def selected_colors(): + if input.colors(): + return f"You selected: {', '.join(input.colors())}" + return "No colors selected" + + +app = App(app_ui, server) \ No newline at end of file diff --git a/components/inputs/checkbox-group/app-kitchensink-express.py b/components/inputs/checkbox-group/app-kitchensink-express.py new file mode 100644 index 00000000..cfd6607f --- /dev/null +++ b/components/inputs/checkbox-group/app-kitchensink-express.py @@ -0,0 +1,34 @@ +from shiny import reactive +from shiny.express import input, render, ui + +ui.page_opts(full_width=True) + +# Create sample choices with HTML formatting for demonstration +choices = { + "red": ui.span("Red", style="color: #FF0000;"), + "green": ui.span("Green", style="color: #00AA00;"), + "blue": ui.span("Blue", style="color: #0000AA;"), +} + +with ui.card(): + ui.card_header("Color Selection Demo") + + # Using input_checkbox_group with all its parameters + ui.input_checkbox_group( + id="colors", # Required: unique identifier + label="Choose colors", # Required: label text + choices=choices, # Required: choices as dict with HTML formatting + selected=["red", "blue"], # Optional: pre-selected values + inline=True, # Optional: display choices inline + width="300px", # Optional: CSS width + ) + + # Add some spacing + ui.hr() + + # Simple output to show selected values + @render.text + def selected_colors(): + if input.colors(): + return f"You selected: {', '.join(input.colors())}" + return "No colors selected" diff --git a/components/inputs/checkbox-group/index.qmd b/components/inputs/checkbox-group/index.qmd index 8613c6bc..2b6406e4 100644 --- a/components/inputs/checkbox-group/index.qmd +++ b/components/inputs/checkbox-group/index.qmd @@ -26,6 +26,13 @@ listing: href: https://shiny.posit.co/py/api/ui.input_checkbox_group.html signature: ui.input_checkbox_group(id, label, choices, *, selected=None, inline=False, width=None) +- id: kitchen-sink + template: ../../_partials/components-detail-kitchen-sink.ejs + contents: + - title: Checkbox Group + core: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbJjmVYnTJMAgujxM6cKITIcAbnAlSIAEzh0JAVw4AdCPoDETAMJSoFVrFQAbOE0JtiHQnBZMA7hzJsmACQAVAFkAGSYaQRgLOQgAc3DBJnUYUhYyOgsOUn1HZ1d3AF4mEH0mMqZdMClVSsQmHQwWVCgIAApKgCU4GvxWMmw7AsqSG0E6wwAxCYAGWemAbkqASjxS8srYqUpa+o5G5rbKgHEtg160gbghomJRunHZkRFZxbAVtbLKgCMbLTgdhpNFrtMAAIV+-3O-UGw1uYyYhjm0yer3eEAAvvp9GhUAB9HRMIoNZqxOC4mi-DiqdoQcq7DCEKB0akfOn0xnM3FsaTqOggkxwuhMADKcDssiytIAInAUstVrS2WVjABVFhceJcVBaMi4xxwQgAay+xAAHrjNsQtKhPN5fFAbDZeGR3M0MvAKHQWKy6Q0tTq9dyjSbzZbrTSlUqqdcRoJvb0EUwugBHHTVOpaCAcVP2KmUOQ0DgaH2RmxQL5i64mJzEFj2WNeyoSRMptPdOplitOiimsglpW5FxuAqD-LN4ytjjphxOIfuKDuVQuYReHz+YJhCJ0KJkGKxftsuviiiqArASrVJsVMA-P6VAC646YAHlUHJSA66qgpABaI8Gk8mHkB0-m9RVI3KLgbC4K4AjoP4n1fd9oBsOolyaMseFHNxeAgaCIH+cCINtVQfGuABmWZUFNK9EyQyVP1MYVhRInwDzRCDjBEVRVFYRh7CBQgNQPBo2D5DjI2MZ8dW1YQt1YMUAO6ICQLcES9itMhZNxHsyBBf9ZG6PVBXjCSyiWfQLIMaz1BoBS6EUPl-TICRNNkiQ6xYdVSCWRBWQAARUXkMF01lbIU48jIbFhWl8g8ODs5yGRM2K-KIiCpDILQ6FpGhKgATStCKlNUOoQAAcgkcqMAAK2cNokui2KlkxMAD0y7LaUqAA5YgHBM4rDJ6LFrJxQlRHQVocXxDgPI0RyljAdF7yAA + express: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbJjmVYnTJM6cKITIcAbnAA6Eeo1aduGOAA9Uoli179BwrqgCuZPCMoATOHXPGO8+faxQA5nAD6xVGRYAKGmMAGyCPAHcOSzI2AF4AFTpjOABKRwgAYiYAYVEoClZYVCC4JkI2Yg5COF0I6KYACTiAWQAZJhpBGDzJCFd2wSZrGFIWMjo8jlJ5Moqq3RimEHkmFaZZMFFLdcQmZxZUKAg-dYAlOC38VjJsYpj1kiDBHfSAMReABk-3gG515Lxlqt1q5RJRtrsOBh9odjmAAOKgiDrcyjG5wO5EYiPOjPT4AQTxn1+YH+gJW6wARkEkuC9gcjusAELUuSXVG3e5Yp5MdJfd4E4mkiAAXzStTYEIwhCgdEsfmSiDJkulso8bDE1josKyXLoTAAynBihJJhAmAARODDP5pVY8pgAVRYXD6RlMHjKcEIAGsKcR1B4QcRjKgmOKmFAQrxfEwDuN4BQ6Cwlc43WQPeqfX6A0GQ8czXbVpEMQ9BMnLvazgBHeybHbGCAcGslSKUSQ0Dg2JV2oJQClGjFZcrEFglUtJ5ErTLV2vnHa9-tBJgUdRkburGaVaoxTdzcyVuA1jh10rlLe6KC6SyVYThxqtfp0LpkHqudcrUfGiiWGLAdabSdKRZdYAF190yAB5HxTUjHYtDgABaT8vW-JgpEjJJkwLQteAgIIuHRBIknApgoMkUhYMGDh9l7Hhd2qXD8IgORsMLCIolidYAGZPlQdRJ3tMiYKCHYsn1fUw0iaIlVSJFWMyPFLEsVhGBKaFCBdFNITYLVZKVTJ9T4IoSmDMgTGEMhiGUYgwlYI0UPONCMOqJUAAFRAgTUMBXNdWOsGg7K-c4PV1fwFXfXgArTKVQvlRVWJwlZRDIYw6DNGh1gATWDQKHMsHYQAAcnMQqMAAKwqI5ovHMLklFMAIuS1KzXWAA5KyatyiRznWeQwGFECgA + image: thumbnail.png --- :::{#example} diff --git a/components/inputs/checkbox-group/thumbnail.png b/components/inputs/checkbox-group/thumbnail.png new file mode 100644 index 00000000..f6eac67b Binary files /dev/null and b/components/inputs/checkbox-group/thumbnail.png differ diff --git a/components/inputs/checkbox/app-kitchensink-core.py b/components/inputs/checkbox/app-kitchensink-core.py new file mode 100644 index 00000000..1a406c7a --- /dev/null +++ b/components/inputs/checkbox/app-kitchensink-core.py @@ -0,0 +1,46 @@ +from shiny import App, reactive, render, ui + +# Define the UI +app_ui = ui.page_fluid( + # Card containing all elements + ui.card( + ui.card_header("Checkbox Demo"), + # Basic checkbox with default value (False) + ui.input_checkbox(id="basic", label="Basic checkbox"), + ui.output_text("basic_value"), # Individual output for basic checkbox + + # Checkbox with initial value set to True + ui.input_checkbox( + id="preset_value", label="Checkbox with preset value", value=True + ), + ui.output_text("preset_value_text"), # Individual output for preset checkbox + + # Checkbox with custom width + ui.input_checkbox( + id="custom_width", + label="Checkbox with custom width (300px)", + value=False, + width="300px", + ), + ui.output_text("custom_width_text") # Individual output for custom width checkbox + ) +) + + +# Define the server +def server(input, output, session): + @render.text + def basic_value(): + return f"Value: {input.basic()}" + + @render.text + def preset_value_text(): + return f"Value: {input.preset_value()}" + + @render.text + def custom_width_text(): + return f"Value: {input.custom_width()}" + + +# Create the app +app = App(app_ui, server) diff --git a/components/inputs/checkbox/app-kitchensink-express.py b/components/inputs/checkbox/app-kitchensink-express.py new file mode 100644 index 00000000..644fa59f --- /dev/null +++ b/components/inputs/checkbox/app-kitchensink-express.py @@ -0,0 +1,33 @@ +from shiny import reactive +from shiny.express import input, ui, render + +ui.page_opts(full_width=True) + +with ui.card(): + ui.card_header("Checkbox Demo") + + # Basic checkbox with default value (False) + ui.input_checkbox(id="basic", label="Basic checkbox") + + @render.text + def basic_value(): + return f"Value: {input.basic()}" + + # Checkbox with initial value set to True + ui.input_checkbox(id="preset_value", label="Checkbox with preset value", value=True) + + @render.text + def preset_value_text(): + return f"Value: {input.preset_value()}" + + # Checkbox with custom width + ui.input_checkbox( + id="custom_width", + label="Checkbox with custom width (300px)", + value=False, + width="300px", + ) + + @render.text + def custom_width_text(): + return f"Value: {input.custom_width()}" diff --git a/components/inputs/checkbox/index.qmd b/components/inputs/checkbox/index.qmd index 27b44687..0ae70f50 100644 --- a/components/inputs/checkbox/index.qmd +++ b/components/inputs/checkbox/index.qmd @@ -25,6 +25,13 @@ listing: - title: ui.input_checkbox() href: https://shiny.posit.co/py/api/ui.input_checkbox.html signature: ui.input_checkbox(id, label, value=False, *, width=None) +- id: kitchen-sink + template: ../../_partials/components-detail-kitchen-sink.ejs + contents: + - title: checkbox + core: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbJjmVYnTJMAgujxM6cKITIcAbnAlSIAEzh0JAVw4AdCPoDETACJwaXOEzJsrAVQCS+tKgD6OpgF4mOrFADmcK40ADY6qgAU+kwxTMYAwlB0qkwk5FBcXP5MUCEhTHAhcPDkLNGxvoRJkeWxFRwYVcmutlDqdFFg8baEANYARsQAHqbFxLpgAJR4tXVxTABCUCwchKk9A8NMAO4cNkzqNFBaIcLyuVpWEQBiuSxwk7N1vlyoWmSuhBuDQxEcqp4Jv1lqsJhIQlB+oVAWAlis1l84H0fhNpk96hhiO83h8KEMyJ1gfDXOcwnBURJ5g41Ap-lpckwsWQcUwaIImETVuskZshuiYvz5t0eT8dns2LwIHsOAzSZdWHBhGRiEwACp0S6Cl4QHGfb7DKIQObG3gAiaoKT3D5y8n4JgQqEhGHC5FbXb7C1wK1MG1gn0XOCedWao0mtGh42+Jm6vEE82WxUkgOuWMUmLGamqWmqen5aPvVnsz3exGuvkRuaChL6kbuiWELQsZXMXaqGxahqvd56kUGwV1f4whtNxiuVvt-D92IO6ETF28sX7YfNsVtiURADMAAYt6gho9JxWTf6yZ5biF7jMjybx2wYdvd3zD8fw8eo9ju7HOsvR7eU3B8VRdMmEzbNc0ZD9hDZOhUkbFdb25MtZkeCAUP0IxRgsCArBsKx7joRQ6H0Q4FQIjQ-h1d4JHzMgJHuFgVlISZEFmAABFR2gwVMKxIzlCCTMkImYwUpDILQ6CNGgJgANQDRAmBALsyAwPihIAXwmWY2I4jQuIAshZhI4tExtf98SEljrxiUTxMkmS5IUpSsATa0A3UzSK20yhOO4uoSJ-GAx3+GwzIJYSrMkRVbNZeyyXkxTKOUgKgrXdywHQgwIASKQoAoaxbBydBnHQLxRHQCIXHcDg6I0QiULANSAF0gA + express: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbJjmVYnTJM6cKITIcAbnAA6Eeo1aduGOAA9Uoli179BwrqgCuZPE2MdzoiABM4defMtYoAczgB9YqjIsAFDTGADbBngDuHLZkbAC8ACp0xnAAlE4QkTEWHBiEUHS2-imI8kxl2bn5tp5sYvZ0-rJgAMK1hADWAEbE6kwAInAwxE1pEKXlAMRMAEJQLByETIRtXT1MmWxM9jRQIcJSUMHJTP4AYocsqeNlLkamnstwHd3q-lGxTZ1zC03mwVCdODBD5gWbzRaPZ49EbXJiwgACNnqGAo6jIsO2TC+4M8ByOcCKJQg5RJIjgZGMdGJNCaADVDslEEwQHcyBhsQsigBfJrpElTVpPVa9Da8CAcSSHJh446XYRkYhMRLJWG3CAmMgPFYvN62EFaOBy3EMuT4Jj-QHApqCqEiiWbA1y6Um37O-EJJJXYnlBFIhwojTo71lTGO8nG-GeVFkQmwkmiClUpg0sD0-FMlnq0xYbThmUElI8sB8yZMG3C9b2pbGFgK5iRaJsVU5VlaoU6uPld5NQg1usRKIxX6dsoWoEg8svStZXu1pQNrL+ADMAAYV6h1Gl8CO3clYudgpc8DuF3Emqv1+ph8GmKMSb7KMjoxi4DRq3OYAPG1HA7Gb-HyUpak6RNDNWVyPtGC-GJuV5CAwC5ABdIA + image: thumbnail.png --- :::{#example} diff --git a/components/inputs/checkbox/thumbnail.png b/components/inputs/checkbox/thumbnail.png new file mode 100644 index 00000000..24267469 Binary files /dev/null and b/components/inputs/checkbox/thumbnail.png differ diff --git a/components/inputs/dark-mode/thumbnail.png b/components/inputs/dark-mode/thumbnail.png new file mode 100644 index 00000000..a7a80885 Binary files /dev/null and b/components/inputs/dark-mode/thumbnail.png differ diff --git a/components/inputs/date-range-selector/app-kitchensink-core.py b/components/inputs/date-range-selector/app-kitchensink-core.py new file mode 100644 index 00000000..56fa1462 --- /dev/null +++ b/components/inputs/date-range-selector/app-kitchensink-core.py @@ -0,0 +1,73 @@ +from datetime import date +from shiny import App, reactive, render, ui + +# Define the UI +app_ui = ui.page_fluid( + # Add descriptive text + ui.h2("Date Range Input Example"), + ui.markdown( + """ + This example demonstrates a date range input with various customization options: + - Custom date format (mm/dd/yyyy) + - Restricted date range (2020-2025) + - Week starting on Monday + - Custom separator + """ + ), + # Layout wrapper + ui.layout_column_wrap( + # Date range input with all parameters + ui.input_date_range( + id="date_range", + label="Select Date Range", + start=date(2023, 1, 1), # Initial start date + end=date(2023, 12, 31), # Initial end date + min=date(2020, 1, 1), # Minimum allowed date + max=date(2025, 12, 31), # Maximum allowed date + format="mm/dd/yyyy", # Display format + startview="decade", # Initial view when opened + weekstart=1, # Week starts on Monday (0=Sunday, 1=Monday) + language="en", # Language for month/day names + separator=" → ", # Custom separator between dates + width="100%", # Width of the input + autoclose=True, # Close the calendar when a date is selected + ), + # Card to display selected range + ui.card( + ui.card_header("Selected Date Range"), + ui.output_text("selected_range"), + ), + ), + # Additional date info output + ui.output_ui("date_info"), +) + + +# Define the server +def server(input, output, session): + @render.text + def selected_range(): + date_range = input.date_range() + if date_range is None: + return "No dates selected" + + start, end = date_range + return f"Start date: {start}\nEnd date: {end}" + + @render.ui + def date_info(): + date_range = input.date_range() + if date_range is None: + return ui.p("Please select a date range", class_="text-muted") + + start, end = date_range + days = (end - start).days + + return ui.div( + ui.p(f"Number of days selected: {days}"), + class_="mt-3", + ) + + +# Create and return the app +app = App(app_ui, server) diff --git a/components/inputs/date-range-selector/app-kitchensink-express.py b/components/inputs/date-range-selector/app-kitchensink-express.py new file mode 100644 index 00000000..d70a2fbd --- /dev/null +++ b/components/inputs/date-range-selector/app-kitchensink-express.py @@ -0,0 +1,64 @@ +from datetime import date +from shiny import reactive +from shiny.express import input, ui, render + +ui.page_opts(full_width=True) + +# Add some descriptive text +ui.h2("Date Range Input Example") +ui.markdown( + """ +This example demonstrates a date range input with various customization options: +- Custom date format (mm/dd/yyyy) +- Restricted date range (2020-2025) +- Week starting on Monday +- Custom separator +""" +) + +with ui.layout_column_wrap(): + # Create a date range input with all possible parameters + ui.input_date_range( + id="date_range", + label="Select Date Range", + start=date(2023, 1, 1), # Initial start date + end=date(2023, 12, 31), # Initial end date + min=date(2020, 1, 1), # Minimum allowed date + max=date(2025, 12, 31), # Maximum allowed date + format="mm/dd/yyyy", # Display format + startview="decade", # Initial view when opened + weekstart=1, # Week starts on Monday (0=Sunday, 1=Monday) + language="en", # Language for month/day names + separator=" → ", # Custom separator between dates + width="100%", # Width of the input + autoclose=True, # Close the calendar when a date is selected + ) + + # Add a card to display the selected range + with ui.card(): + ui.card_header("Selected Date Range") + + @render.text + def selected_range(): + date_range = input.date_range() + if date_range is None: + return "No dates selected" + + start, end = date_range + return f"Start date: {start}\nEnd date: {end}" + + +# Add some additional information about the selection +@render.ui +def date_info(): + date_range = input.date_range() + if date_range is None: + return ui.p("Please select a date range", class_="text-muted") + + start, end = date_range + days = (end - start).days + + return ui.div( + ui.p(f"Number of days selected: {days}"), + class_="mt-3", + ) diff --git a/components/inputs/date-range-selector/index.qmd b/components/inputs/date-range-selector/index.qmd index c9e0774b..2bd64252 100644 --- a/components/inputs/date-range-selector/index.qmd +++ b/components/inputs/date-range-selector/index.qmd @@ -27,6 +27,13 @@ listing: signature: ui.input_date_range(id, label, *, start=None, end=None, min=None, max=None, format='yyyy-mm-dd', startview='month', weekstart=0, language='en', separator=' to ', width=None, autoclose=True) +- id: kitchen-sink + template: ../../_partials/components-detail-kitchen-sink.ejs + contents: + - title: Date Range Selector + core: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAEygrIEt4nvVi6ZVuzgAdCPUZMAzgAtOEbLxj9BTAILo8TOnCiEuANzjbdEFnDraArp3HiAxEwAicGgrhMyszwFUAkuJoqAD6tkwAvEy2WFAA5nAhNAA2tiwAFOJM2UxO6iwsrHDShHScqEaeFAAeZFk5MbIATJlgziJMAEpQEAlM-hCo1kIAotWwqMliYACUePXZMTBQdADWLMQA7hCZEDn7TKJgRyd7OQAq8tJMcOMqU0UwpNJkdCLXUMIUOj19CkNCTacbxMQwrTjEazXQhQsiMTgAL3YEL2xAqKOkiAWTAAtEwAMKwqRsb40ATLITpGAwAD0BRp2EZ2Bm2LxnWKr04BjghRJnjevU86SaAAZRTjRU0AKwss7ZPEAdTgcFWMjIKy4vSYpCYAFlSGxsKyCUTmNI4KgVuwBNiTsdjnKmHNsU4ADJQbCQwFvdCWbExZIer0hEipGAQEKbH27A45Jztb4Cv6DYZMIEgqDJZJMS1veAUOjSbH7GL-YYhPkhJNwGOxg6cFgRI6V6tHeaOutMQMAIzgySbYAAyn24AYXB1uoK28W6y8NRE+cKxQBmbQARnXc2yTgGwM4mbVGq+Yg7dcojcXktXTDXTW0y7XW9y-Qge4P5+PM9jMAUC5ES9FddN20Z9dQUbhrGYTNki2HlP1Pb8oGqP8KAAqV1zvJgHyfJxdSQiCoKzWDeREL8DjJOgKQHak6RYBkmTbbcXE4aRJg9JgKIpMj9jnQRDE4OBNgHCxCCgCxGOfXcuAPfjBLTHxUVQSgeW4nJNmVVZeLICINyYpUVUPQRrh1fVzHY9IRQiQdrDM7B1wiUzDVlTt9kDXprHiOAB0oCS3V+Dy+gopgnnIWQ6XY6B4CLBCDnNXNrToAcmEAJMJDnwJjCReKQ4qtOE6CYXsyHUyhj2ily1IbbwBzXEURQAUl8pgFUq2RtRoLwfF4FM6hi-YoGGYhCBg80InOOhrBMDLhqqTrRKmMz8s2BSmE+PleGuc0pm5FgyOdGKnHxFZCjhVgWLYpRNtHChClbGKYlEugMlUxZOAwB6WBCHwxMsVphy267x2+ScEiOPbypejAvQBEIajIVpLu2qtfmmMG61R7J0effIWD3UgDzWhQyW1YYAX9V6ofLWxWkrQniFB9tZXsCB4zcDwOs8c06GMOhxAsdrOe59IyzIbQKZFmRimkFEZixR0AAEzAsOgMFh7E+Yl-6eSRwV0hlsiW2RyIuoBDADZ15y604dqzb+a4ADlSDgWXwZ0OAyGsOg9iOB3So1q6VIdMitO0D8ohtk9O10d3PY4o5B3VNQ+UQJgQC0gBfURxBGcxj2TkBzwzwP5cVywMFsNW3GPEJad15263Do3hdNkRtYSXWyKtqvq3WpgHYgJ3ntd6O9hiVBWgABSmKBzT9sdVo6Vt0qG6fpBCAdYZxGBhgDxmYuDm4c7Dlvbs7Q1riidIPzxLSZmb7BorIqOPZH16ccMWtytH9IaG9yDe3y4g1sPQbRHNtPOZ9C6Y07MvaQq9qJkBxMuacMVd6OAJLoDoPQbpu2fuzFa6AgjoCNpoMewQwicG0ALSwsowBpwALpAA + express: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAEygrIEt4nvVi6ZVuzgAdCPUZMAzgAtOEbLxj9BTOnCiEuANzESGzOQuwY4AD1Qbp05aqELUAVzJ4mTzm40QWcOuPEPLCgAczgAfWJUMmkAChonABtE8IB3ThYyWQBeABU6JzgASgCIAGImAEEWFhlGOFY4aUI6TmjOPSYKczJAzgxZACZY0TAAEREmACUoCDCmAEkIZyEAUXNYVESxMBKIIJgoOgBrFmJUiBGIJhumUfuwcVz5WwtN7caYUmkyOhFbKDCCjqWbzRwuJjpLJMHRHTjEJy2QiIsiMTgAL3Y8OuUS430Q4gAtEwAMIoqRsYE0ASHISxGAwAD0NUZ2DZ2D2xKmTV+nG0cFqlIafzmDVigwADJLCZLBgBWTlMADqcDgxxkZCOXDmTFITAAsqQ2NgiaTyUY4KgjuwBAFHvbxHtxFDZO5+okoNgEWRwiREk4YBA0n9ULEigTrrcKiSNJNAUKQaLeMsIS6mFBkkx+DZOAAjD5Wv7wCh0aTiW5ujDgn1C8IisJXCsVjLZUa1+s7PDlps3D25uCJVtgADKA7g2iYE2BM1Foy7kZ7Py12SF4qlAGY3ABGbdFNxMCpLThcDMarVA-Q9m6UFgrkRrwabphbwZuddbvc3Q8QY+cU83i9ux7GAFDvCgHwlbdd33Cp9QUbgA3TZJzgFQCFybQ5zDAuAHzlbdXyYd9PwPA0oHMBDmAzRIUMFEQgKbak6FpIcGWZFhWXZOcv0nThpC2T0mEY2l6IrJdBB0Tg4FSIdfEIKBfC4kijxPRIYUk1JIVkShdVQSgBRE25UlVY4xLIbId24lU1TPQRbD1Q0fAE2IJWyYcnEc7Bt2yBzjT2K8mA9OYnFCOAh0oRSKgAGVBYL5kYpgvnIWRmQE6B4DLdDRMta1UToIcmEAJMI7nwbiyR+KRpGyv5cqYfsyCM7ShQy-z0kyHJRi3CUJQAUgi5UMmhYgaC6LTkxWAybigFxiEIajKryAo4Bg0k5oaLIGjk7ZHLoTTtPjSZeJkMd+RYeinXQipqlqQE5LoWpUVYXj+KUdaju2E7EzCei0yCW6WDDCN-N+o4WHCLT5L8EYR2OihainBoZy+3ZSn8gABbxfDoDBul6TLbl8YbKve2G61BHDwwmpt2zJphsjGlwMGp0Uw0p5thqZsFbAAOVIOBAf8q8NDIJw6GuUYeYvWwifHWH7ggVnblMtwALpjnLwFm4hZF64aFGYdNTUIVECYEBTIAX1EcRVh8C9jZAG8LceeXncumo6h4eSWF-UhTwUISsT1KBc29EaGml7RsXEdGbz8DAPHEAmL3CP3iAB+i1dp+myEZkRSeZvzbk4dnc47Xhud5-mey10XK1DUYAAVtigSq3pl9ML0+zsmFm5vpHCIcccJGAXH05HndEg3XCYFWk47dPPVsOnYgA4lTKKHPsAy+jq+uIIvZ0RsryCUNdbALmA37HahuETfW5Ou3jWkR290pnubH70YYDIQl1znM7xDAGbAAukAA + image: thumbnail.png --- :::{#example} diff --git a/components/inputs/date-range-selector/thumbnail.png b/components/inputs/date-range-selector/thumbnail.png new file mode 100644 index 00000000..ac1d283a Binary files /dev/null and b/components/inputs/date-range-selector/thumbnail.png differ diff --git a/components/inputs/date-selector/app-kitchensink-core.py b/components/inputs/date-selector/app-kitchensink-core.py new file mode 100644 index 00000000..6c86633c --- /dev/null +++ b/components/inputs/date-selector/app-kitchensink-core.py @@ -0,0 +1,137 @@ +from datetime import date + +from shiny import App, render, ui + +app_ui = ui.page_fluid( + ui.panel_title("Date Input Parameters Demo"), + ui.layout_column_wrap( + # Basic date input example + ui.card( + ui.card_header("Default date input"), + ui.input_date("date1", "", value="2024-01-01"), + ui.output_text("selected_date1"), + ), + # Date input with minimum and maximum date constraints + ui.card( + ui.card_header("Date input with min/max"), + ui.input_date( + "date2", + "", + value=date(2024, 1, 1), + min="2024-01-01", + max="2024-12-31", + ), + ui.output_text("selected_date2"), + ), + # Date input with custom date format + ui.card( + ui.card_header("Custom format (mm/dd/yy)"), + ui.input_date( + "date3", + "", + value="2024-01-01", + format="mm/dd/yy", + ), + ui.output_text("selected_date3"), + ), + # Date input that opens to decade view + ui.card( + ui.card_header("Start in decade view"), + ui.input_date("date4", "", value="2024-01-01", startview="decade"), + ui.output_text("selected_date4"), + ), + # Date input with week starting on Monday + ui.card( + ui.card_header("Week starts on Monday"), + ui.input_date("date5", "", value="2024-01-01", weekstart=1), + ui.output_text("selected_date5"), + ), + # Date input with German language localization + ui.card( + ui.card_header("German language"), + ui.input_date("date6", "", value="2024-01-01", language="de"), + ui.output_text("selected_date6"), + ), + # Date input with custom width + ui.card( + ui.card_header("Custom width"), + ui.input_date("date7", "", value="2024-01-01", width="400px"), + ui.output_text("selected_date7"), + ), + # Date input where calendar doesn't auto-close + ui.card( + ui.card_header("Autoclose disabled"), + ui.input_date("date8", "", value="2024-01-01", autoclose=False), + ui.output_text("selected_date8"), + ), + # Date input with specific dates disabled + ui.card( + ui.card_header("Specific dates disabled"), + ui.input_date( + "date9", + "", + value="2024-01-01", + datesdisabled=["2024-01-15", "2024-01-16", "2024-01-17"], + ), + ui.output_text("selected_date9"), + ), + # Date input with weekend days disabled + ui.card( + ui.card_header("Weekends disabled"), + ui.input_date( + "date10", + "", + value="2024-01-01", + daysofweekdisabled=[0, 6], # 0 = Sunday, 6 = Saturday + ), + ui.output_text("selected_date10"), + ), + width="300px", + ), +) + + +def server(input, output, session): + # Server functions remain unchanged + @render.text + def selected_date1(): + return f"Selected date: {input.date1()}" + + @render.text + def selected_date2(): + return f"Selected date: {input.date2()}" + + @render.text + def selected_date3(): + return f"Selected date: {input.date3()}" + + @render.text + def selected_date4(): + return f"Selected date: {input.date4()}" + + @render.text + def selected_date5(): + return f"Selected date: {input.date5()}" + + @render.text + def selected_date6(): + return f"Selected date: {input.date6()}" + + @render.text + def selected_date7(): + return f"Selected date: {input.date7()}" + + @render.text + def selected_date8(): + return f"Selected date: {input.date8()}" + + @render.text + def selected_date9(): + return f"Selected date: {input.date9()}" + + @render.text + def selected_date10(): + return f"Selected date: {input.date10()}" + + +app = App(app_ui, server) diff --git a/components/inputs/date-selector/app-kitchensink-express.py b/components/inputs/date-selector/app-kitchensink-express.py new file mode 100644 index 00000000..c5a86d5d --- /dev/null +++ b/components/inputs/date-selector/app-kitchensink-express.py @@ -0,0 +1,114 @@ +from datetime import date + +from shiny.express import input, render, ui + +ui.page_opts(title="Date Input Parameters Demo", full_width=True) + +with ui.layout_column_wrap(width="300px"): + with ui.card(full_screen=False, height="auto"): + ui.card_header("Default date input") + # Basic date input + ui.input_date("date1", "", value="2024-01-01") + + @render.text + def selected_date1(): + return f"Selected date: {input.date1()}" + + with ui.card(full_screen=False, height="auto"): + ui.card_header("Date input with min/max") + # Date input with min and max dates + ui.input_date( + "date2", + "", + value=date(2024, 1, 1), + min="2024-01-01", + max="2024-12-31", + ) + + @render.text + def selected_date2(): + return f"Selected date: {input.date2()}" + + with ui.card(full_screen=False, height="auto"): + ui.card_header("Custom format (mm/dd/yy)") + # Date input with custom format + ui.input_date( + "date3", "", value="2024-01-01", format="mm/dd/yy" + ) + + @render.text + def selected_date3(): + return f"Selected date: {input.date3()}" + + with ui.card(full_screen=False, height="auto"): + ui.card_header("Start in decade view") + # Date input with decade view + ui.input_date("date4", "", value="2024-01-01", startview="decade") + + @render.text + def selected_date4(): + return f"Selected date: {input.date4()}" + + with ui.card(full_screen=False, height="auto"): + ui.card_header("Week starts on Monday") + # Date input with week starting on Monday + ui.input_date("date5", "", value="2024-01-01", weekstart=1) + + @render.text + def selected_date5(): + return f"Selected date: {input.date5()}" + + with ui.card(full_screen=False, height="auto"): + ui.card_header("German language") + # Date input with German language + ui.input_date("date6", "", value="2024-01-01", language="de") + + @render.text + def selected_date6(): + return f"Selected date: {input.date6()}" + + with ui.card(full_screen=False, height="auto"): + ui.card_header("Custom width") + # Date input with custom width + ui.input_date("date7", "", value="2024-01-01", width="400px") + + @render.text + def selected_date7(): + return f"Selected date: {input.date7()}" + + with ui.card(full_screen=False, height="auto"): + ui.card_header("Autoclose disabled") + # Date input with autoclose disabled + ui.input_date("date8", "", value="2024-01-01", autoclose=False) + + @render.text + def selected_date8(): + return f"Selected date: {input.date8()}" + + with ui.card(full_screen=False, height="auto"): + ui.card_header("Specific dates disabled") + # Date input with specific dates disabled + ui.input_date( + "date9", + "", + value="2024-01-01", + datesdisabled=["2024-01-15", "2024-01-16", "2024-01-17"], + ) + + @render.text + def selected_date9(): + return f"Selected date: {input.date9()}" + + with ui.card(full_screen=False, height="auto"): + ui.card_header("Weekends disabled") + # Date input with specific days of week disabled + ui.input_date( + "date10", + "", + value="2024-01-01", + daysofweekdisabled=[0, 6], # 0 = Sunday, 6 = Saturday + ) + + @render.text + def selected_date10(): + return f"Selected date: {input.date10()}" diff --git a/components/inputs/date-selector/index.qmd b/components/inputs/date-selector/index.qmd index f3935793..8e5713b1 100644 --- a/components/inputs/date-selector/index.qmd +++ b/components/inputs/date-selector/index.qmd @@ -27,6 +27,13 @@ listing: signature: ui.input_date(id, label, *, value=None, min=None, max=None, format='yyyy-mm-dd', startview='month', weekstart=0, language='en', width=None, autoclose=True, datesdisabled=None, daysofweekdisabled=None) +- id: kitchen-sink + template: ../../_partials/components-detail-kitchen-sink.ejs + contents: + - title: Date Selector + core: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAEygrIEt4nvVi6ZVuzgAdCOPqMmAZwAWnCNl4x+gpgEF0eJnUos4dHQFdO48WlQB9U0wC8TU1igBzOFZoAbUywAU4pkDHTmcIOE8rLjJPOH8wABERJgBJCFRjIQAFKDpYOAo6GSZ4uBhiUTAASjwAoKdPKGxiDKsSbxgIKwB3XNR-CCDBpgBiJgAhKBlOQmEKXjSMpjgAD1hUGNqh4IxCHL9NrbqQ3boWKzk4KAM6OJKaKGNPITY5xXSyCuqDw+23lpfYhUAQBGCo6CpgpgANyg3jgdgqACYAAyIgAsAFpkcCsaCqjUBj8jhhmmR3pEVmQ4jJwnBCBQziDPgSfl9CVtRolXgshF1OGQ5EwYIpuMZmFAICwhVBlqLmACmCQIDIyLlFGQZN9iSd9uyiU4dedLtdbkk-rz+YLhRAAPQwGXMrVbJzmqwA-pEw5AkSIsFOokQ-D+n4wuF2d0o9E6YHRtmerbWhFgSOY7G4v16+PS5ZJlMY4GIjEAZjxLPjcfjTlJ5IoyypFRpMXpcEZPsdmaCFY5xTNPKYfIFiuMKukCpoAntHw7gQNew9leOeyNV0McQAwsOyNJx3RJ0xfDAYDaWCwbdhsJV21mXTy3SJ51nAt6KEWM4+goGy+-Q8Z4UjUamOLYm+75MDuk5Joex6nueIGel2+ohNWLS1vWYCNnSDJ3i+V6HAhgycr27xMAK7BMMQqCUEUW6sHSK7QpwcBdP6s6nA+iE7EuFwrjcFQAMpkDkQiKLRuwGAxTG4Z6N7ku6z5wGikKftCsK-rmAG4um+CyIJghQoxXRJgYYliPiwbEshZAUnW1K0s2rYUIpZnTkw+FBIR3LEQOgpdHAcAANY6UJiguORAwALKkGw2AsYubHmTOcVnNxJoVAA6n5gUqkJRSkEwkWSo0Ukca6clgACACsSlgJCP5-smGlpsB2m+QF2WCHYwJuc6SEZDWlK2U2WGVcVgzdSMPaeYs3lMAA4oY9oDA0EAuMYrhwEwnjELsnicAAXuwnCkLFnHxS5gysclxqrhU827hKm0Sqt62jYcMn-Pe8kAGzVbVqn1XmTWlo9K1rW4RmmeNF29WSKEDQ2dnDSIP3OayX5DB5G3mv2lpDiOzB8iwAonTq7E-Jdy6pWAG74zjRNyK9PUYKVn3lSIADsv3aXV6noppzU6ITApJmiyLIqgyyM0MVZ9XDNkI0NLbYXAnOo3h6MEZNWN9l0Fx6IqsL6DkrDEHAMgQAA5EIDxbhihBbTSJNzgl2yGilN1gBoGTbQ7G0sJwMhQAARjELBS9DzO3mVAIABxczoPP-nzQOQjbPvEDSdgAGKwjSUMWbLVmoYNmFK7HUvjZj8xebjMiUYQnA0NMsxm6wAfB6HTtndeSWUx7fH143zcAkU-uByHLbh8SLMUGT8byQAnHBj6fi7gyJw1ydAaWa9BCPY8dy2djAEngH5lV2mn5pwIo+Cm9n8CqsALoa+rLsy7DRfw+hiNlyIS9qy2JXLW1dpq41av5fQwhsCj3bhPMOLlLpzyZm7a6vEwAZQCvoWB49O6AJKlHT650vRswoMCZEy8syr2IVsDegNt6UPjNFGQxAaAQIPvA4+yIdBfRfoEUYyJ7BMD4sYQq2AeFCL4uwYwpwio0Ncq-JmllrJoQwvZZW5CK6KLpsLCoRYxYS2XmyS8EhTEGBoLIQwUJVzmh0JZHQNIZBTFIJURABxRh8SsYYMCoj6RHWVLoUoUARK+LkE9SeeoAACehJSGAwKhA45jLGKwcnAYEvhXH+j0GQGRAwaD8V-lKAEiAmAgHNBgEEGSAC+EJTGDGifoOJCS9RJLUUjCgiIMluJctk3JYECkpJbiUspPIKk+mqbUg4DTYl0HiZSRJcALFtL-i+LpWT8h9PyWATxgzimlPKQCIsEyap1KCNM64cy6wLKWYU5WaI1k9I2XQPJAzS5FJEMMg5Ih7mVBqScqZMSLnNMGK025lUHk-F6c8-p2zClDP2aM8FvzJlRMBU0+ZLTFnJLecrL6ELDhQpebC3ZHyEXvDGRQPFyL-mosabM4Fe8sXLNSezfFWxCUwp2W8+FIzyUAlZdS8wtKZmXKnCCplYKRAxzZUMDlWyuX2R5V8ig0rBWnMCOc9FVzMU3JScrBeMrBhyteYqvZvKMgUrgAatVAK6Wiuudi9RIJkSGqCMa4l3KzXKrSS6m1pjLBCK0H0SwNhOAOK8XQExYAqlPyAA + express: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAEygrIEt4nvVi6ZVuzgAdCOPqMmAZwAWnCNgxwAHqjpwZM3jH6DeEVAFcyeJpogs4dc8c7jx9rFADmcAPrFUZGQAouMgAbOABeUTAAEREmAEkjUyYABSg6WDgKOh1IuBhiCPMaYyCgjwB3ThYyOVCAFTpjOABKRwgK6qZnIKhsYlMPEiDjGAhytNQ-CqqaiIBmAAZ51FUIpsRxJk2mdrlOzgxCVJY-IpKPGUJNSlCAMSggmThzOThOVzkycJRTfLA1ja2gOchzoLA8Lyg1jofgiORoUGKQjYFEMJjIqwBgM2AGImAAhKAyTiEYQoxRozFY5zk-rIuAwsB0gCMBSYEVZADd7o0vgAmea8gAsAFp5kzRSy-q0sVsAAKWKEYCiqdEQGWbaw0WRwEKEChg5l+f5q9WAzRkYx0NU0CIAZR1cD1cBYpLgiCYIBpZAwhqaAF92RITZsdnsDkcTsVShcrhBbvdHs9Xu9PhEEWRfsbTcCjuC4JCbAzomSEkJQzBFAB6GBQFZS4NY3HFuCoxLlxRMKBWJg11SumSUoH7L0eOkwhumiJ03kFQfq9n4OcyrlDMJj-lC8xMrdNPBLrEVuMRDcisUS2cT9W9vkCkVM3nC2aSveXzYtIOm+WURXK1WmzXarq+qjiIvJGusr5YualrWnaDpOi6dLup6pY+qBRoBmA0pbKGOagpGZwxnA1x3A8TxMC8bwfF86aZhB2b7CCYIQlCDIAMLGDIGbMDQAg1kIfgwDAlYsCwlbYNgLT1qaTYxF62ycB0hCcdxTC8XQ-H7tSpYgRQ46moCU4iLMrILuYK48set4Sue+BqXx7BfEJIliRJgamu++5flYNhKmof7qgBjxAc6ulwLM4H7maGQwWpcEhYhIjIV6aEUBF-qBpSuGMRGpzRpcxFxqRiYUcm1Fpj8qz0eqeHMfmrF2mQqRCB21iHNYTAcpwcBlBikGySWaIKR0bUFp13W9ZB2lomFDJ0oKplYXZFlhFZQo2WKrJcc1XU9V8o3WH1XkKr5v77kF8HAfNkWQdFFpWnFYD2glrrJah10ZVhH44Ypuy1QR+WxvGZFJlRqbfBmVVaTloJ5gW0IRAA6sRADWshNYIOikEwACypBsNgfUyUwzatmWv3bKj6PNYorhMNjeNWD00MYCOY5GRQACsi2ctyq1gCeG3PpTcAo9tgihEynmQd5P7+edcBasFjpXSInM3QZWzQQ9NpPZdzqvR6KV0urn3YSGFP-Xl5wFSRCbkZRKY0ZVfzVTKtVww1YAAOI2DWardBArjGG4YjSeqA0tvJoa+xpXZMIHwehyzbMiHNIgAGw88tfM3utZ6bXZich+4+1h9Ln4nXQfkqgrSv6wamca5rFgxTr8UqwbSFG+9Tdm99FsdFbUY20DxUO2V4O0VDU0w3V8PsSp0hTNURMRyTcmlsNuzKVxy+VKvs+szp7OMiIADs2fmbna2nuKhfmCvMxgIKizLEdMtVzXAUyhdCVhefZumttawT1i9buKE0SpTgIA-uWVLZzwBqPQqwMSqO3KhDOiLMmKe0LBEAAgj8QgQRiCPFYJwGQUAABGIQWBrxlJHMm29OxEJIWQlgFDqG0JTifNOHM4AAA4r6dRvgLayBdha0WIaQsI48K7qllqdeWkE-6d0bhQARQCDIgMes9NRhtIGmGgZouBDZsrhnwtbIidsQalTBs7SGrtsG5hYngp6qBHScBoMSfs5DKE0OdPQxsG9BptgpjIDxhAvE+LpDoDh-juFH1TnpKKWx+EAE4LwtzZEtF82SVp5zvrZPJLdYnxK4c6UIwBb42SZNzOyNSzxMizg0sR+dxRMkvmAAAuiUmU8iZSKOrmdFRitAJqLCukrRpodG6z0QhAxxsRBTNMYCcxTEkHWKKvbUGTsKqOKzDVOeuCEZgGRqLb8cTOEBLoeHBhISo5b1DBEzx3iSQEyxlqMoVNyk3J4TNdmt00lnwoEyeYWSW5mVSZsApjT77PmhcIbAMhiA0G+aLX5tCqnzHMBnXpOImDzCYKEJgtpjBM2wLi4lpL2CWgJvuAZWIhnfzruMhCYUwXTPVLMjuCyIFLNBfMDCgYwB+m6UAA + image: thumbnail.png --- :::{#example} diff --git a/components/inputs/date-selector/thumbnail.png b/components/inputs/date-selector/thumbnail.png new file mode 100644 index 00000000..b1397c43 Binary files /dev/null and b/components/inputs/date-selector/thumbnail.png differ diff --git a/components/inputs/numeric-input/app-kitchensink-core.py b/components/inputs/numeric-input/app-kitchensink-core.py new file mode 100644 index 00000000..060e2f11 --- /dev/null +++ b/components/inputs/numeric-input/app-kitchensink-core.py @@ -0,0 +1,59 @@ +from shiny import App, reactive, render, ui + +app_ui = ui.page_fluid( + ui.h2("Numeric Input Demo"), + ui.layout_column_wrap( + ui.card( + ui.card_header("Basic Numeric Input"), + ui.input_numeric(id="basic", label="Basic numeric input", value=10), + ui.output_text("basic_value"), + ), + ui.card( + ui.card_header("With Min/Max"), + ui.input_numeric( + id="with_min_max", + label="With min and max values", + value=5, + min=0, + max=10, + ), + ui.output_text("minmax_value"), + ), + ui.card( + ui.card_header("With Step Size"), + ui.input_numeric( + id="with_step", label="With step size", value=0, min=0, max=100, step=5 + ), + ui.output_text("step_value"), + ), + ui.card( + ui.card_header("With Custom Width"), + ui.input_numeric( + id="with_width", label="With custom width", value=42, width="200px" + ), + ui.output_text("width_value"), + ), + width=1 / 2, + ) +) + + +def server(input, output, session): + @render.text + def basic_value(): + return f"Current value: {input.basic()}" + + @render.text + def minmax_value(): + return f"Current value: {input.with_min_max()}" + + @render.text + def step_value(): + return f"Current value: {input.with_step()}" + + @render.text + def width_value(): + return f"Current value: {input.with_width()}" + + +app = App(app_ui, server) diff --git a/components/inputs/numeric-input/app-kitchensink-express.py b/components/inputs/numeric-input/app-kitchensink-express.py new file mode 100644 index 00000000..02c56fae --- /dev/null +++ b/components/inputs/numeric-input/app-kitchensink-express.py @@ -0,0 +1,46 @@ +from shiny import reactive +from shiny.express import input, ui, render + +# Set page title +ui.page_opts(full_width=True) + +ui.h2("Numeric Input Demo") + +with ui.layout_column_wrap(width=1 / 2): + with ui.card(): + ui.card_header("Basic Numeric Input") + ui.input_numeric(id="basic", label="Basic numeric input", value=10) + + @render.text + def basic_value(): + return f"Current value: {input.basic()}" + + with ui.card(): + ui.card_header("With Min/Max") + ui.input_numeric( + id="with_min_max", label="With min and max values", value=5, min=0, max=10 + ) + + @render.text + def minmax_value(): + return f"Current value: {input.with_min_max()}" + + with ui.card(): + ui.card_header("With Step Size") + ui.input_numeric( + id="with_step", label="With step size", value=0, min=0, max=100, step=5 + ) + + @render.text + def step_value(): + return f"Current value: {input.with_step()}" + + with ui.card(): + ui.card_header("With Custom Width") + ui.input_numeric( + id="with_width", label="With custom width", value=42, width="200px" + ) + + @render.text + def width_value(): + return f"Current value: {input.with_width()}" diff --git a/components/inputs/numeric-input/index.qmd b/components/inputs/numeric-input/index.qmd index a2ac7686..38559218 100644 --- a/components/inputs/numeric-input/index.qmd +++ b/components/inputs/numeric-input/index.qmd @@ -26,6 +26,13 @@ listing: href: https://shiny.posit.co/py/api/ui.input_numeric.html signature: ui.input_numeric(id, label, value, *, min=None, max=None, step=None, width=None) +- id: kitchen-sink + template: ../../_partials/components-detail-kitchen-sink.ejs + contents: + - title: Numeric Input + core: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbJjmVYnTJMAgujxM6cKITIcAbnAlSIAEzh0JAVw4AdCPrSoA+jqYBeJjqxQA5nGM0ANjtUAKfUy9WOGNgCYPMAA5LXg6DkImAEkIVC1hABE4GGJdMABKPE9vaycobGIE4xIXGAhjAHc6NA8IbwafDEIoOnccxsbrFrbjNml1OiCAISgWSKZQ8InY+LJ0rI7O3N8uOeMIMI1Itw5Vc3SAIzHI9Il8w7gnA7BR8ajN6ai1hLOmeSgXOHMARgAGRb1ZYNaxFMjrCgADzIQWO92MHy+C2yQM6gOB3Va7VRwKaPVUfQGGiCAHUOGQ2EwALJcAD0VKgkORSwxqzixUe20IdVxyz2N0q5LYxhgXBFjLOLN5TAuVxuZIpTFF9SgaiVjPeny0cBYkpx0s1X3MAFYUQaGsrzH8zeavDBGb9rVK0TbeaCEhC4NCgsr7ZCEVq4Mz9d50ctMW0edKIwT+lBBqShUwAMoUVApjgALyDmVduOsLzIGy2EW5ztx-PSgopxhYabesuu6QVlLrcHT42zb0R2qtEkt1vVkMdg7bqBN5YaYbdvjBnu96THAaRufL066vnxUZnzSxhPjxObSYAwlo64wmGTVBTgwaC+yi5zS9vzZWwNXhYLr2wG1BLk2wBbJhCDPMgLy-G98ENXsABZ-AkCC2Bufw-j+VAmTASdQzzVkMDnYooRhKs9hrHsc3XKccO8RDfiYWkmHgpYMn0ZiDDY9QaFYDRFCGQsJHwsgJBYHVxlIDJECWAABFRBgwQilg4pg4UiZdtTccTyykMgtDoeoaHSU86BUYQyMQJgQELDBlO5DIAF90n0KSZI0OSvXmHFFN9RlVLgdSJJDLwtJ0vSDJ04zoLgMyLIfDAPxFMU-XU+zMLYhppMoWT5I8uBOKXMi-M0uBtN0ph9LAQzwtM8zLLisckoc1LvHStQXKyhpFMQnyCoCyQiuC0rQqMygTMDKKaqFKoSLYeqUsc6B0AsUR0DcIxTA4ITuI0ViwFsgBdIA + express: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbJjmVYnTJM6cKITIcAbnAA6Eeo1aduGOAA9Uoli179BwrqgCuZPE2MdzoiABM4defIDETAMpxhqKAHM4TSTIAGzkISyxfOAB9YlQyFgAKGmMgoKiAdw5bMjYAXgAVOmM4AEonMI4MNgAmBNkwADljeDoOQiYASQgTYQAROBhierKIeUyci0qgqGxiUyiSIOaIDLo0BMzsvIBGJgB6JmqSxHkmM6ZxtkmMQig6WwTj0-OX8Nv7qLYxezo6sAAhKAsNpMJotEFdHrDZ4vM7hIzzMLgwgJLK5eoAIyBbXq5mmGLgQXRAOx7SRDhBCLIuKYUigSzguW2AAYRjDYQABGw-DAUdTUiCw872GhMLHAwhROkMx4nQVC2GiMjGOiCmj1ADCKpswmlxUQTBAVIw4rajwAvvVyi9Ltd3g8nvKhW87rZPt8HH8AOocCYAWS4ez9UHU0KdsPh3URzQpKPZCt4tmJlyiMC4qZDNPxhOJPomacFUDsTBgIdp9OKLBpesZAFZzAXcsyGyGmcz4+c2eGXlzKDy+QKEyKS1xS+opRW4LKO0KlSq1ZrtZRdZODUao2QMCmCxn1BaraNw7aXfdp93zie3V8oD9vb6rm4KKh3BwAF5yMAjBORnpRcmtONzyFNF6hTFgnyzKACSJeo8yucC4GfYF32rScmwbLh0JLVsWWbVgn1yWsZyYLsE17OwHF5DRBwVYcENQCcZUdBMXjnVUmHVMAtToHVywZNdjTAp99zAa1zmPSp7TPb9JNdd0b09WD7yYLVwKUH0tjDGSMCpP8YwAuogNhECwBTTYckg6Dc2UwhjDU5hzLYVCGVyAAWapzEc4lqmZZlUFDUSjNIhVyP7ajiOHRzGOKaSWLONiFy4pdyD4-VDUE+8MiyHIRPkMBzQAXSAA + image: thumbnail.png --- :::{#example} diff --git a/components/inputs/numeric-input/thumbnail.png b/components/inputs/numeric-input/thumbnail.png new file mode 100644 index 00000000..35c33fad Binary files /dev/null and b/components/inputs/numeric-input/thumbnail.png differ diff --git a/components/inputs/password-field/app-kitchensink-core.py b/components/inputs/password-field/app-kitchensink-core.py new file mode 100644 index 00000000..b18cb8db --- /dev/null +++ b/components/inputs/password-field/app-kitchensink-core.py @@ -0,0 +1,54 @@ +from shiny import App, render, ui + +# Define the UI +app_ui = ui.page_fluid( + # Card container + ui.card( + ui.card_header("Password Input Example"), + # Create password input + ui.input_password( + id="pwd", + label="Enter Password", + value="default123", + width="300px", + placeholder="Type your password here", + ), + # Checkbox to show/hide password + ui.input_checkbox( + id="show_password", + label="Show actual password", + value=False, + ), + # Output for password length + ui.output_text("password_length"), + # Output for masked password + ui.output_text("password_masked"), + ) +) + + +# Define the server +def server(input, output, session): + # Show current input length + @render.text + def password_length(): + pwd = input.pwd() + if not pwd: + return "No password entered" + return f"Password length: {len(pwd)} characters" + + # Show masked or actual password based on checkbox + @render.text + def password_masked(): + pwd = input.pwd() + if not pwd: + return "" + + if input.show_password(): + return f"Password: {pwd}" + else: + return f"Masked password: {'*' * len(pwd)}" + + +# Create and return the app +app = App(app_ui, server) diff --git a/components/inputs/password-field/app-kitchensink-express.py b/components/inputs/password-field/app-kitchensink-express.py new file mode 100644 index 00000000..a0287335 --- /dev/null +++ b/components/inputs/password-field/app-kitchensink-express.py @@ -0,0 +1,43 @@ +from shiny.express import input, render, ui + +# Set page title +ui.page_opts(full_width=True) + +with ui.card(): + ui.card_header("Password Input Example") + + # Create password input + ui.input_password( + id="pwd", + label="Enter Password", + value="default123", + width="300px", + placeholder="Type your password here", + ) + + # Checkbox to show/hide password + ui.input_checkbox( + id="show_password", + label="Show actual password", + value=False, + ) + + # Show current input length + @render.text + def password_length(): + pwd = input.pwd() + if not pwd: + return "No password entered" + return f"Password length: {len(pwd)} characters" + + # Show masked password + @render.text + def password_masked(): + pwd = input.pwd() + if not pwd: + return "" + + if input.show_password(): + return f"Password: {pwd}" + else: + return f"Masked password: {'*' * len(pwd)}" diff --git a/components/inputs/password-field/index.qmd b/components/inputs/password-field/index.qmd index 2e7b6aa9..39ac469e 100644 --- a/components/inputs/password-field/index.qmd +++ b/components/inputs/password-field/index.qmd @@ -25,6 +25,13 @@ listing: - title: ui.input_password href: https://shiny.posit.co/py/api/ui.input_password.html signature: ui.input_password(id, label, value='', *, width=None, placeholder=None) +- id: kitchen-sink + template: ../../_partials/components-detail-kitchen-sink.ejs + contents: + - title: Password Field + core: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbJjmVYnTJMAgujxM6lACZw6EgK4cAOhFUBiJgBE4NLnCZk2BgKoBJVWlQB9JUwC8TJVigBzONZoAbJdIAUqkxBTJoAwlB00kwk5FD6dIHBzoQR-onBSRwYKZHWxlCydAFgAApQLCwA7oJRZhCoCsIAogAesKhecMpgAJR46RkhTKFSUBRMqOVVNbz1jQMZzlwNZNaTFdWRARCDu7zS9t2oldLd-Tt7GV5QAEZwXodgTeRyTGUbNWcLewBuUD5wR6yGhQBReMgARgATABmL4XS5BSocaRGR4wgAMGNQLXhiOCHSghDgbGIXkKjwAKthUAZsMQFHQJlNNlFjFI8Xs+t8gmFjIQANY3YgtQzEVikyoAek4smZH0iPKcWWWjWshH5QpF23xQRRj3YxEqaxZn3wSqut3ujwAypKmESyAp-vLporzQjEX8AfYAGL-Fhwc6XbmejKaADyjRWTBogldrKYnQgriMSucDLIK2sFBaZGK6zd0msydTbG6ocukejjVj8Zg5QFcCihdZ6aymezufzR1NuQbLCbp16weCPVU47UU80Oj0EAMRgMgboPzkqmBrDkq6KqrIEk7jQkgYqHFIPUQA00dqN0UZUnIsxjpbTnoAAvfChhuwMN62aiXKDLPxzyVY4okcXcsBOYClQ4GgmAgYhhDAi8wz2KQnToHZugAOXFP9IiYSgKCkYclQwxkdhobp3iLJNAKMRAmBAZM-DAnoAF9ojYCJHTkFhulUS8mGvSomAHIcmHjR1nS8BMZhucpmyknYNTgQVhVxN8PzkL84DzH9dHk-tG2bYDUMuMCHEfRooP8SdLjghCkImE4LN1CisKYQSwCEtC9XgyDDWNAj7Pc-FPKomi+2kJiQDAjjBP8oivEDcLEUi2NugAWVMlsYrigByAAqQqmGK+iIDYk5OKSvywlGcYoAgKJMsXB10EsdBrLEVA-CsWwOCPLc5EnMAOIAXSAA + express: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbDOAD1R04LFkw4xUxOmTERUAVzJ4mQiABM4dZfI4AdCPoDETAMpwZqKAHM4TMhzIAbOPp1ZrcAPrFUZFgAoaeUdHTwB3DjUyNgBeABU6eTgASn19COimN0IoOjV-ZMR9JhKsjgwcvM82OCgNOn9dMAAFKBEwqTUmAEk5RSYAUT5YVGcm1IMIUqZjAGEhKAomS3bO2QUyYtK3Lg3PFZYOvMap6dLImKbUMLUmvC2zpkcoACM4R0uwAfJNJlbVvJ3B5nABuUEcSU+GhoUGCZAAjAAmADMQNOjwiUViTWRAAZcag+GjHiVRlBCHA2MRHPVPnFsKhbNhiPI6Ms2oc1jUhMTShNgXMaoQANYvYh8OzEVhUsIAek4GnZANu6LKGF2ik8hCFovFJxJYjUn3YxDC+w5R1u+GB02ebw+TRMMqY5LI8nBSs5gOtqumYIhcBiADFwSw4PdVfzVcYnaamIRWaoZBqZM4IFZosCAAKqeoYCh8Taq6Gey2eNMZtgFIq+0rXLoxdaKLA3Ao2840JgQYgWG41g3TIRuuhTJoAOSlB0tTEoFCEVvbJSHrKmNCa-y9XQr0UQTBAaf89eSAF942xcq7NCwmmlo6ZnTA2sK4F0p51s7nNPn+EXpiW31Uj4sM++SFIuyw3EwjYpi2oHgRwnbdr2aj9gOS7mCuTA3mAt4GghTZkBgJpmgBoGoWhy4jkwa4tBanS7iA9bHjetYlO8YbkQOlGrk0ACyT4vqW9F7gA5AAVCJTBiU8lCHjcJ4sWAx4ALpAA + image: thumbnail.png --- :::{#example} diff --git a/components/inputs/password-field/thumbnail.png b/components/inputs/password-field/thumbnail.png new file mode 100644 index 00000000..bb8f759c Binary files /dev/null and b/components/inputs/password-field/thumbnail.png differ diff --git a/components/inputs/radio-buttons/app-kitchensink-core.py b/components/inputs/radio-buttons/app-kitchensink-core.py new file mode 100644 index 00000000..54de3256 --- /dev/null +++ b/components/inputs/radio-buttons/app-kitchensink-core.py @@ -0,0 +1,36 @@ +from shiny import App, reactive, render, ui + +# Create sample choices with HTML content +choices = { + "choice1": ui.span("Choice 1", style="color: red;"), + "choice2": ui.span("Choice 2", style="color: blue;"), + "choice3": ui.span("Choice 3", style="color: green;"), +} + +# Define the UI +app_ui = ui.page_fluid( + ui.card( + ui.card_header("Radio Buttons Example"), + # Create radio buttons with all possible parameters + ui.input_radio_buttons( + id="radio_demo", # Required: unique identifier + label="Demo Radio Group", # Required: label text + choices=choices, # Required: choices as dict with HTML content + selected="choice1", # Optional: initial selected value + inline=True, # Optional: display buttons inline + ), + # Output for displaying selection + ui.output_text("selection"), + ) +) + + +# Define the server +def server(input, output, session): + @render.text + def selection(): + return f"You selected: {input.radio_demo()}" + + +# Create and return the app +app = App(app_ui, server) diff --git a/components/inputs/radio-buttons/app-kitchensink-express.py b/components/inputs/radio-buttons/app-kitchensink-express.py new file mode 100644 index 00000000..4b6fc7f0 --- /dev/null +++ b/components/inputs/radio-buttons/app-kitchensink-express.py @@ -0,0 +1,30 @@ +from shiny import reactive +from shiny.express import input, render, ui + +# Set page title +ui.page_opts(full_width=True) + +# Create sample choices with HTML content +choices = { + "choice1": ui.span("Choice 1", style="color: red;"), + "choice2": ui.span("Choice 2", style="color: blue;"), + "choice3": ui.span("Choice 3", style="color: green;"), +} + +# Create a card to contain the radio buttons and output +with ui.card(): + ui.card_header("Radio Buttons Example") + + # Create radio buttons with all possible parameters + ui.input_radio_buttons( + id="radio_demo", # Required: unique identifier + label="Demo Radio Group", # Required: label text + choices=choices, # Required: choices as dict with HTML content + selected="choice1", # Optional: initial selected value + inline=True, # Optional: display buttons inline + ) + + # Display the current selection + @render.text + def selection(): + return f"You selected: {input.radio_demo()}" diff --git a/components/inputs/radio-buttons/index.qmd b/components/inputs/radio-buttons/index.qmd index 7b3dec75..a0d5b4c4 100644 --- a/components/inputs/radio-buttons/index.qmd +++ b/components/inputs/radio-buttons/index.qmd @@ -26,6 +26,13 @@ listing: href: https://shiny.posit.co/py/api/ui.input_radio_buttons.html signature: ui.input_radio_buttons(id, label, choices, *, selected=None, inline=False, width=None) +- id: kitchen-sink + template: ../../_partials/components-detail-kitchen-sink.ejs + contents: + - title: Radio Buttons + core: https://shinylive.io/py/editor/#code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbJjmVYnTJMAgujxM6cKITIcAbnAlSIAEzh0JAVw4AdCPoDETAMJSoFVrFQAbOE0JtiHQnBZMA7hzJsmACQAVAFkAGQdSCnJ9R2dXdwBeJhB9JlSmXSInFzgARgzEJh0MFlQoCAAKDJMs1yY8-FYybDt4jJIbQQKpVQBuDIBKPBS0tpq4ACZ8wo5i0oqqsaZJhpYmlrbiDroCgCMbLTg+sEHh1NHYuABmKaKSssqwaouma5W1uFaiTc6mAHMpShHE4QAC++iMTAAInAaFx7D57ABVACS+jQqAA+jomIkiqVfnAMTR9hxVJUIGlphhCFA6GTTpSqTS6Ri2NJ1HQHgAlKCqDjEJgAIS0ZDIpHcAFEAB7WOwDIYUxmpYxmaSWOi8-lMHYisUQdxeHxMKA2GxMAQsFgcPb2Uoa+AUOgsBmUopcVAijEavnEDE60Xi8lKpWkz7e-kY9QwYgZCRMYxcuAARx03QKWggHBT9lJlDksI0LuDNigOzgNk+0OjTB5PqYAHEGFpULHlTXk6m4KoCiWy2aKFKyEWlTFsix4qO4nGEx2OGmHGN3FB3HzZJ5vL5AqFwuQ88PGSxy3BZF3PpPcq340wAPKoOSkE0FLjeDgm1hHk+qJjyE0HfeUrgbDheIAjoA5pxvO9+WgGwCj5EoSx4f09XcQC4X3YFgyva8RQ9YQaEEJh4NsKBsC4X53zsWRoP3IpiFwz0BzIB5Dyo+8DGOBVKX6fQeIMfjjGhWEIHhNl3zoRQ6H0dQaHEyTyndEUJHosg8IkQ9LWg-pEAZAABFQOQwJiGRkyjj3Y8ptP3KQyC0OgKRoDIAE16LMz8ChARSyAwcNfSjYhLLBMBwQE0xzEsMovxsuyKQRY10DRdAcVEdBynRLEOHUjRJL4sAQQAXSAA + express: https://shinylive.io/py/editor/#code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbJjmVYnTJM6cKITIcAbnAA6Eeo1aduGOAA9Uoli179BwrqgCuZPCMoATOHXPGO8+QGImAZTjDUUAOZwmksgAbOQh7LB84AH1iVDIWAAoaY0DAyIB3DksyNgBeABU6YzgASkcIFwBhUSgKVlhUYKZCNmIOQjhdDOymAAk8gFkAGSbSCnJ5Ztb23RymEHkmRaZZIha2uABGFcQmMJYvCHiVirX2pi38VjJsYJyVkkDBHdFLAG4V4rwFpfvTuAAmba7DgYfZQQ7HP5MQGXFjXW73YiPOg7ABGgSK7zAn2+i1+UzgAGYgXsDkcwCcCUxibD4XA7kQkU8mN5RJQsTiIABfMqVaq1KBNKB0Sz+YgjchQLj+Nh+OhQSwccWo0xkUi6cGi4imExkeRdNjAjCEYWWeLFRC4o0mkWRWUKmzkgBKCqVTAAQqr1UwAKLqerBD5lJZMPliWryxXKr0QTocbpQFJMAQ6DjovxeeXwCh0FhWsJGUyRSNKyIqshq2NHCAhkOZBkl4iRawwYgrcyhphOuAAR3sLx2xggHD7fkylEkNA4NitIcCUFRcECDIAInBW13XeKAOIMYyoduLFzdvscAdMeeLwL+DR6mu1xaTdYsHJP6Yd4+9-twSw7N8dJgoF0RUJCYA1egGYYSHICdZyWFglzgCQfwZf8Lg-JgAHlYiVaBAh2Lh4w4RNWEQ5DRSkRMijgxYuECLh6QKIoMOwyRSETHZFX2eceHLStdDohirVKCArRcFcOG4qAeGyPxCGMOhRHIUjggkXCrQAASU6w6AwCh1DvENrBoFSkLYw4LRoiwyAUmsaBWABNbVTPInYQELMgMEbZt12Ic0eTAeQwC5ABdIA + image: thumbnail.png --- :::{#example} diff --git a/components/inputs/radio-buttons/thumbnail-old.png b/components/inputs/radio-buttons/thumbnail-old.png new file mode 100644 index 00000000..c72b8ac3 Binary files /dev/null and b/components/inputs/radio-buttons/thumbnail-old.png differ diff --git a/components/inputs/radio-buttons/thumbnail.png b/components/inputs/radio-buttons/thumbnail.png new file mode 100644 index 00000000..f9df4987 Binary files /dev/null and b/components/inputs/radio-buttons/thumbnail.png differ diff --git a/components/inputs/select-multiple/app-kitchensink-core.py b/components/inputs/select-multiple/app-kitchensink-core.py new file mode 100644 index 00000000..2b33452a --- /dev/null +++ b/components/inputs/select-multiple/app-kitchensink-core.py @@ -0,0 +1,113 @@ +from shiny import App, render, ui + +# Sample data for different types of choices +simple_choices = ["A", "B", "C", "D"] +dict_choices = {"a": "Option A", "b": "Option B", "c": "Option C"} +grouped_choices = { + "Group 1": {"g1a": "Group 1 - A", "g1b": "Group 1 - B"}, + "Group 2": {"g2a": "Group 2 - A", "g2b": "Group 2 - B"}, +} + +app_ui = ui.page_fluid( + ui.layout_column_wrap( + # Basic select with simple choices + ui.card( + ui.card_header("Basic Select"), + ui.input_select( + id="select1", + label="Basic select (simple list)", + choices=simple_choices, + selected="A", + ), + ui.output_text("selected_value1"), + ), + # Select with dictionary choices + ui.card( + ui.card_header("Dictionary Choices"), + ui.input_select( + id="select2", + label="Select with dictionary choices", + choices=dict_choices, + selected="a", + ), + ui.output_text("selected_value2"), + ), + # Select with grouped choices + ui.card( + ui.card_header("Grouped Choices"), + ui.input_select( + id="select3", + label="Select with grouped choices", + choices=grouped_choices, + selected="g1a", + ), + ui.output_text("selected_value3"), + ), + # Multiple select + ui.card( + ui.card_header("Multiple Select"), + ui.input_select( + id="select4", + label="Multiple select", + choices=simple_choices, + selected=["A", "B"], + multiple=True, + ), + ui.output_text("selected_value4"), + ), + # Select with custom width + ui.card( + ui.card_header("Custom Width"), + ui.input_select( + id="select5", + label="Select with custom width", + choices=simple_choices, + width="200px", + ), + ui.output_text("selected_value5"), + ), + # Select with size parameter + ui.card( + ui.card_header("Box Style"), + ui.input_select( + id="select6", + label="Select with size parameter", + choices=simple_choices, + size="4", # Shows 4 items at once + ), + ui.output_text("selected_value6"), + ), + width="300px", + heights_equal="row" + ), +) + + +def server(input, output, session): + + @render.text + def selected_value1(): + return f"Selected: {input.select1()}" + + @render.text + def selected_value2(): + return f"Selected: {input.select2()}" + + @render.text + def selected_value3(): + return f"Selected: {input.select3()}" + + @render.text + def selected_value4(): + return f"Selected: {input.select4()}" + + @render.text + def selected_value5(): + return f"Selected: {input.select5()}" + + @render.text + def selected_value6(): + return f"Selected: {input.select6()}" + + +app = App(app_ui, server) diff --git a/components/inputs/select-multiple/app-kitchensink-express.py b/components/inputs/select-multiple/app-kitchensink-express.py new file mode 100644 index 00000000..bfcd90b5 --- /dev/null +++ b/components/inputs/select-multiple/app-kitchensink-express.py @@ -0,0 +1,98 @@ +from shiny.express import input, render, ui + +# Sample data for different types of choices +simple_choices = ["A", "B", "C", "D"] +dict_choices = {"a": "Option A", "b": "Option B", "c": "Option C"} +grouped_choices = { + "Group 1": {"g1a": "Group 1 - A", "g1b": "Group 1 - B"}, + "Group 2": {"g2a": "Group 2 - A", "g2b": "Group 2 - B"}, +} + +# Page options +ui.page_opts(full_width=True) + +with ui.layout_column_wrap(width="300px", heights_equal=True): + # Basic select with simple choices + with ui.card(): + ui.card_header("Basic Select") + ui.input_select( + id="select1", + label="Basic select (simple list)", + choices=simple_choices, + selected="A", + ) + + @render.text + def selected_value1(): + return f"Selected: {input.select1()}" + + # Select with dictionary choices + with ui.card(): + ui.card_header("Dictionary Choices") + ui.input_select( + id="select2", + label="Select with dictionary choices", + choices=dict_choices, + selected="a", + ) + + @render.text + def selected_value2(): + return f"Selected: {input.select2()}" + + # Select with grouped choices + with ui.card(): + ui.card_header("Grouped Choices") + ui.input_select( + id="select3", + label="Select with grouped choices", + choices=grouped_choices, + selected="g1a", + ) + + @render.text + def selected_value3(): + return f"Selected: {input.select3()}" + + # Multiple select + with ui.card(): + ui.card_header("Multiple Select") + ui.input_select( + id="select4", + label="Multiple select", + choices=simple_choices, + selected=["A", "B"], + multiple=True, + ) + + @render.text + def selected_value4(): + return f"Selected: {input.select4()}" + + # Select with custom width + with ui.card(): + ui.card_header("Custom Width") + ui.input_select( + id="select5", + label="Select with custom width", + choices=simple_choices, + width="200px", + ) + + @render.text + def selected_value5(): + return f"Selected: {input.select5()}" + + # Select with size parameter + with ui.card(): + ui.card_header("Box Style") + ui.input_select( + id="select6", + label="Select with size parameter", + choices=simple_choices, + size="4", # Shows 4 items at once + ) + + @render.text + def selected_value6(): + return f"Selected: {input.select6()}" diff --git a/components/inputs/select-multiple/index.qmd b/components/inputs/select-multiple/index.qmd index 42f75037..cdfb3cca 100644 --- a/components/inputs/select-multiple/index.qmd +++ b/components/inputs/select-multiple/index.qmd @@ -44,6 +44,13 @@ listing: - title: Core file: app-variation-select-list-with-grouped-choices-core.py shinylive: https://shinylive.io/py/editor/#code=NobwRAdghgtgpmAXAAjFADugdOgnmAGlQGMB7CAFzkqVQDMAnUmZAZwAsBLCXZTmdKQYVkAQUxEG1ACZwGRAK6cAOhFUZ0AfSXIAvMiU4oAczia6AGyXSAFKuQODnLN3QKKm1nAtxiFGw4AxMgAPCH2jpHKYF4+ftFEyMFhEZEO0QDK3r4ipOgUnOSsyABG3qQA7ogJQaHhEGmOINEAjKLRKNEAwuyknMRwyG01rQBCHcjdvf2DLeOEk2AtXRNTfQNDK2AAvonJ9Y0OMAoWBeg+ugAqDApwe3WpyACU9ykNjoak7m4eVAAe-miADcoFY4NEXqonqoYRBZHQ2HIgXIbK53EQvhQfkQvKxWIUIE9qu8HAABKRwuRYf4UR7w5AgsE2ImPSJSCgKBgNOjREBoihYWI5ZnbaKw9SYPRiTA2DTaTg4pFyaEQBZgCi4dAIFDquAAnYAXSAA +- id: kitchen-sink + template: ../../_partials/components-detail-kitchen-sink.ejs + contents: + - title: Select + core: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbJjmVYnTJMAgujxM6lACZw6EgK4cAOhFUBiJgGVYqADZwm0qGShMagoxxo05lYWWyo4LJsRpNCbYh0IvVLHz6cAD6Xj5+rgC8TMDKYCLxEvEAQklM8QDC6fEAIvEAuqrSvmRh3r4uTDEg8VDxiBlgAPKoZBykojlgAEYNTa3tnWn4TYT98YMdEEzZYAC+qgDmDArO0uURVTWqTHtNAOKrqEwAjP21YEun9UiHx2dMALRdo-HXfXfxR8Rrjy8jeZ4Xb7b4PABMF3e4NujTBvxO4Oer2SV3BnzhYB+fyRAPiQNUizU0HQISU1SYSiwUCWoRoeiU0gAFCC9lS9FBsL8yiQGTAICEAO50NAsmb7CWaFJQQKEVhwAyEYSCjhkNisIIGTwVSKsiWUjgYQhQOjMvX6-ZU42mkJsOBQWR0FlgaWy7QKuBK+IASmB4otEqpXFQCjKLA9SrFAejvGkUXi4cVZHO+HNMb2HJ6CvjLplvnlSaYTMC-C1eg4LDI3qSafT4UqLCiJeCmwbfvTFsTnoocfiiVT-pjvtr+qp3JDZQoAA8yM6u0q4BsAG5QBlwFPDwcSzfRzRaCPK1XqkpK6Ymnj13Vby2G61m68Wq0mjZ2h1yZ25Upnug8TI6-xgDuHZBhAE4hPOs4jtGHC9mAEGQgOHb6pm2bxPuhYqmqVinqQ57alsLA1g+MaXi4UQnjy-4sO2SH7BBi45rcNHpkB6ZjqGYHTpBcEHouIQrmuCGsfqwmSu6GFHkwKwIou+ENiOT6mlGwG3s+tr2o6zrYussxUT6zExiBYEQcptGxjmEEAMxEWZGZQFmeg5uh3ZMJh6rSWssmkYRiG2d5UQeesraRAZSH0bB1xMVB+yiQG7FkJxcAznOvHLquChwNZgGhTFOV7JoACyCh6O0wQFt2CmqUp0VslVL4ae+8RFSVHBlc5XrZTVBoYMGobgQepm0TBFkHgALDZtkoY5TXFaVWoQRNZn+c2BjBS4eUxuFURxAk3QjAUG3RjAs2tQYUQACp0Blh25V18WJclCapfx6VwONnXEbF+XiS5bmeAolaMK5MFqpVRrPoN0aKfVb5OlkANkEDADqINsPpd2Gr1YYDV1ErDU9SYAKyLbRU1OQewNYYQCNAyq0ig75S1UU2mqhN5N0WnTao5uCAAMvOoFOJPRl9o6GuOfVcSlSZ8QJGXEx9IsbXuFN-YEABehioCasBwBQdBg3ekNxXV6mw86KTEFO2iOAY6PEYGmOgX1Jm4-s+M8UmABswsdmTaGq5JGtazr8D677dbMytbNURz+rBzm70SEwe7eIKrijbwFAwK4JhuBAfhdaLjsYBLk5Jdx4UvWuPuKwGotc2wOaWfzgsR0wdocEsbBkCwIRwAAjgoq45gwgrxHqm7VsSxRwB44Z0Eu75YxIZcSOGLCBKQ3qIKoeoAAJSBAjoYFxeqyPPz1y+uTI7yOUhkAodAzDQAcy9IjQgFjGAQact+LGAPeg5D4yDkKfCu5857lQXGlQSt9d7EQfk-F+b9uyLk-t-eC-8J7EglCA4+YCz6DgvtAns1cMqWXgffPWyDzCoJgRg52ZAf4Hkod6ABQC8FHxPkQiUJCq7X1GlQxBNDn50LAO1HsjCJwsKTEI9hOCD7cMIRA4hUCBGvUJsI6MSCxGvwkalaRoZZHdi0QowBuD9j4J4aovh6ir6vS9togMuiUEGPfkY5hEEnHmKAaoNAJwYhiFQEyAJZIODrzkEvOg08FgFCAA + express: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbDOAD1R04LFkw4xUxOmTERUAVzJ4mQiABM4dZfI4AdCPoDETAMqxUAGzhM1UMlCY0pNjjRqbKMstlTCmxGiZCNmIOQmF9FnFLOAB9YNDw0QBeJmBdMABBDOUMgCEcpgyAYUKMgBEMgF19NTCyeJCwv1SQDKgMxCKwAHlUMg5SJmz8boAjTu6+gaGC0YzCSYzpwYgmUrAAX30AcwZ5XzVGxJamNrWmS4yAcX3UJgBGSbawHYeOpG7b4gPHpgBaYZlV4PCafG53P6AuabPD6S5XMDfX4AJmeGR2KI+XQhP3uKIBQPmrxRYJxSMhBOhGVh+m2BggxgAClAdtZiP1Vix9DosKy4hyyCwABQ0eQWCyxADuHDUZDYyQAKnR5HAAJT6fQy+VMXkWKDYH4NEgWeQwCDSuhoYUyuUKjIAZgADE7UHxCmw4BwdmwhbE4ABHeRQCxKlXqxDwhHGPJQKKEVhwKyEGTatisaJWIJNJJRy5p3UcDCEKB0NTCtWRi4IhG8ktl2KeqAaOjC-JxsKmJNwFMZDXVmuFjBcBQNFjdlNtgeDhGy5IZcfJshPfB5mcI-VjJPzsCx+OJpdMYVRCRZiwcFhkDWr6frhLNFjJE8xY4PuG3meLnsUNQ7kbv9cmH7NcawAAVUFsMAoPgyBAhENECL8UzgI4ADcQ1VB4KyrQCayEMh5DoNYaAyEwJx-LoQBHRQMCQ5cK22MBNQHYwyMPAs6hTVZS2wbMTm5AcCzrUty0rODLmEhsmxbNswHKepuLoXjihzCIwH7QDeWosdyKnXDZ1-BdyLRG99MuTdt1I8imA4hTSB4viHxycTB3vJJkk441VJYACzLolCdw+XyZ2Aj8mHAyhIOg2CwoQg9vxQ2J0NNOAUWwly8LgAiiMcKylxQyjtNo4yGIyZia1Y6yCz2PEUMc3NBI4HVJNEnD1xaxs4GbTRZORQ51m8vsXK0uRFFiOi9LMucjKXB1nLCmsLNDPLvxspr0xqg46rctTgtwnbH02w5XySPbAP8wyQSClzQsAiL1E0KD+BiwC4oupKMLgB10oWhF8MI4iVuQtRCtGshitm0qmIZCqmAAWXFAYYni3tGuaot61a4aMZEzrutbDIEYsJGszY78hrCkbR3G3SMoMnc6IAFnmsymCWnciZJ6w6JZsyDqfTM4gOs71wu5J0iyYE5iqEWZxgRGOBiMNVVloDyvXe6ouely3vIxLktVRmftZ-6cpIsAyeB0HRwh78jbVRj1cuSr2PWoJ5EvRg1rtNchJxstjfa-2jmknqSg9sgvYAdVleUKc0ottJppdJv06awDogBWXn9PZoHUzdwgI692049MvnvIF08he81Wa1L+0wBRF03Rzwdbo1iDHuinW4EQvW0M+zPA-003AYtgfrZorOoadpgXdWgsogAL2sVBS1gLLNF9t2WpHwcOtDgnd2IPhTG8Kx46D4cweT79U9w9O6IANjbwC84n12dRXteN-gCg6BvzvJXZ8VgTrCDrgiH+O5majHnqYEIUpRCMzEBQGAog7D+AgOEG6c8wJdzoE9GCvd+75UHilZ++9AJj1yp-BKIMzhFRfrPCAWwqhAA + image: thumbnail.png --- :::{#example} diff --git a/components/inputs/select-multiple/thumbnail.png b/components/inputs/select-multiple/thumbnail.png new file mode 100644 index 00000000..02cea77c Binary files /dev/null and b/components/inputs/select-multiple/thumbnail.png differ diff --git a/components/inputs/select-single/app-kitchensink-core.py b/components/inputs/select-single/app-kitchensink-core.py new file mode 100644 index 00000000..2b33452a --- /dev/null +++ b/components/inputs/select-single/app-kitchensink-core.py @@ -0,0 +1,113 @@ +from shiny import App, render, ui + +# Sample data for different types of choices +simple_choices = ["A", "B", "C", "D"] +dict_choices = {"a": "Option A", "b": "Option B", "c": "Option C"} +grouped_choices = { + "Group 1": {"g1a": "Group 1 - A", "g1b": "Group 1 - B"}, + "Group 2": {"g2a": "Group 2 - A", "g2b": "Group 2 - B"}, +} + +app_ui = ui.page_fluid( + ui.layout_column_wrap( + # Basic select with simple choices + ui.card( + ui.card_header("Basic Select"), + ui.input_select( + id="select1", + label="Basic select (simple list)", + choices=simple_choices, + selected="A", + ), + ui.output_text("selected_value1"), + ), + # Select with dictionary choices + ui.card( + ui.card_header("Dictionary Choices"), + ui.input_select( + id="select2", + label="Select with dictionary choices", + choices=dict_choices, + selected="a", + ), + ui.output_text("selected_value2"), + ), + # Select with grouped choices + ui.card( + ui.card_header("Grouped Choices"), + ui.input_select( + id="select3", + label="Select with grouped choices", + choices=grouped_choices, + selected="g1a", + ), + ui.output_text("selected_value3"), + ), + # Multiple select + ui.card( + ui.card_header("Multiple Select"), + ui.input_select( + id="select4", + label="Multiple select", + choices=simple_choices, + selected=["A", "B"], + multiple=True, + ), + ui.output_text("selected_value4"), + ), + # Select with custom width + ui.card( + ui.card_header("Custom Width"), + ui.input_select( + id="select5", + label="Select with custom width", + choices=simple_choices, + width="200px", + ), + ui.output_text("selected_value5"), + ), + # Select with size parameter + ui.card( + ui.card_header("Box Style"), + ui.input_select( + id="select6", + label="Select with size parameter", + choices=simple_choices, + size="4", # Shows 4 items at once + ), + ui.output_text("selected_value6"), + ), + width="300px", + heights_equal="row" + ), +) + + +def server(input, output, session): + + @render.text + def selected_value1(): + return f"Selected: {input.select1()}" + + @render.text + def selected_value2(): + return f"Selected: {input.select2()}" + + @render.text + def selected_value3(): + return f"Selected: {input.select3()}" + + @render.text + def selected_value4(): + return f"Selected: {input.select4()}" + + @render.text + def selected_value5(): + return f"Selected: {input.select5()}" + + @render.text + def selected_value6(): + return f"Selected: {input.select6()}" + + +app = App(app_ui, server) diff --git a/components/inputs/select-single/app-kitchensink-express.py b/components/inputs/select-single/app-kitchensink-express.py new file mode 100644 index 00000000..bfcd90b5 --- /dev/null +++ b/components/inputs/select-single/app-kitchensink-express.py @@ -0,0 +1,98 @@ +from shiny.express import input, render, ui + +# Sample data for different types of choices +simple_choices = ["A", "B", "C", "D"] +dict_choices = {"a": "Option A", "b": "Option B", "c": "Option C"} +grouped_choices = { + "Group 1": {"g1a": "Group 1 - A", "g1b": "Group 1 - B"}, + "Group 2": {"g2a": "Group 2 - A", "g2b": "Group 2 - B"}, +} + +# Page options +ui.page_opts(full_width=True) + +with ui.layout_column_wrap(width="300px", heights_equal=True): + # Basic select with simple choices + with ui.card(): + ui.card_header("Basic Select") + ui.input_select( + id="select1", + label="Basic select (simple list)", + choices=simple_choices, + selected="A", + ) + + @render.text + def selected_value1(): + return f"Selected: {input.select1()}" + + # Select with dictionary choices + with ui.card(): + ui.card_header("Dictionary Choices") + ui.input_select( + id="select2", + label="Select with dictionary choices", + choices=dict_choices, + selected="a", + ) + + @render.text + def selected_value2(): + return f"Selected: {input.select2()}" + + # Select with grouped choices + with ui.card(): + ui.card_header("Grouped Choices") + ui.input_select( + id="select3", + label="Select with grouped choices", + choices=grouped_choices, + selected="g1a", + ) + + @render.text + def selected_value3(): + return f"Selected: {input.select3()}" + + # Multiple select + with ui.card(): + ui.card_header("Multiple Select") + ui.input_select( + id="select4", + label="Multiple select", + choices=simple_choices, + selected=["A", "B"], + multiple=True, + ) + + @render.text + def selected_value4(): + return f"Selected: {input.select4()}" + + # Select with custom width + with ui.card(): + ui.card_header("Custom Width") + ui.input_select( + id="select5", + label="Select with custom width", + choices=simple_choices, + width="200px", + ) + + @render.text + def selected_value5(): + return f"Selected: {input.select5()}" + + # Select with size parameter + with ui.card(): + ui.card_header("Box Style") + ui.input_select( + id="select6", + label="Select with size parameter", + choices=simple_choices, + size="4", # Shows 4 items at once + ) + + @render.text + def selected_value6(): + return f"Selected: {input.select6()}" diff --git a/components/inputs/select-single/index.qmd b/components/inputs/select-single/index.qmd index e8c9ab66..eddffb3a 100644 --- a/components/inputs/select-single/index.qmd +++ b/components/inputs/select-single/index.qmd @@ -42,6 +42,13 @@ listing: - title: Core file: app-variation-select-list-with-grouped-choices-core.py shinylive: https://shinylive.io/py/editor/#code=NobwRAdghgtgpmAXAAjFADugdOgnmAGlQGMB7CAFzkqVQDMAnUmZAZwAsBLCXZTmdKQYVkAQUxEG1ACZwGRAK6cAOhFUZ0AfSXIAvMiU4oAczia6AGyXSAFKuQODnLN3QKKm1nAtxiFOxCOQcjKYF4+fqEE9sEOoQDK3r4iUIGk6BSc5MgARt6kAO6IUTGxIKWxjqEAjKEo5WDVonUhYADC7KScxHDITVGt1QBCLaEdXT19I4SDbaPtnd291XNgAL7RgZVBoQBMLQ27zbRji5NHA3vTKKcTvbvTRHurNwt3yLurGxVB31sOAEpNkFDKR3G4PFQAB7+UIANygVjgoSBqgBqgxEFkdDYcjhchsrncRDBFAhRC8rFYWQgAOK-2QAAEpFi5FhoRQKtjkAikTY6T9HFIKAoGIE6KEQESKFhwsl+WtQpj1Jg9GJMDYNNpOBS8XJ0RAZmAKLh0AgUMa4DD1gBdIA +- id: kitchen-sink + template: ../../_partials/components-detail-kitchen-sink.ejs + contents: + - title: Select + core: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbJjmVYnTJMAgujxM6lACZw6EgK4cAOhFUBiJgGVYqADZwm0qGShMagoxxo05lYWWyo4LJsRpNCbYh0IvVLHz6cAD6Xj5+rgC8TMDKYCLxEvEAQklM8QDC6fEAIvEAuqrSvmRh3r4uTDEg8VDxiBlgAPKoZBykojlgAEYNTa3tnWn4TYT98YMdEEzZYAC+qgDmDArO0uURVTWqTHtNAOKrqEwAjP21YEun9UiHx2dMALRdo-HXfXfxR8Rrjy8jeZ4Xb7b4PABMF3e4NujTBvxO4Oer2SV3BnzhYB+fyRAPiQNUizU0HQISU1SYSiwUCWoRoeiU0gAFCC9lS9FBsL8yiQGTAICEAO50NAsmb7CWaFJQQKEVhwAyEYSCjhkNisIIGTwVSKsiWUjgYQhQOjMvX6-ZU42mkJsOBQWR0FlgaWy7QKuBK+IASmB4otEqpXFQCjKLA9SrFAejvGkUXi4cVZHO+HNMb2HJ6CvjLplvnlSaYTMC-C1eg4LDI3qSafT4UqLCiJeCmwbfvTFsTnoocfiiVT-pjvtr+qp3JDZQoAA8yM6u0q4BsAG5QBlwFPDwcSzfRzRaCPK1XqkpK6Ymnj13Vby2G61m68Wq0mjZ2h1yZ25Upnug8TI6-xgDuHZBhAE4hPOs4jtGHC9mAEGQgOHb6pm2bxPuhYqmqVinqQ57alsLA1g+MaXi4UQnjy-4sO2SH7BBi45rcNHpkB6ZjqGYHTpBcEHouIQrmuCGsfqwmSu6GFHkwKwIou+ENiOT6mlGwG3s+tr2o6zrYussxUT6zExiBYEQcptGxjmEEAMxEWZGZQFmeg5uh3ZMJh6rSWssmkYRiG2d5UQeesraRAZSH0bB1xMVB+yiQG7FkJxcAznOvHLquChwNZgGhTFOV7JoACyCh6O0wQFt2CmqUp0VslVL4ae+8RFSVHBlc5XrZTVBoYMGobgQepm0TBFkHgALDZtkoY5TXFaVWoQRNZn+c2BjBS4eUxuFURxAk3QjAUG3RjAs2tQYUQACp0Blh25V18WJclCapfx6VwONnXEbF+XiS5bmeAolaMK5MFqpVRrPoN0aKfVb5OlkANkEDADqINsPpd2Gr1YYDV1ErDU9SYAKyLbRU1OQewNYYQCNAyq0ig75S1UU2mqhN5N0WnTao5uCAAMvOoFOJPRl9o6GuOfVcSlSZ8QJGXEx9IsbXuFN-YEABehioCasBwBQdBg3ekNxXV6mw86KTEFO2iOAY6PEYGmOgX1Jm4-s+M8UmABswsdmTaGq5JGtazr8D677dbMytbNURz+rBzm70SEwe7eIKrijbwFAwK4JhuBAfhdaLjsYBLk5Jdx4UvWuPuKwGotc2wOaWfzgsR0wdocEsbBkCwIRwAAjgoq45gwgrxHqm7VsSxRwB44Z0Eu75YxIZcSOGLCBKQ3qIKoeoAAJSBAjoYFxeqyPPz1y+uTI7yOUhkAodAzDQAcy9IjQgFjGAQact+LGAPeg5D4yDkKfCu5857lQXGlQSt9d7EQfk-F+b9uyLk-t-eC-8J7EglCA4+YCz6DgvtAns1cMqWXgffPWyDzCoJgRg52ZAf4Hkod6ABQC8FHxPkQiUJCq7X1GlQxBNDn50LAO1HsjCJwsKTEI9hOCD7cMIRA4hUCBGvUJsI6MSCxGvwkalaRoZZHdi0QowBuD9j4J4aovh6ir6vS9togMuiUEGPfkY5hEEnHmKAaoNAJwYhiFQEyAJZIODrzkEvOg08FgFCAA + express: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbDOAD1R04LFkw4xUxOmTERUAVzJ4mQiABM4dZfI4AdCPoDETAMqxUAGzhM1UMlCY0pNjjRqbKMstlTCmxGiZCNmIOQmF9FnFLOAB9YNDw0QBeJmBdMABBDOUMgCEcpgyAYUKMgBEMgF19NTCyeJCwv1SQDKgMxCKwAHlUMg5SJmz8boAjTu6+gaGC0YzCSYzpwYgmUrAAX30AcwZ5XzVGxJamNrWmS4yAcX3UJgBGSbawHYeOpG7b4gPHpgBaYZlV4PCafG53P6AuabPD6S5XMDfX4AJmeGR2KI+XQhP3uKIBQPmrxRYJxSMhBOhGVh+m2BggxgAClAdtZiP1Vix9DosKy4hyyCwABQ0eQWCyxADuHDUZDYyQAKnR5HAAJT6fQy+VMXkWKDYH4NEgWeQwCDSuhoYUyuUKjIAZgADE7UHxCmw4BwdmwhbE4ABHeRQCxKlXqxDwhHGPJQKKEVhwKyEGTatisaJWIJNJJRy5p3UcDCEKB0NTCtWRi4IhG8ktl2KeqAaOjC-JxsKmJNwFMZDXVmuFjBcBQNFjdlNtgeDhGy5IZcfJshPfB5mcI-VjJPzsCx+OJpdMYVRCRZiwcFhkDWr6frhLNFjJE8xY4PuG3meLnsUNQ7kbv9cmH7NcawAAVUFsMAoPgyBAhENECL8UzgI4ADcQ1VB4KyrQCayEMh5DoNYaAyEwJx-LoQBHRQMCQ5cK22MBNQHYwyMPAs6hTVZS2wbMTm5AcCzrUty0rODLmEhsmxbNswHKepuLoXjihzCIwH7QDeWosdyKnXDZ1-BdyLRG99MuTdt1I8imA4hTSB4viHxycTB3vJJkk441VJYACzLolCdw+XyZ2Aj8mHAyhIOg2CwoQg9vxQ2J0NNOAUWwly8LgAiiMcKylxQyjtNo4yGIyZia1Y6yCz2PEUMc3NBI4HVJNEnD1xaxs4GbTRZORQ51m8vsXK0uRFFiOi9LMucjKXB1nLCmsLNDPLvxspr0xqg46rctTgtwnbH02w5XySPbAP8wyQSClzQsAiL1E0KD+BiwC4oupKMLgB10oWhF8MI4iVuQtRCtGshitm0qmIZCqmAAWXFAYYni3tGuaot61a4aMZEzrutbDIEYsJGszY78hrCkbR3G3SMoMnc6IAFnmsymCWnciZJ6w6JZsyDqfTM4gOs71wu5J0iyYE5iqEWZxgRGOBiMNVVloDyvXe6ouely3vIxLktVRmftZ-6cpIsAyeB0HRwh78jbVRj1cuSr2PWoJ5EvRg1rtNchJxstjfa-2jmknqSg9sgvYAdVleUKc0ottJppdJv06awDogBWXn9PZoHUzdwgI692049MvnvIF08he81Wa1L+0wBRF03Rzwdbo1iDHuinW4EQvW0M+zPA-003AYtgfrZorOoadpgXdWgsogAL2sVBS1gLLNF9t2WpHwcOtDgnd2IPhTG8Kx46D4cweT79U9w9O6IANjbwC84n12dRXteN-gCg6BvzvJXZ8VgTrCDrgiH+O5majHnqYEIUpRCMzEBQGAog7D+AgOEG6c8wJdzoE9GCvd+75UHilZ++9AJj1yp-BKIMzhFRfrPCAWwqhAA + image: thumbnail.png --- :::{#example} diff --git a/components/inputs/select-single/thumbnail-old.png b/components/inputs/select-single/thumbnail-old.png new file mode 100644 index 00000000..54740151 Binary files /dev/null and b/components/inputs/select-single/thumbnail-old.png differ diff --git a/components/inputs/select-single/thumbnail.png b/components/inputs/select-single/thumbnail.png new file mode 100644 index 00000000..02cea77c Binary files /dev/null and b/components/inputs/select-single/thumbnail.png differ diff --git a/components/inputs/selectize-multiple/app-kitchensink-core.py b/components/inputs/selectize-multiple/app-kitchensink-core.py new file mode 100644 index 00000000..afa09b95 --- /dev/null +++ b/components/inputs/selectize-multiple/app-kitchensink-core.py @@ -0,0 +1,42 @@ +from shiny import App, reactive, render, ui + +# Sample data for states +states = { + "East Coast": {"NY": "New York", "NJ": "New Jersey", "CT": "Connecticut"}, + "West Coast": {"WA": "Washington", "OR": "Oregon", "CA": "California"}, + "Midwest": {"MN": "Minnesota", "WI": "Wisconsin", "IA": "Iowa"}, +} + +app_ui = ui.page_fluid( + ui.h2("Input Selectize Demo"), + ui.input_selectize( + id="state", + label="Choose state(s):", + choices=states, + selected=["NY", "CA"], + multiple=True, + options={ + "placeholder": "Select states...", + "plugins": ["clear_button"], + "render": ui.js_eval( + '{option: function(item, escape) {return "
" + escape(item.label) + "
";}}' + ), + }, + ), + # Main panel + ui.card( + ui.card_header("Selection Results"), + ui.output_text("selection"), + ), +) + + +def server(input, output, session): + @render.text + def selection(): + if not input.state(): + return "No states selected" + return f"You selected: {', '.join(input.state())}" + + +app = App(app_ui, server) diff --git a/components/inputs/selectize-multiple/app-kitchensink-express.py b/components/inputs/selectize-multiple/app-kitchensink-express.py new file mode 100644 index 00000000..e4ae21ad --- /dev/null +++ b/components/inputs/selectize-multiple/app-kitchensink-express.py @@ -0,0 +1,39 @@ +from shiny import reactive +from shiny.express import input, ui, render + +# Sample data for states +states = { + "East Coast": {"NY": "New York", "NJ": "New Jersey", "CT": "Connecticut"}, + "West Coast": {"WA": "Washington", "OR": "Oregon", "CA": "California"}, + "Midwest": {"MN": "Minnesota", "WI": "Wisconsin", "IA": "Iowa"}, +} + +# Set page options +ui.page_opts(full_width=True) + +ui.h2("Input Selectize Demo") + +# Basic selectize with all parameters +ui.input_selectize( + id="state", + label="Choose state(s):", + choices=states, + selected=["NY", "CA"], + multiple=True, + options={ + "placeholder": "Select states...", + "plugins": ["clear_button"], + "render": ui.js_eval( + '{option: function(item, escape) {return "
" + escape(item.label) + "
";}}' + ), + }, +) + +with ui.card(): + ui.card_header("Selection Results") + + @render.text + def selection(): + if not input.state(): + return "No states selected" + return f"You selected: {', '.join(input.state())}" diff --git a/components/inputs/selectize-multiple/index.qmd b/components/inputs/selectize-multiple/index.qmd index ab762add..3d05f6ba 100644 --- a/components/inputs/selectize-multiple/index.qmd +++ b/components/inputs/selectize-multiple/index.qmd @@ -44,6 +44,13 @@ listing: - title: Core file: app-variation-selectize-with-grouped-choices-core.py shinylive: https://shinylive.io/py/editor/#code=NobwRAdghgtgpmAXAAjFADugdOgnmAGlQGMB7CAFzkqVQDMAnUmZAZwAsBLCXZTmdKQYVkAQUxEG1ACZwGRAK6cAOhFUZ0AfSXIAvMiU4oAczia6AGyXSAFKuQODnLN3QKKm1nAtxiFTgBecDYOAMTIADwR9o6xymBePn6BcPFEyOFRMbEO8QDK3r4ipOj+5KzIAEbepADuiGlhkdEQOY4gTVmtbTnxAIzxKCD9ooPI8QDC7KScxHDIfaOE42B9AEJjk9Oz8+uN-RObYFMzcwuHYAC+6ZktPb1gAExjw09LKFun849LRPGPG1onx2yAB+yeFw+x22Z0eF2unTuPQRGWa2RyMAUFn86B8ugAKgwFHAbmjug4AJSkrqxQykdxuDxUAAeFDsYAAblArKkwFTVBTVEKILI6Gw5By5DZXO4iPSKIyiF5WKxOOQKQ1ycgAAJSEVyLAsijo0XILk8mwa9GxKQUBQMVp0eIgGUULCJIopS2XeLC9SYPRiTA2DTaThKiVyQUQZZgCi4dAIFBxuCsq4AXSAA +- id: kitchen-sink + template: ../../_partials/components-detail-kitchen-sink.ejs + contents: + - title: Selectize + core: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbJjmVYnTJMAgujxM6cKITIcAbnAlSIAEzh0JAVw4AdCPoDETAMqxUAGzhNVUMlCY1BrexRb6WruCyYBeJiD6TMFMumAAolCeTADCxFFkYYgBYQByAJpJoWCpcADuTOmCANZhEmkAUllp+UwVGixw2GXZMQAq1WBxEBBwshyEWolgAL54QSFhAOrewnEJWYFgUyKdU1GcEADmZKQtYQDyAEqdB1Jbe-itq0itUBYcTnQQHFBhYxPBYQCyHKp5s0WP1SnV+PW8xHs+2WAEk1hwWCQICwuNCYTdkmEYcQ8m9RuMICN9Po0KgAPo6PxMHRYKBbOBkmgWHSqAAUn2pHAwbAATOywDCIKghqY4FZ+gAvawAETgMGIYQAlASQpyMFxhWQyY1xXIpeyIKrVX9fGFPHY4GUOaqLFAAEZi01dNjEYiNFwW1ksRWIK2Go3BQgugbeXzmtwqgOsMV9CiqXzANKZK5hGI3AC6kYDMC0FjkljgvjadC0SmtIWIqDkpBYvkC-qjkzAlhkcBdFnUdE6Jhjsg9bgwg79jdVYUsWi2XHct0TRCsUDoZLtQ12BjAmfLAbCKk7WRpACsWGS4PJ7gaR1GAOQgSvViDJGhaCD9UisjgUGASbyENBwRUBKQyC0Z5sgAHlUBQAD5QM8BhtkgsImAAaiYb9fzfD8MFtB0LH-FCwlAgB6WDSC2aDCIg+QELAABuEYRkvTcjWVJiPgbJgWPY4xvigLgmFQKBegsDkaR-Og2SY0SF1UMk2GkTt+R7XUOFIJgjm8XMyGnTjGxpYghk1MkKAADzIfkdVjFS1x0kJOMVYkDDUOAaGjOhFDoN8hSGCR9LITUJEaFgUVIH0OQAAR3DQMBMxJ2PUFyLJfCBWVC9jjRciBIV4LyyAwcM4BS300qjQDgMNNJiH7bxo11OBVDCJjSpAmgwiKLQatjOrkhAS8JEvDB92ILhPM1PKvBSxUiTABySXQKkxFQVlSQpDgAo0dz7IgUZ0yAA + express: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbJjmVYnTJM6cKITIcAbnAA6Eeo1aduGOAA9Uoli179BwrqgCuZPE2MdzoiABM4defIDETAMqxUAGzhNbUMigmGkFWQIoWeRZwuF0AXiYQeSYUplkwAFEoaKYAYWJssnTERPSAOQBNYrSwMrgAdyYKwQBrdPNygClq8oamTocWOGx2mtyAFR6wfIgIOAkOQlN0gF88ZNT0gHVY4XzC6qSwLYBBKa3slQBzMlJR9IB5ACUph9Eru-wxs6QxqC8OCE6BAOFBVusIKkagBZDi2eq7Q7paFlKaw2axYiBe7HACS5w4LBIEBYXBxuJ+JXSuOI9TBYDW8hWTggrjccGEqCgV18xFQklIkQgliw3LgAH0+WQWAAKGjGLxecX1OFkNhxcZ0YxwACULJFbAATDLqRATMJ2T4FgAvXwAETgMGI6T1EBcTAAQtlFqw4FbJLamCq1Ux-l4mFy6LAOYN5CKjKZxUN-RxbSbIak4XF0tEAnJ8BsUl4oAAjP3Z6ZsYjEIZhPMylg6xDtQtMQhVxaxOK5iIQqHJ+YUWxxYDlKpfdK5H4AXT7qRgCsk3jgGq1cDnKSlHEFcSSGahKXS3nEcCrXnsjl+6Utg7rEQwD5b+4PR68xiuXEiv1HRB8UDo4olqYtxumAs6tlC6Q2Be1QigAViw4pwFI-zpge6FMAA5CAW6kCU8oQAspAyhwFAwOYsSEGguqJKIZDGMCNQADy2NIAB8THRAwEBXGx6RMAA1EwlHUSRZEYMWZZeDqgnMQA9FxpC8UxcmsVIfFgAA3CsKyYRBqQ6huTCMhArryMGbAWBwGBUXQtgyk2rYirZtjimwYgXiaYA3kRkJPLEi5fmZz4AALQQ4GAUOoRTPvYNC+imxGOc+UKAkwEBYrwZqmBgPZwA5zYpRhdEMZC5TEHesQJYOcC2Ok+kpCVjE0OkzTGNVEi1SUICYeYmEYHBxBcCR2VkLlMQOTqzJgPIDLTkAA + image: thumbnail.png --- :::{#example} diff --git a/components/inputs/selectize-multiple/thumbnail-old.png b/components/inputs/selectize-multiple/thumbnail-old.png new file mode 100644 index 00000000..7e50b6e0 Binary files /dev/null and b/components/inputs/selectize-multiple/thumbnail-old.png differ diff --git a/components/inputs/selectize-multiple/thumbnail.png b/components/inputs/selectize-multiple/thumbnail.png new file mode 100644 index 00000000..0153de88 Binary files /dev/null and b/components/inputs/selectize-multiple/thumbnail.png differ diff --git a/components/inputs/selectize-single/app-kitchensink-core.py b/components/inputs/selectize-single/app-kitchensink-core.py new file mode 100644 index 00000000..4b55574f --- /dev/null +++ b/components/inputs/selectize-single/app-kitchensink-core.py @@ -0,0 +1,44 @@ +from shiny import App, reactive, render, ui + +# Sample data for states +states = { + "East Coast": {"NY": "New York", "NJ": "New Jersey", "CT": "Connecticut"}, + "West Coast": {"WA": "Washington", "OR": "Oregon", "CA": "California"}, + "Midwest": {"MN": "Minnesota", "WI": "Wisconsin", "IA": "Iowa"}, +} + +app_ui = ui.page_fluid( + ui.h2("Input Selectize Demo"), + ui.input_selectize( + id="state", + label="Choose state(s):", + choices=states, + selected=["NY", "CA"], + multiple=False, + options={ + "placeholder": "Select states...", + "plugins": ["clear_button"], + "render": ui.js_eval( + '{option: function(item, escape) {return "
" + escape(item.label) + "
";}}' + ), + }, + ), + # Main panel + ui.card( + ui.card_header("Selection Results"), + ui.output_text("selection"), + ), +) + + +def server(input, output, session): + @render.text + def selection(): + if not input.state(): + return "No states selected" + # multiple=False -> str (single selected value) + # multiple=True -> tuple (of selected string values, empty tuple if none selected) + return f"You selected: {input.state()}" + + +app = App(app_ui, server) diff --git a/components/inputs/selectize-single/app-kitchensink-express.py b/components/inputs/selectize-single/app-kitchensink-express.py new file mode 100644 index 00000000..56e6db35 --- /dev/null +++ b/components/inputs/selectize-single/app-kitchensink-express.py @@ -0,0 +1,41 @@ +from shiny import reactive +from shiny.express import input, ui, render + +# Sample data for states +states = { + "East Coast": {"NY": "New York", "NJ": "New Jersey", "CT": "Connecticut"}, + "West Coast": {"WA": "Washington", "OR": "Oregon", "CA": "California"}, + "Midwest": {"MN": "Minnesota", "WI": "Wisconsin", "IA": "Iowa"}, +} + +# Set page options +ui.page_opts(full_width=True) + +ui.h2("Input Selectize Demo") + +# Basic selectize with all parameters +ui.input_selectize( + id="state", + label="Choose state(s):", + choices=states, + selected=["NY", "CA"], + multiple=False, + options={ + "placeholder": "Select states...", + "plugins": ["clear_button"], + "render": ui.js_eval( + '{option: function(item, escape) {return "
" + escape(item.label) + "
";}}' + ), + }, +) + +with ui.card(): + ui.card_header("Selection Results") + + @render.text + def selection(): + if not input.state(): + return "No states selected" + # multiple=False -> str (single selected value) + # multiple=True -> tuple (of selected string values, empty tuple if none selected) + return f"You selected: {input.state()}" diff --git a/components/inputs/selectize-single/index.qmd b/components/inputs/selectize-single/index.qmd index 5b2778db..073cd7e5 100644 --- a/components/inputs/selectize-single/index.qmd +++ b/components/inputs/selectize-single/index.qmd @@ -44,6 +44,13 @@ listing: - title: Core file: app-variation-selectize-with-grouped-choices-core.py shinylive: https://shinylive.io/py/editor/#code=NobwRAdghgtgpmAXAAjFADugdOgnmAGlQGMB7CAFzkqVQDMAnUmZAZwAsBLCXZTmdKQYVkAQUxEG1ACZwGRAK6cAOhFUZ0AfSXIAvMiU4oAczia6AGyXSAFKuQODnLN3QKKm1nAtxiFTgBecHYQjmHIymBePn6BcJEE9uEOkQDK3r4iUKGk6P7kyABG3qQA7ogJSckgVcmOkQCMkSg1YA2izRFgAMLspJzEcMjtCV0NAEKdkb39g8OThGPdUz19A0MNy2AAvomhdWGRAEydrUcdtNNrc+ejxwsoV7NDRwtEx1uPq8-IR1u7tTCAP2DgAlHswoZSO43B4qAAPCh2MAANygVniYHBqlBqjxEFkdDYchRchsrncRGhFFhRC8rFYnHIoIqIOQAAEpAS5FgERRaoTkGiMTYWYDHFIKAoGKE6JEQBSKFhopk4qLtpF8epMHoxJgbBptJw6SS5LiIIswBRcOgECgrXBETsALpAA +- id: kitchen-sink + template: ../../_partials/components-detail-kitchen-sink.ejs + contents: + - title: Selectize + core: https://shinylive.io/py/editor/#code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbJjmVYnTJMAgujxM6cKITIcAbnAlSIAEzh0JAVw4AdCPoDETAMqxUAGzhNVUMlCY1BrexRb6WruCyYBeJiD6TMFMumAAolCeTADCxFFkYYgBYQByAJpJoWCpcADuTOmCANZhEmkAUllp+UwVGixw2GXZMQAq1WBxEBBwshyEWolgAL54QSFhAOrewnEJWYFgUyKdU1GcEADmZKQtYQDyAEqdB1Jbe-itq0itUBYcTnQQHFBhYxPBYQCyHKp5s0WP1SnV+PW8xHs+2WAEk1hwWCQICwuNCYTdkmEYcQ8m9RuMICN9Po0KgAPo6PxMHRYKBbOBkmgWHSqAAUn2pHAwbAATOywDCIKghqY4FZ+gAvawAETgMGIYQAlASQpyMFxhWQyY1xXIpeyIKrVX9fGFPHY4GUOaqLFAAEZi01dNjEYiNFwW1ksRWIK2Go3BQgugbeXzmtwqgOsMV9CiqXzANKZK5hGI3AC6kYDMC0FjkljgvgAYvdGlmjcRUHJSCxfIF-VHJmBLDI4C6LOo6J0TDHZB63BhB37G6qwpYtFsuO5bomiFYoHQyXahrsDGBM9ao2EVJ2sjSAFYsMlweT3A0jqMAchAlerEGSNC0EH6pFZHAoMAk3kIaDgioCUhkFozzZAAPKoCgAHygZ4DDbJBYRMAA1Ew36-m+H4YLaDoWP+KFhKBAD0sGkFs0GERB8gIWAADcIwjJem4BsqTFMB8DZMCxHHGN8UBcEwqBQL0FgcjSP50GyrFiQuqhkmw0idvyPa6hwpBMEc3i5mQ05cY2NLEEMmpkhQAAeZD8jqsaqWuukhFxirEgYahwDQ0Z0IodBvkKQwSAZZCahIjQsCipA+hyAACO4aBgpmJBx6iuZZL4QKyYUccarkQJCvDeWQGDhnAqW+ulUaAcBhppMQ-beNGupwKoYSscYwQ5nmHAFsWpbWAAtJBLh0MEXpcFsVi1bG9VMKezJ-k1IStfmVi+G0dBaNYTC9UwQEFkwrLEIlvZxv1w2Tfcq0sF+-BkDwW2jY8TBZb0Y2yPVDklcEZUgTQYRFFoT1xskIAakM+VeKlRJgI5JLoFSYioKypIUhwgUaB5r2jOmQA + express: https://shinylive.io/py/editor/#code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbJjmVYnTJM6cKITIcAbnAA6Eeo1aduGOAA9Uoli179BwrqgCuZPE2MdzoiABM4defIDETAMqxUAGzhNbUMigmGkFWQIoWeRZwuF0AXiYQeSYUplkwAFEoaKYAYWJssnTERPSAOQBNYrSwMrgAdyYKwQBrdPNygClq8oamTocWOGx2mtyAFR6wfIgIOAkOQlN0gF88ZNT0gHVY4XzC6qSwLYBBKa3slQBzMlJR9IB5ACUph9Eru-wxs6QxqC8OCE6BAOFBVusIKkagBZDi2eq7Q7paFlKaw2axYiBe7HACS5w4LBIEBYXBxuJ+JXSuOI9TBYDW8hWTggrjccGEqCgV18xFQklIkQgliw3LgAH0+WQWAAKGjGLxecX1OFkNhxcZ0YxwACULJFbAATDLqRATMJ2T4FgAvXwAETgMGI6T1EBcTAAQtlFqw4FbJLamCq1Ux-l4mFy6LAOYN5CKjKZxUN-RxbSbIak4XF0tEAnJ8BsUl4oAAjP3Z6ZsYjEIZhPMylg6xDtQtMQhVxaxOK5iIQqHJ+YUWxxYDlKpfdK5H4AXT7qRgCsk3jgcQAYv8hnOUlKOIK4kkM1CUulvOI4FWvPZHL90pbB3WIhgny3D0eT15jFcuJFfqOiD4oDocUS1MW43TAWdWyhdIbCvaoRQAKxYcU4Ckf50yPTCmAAchAHdSBKeUIAWUgZQ4CgYHMWJCDQXVElEMhjGBGoAB5bGkAA+FjogYCArg49ImAAaiYajaLIiiMGLMsvB1YTWIAeh40h+JYhT2KkASwAAbhWFZsKg1IdS3JhGQgV15GDNgLA4DAaLoWwZSbVsRXs2xxTYMQrxNMA7xIyEnliRcfws18AAFYIcDAKHUIpX3sGhfRTUjnNfKFASYCAsV4M1TAwHs4Cc5s0qwhimMhcpiAfWIksHOBbHSQyUlcFIFy8JcfDXDdfAAWg4sI6BSBsuCuHxaokeqmDQj9dSapgWqYNqOpXTVtRSPqmEY5cmBlYhEoHCbbAGkapv+bUWCo-gyB4LaxoyrK5nGodXSwkQOXK4J0maYwnvqkoQATMh8piJzmTAeQGWnIA + image: thumbnail.png --- :::{#example} diff --git a/components/inputs/selectize-single/thumbnail.png b/components/inputs/selectize-single/thumbnail.png new file mode 100644 index 00000000..3e0f5b44 Binary files /dev/null and b/components/inputs/selectize-single/thumbnail.png differ diff --git a/components/inputs/slider-range/app-kitchensink-core.py b/components/inputs/slider-range/app-kitchensink-core.py new file mode 100644 index 00000000..be7475d0 --- /dev/null +++ b/components/inputs/slider-range/app-kitchensink-core.py @@ -0,0 +1,161 @@ +from datetime import datetime, timezone + +from shiny import App, reactive, render, ui + +# Define a consistent timezone +TIMEZONE = timezone.utc + +app_ui = ui.page_fluid( + ui.panel_title("Slider Parameters Demo"), + ui.layout_column_wrap( + # Numeric Slider - basic parameters + ui.card( + ui.card_header("Basic Numeric Slider"), + ui.input_slider("slider1", "Min, max, value", min=0, max=100, value=50), + ui.output_text("value1"), + ), + # Numeric Slider with step + ui.card( + ui.card_header("Step Parameter"), + ui.input_slider( + "slider2", "Step size = 10", min=0, max=100, value=50, step=10 + ), + ui.output_text("value2"), + ), + # Range Slider + ui.card( + ui.card_header("Range Slider"), + ui.input_slider( + "slider3", "Select a range", min=0, max=100, value=(30, 70) + ), + ui.output_text("value3"), + ), + # Date Slider + ui.card( + ui.card_header("Date Slider"), + ui.input_slider( + "slider4", + "Select a date", + min=datetime(2023, 1, 1, 0, 0, tzinfo=TIMEZONE), + max=datetime(2023, 12, 31, 0, 0, tzinfo=TIMEZONE), + value=datetime(2023, 6, 15, 12, 30, tzinfo=TIMEZONE), + time_format="%Y-%m-%d", + ), + ui.output_text("value4"), + ), + # Animated Slider + ui.card( + ui.card_header("Animated Slider"), + ui.input_slider( + "slider5", "With animation", min=0, max=100, value=50, animate=True + ), + ui.output_text("value5"), + ), + # Slider with custom formatting + ui.card( + ui.card_header("Custom Formatting"), + ui.input_slider( + "slider6", + "With prefix and suffix", + min=0, + max=100, + value=50, + pre="$", + post="%", + sep=",", + ), + ui.output_text("value6"), + ), + # Slider with ticks + ui.card( + ui.card_header("Ticks Display"), + ui.input_slider( + "slider7", "With tick marks", min=0, max=100, value=50, ticks=True + ), + ui.output_text("value7"), + ), + # Date Range Slider with drag_range + ui.card( + ui.card_header("Date Range"), + ui.input_slider( + "slider9", + "Draggable range", + min=datetime(2023, 1, 1, 0, 0, tzinfo=TIMEZONE), + max=datetime(2023, 12, 31, 0, 0, tzinfo=TIMEZONE), + value=( + datetime(2023, 3, 1, 0, 0, tzinfo=TIMEZONE), + datetime(2023, 9, 30, 0, 0, tzinfo=TIMEZONE), + ), + time_format="%Y-%m-%d", + timezone="UTC", + drag_range=True, + ), + ui.output_text("value9"), + ), + # Datetime slider + ui.card( + ui.card_header("Datetime Slider"), + ui.input_slider( + "slider10", + "With time format", + min=datetime(2023, 1, 1, 0, 0, tzinfo=TIMEZONE), + max=datetime(2023, 12, 31, 23, 59, tzinfo=TIMEZONE), + value=datetime(2023, 6, 15, 12, 30, tzinfo=TIMEZONE), + time_format="%Y-%m-%d %H:%M", + timezone="UTC", + ), + ui.output_text("value10"), + ), + width="400px", + ), +) + + +def server(input, output, session): + @render.text + @reactive.event(input.slider1) + def value1(): + return f"Value: {input.slider1()}" + + @render.text + @reactive.event(input.slider2) + def value2(): + return f"Value: {input.slider2()}" + + @render.text + @reactive.event(input.slider3) + def value3(): + return f"Value: {input.slider3()}" + + @render.text + @reactive.event(input.slider4) + def value4(): + return f"Value: {input.slider4()}" + + @render.text + @reactive.event(input.slider5) + def value5(): + return f"Value: {input.slider5()}" + + @render.text + @reactive.event(input.slider6) + def value6(): + return f"Value: {input.slider6()}" + + @render.text + @reactive.event(input.slider7) + def value7(): + return f"Value: {input.slider7()}" + + @render.text + @reactive.event(input.slider9) + def value9(): + return f"Value: {input.slider9()}" + + @render.text + @reactive.event(input.slider10) + def value10(): + return f"Value: {input.slider10()}" + + +app = App(app_ui, server) diff --git a/components/inputs/slider-range/app-kitchensink-express.py b/components/inputs/slider-range/app-kitchensink-express.py new file mode 100644 index 00000000..47d16a08 --- /dev/null +++ b/components/inputs/slider-range/app-kitchensink-express.py @@ -0,0 +1,131 @@ +from datetime import datetime, timezone + +from shiny.express import input, render, ui + +# Define a consistent timezone +TIMEZONE = timezone.utc + +ui.page_opts(title="Slider Parameters Demo", full_width=True) + +with ui.layout_column_wrap(width="400px"): + # Numeric Slider - basic parameters + with ui.card(): + ui.card_header("Basic Numeric Slider") + ui.input_slider("slider1", "Min, max, value", min=0, max=100, value=50) + + @render.text + def value1(): + return f"Value: {input.slider1()}" + + # Numeric Slider with step + with ui.card(): + ui.card_header("Step Parameter") + ui.input_slider("slider2", "Step size = 10", min=0, max=100, value=50, step=10) + + @render.text + def value2(): + return f"Value: {input.slider2()}" + + # Range Slider + with ui.card(): + ui.card_header("Range Slider") + ui.input_slider("slider3", "Select a range", min=0, max=100, value=(30, 70)) + + @render.text + def value3(): + return f"Value: {input.slider3()}" + + # Date Slider + with ui.card(): + ui.card_header("Date Slider") + ui.input_slider( + "slider4", + "Select a date", + min=datetime(2023, 1, 1, 0, 0, tzinfo=TIMEZONE), + max=datetime(2023, 12, 31, 0, 0, tzinfo=TIMEZONE), + value=datetime(2023, 6, 15, 12, 30, tzinfo=TIMEZONE), + time_format="%Y-%m-%d", + timezone="UTC", + ) + + @render.text + def value4(): + return f"Value: {input.slider4()}" + + # Animated Slider + with ui.card(): + ui.card_header("Animated Slider") + ui.input_slider( + "slider5", "With animation", min=0, max=100, value=50, animate=True + ) + + @render.text + def value5(): + return f"Value: {input.slider5()}" + + # Slider with custom formatting + with ui.card(): + ui.card_header("Custom Formatting") + ui.input_slider( + "slider6", + "With prefix and suffix", + min=0, + max=100, + value=50, + pre="$", + post="%", + sep=",", + ) + + @render.text + def value6(): + return f"Value: {input.slider6()}" + + # Slider with ticks + with ui.card(): + ui.card_header("Ticks Display") + ui.input_slider( + "slider7", "With tick marks", min=0, max=100, value=50, ticks=True + ) + + @render.text + def value7(): + return f"Value: {input.slider7()}" + + # Date Range Slider with drag_range + with ui.card(): + ui.card_header("Date Range") + ui.input_slider( + "slider9", + "Draggable range", + min=datetime(2023, 1, 1, 0, 0, tzinfo=TIMEZONE), + max=datetime(2023, 12, 31, 0, 0, tzinfo=TIMEZONE), + value=( + datetime(2023, 3, 1, 0, 0, tzinfo=TIMEZONE), + datetime(2023, 9, 30, 0, 0, tzinfo=TIMEZONE), + ), + time_format="%Y-%m-%d", + timezone="UTC", + drag_range=True, + ) + + @render.text + def value9(): + return f"Value: {input.slider9()}" + + # Datetime slider + with ui.card(): + ui.card_header("Datetime Slider") + ui.input_slider( + "slider10", + "With time format", + min=datetime(2023, 1, 1, 0, 0, tzinfo=TIMEZONE), + max=datetime(2023, 12, 31, 23, 59, tzinfo=TIMEZONE), + value=datetime(2023, 6, 15, 12, 30, tzinfo=TIMEZONE), + time_format="%Y-%m-%d %H:%M", + timezone="UTC", + ) + + @render.text + def value10(): + return f"Value: {input.slider10()}" diff --git a/components/inputs/slider-range/index.qmd b/components/inputs/slider-range/index.qmd index d8c73e57..5eb9be00 100644 --- a/components/inputs/slider-range/index.qmd +++ b/components/inputs/slider-range/index.qmd @@ -37,6 +37,13 @@ listing: href: https://shiny.posit.co/py/api/render.DataTable.html signature: render.DataTable(self, data, *, width='fit-content', height='500px', summary=True, filters=False, row_selection_mode='none') +- id: kitchen-sink + template: ../../_partials/components-detail-kitchen-sink.ejs + contents: + - title: slider + core: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAEygrIEt4nvVi6ZVuzhd4eJmLgAvUnAA6ERfUZMAzgAtOEbLxj9BTAILoJdOFEJcAbnDOUWcOhICunRYoDETACJwa2nBMUEwkEGqcahTkktwycooAKgCSALIAogBaAPIAculMALyx8LIQcBguZIQe0OgA+m5FTG5YUADmcPU0ADZuLAAUikwjLZxt5T31XGQ9cENgAMo9nI50TAAKUHSwok5qvnAwxPJgAJR4w6OtPVDYxFX1JH0wEPUA7juoQxCjf0zeXIueB0TiEJjLVZOJgAWiYACMoBFwahtrsKHQ1Fd-mMMIRtoNsTjruN8XQWPUNBY1gsAEJIsFMIEgxmQtanC5E4m47SoR5qFY004CqF0ACMpwkp1S2gkMCgAA8JNYoH0FPgmDBtIUAAxyxWFMU6vVMFVqwoAVh1nN+3JJGAeZD5ZGmcAVZAWZpccAl50utpxNu5gOBTlZguh704ZA06goqC59rJhIDdtaycp1KcC0W8c2aPgGI5-rt9t5-IjdB+pZxwsrACZJUxTrm4Kh1JxpEFikam1qILr9QrDcblarvZaTVE2yPE4GSzXWo7na73Z7x3BG3650wg8TvAAlKAQToQys79ME6uL0kEzNQIVgI8noJspzFnd-Vrll0ioWpmtmzAP8nAAZibFs4DmKxgiYHYXz7bUTXlYcjRNL04EKAZQJNAB2a1P1GPdSyXKoVwoNdTgw8DtwAoiFxxbwfBEM9RQvW9yWvEiOIpKkH2zU5mIoVj2VowDvwgFcQKrQja2AysABZJVk-5IOgoQQjYChlLo0t+0KLTRDiAZ6x1etQIkMVLIkE0TTIaRtBoYhChSDIcnyYjAM1A1DKkEyzIspgxXrCRQKsphbIkezHOc1ysjydJPMAjCDJEPzTPMiQADZLItSyQqYHCoociAnJctJ4o8hivKkboBHlMhClOABSABNGFmpgDqWB0wCkuJUinUeCiPSojclLE4l+pGbwjAgbgRBYET3103Fky4tMePvR85oWiglrfOgP1Wr9xh-eppI2wC61FC0ILAAB1aNY2PPbOFIRCB2Qg00LHc0rQkV6GswxI6G9FTpv+QbyLdUawAwu7JvnHdvEOpgoxjUIXCiVQnLoBquBPdi8SvFTL3JbaBLAABhbGyFUAAxer2EJ9pjvEs7JIrUUrprG61iy3qvJGU4nsx1BzACBVgggJa1BcGgpaF4X9L1FS-hQkc1ZO4kUoB9XRglzDTgAEmVrz+CiJqwGa83ALUGdlPwCHqu5aHhth9c1UFpH-kh1HK3R57YkIABrLFVvJlMOZJim+MfRIwXD3xIlQW5sHZm8MHOy6DZF+TRVw+6xdjLgw+8uhw8+wdvNQ0dTQ3ScoqTtQXLBhQdZGSHTodMiPco+GNyL32-n93wWOfU80Yx2MWB2dp6ngzpifWsmtvjqmhKCSf1W7ssud-StedLfmnAATjtvmwB8ef2igeE5jg49l+dzv-n03zjIywLwvCyLJBKmVOK7lEquxrJrT+8B-KZSCgVMKNkEEAJiuVNyCU944hSsfLykD5jf1CtZCKiDoqlVihVEB6C7Q4OgYFM+oV-52UAaQ1BVU867jAaWWqeMGrWzah1LqzUeqv2FiMKQZRjZgAAKqJGppfUsc8OiL2fiDdu7C-aqJ7sufucMMIXxHvRFG48OBxHUOeSOPEsE9wzBvGS180rGMOpnbi2cD4XSPqw0+4odSyLtKLYOUgmBcPYN47kH87FQLwUFAh-9iFALIWg9RxIIFhNwQFfKoVwowItLQpBJCUGVVAawlKVCIk5SCnlWBdDirIOAfE1hnDmaNRau1Tq3UmDNQABKIGaqkYJxJRFyGtlImRQiawUPdi6EaXtvS9j0V3VRUYWAxmtgpY0qAFTmxtGcWoihHA0HUE4WwVYfwSE0WQCQDs1ARFIGcRARIAAC5hZZOAwCNe55hLA2AqHAWw5ABg-gwNJMUWzUy7IbmqMUAwbk7nMGQFwdBfg0FOAANQ3IgJgIB-mAshQAX1OLUP4DyHDPNeamQlHzOC2AwN8ygHpMUNmBX8UFGF6yQtuatGFcKEXItReiulooWVnFxWAfFoxCVPLoC82GbyLBWApV8n5tKD4AsrKBBlowmUblAqy6FohOUBO5WqNFGKlXSS1YKvFShSWPLWJK900ryWUupb8vlawFJqpGBqtUCltXst1fC-VYAUWGt5SaxSOKLXSvFbasg9rZWOoVX80Nt13WsH8GC70FofXcg5f6xFgaeXGudMq264bhWWoJda4lUqrUys+VShNLqnBZRTZ670WUs3EhzVy-NwbC1VGLQLUtIqRhiptSSitta5X1ppYmot0lcItrTRhXCHacRdoDUG70RrG10BXeastkax3VonQ6+VM6d1n0XXsnRq7-jrrzZuuA26k1rDPkO8torK0SvHZ+yd8bz0vqcEaK96afQ6lvX8e9Bqt0hrnZWI077ahoHbMUEw3xkONE4Ocg5ThgVgGxQAXSAA + express: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAEygrIEt4nvVi6ZVuzhd4eJmLgAvUnAA6ERfUZMAzgAtOEbBjgAPVHThq1vGP0G8IqAK5kJxiCzh0JtzosUBiJgBE4Gm04JigmEgg1TjUKckluGTlFABUASQBZAFEALQB5ADlMpgBeePhZCDgMe0IvCA8sKABzOAB9YlQyNQAKLjIAGzhi+TAAZX7OFzomAAUoOlhRVzMAmGIRiRpbfv7WgHdJsg1i5LpbOABKOoOjpgb+qGxie1aSftsYCH2F1G6DliOwzAABYAAyg1D6EYXRCKJjwpi+fIfVycQhMcaTVxMAC0TAARlAoujUPNFhQ6Go4Qibho7pwMIR5ixujDqQiEQ0mXQWK0NHAoFNuiMAEJEtFMZHwOgSzFTaHsjn0jDaOxkVpqCZCkaarF0ACMGyYI3S2gkMCg+gkADcoO8FPgmDBtMVQebLcV9eCbXbzsUAKygq5KCBKhEAAScUwwFH0ZEVHJcNCYtvt+tZsNDYaVxjItjooZoIwAar64IgmCBVfYMLqpumLgBfEZ1DlIlEy9Fy7G09QUVCK3tc5kZhOchnc3n8wWuYVjfuzMnwCkKrNhhrV9V12c6rWuABMRpGowXUWkIVKXqNzogrvd+k93pTZYDbr7cFQj+DY-hkco0djeM1yVJNn3tfdR2A7MmFzfNCxLMsKyrGwa23OgIKbFsQzbJgACUoAgFoMT3OhB04W5hx5SDoMoqcBW1MB8MIkJu1IsBgxohlNw1Ei5zQgBmI8xjgQZCCEMIFmY68XTfC0Hy9N9Uz9bp+LfAB2INvygiMo1cGMDCA6DQKUuB+Oo6CEVggsmCLMBS3tJDN1rEizMwsBWwRXw-BEYi9TIiiJxHNltPhWi+XoncwG8ihfPldif2Vbi0OFEKlV3PVgQ2BKOWPES4DE0JhAoLLUo5G9ijYDgEm6fdQX3fiJH1RqJDfN8yGkbQaGIE4MhyApMguPBsoROSKpEKQarqhqmH1fcJH4pqmFaiR2s67q0iyPJCkG4b4RMsaqvgSb6okAA2Rr-UauamFUlaOogLqes2-qdtKhEpFaLq6AtMggQAUgATRxP6YGBlgSos96EgqIYRgAVWSABhCHsy06C-2cPTAIS4yy2BczIas+C7MQysnLQ-G3I8+FfAAQQgbgRBYWLXH8ulaIJpUwunBj6cZihmdY1dOJVFCt143bjTAND-SEgB1ci6QI-nOFIaTb1kj0FJ9e1XwkZWfqGU5zgStHswxgCDJxwIwPOf1OegombIQhyybF5y9XtqnsM8lnpl7QhbBiVQvp+rhCLZ5VJwd8dGWZcKZzoOdEaDshVAAMQEMPtCaYXsw3MWeL1FLIfhdKplOlHIZGBXbiMQJOH0UJnHUWwaCCKF8El8q3W7rXvUl-bAyGt74XroEABIq4s-gYn+6foLUD8gSGrvUrNsMLaxq3Utx+1TpjsMnds+zzkc920IP73FV8VimF7LhCAAaypYCh0CqjgpFycE4Y5I0Rfv4aIqAHjYDzuuLihdkqS3Lq4NS8tFbxGfk6eYL91Z3hQfJJ8Q82oALUCcM4Ch17UyVFvOg+k4zW2TCZNSh8cyiDgs7EmrtkJqg9lMWh19gJeR8kxIid9ewsAWE0VokkWiRw5l-fOH86KJznNFEIfCHQcWkaLNURdtSjylmhAAnAvbMIw-DCKaFAfEgwYIEXEWvUuToXSVVENVWqJ0ZrNSWi1O6a0np9W2iPGxo17ETScdNWa81FrLUkPdR6G1vEDV8aXfaJcbEIgCY4qa81XHhNWg9davUtqxMlomcaqTnE6PmuEtqkScnPR8ZLV6NiPqh3YP9IGIMwb6LDFIGGQIEbI2saXIRzRRGWKNoQuJYYN6kN0uQ7Gu8bYmR0XQjkx8XZnzdmw3RrJmzuR9jTfwRSeBoQkTIuh3MIpJ0MfsliJFwFc0geo6BWjYEGlBO0tKYBa50ikDZLO7BXllTsZc46wSMnuIiZ46JeS6ml38YCoJV1QkSGcf6UpYLsleMhWMiy+0UlHThUwc6M1LozWurdVFUTckvUxdBBpPzfojEBsDUGf1mZ-QABKID+ukP5UNyhyG6UjV5EyORkIoYZbMe9zhekWZZBh1kT6k1YahEiUrvZgEbAAXSAA + image: thumbnail.png --- :::{#example} @@ -64,3 +71,6 @@ The value of an input component is accessible as a reactive value within the `se 1. Use `input.()` (e.g., `input.slider()`) to access the value of the slider. If `value` is a list and the slider specifies a range, the server value of a slider will be a list of length 2. See also: [Slider](../slider/index.qmd) + +:::{#kitchen-sink} +::: diff --git a/components/inputs/slider-range/thumbnail.png b/components/inputs/slider-range/thumbnail.png new file mode 100644 index 00000000..c0743b56 Binary files /dev/null and b/components/inputs/slider-range/thumbnail.png differ diff --git a/components/inputs/slider/app-kitchensink-core.py b/components/inputs/slider/app-kitchensink-core.py new file mode 100644 index 00000000..be7475d0 --- /dev/null +++ b/components/inputs/slider/app-kitchensink-core.py @@ -0,0 +1,161 @@ +from datetime import datetime, timezone + +from shiny import App, reactive, render, ui + +# Define a consistent timezone +TIMEZONE = timezone.utc + +app_ui = ui.page_fluid( + ui.panel_title("Slider Parameters Demo"), + ui.layout_column_wrap( + # Numeric Slider - basic parameters + ui.card( + ui.card_header("Basic Numeric Slider"), + ui.input_slider("slider1", "Min, max, value", min=0, max=100, value=50), + ui.output_text("value1"), + ), + # Numeric Slider with step + ui.card( + ui.card_header("Step Parameter"), + ui.input_slider( + "slider2", "Step size = 10", min=0, max=100, value=50, step=10 + ), + ui.output_text("value2"), + ), + # Range Slider + ui.card( + ui.card_header("Range Slider"), + ui.input_slider( + "slider3", "Select a range", min=0, max=100, value=(30, 70) + ), + ui.output_text("value3"), + ), + # Date Slider + ui.card( + ui.card_header("Date Slider"), + ui.input_slider( + "slider4", + "Select a date", + min=datetime(2023, 1, 1, 0, 0, tzinfo=TIMEZONE), + max=datetime(2023, 12, 31, 0, 0, tzinfo=TIMEZONE), + value=datetime(2023, 6, 15, 12, 30, tzinfo=TIMEZONE), + time_format="%Y-%m-%d", + ), + ui.output_text("value4"), + ), + # Animated Slider + ui.card( + ui.card_header("Animated Slider"), + ui.input_slider( + "slider5", "With animation", min=0, max=100, value=50, animate=True + ), + ui.output_text("value5"), + ), + # Slider with custom formatting + ui.card( + ui.card_header("Custom Formatting"), + ui.input_slider( + "slider6", + "With prefix and suffix", + min=0, + max=100, + value=50, + pre="$", + post="%", + sep=",", + ), + ui.output_text("value6"), + ), + # Slider with ticks + ui.card( + ui.card_header("Ticks Display"), + ui.input_slider( + "slider7", "With tick marks", min=0, max=100, value=50, ticks=True + ), + ui.output_text("value7"), + ), + # Date Range Slider with drag_range + ui.card( + ui.card_header("Date Range"), + ui.input_slider( + "slider9", + "Draggable range", + min=datetime(2023, 1, 1, 0, 0, tzinfo=TIMEZONE), + max=datetime(2023, 12, 31, 0, 0, tzinfo=TIMEZONE), + value=( + datetime(2023, 3, 1, 0, 0, tzinfo=TIMEZONE), + datetime(2023, 9, 30, 0, 0, tzinfo=TIMEZONE), + ), + time_format="%Y-%m-%d", + timezone="UTC", + drag_range=True, + ), + ui.output_text("value9"), + ), + # Datetime slider + ui.card( + ui.card_header("Datetime Slider"), + ui.input_slider( + "slider10", + "With time format", + min=datetime(2023, 1, 1, 0, 0, tzinfo=TIMEZONE), + max=datetime(2023, 12, 31, 23, 59, tzinfo=TIMEZONE), + value=datetime(2023, 6, 15, 12, 30, tzinfo=TIMEZONE), + time_format="%Y-%m-%d %H:%M", + timezone="UTC", + ), + ui.output_text("value10"), + ), + width="400px", + ), +) + + +def server(input, output, session): + @render.text + @reactive.event(input.slider1) + def value1(): + return f"Value: {input.slider1()}" + + @render.text + @reactive.event(input.slider2) + def value2(): + return f"Value: {input.slider2()}" + + @render.text + @reactive.event(input.slider3) + def value3(): + return f"Value: {input.slider3()}" + + @render.text + @reactive.event(input.slider4) + def value4(): + return f"Value: {input.slider4()}" + + @render.text + @reactive.event(input.slider5) + def value5(): + return f"Value: {input.slider5()}" + + @render.text + @reactive.event(input.slider6) + def value6(): + return f"Value: {input.slider6()}" + + @render.text + @reactive.event(input.slider7) + def value7(): + return f"Value: {input.slider7()}" + + @render.text + @reactive.event(input.slider9) + def value9(): + return f"Value: {input.slider9()}" + + @render.text + @reactive.event(input.slider10) + def value10(): + return f"Value: {input.slider10()}" + + +app = App(app_ui, server) diff --git a/components/inputs/slider/app-kitchensink-express.py b/components/inputs/slider/app-kitchensink-express.py new file mode 100644 index 00000000..47d16a08 --- /dev/null +++ b/components/inputs/slider/app-kitchensink-express.py @@ -0,0 +1,131 @@ +from datetime import datetime, timezone + +from shiny.express import input, render, ui + +# Define a consistent timezone +TIMEZONE = timezone.utc + +ui.page_opts(title="Slider Parameters Demo", full_width=True) + +with ui.layout_column_wrap(width="400px"): + # Numeric Slider - basic parameters + with ui.card(): + ui.card_header("Basic Numeric Slider") + ui.input_slider("slider1", "Min, max, value", min=0, max=100, value=50) + + @render.text + def value1(): + return f"Value: {input.slider1()}" + + # Numeric Slider with step + with ui.card(): + ui.card_header("Step Parameter") + ui.input_slider("slider2", "Step size = 10", min=0, max=100, value=50, step=10) + + @render.text + def value2(): + return f"Value: {input.slider2()}" + + # Range Slider + with ui.card(): + ui.card_header("Range Slider") + ui.input_slider("slider3", "Select a range", min=0, max=100, value=(30, 70)) + + @render.text + def value3(): + return f"Value: {input.slider3()}" + + # Date Slider + with ui.card(): + ui.card_header("Date Slider") + ui.input_slider( + "slider4", + "Select a date", + min=datetime(2023, 1, 1, 0, 0, tzinfo=TIMEZONE), + max=datetime(2023, 12, 31, 0, 0, tzinfo=TIMEZONE), + value=datetime(2023, 6, 15, 12, 30, tzinfo=TIMEZONE), + time_format="%Y-%m-%d", + timezone="UTC", + ) + + @render.text + def value4(): + return f"Value: {input.slider4()}" + + # Animated Slider + with ui.card(): + ui.card_header("Animated Slider") + ui.input_slider( + "slider5", "With animation", min=0, max=100, value=50, animate=True + ) + + @render.text + def value5(): + return f"Value: {input.slider5()}" + + # Slider with custom formatting + with ui.card(): + ui.card_header("Custom Formatting") + ui.input_slider( + "slider6", + "With prefix and suffix", + min=0, + max=100, + value=50, + pre="$", + post="%", + sep=",", + ) + + @render.text + def value6(): + return f"Value: {input.slider6()}" + + # Slider with ticks + with ui.card(): + ui.card_header("Ticks Display") + ui.input_slider( + "slider7", "With tick marks", min=0, max=100, value=50, ticks=True + ) + + @render.text + def value7(): + return f"Value: {input.slider7()}" + + # Date Range Slider with drag_range + with ui.card(): + ui.card_header("Date Range") + ui.input_slider( + "slider9", + "Draggable range", + min=datetime(2023, 1, 1, 0, 0, tzinfo=TIMEZONE), + max=datetime(2023, 12, 31, 0, 0, tzinfo=TIMEZONE), + value=( + datetime(2023, 3, 1, 0, 0, tzinfo=TIMEZONE), + datetime(2023, 9, 30, 0, 0, tzinfo=TIMEZONE), + ), + time_format="%Y-%m-%d", + timezone="UTC", + drag_range=True, + ) + + @render.text + def value9(): + return f"Value: {input.slider9()}" + + # Datetime slider + with ui.card(): + ui.card_header("Datetime Slider") + ui.input_slider( + "slider10", + "With time format", + min=datetime(2023, 1, 1, 0, 0, tzinfo=TIMEZONE), + max=datetime(2023, 12, 31, 23, 59, tzinfo=TIMEZONE), + value=datetime(2023, 6, 15, 12, 30, tzinfo=TIMEZONE), + time_format="%Y-%m-%d %H:%M", + timezone="UTC", + ) + + @render.text + def value10(): + return f"Value: {input.slider10()}" diff --git a/components/inputs/slider/index.qmd b/components/inputs/slider/index.qmd index 6d3d310d..24bfa1a9 100644 --- a/components/inputs/slider/index.qmd +++ b/components/inputs/slider/index.qmd @@ -27,6 +27,13 @@ listing: signature: ui.input_slider(id, label, min, max, value, *, step=None, ticks=False, animate=False, width=None, sep=',', pre=None, post=None, time_format=None, timezone=None, drag_range=True) +- id: kitchen-sink + template: ../../_partials/components-detail-kitchen-sink.ejs + contents: + - title: slider + core: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAEygrIEt4nvVi6ZVuzhd4eJmLgAvUnAA6ERfUZMAzgAtOEbLxj9BTAILoJdOFEJcAbnDOUWcOhICunRYoDETACJwa2nBMUEwkEGqcahTkktwycooAKgCSALIAogBaAPIAculMALyx8LIQcBguZIQe0OgA+m5FTG5YUADmcPU0ADZuLAAUikwjLZxt5T31XGQ9cENgAMo9nI50TAAKUHSwok5qvnAwxPJgAJR4w6OtPVDYxFX1JH0wEPUA7juoQxCjf0zeXIueB0TiEJjLVZOJgAWiYACMoBFwahtrsKHQ1Fd-mMMIRtoNsTjruN8XQWPUNBY1gsAEJIsFMIEgxmQtanC5E4m47SoR5qFY004CqF0ACMpwkp1S2gkMCgAA8JNYoH0FPgmDBtIUAAxyxWFMU6vVMFVqwoAVh1nN+3JJGAeZD5ZGmcAVZAWZpccAl50utpxNu5gOBTlZguh704ZA06goqC59rJhIDdtaycp1KcC0W8c2aPgGI5-rt9t5-IjdB+pZxwsrACZJUxTrm4Kh1JxpEFikam1qILr9QrDcblarvZaTVE2yPE4GSzXWo7na73Z7x3BG3650wg8TvAAlKAQToQys79ME6uL0kEzNQIVgI8noJspzFnd-Vrll0ioWpmtmzAP8nAAZibFs4DmKxgiYHYXz7bUTXlYcjRNL04EKAZQJNAB2a1P1GPdSyXKoVwoNdTgw8DtwAoiFxxbwfBEM9RQvW9yWvEiOIpKkH2zU5mIoVj2VowDvwgFcQKrQja2AysABZJVk-5IOgoQQjYChlLo0t+0KLTRDiAZ6x1etQIkMVLIkE0TTIaRtBoYhChSDIcnyYjAM1A1DKkEyzIspgxXrCRQKsphbIkezHOc1ysjydJPMAjCDJEPzTPMiQADZLItSyQqYHCoociAnJctJ4o8hivKkboBHlMhClOABSABNGFmpgDqWB0wCkuJUinUeCiPSojclLE4l+pGbwjAgbgRBYET3103Fky4tMePvR85oWiglrfOgP1Wr9xh-eppI2wC61FC0ILAAB1aNY2PPbOFIRCB2Qg00LHc0rQkV6GswxI6G9FTpv+QbyLdUawAwu7JvnHdvEOpgoxjUIXCiVQnLoBquBPdi8SvFTL3JbaBLAABhbGyFUAAxer2EJ9pjvEs7JIrUUrprG61iy3qvJGU4nsx1BzACBVgggJa1BcGgpaF4X9L1FS-hQkc1ZO4kUoB9XRglzDTgAEmVrz+CiJqwGa83ALUGdlPwCHqu5aHhth9c1UFpH-kh1HK3R57YkIABrLFVvJlMOZJim+MfRIwXD3xIlQW5sHZm8MHOy6DZF+TRVw+6xdjLgw+8uhw8+wdvNQ0dTQ3ScoqTtQXLBhQdZGSHTodMiPco+GNyL32-n93wWOfU80Yx2MWB2dp6ngzpifWsmtvjqmhKCSf1W7ssud-StedLfmnAATjtvmwB8ef2igeE5jg49l+dzv-n03zjIywLwvCyLJBKmVOK7lEquxrJrT+8B-KZSCgVMKNkEEAJiuVNyCU944hSsfLykD5jf1CtZCKiDoqlVihVEB6C7Q4OgYFM+oV-52UAaQ1BVU867jAaWWqeMGrWzah1LqzUeqv2FiMKQZRjZgAAKqJGppfUsc8OiL2fiDdu7C-aqJ7sufucMMIXxHvRFG48OBxHUOeSOPEsE9wzBvGS180rGMOpnbi2cD4XSPqw0+4odSyLtKLYOUgmBcPYN47kH87FQLwUFAh-9iFALIWg9RxIIFhNwQFfKoVwowItLQpBJCUGVVAawlKVCIk5SCnlWBdDirIOAfE1hnDmaNRau1Tq3UmDNQABKIGaqkYJxJRFyGtlImRQiawUPdi6EaXtvS9j0V3VRUYWAxmtgpY0qAFTmxtGcWoihHA0HUE4WwVYfwSE0WQCQDs1ARFIGcRARIAAC5hZZOAwCNe55hLA2AqHAWw5ABg-gwNJMUWzUy7IbmqMUAwbk7nMGQFwdBfg0FOAANQ3IgJgIB-mAshQAX1OLUP4DyHDPNeamQlHzOC2AwN8ygHpMUNmBX8UFGF6yQtuatGFcKEXItReiulooWVnFxWAfFoxCVPLoC82GbyLBWApV8n5tKD4AsrKBBlowmUblAqy6FohOUBO5WqNFGKlXSS1YKvFShSWPLWJK900ryWUupb8vlawFJqpGBqtUCltXst1fC-VYAUWGt5SaxSOKLXSvFbasg9rZWOoVX80Nt13WsH8GC70FofXcg5f6xFgaeXGudMq264bhWWoJda4lUqrUys+VShNLqnBZRTZ670WUs3EhzVy-NwbC1VGLQLUtIqRhiptSSitta5X1ppYmot0lcItrTRhXCHacRdoDUG70RrG10BXeastkax3VonQ6+VM6d1n0XXsnRq7-jrrzZuuA26k1rDPkO8torK0SvHZ+yd8bz0vqcEaK96afQ6lvX8e9Bqt0hrnZWI077ahoHbMUEw3xkONE4Ocg5ThgVgGxQAXSAA + express: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAEygrIEt4nvVi6ZVuzhd4eJmLgAvUnAA6ERfUZMAzgAtOEbBjgAPVHThq1vGP0G8IqAK5kJxiCzh0JtzosUBiJgBE4Gm04JigmEgg1TjUKckluGTlFABUASQBZAFEALQB5ADlMpgBeePhZCDgMe0IvCA8sKABzOAB9YlQyNQAKLjIAGzhi+TAAZX7OFzomAAUoOlhRVzMAmGIRiRpbfv7WgHdJsg1i5LpbOABKOoOjpgb+qGxie1aSftsYCH2F1G6DliOwzAABYAAyg1D6EYXRCKJjwpi+fIfVycQhMcaTVxMAC0TAARlAoujUPNFhQ6Go4Qibho7pwMIR5ixujDqQiEQ0mXQWK0NHAoFNuiMAEJEtFMZHwOgSzFTaHsjn0jDaOxkVpqCZCkaarF0ACMGyYI3S2gkMCg+gkADcoO8FPgmDBtMVQebLcV9eCbXbzsUAKygq5KCBKhEAAScUwwFH0ZEVHJcNCYtvt+tZsNDYaVxjItjooZoIwAar64IgmCBVfYMLqpumLgBfEZ1DlIlEy9Fy7G09QUVCK3tc5kZhOchnc3n8wWuYVjfuzMnwCkKrNhhrV9V12c6rWuABMRpGowXUWkIVKXqNzogrvd+k93pTZYDbr7cFQj+DY-hkco0djeM1yVJNn3tfdR2A7MmFzfNCxLMsKyrGwa23OgIKbFsQzbJgACUoAgFoMT3OhB04W5hx5SDoMoqcBW1MB8MIkJu1IsBgxohlNw1Ei5zQgBmI8xjgQZCCEMIFmY68XTfC0Hy9N9Uz9bp+LfAB2INvygiMo1cGMDCA6DQKUuB+Oo6CEVggsmCLMBS3tJDN1rEizMwsBWwRXw-BEYi9TIiiJxHNltPhWi+XoncwG8ihfPldif2Vbi0OFEKlV3PVgQ2BKOWPES4DE0JhAoLLUo5G9ijYDgEm6fdQX3fiJH1RqJDfN8yGkbQaGIE4MhyApMguPBsoROSKpEKQarqhqmH1fcJH4pqmFaiR2s67q0iyPJCkG4b4RMsaqvgSb6okAA2Rr-UauamFUlaOogLqes2-qdtKhEpFaLq6AtMggQAUgATRxP6YGBlgSos96EgqIYRgAVWSABhCHsy06C-2cPTAIS4yy2BczIas+C7MQysnLQ-G3I8+FfAAQQgbgRBYWLXH8ulaIJpUwunBj6cZihmdY1dOJVFCt143bjTAND-SEgB1ci6QI-nOFIaTb1kj0FJ9e1XwkZWfqGU5zgStHswxgCDJxwIwPOf1OegombIQhyybF5y9XtqnsM8lnpl7QhbBiVQvp+rhCLZ5VJwd8dGWZcKZzoOdEaDshVAAMQEMPtCaYXsw3MWeL1FLIfhdKplOlHIZGBXbiMQJOH0UJnHUWwaCCKF8El8q3W7rXvUl-bAyGt74XroEABIq4s-gYn+6foLUD8gSGrvUrNsMLaxq3Utx+1TpjsMnds+zzkc920IP73FV8VimF7LhCAAaypYCh0CqjgpFycE4Y5I0Rfv4aIqAHjYDzuuLihdkqS3Lq4NS8tFbxGfk6eYL91Z3hQfJJ8Q82oALUCcM4Ch17UyVFvOg+k4zW2TCZNSh8cyiDgs7EmrtkJqg9lMWh19gJeR8kxIid9ewsAWE0VokkWiRw5l-fOH86KJznNFEIfCHQcWkaLNURdtSjylmhAAnAvbMIw-DCKaFAfEgwYIEXEWvUuToXSVVENVWqJ0ZrNSWi1O6a0np9W2iPGxo17ETScdNWa81FrLUkPdR6G1vEDV8aXfaJcbEIgCY4qa81XHhNWg9davUtqxMlomcaqTnE6PmuEtqkScnPR8ZLV6NiPqh3YP9IGIMwb6LDFIGGQIEbI2saXIRzRRGWKNoQuJYYN6kN0uQ7Gu8bYmR0XQjkx8XZnzdmw3RrJmzuR9jTfwRSeBoQkTIuh3MIpJ0MfsliJFwFc0geo6BWjYEGlBO0tKYBa50ikDZLO7BXllTsZc46wSMnuIiZ46JeS6ml38YCoJV1QkSGcf6UpYLsleMhWMiy+0UlHThUwc6M1LozWurdVFUTckvUxdBBpPzfojEBsDUGf1mZ-QABKID+ukP5UNyhyG6UjV5EyORkIoYZbMe9zhekWZZBh1kT6k1YahEiUrvZgEbAAXSAA + image: thumbnail.png --- :::{#example} @@ -54,3 +61,6 @@ The value of an input component is accessible as a reactive value within the `se 1. Use `input.()` (e.g., `input.slider()`) to access the value of the slider. The server value of a slider is a number, date, or date-time (depending on the class of `value`). See also: [Slider Range](../slider-range/index.qmd) + +:::{#kitchen-sink} +::: diff --git a/components/inputs/slider/thumbnail-old.png b/components/inputs/slider/thumbnail-old.png new file mode 100644 index 00000000..7e4d41a7 Binary files /dev/null and b/components/inputs/slider/thumbnail-old.png differ diff --git a/components/inputs/slider/thumbnail.png b/components/inputs/slider/thumbnail.png new file mode 100644 index 00000000..c0743b56 Binary files /dev/null and b/components/inputs/slider/thumbnail.png differ diff --git a/components/inputs/switch/app-kitchensink-core.py b/components/inputs/switch/app-kitchensink-core.py new file mode 100644 index 00000000..e09157a0 --- /dev/null +++ b/components/inputs/switch/app-kitchensink-core.py @@ -0,0 +1,40 @@ +from shiny import App, render, ui + +# Define the UI +app_ui = ui.page_fluid( + # Create a card to contain the switches + ui.card( + ui.card_header("Switch Demo"), + # Basic switch with default parameters + ui.input_switch( + id="switch1", label="Basic switch (default params)", value=False + ), + # Output for switch1 state + ui.output_text("switch1_state"), + + # Switch with custom width + ui.input_switch( + id="switch2", label="Switch with custom width", value=True, width="300px" + ), + # Output for switch2 state + ui.output_text("switch2_state"), + full_screen=True, + height="300px", + id="card1", + ) +) + + +# Define the server +def server(input, output, session): + @render.text + def switch1_state(): + return f"Switch 1 state: {input.switch1()}" + + @render.text + def switch2_state(): + return f"Switch 2 state: {input.switch2()}" + + +# Create the app +app = App(app_ui, server) diff --git a/components/inputs/switch/app-kitchensink-express.py b/components/inputs/switch/app-kitchensink-express.py new file mode 100644 index 00000000..346de4ed --- /dev/null +++ b/components/inputs/switch/app-kitchensink-express.py @@ -0,0 +1,27 @@ +from shiny import reactive +from shiny.express import input, render, ui + +# Set page title +ui.page_opts(full_width=True) + +# Create a card to contain the switches +with ui.card(full_screen=True, height="300px", id="card1"): + ui.card_header("Switch Demo") + + # Basic switch with default parameters + ui.input_switch(id="switch1", label="Basic switch (default params)", value=False) + + # Output for switch1 state directly after the switch + @render.text + def switch1_state(): + return f"Switch 1 state: {input.switch1()}" + + # Switch with custom width + ui.input_switch( + id="switch2", label="Switch with custom width", value=True, width="300px" + ) + + # Output for switch2 state directly after the switch + @render.text + def switch2_state(): + return f"Switch 2 state: {input.switch2()}" diff --git a/components/inputs/switch/index.qmd b/components/inputs/switch/index.qmd index eab587f2..3f1b3561 100644 --- a/components/inputs/switch/index.qmd +++ b/components/inputs/switch/index.qmd @@ -25,6 +25,13 @@ listing: - title: ui.input_switch href: https://shiny.posit.co/py/api/ui.input_switch.html signature: ui.input_switch(id, label, value=False, *, width=None) +- id: kitchen-sink + template: ../../_partials/components-detail-kitchen-sink.ejs + contents: + - title: Switch + core: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbJjmVYnTJMAgujxM6lACZw6EgK4cAOhFUBiJgBE4NLnCZk2BgKoBJVWlQB9JUwC8TJVigBzONZoAbJdIAUqkxBTJoAwlJQFExQTIRQdNKGxLGkZFBchsasAO4cZITGLIHBznEJARDBVU4cGGXS1sZQsnQBYADKufls2nAwxMpgAJR4xdUhTABCUCwchDl5BUxdPbI0UApewqjxsHAUdEWV4zUYXKgKZNYsXQUVJ9Uc0vaDN4tsAIyDEl5QAEZwLwvMDTWbzN7dJh+NYbLZMHZ0WAsIbfJgANygPjg9gAYpiWHAxtURkSqpoAPKXC7CGiCBbdD6sNIUUklWrEKmXawUAAeZDaEIKH2uzMJw1GamO400nXeyzyPUIChYZEY8ukRlZQWc5y5grY9wewSewP1ACZUb8AUDBrLIStYsrVcxchq2KiMVj7AAVOgKOASV1GYEAZgADGHUDzBlqmCSpdUKZyaXTzUzIoSE1VnByyNTuXA+QLbmwzSKM4N4w8aJsvNdCFJKD6-QHY8YOK42GRQxGo99YybBvUvvgiSiIOPVBpenoIAYjAYCXQ0XJVGtWHIV61dWQJLnqRICSxZqQhogiQABKQQFoYXlkInr-XClUZvxn2NSMgKOiVGi2ksmEZV8KEQJgQB3DBn3fABfGME0va9b3vR9dHpAoyxAuB33PLNgi-H8-wAuUzXTUDwMg81YPgqcIDCCIogXaJ0EsdAHFEdA-CsWwOEPTc5HHMAYIAXSAA + express: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbJjmVYnTJM6cKITIcAbnAA6Eeo1aduGOAA9Uoli179BwrqgCuZPCMoATOHXPGO8+QGImAZTjDUUAOZwmksgAbOQh7LB84AH1iVDIWAAoaY0DAyIB3DksyNgBeABU6YzgASkcIFwBhUSgKJigmQig6S39iBtIyKC5-Nj8WDLJCXpZ5AbYmMMbmxOTUlkJRSnzCuHNejm82MhzZMABmAAYD1HVd80ydoibLAEZd4sR5JmeJjgwpy0jeqGs6eN3XAMhkwACJwGDEe5lF5MFwAISgLA4hFYQPGYyY1hoUGSniasA8NhGEBhYSMpki-Q4gzY8QuuypNLu+CYgSgACM4IFLgikSjGcD4licYE8XRYCxSiypFBAkUcgAxWUsEpPF5q54uADyphMwhoglR1KGN1YnVqlg4ogkgR4UBoFDoPT6aI1TAAAqIIL8MBR1GQ3VijUzKea4PEHm6YaIyMY6CSaAC0UxTSww4gmCByWQMAK2DcIwBfXbQl4uQHG9HU8aEYxppQZLJsN1kiB6ylo-4kmEvelgPMAJjOrI5XMuFZpTAxtfrzEb2WHMrlcGWRXM89yu0Ox1OYDdpW7zzd2t1piYBqdg7NNT8lutQTtDpszuDQzdnqsNl9GgDh8xcBoV82AHUMbwjR4-2jDw4wTJNKyYAdrwoDMszbUxczRAcixLCAwELABdIA + image: thumbnail.png --- :::{#example} diff --git a/components/inputs/switch/thumbnail-old.png b/components/inputs/switch/thumbnail-old.png new file mode 100644 index 00000000..dcdc613c Binary files /dev/null and b/components/inputs/switch/thumbnail-old.png differ diff --git a/components/inputs/switch/thumbnail.png b/components/inputs/switch/thumbnail.png new file mode 100644 index 00000000..0724e3c4 Binary files /dev/null and b/components/inputs/switch/thumbnail.png differ diff --git a/components/inputs/text-area/app-kitchensink-core.py b/components/inputs/text-area/app-kitchensink-core.py new file mode 100644 index 00000000..70ba252b --- /dev/null +++ b/components/inputs/text-area/app-kitchensink-core.py @@ -0,0 +1,39 @@ +from shiny import App, reactive, render, ui + +# Define the UI +app_ui = ui.page_fluid( + # Page title is set in the page_fluid + ui.tags.head(ui.tags.title("Text Area Demo")), + # Create a text area with all possible parameters + ui.input_text_area( + id="text_input", + label="Enter your text:", + value="This is some default text.\nIt has multiple lines.\nYou can edit it!", + width="500px", + height="200px", + cols=50, + rows=8, + placeholder="Type something here...", + resize="both", + autoresize=True, + spellcheck="true", + ), + # Add some spacing + ui.br(), + ui.br(), + # Add a header for the output + ui.h4("Output:"), + # Add the output text area + ui.output_text("show_text"), +) + + +# Define the server +def server(input, output, session): + @render.text + def show_text(): + return f"You entered:\n{input.text_input()}" + + +# Create the app +app = App(app_ui, server) diff --git a/components/inputs/text-area/app-kitchensink-express.py b/components/inputs/text-area/app-kitchensink-express.py new file mode 100644 index 00000000..5b3e1ae2 --- /dev/null +++ b/components/inputs/text-area/app-kitchensink-express.py @@ -0,0 +1,35 @@ +from shiny import reactive +from shiny.express import input, render, ui + +ui.page_opts(full_width=True) + +ui.tags.head( + ui.tags.title("Text Area Demo"), +) +# Create a text area with all possible parameters +ui.input_text_area( + id="text_input", + label="Enter your text:", + value="This is some default text.\nIt has multiple lines.\nYou can edit it!", + width="500px", + height="200px", + cols=50, + rows=8, + placeholder="Type something here...", + resize="both", + autoresize=True, + spellcheck="true", +) + +# Add some spacing +ui.br() +ui.br() + +# Add a header for the output +ui.h4("Output:") + + +# Display the input value in a pre-formatted text block +@render.text +def show_text(): + return f"You entered:\n{input.text_input()}" diff --git a/components/inputs/text-area/index.qmd b/components/inputs/text-area/index.qmd index 317a3090..d43921ff 100644 --- a/components/inputs/text-area/index.qmd +++ b/components/inputs/text-area/index.qmd @@ -27,6 +27,13 @@ listing: signature: ui.input_text_area(id, label, value='', *, width=None, height=None, cols=None, rows=None, placeholder=None, resize=None, autoresize=False, autocomplete=None, spellcheck=None) +- id: kitchen-sink + template: ../../_partials/components-detail-kitchen-sink.ejs + contents: + - title: Text Area + core: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbJjmVYnTJMAgujxM6cKITIcAbnAlSIAEzh0JAVw4AdCPoDETACJwaXOEzJsrAVQCS+tKgD6OpgF4mOrFADmcK40ADY6qgAU+kwxTMYACgFWcmQhVhwsrHDCXNa2TKhJwWEcqtGxvmQBLBi2UJGV1RgpaVFgACpwAB7CIlJQpnAwxLpgAJRjeOUxxgDC-RRMAxQ9S-1MAO4cNkshIQXELCwcAEZpBVB0sNkaLNM+HBhcqFpkritvl9JRELF-vKpPKMPq5nq9RlNfv8YiEoCc4CEgWAAKLkDRMbDELR0azdMiICH3P7yKBhOBI9qcTIZViMKzqGhQLQhYQfDC6fQOYRsKCZGDMuSoc4hSw1DkQACaWKYhCgvzgqm2vDIAEJCVDoVtVDYkQBWAAM+tQXXV0Jitg4-jYZCRACZDcbTWaSCEWJ4DZCzZJiBs3QAOT1moUyOBsYghdR0CnYVBWFh0mxcfxMWxSDDpp3QqTHABe5NGJ2INkz-yZZEEcFz5PadC0SiJsRYsb2hFshAA1kiyLW4CXJvdjCJVKpafBWIVCEn7r4TnQIv2NQ8MLP54GZqJh0sU9JI0waII8lYsWQXmRp482AAWNoAeVep4J4zXcQ3I5sR-vr1xqy+UHPGGPU93jxNp2B9YCelGBcxn0WCIGMMwLAgZJ8hYDRFDofQGSyOgMIiMEyAkQDXgkNCjg4UgxgJRcAAEVEjZo8XubCwI2CCyHnaivSkMhsV+GhRilLQmEoCgpFUAl9BAAjGJ6UEIFPecAF9RjgowmHmaRFnfJZ0GcdAvFEdAIhcdwOFI9CNBgiAwCUgBdIA + express: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbJjmVYnTJM6cKITIcAbnAA6Eeo1aduGOAA9Uoli179BwrqgCuZPCMoATOHXPGO8+faxQA5nAD6xVGRYAKGmMAGyCPAHcOSzI2AF4AFTpjOABKRwhnMjcWDDYxSz95JiKmDKyMSTIguAKwOI1hAEFRKCYAETgYYlkwZLx5VIgAYiYAYWaKJhaKdWEoZqYI6MmQpgEdDgAjKtW52DgKOhYnDgwjUw9psg85sQKIYt5LGO7LjzOybr774qCoDbggs8wABRcg2JjYYjGOhMS6IT6FYpSKBBJJAuKcXQcXQsRhwJjWGhQYLCS4YWTyACSwjYUF0MBJHFQ2yCXDg2QpEAAmlCmIQoPc4JYOIYyABCBHfIoRKKxboAVgADIrUOpJQ9chxXGwyECAEzK1Xq4okIIsGJKr4PBhhc0ADitxWZ4jgbGIQWsdHR2FQ+Nx8GiXFcTFyogw4eNRW0HAAXnAgRtiNFI5NTIJ2bH4wkko6iixfSFCLlCABrIFkRJyfD9NLDBqWSysPGsVDiIPHDAbOh+AbOLs92tMeuNlq5KCepg0QSw3JMKFkEwfdInNgAFhqAHlTIv4T00vJhq1sc6eNF8e8mMjUef7i0tHAALRTugwKBkCiNy5MLbEUvyAACogQJ65T1PIhLKMQYQXPUPbwlKFhkNC9w0N0PLGEwlAHEK8LyCA7ygTMbwQIuPYAL7dPIYBkQAukAA + image: thumbnail.png --- :::{#example} diff --git a/components/inputs/text-area/thumbnail-old.png b/components/inputs/text-area/thumbnail-old.png new file mode 100644 index 00000000..b3394631 Binary files /dev/null and b/components/inputs/text-area/thumbnail-old.png differ diff --git a/components/inputs/text-area/thumbnail.png b/components/inputs/text-area/thumbnail.png new file mode 100644 index 00000000..0ab4c914 Binary files /dev/null and b/components/inputs/text-area/thumbnail.png differ diff --git a/components/inputs/text-box/app-kitchensink-core.py b/components/inputs/text-box/app-kitchensink-core.py new file mode 100644 index 00000000..eae9eb6a --- /dev/null +++ b/components/inputs/text-box/app-kitchensink-core.py @@ -0,0 +1,32 @@ +from shiny import App, reactive, render, ui + +# Define the UI +app_ui = ui.page_fluid( + # Create a card to contain the input and output + ui.card( + ui.card_header("Text Input Demo"), + # Create text input with all possible parameters + ui.input_text( + id="demo_text", # Required: unique identifier + label="Demo Text Input", # Required: label text + value="Initial value", # Optional: starting value + width="300px", # Optional: CSS width + placeholder="Enter text here", # Optional: hint text + autocomplete="username", # Optional: browser autocomplete behavior + spellcheck="true", # Optional: browser spellcheck behavior + ), + # Output area for the current value + ui.output_text("current_value"), + ) +) + + +# Define the server function +def server(input, output, session): + @render.text + def current_value(): + return f"Current value: {input.demo_text()}" + + +# Create and return the app object +app = App(app_ui, server) diff --git a/components/inputs/text-box/app-kitchensink-express.py b/components/inputs/text-box/app-kitchensink-express.py new file mode 100644 index 00000000..b5e3d74f --- /dev/null +++ b/components/inputs/text-box/app-kitchensink-express.py @@ -0,0 +1,25 @@ +from shiny import reactive +from shiny.express import input, ui, render + +# Set page options for a clean layout +ui.page_opts(full_width=True) + +# Create a card to contain the input and output +with ui.card(): + ui.card_header("Text Input Demo") + + # Create text input with all possible parameters + ui.input_text( + id="demo_text", # Required: unique identifier + label="Demo Text Input", # Required: label text + value="Initial value", # Optional: starting value + width="300px", # Optional: CSS width + placeholder="Enter text here", # Optional: hint text + autocomplete="username", # Optional: browser autocomplete behavior + spellcheck="true", # Optional: browser spellcheck behavior + ) + + # Display area for the current value + @render.text + def current_value(): + return f"Current value: {input.demo_text()}" diff --git a/components/inputs/text-box/index.qmd b/components/inputs/text-box/index.qmd index 4fefa27d..29582e0b 100644 --- a/components/inputs/text-box/index.qmd +++ b/components/inputs/text-box/index.qmd @@ -26,6 +26,13 @@ listing: href: https://shiny.posit.co/py/api/ui.input_text.html signature: ui.input_text(id, label, value='', *, width=None, placeholder=None, autocomplete='off', spellcheck=None) +- id: kitchen-sink + template: ../../_partials/components-detail-kitchen-sink.ejs + contents: + - title: Text Box + core: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbJjmVYnTJMAgujxM6cKITIcAbnAlSIAEzh0JAVw4AdCPoDETACJwaXOEzJsrAVQCS+tKgD6OpgF4mOrFADmcK40ADY6qgAU+kwxTMYAwlJQFExQTIRQdKrWxOmkZFBc1ra8EKhawlBqTMQV5WTRsb4ZWVEQsR0+HBgtqq62UOp0UWAAKnAAHsIOZRWmcDDEumAAlHiNnXFMidIpFFOl9UwA7hw2qSEhTAIsLBwARiFWqJmwcBR0LBudvlz1rvsyG1NpsOKpPMt1IsAZMGvgYsYAEpwACOOikqkQPggHDRVjBlDkFg03xBTBCUHucBCELAZkWTHGBxm9WWEi2yLRHAxWIpVKugNJIPkUDCcFpMzOHFFTBFYrZCKYAHlUHJSKKsSwCkIuP5ZaKtHAhZtTqobLSAMwABitqAmCq2KrV0BCWPiAGV3ScwTZjZ1UBTCHA2MQQkNaQBRcgaaywpi2KQO4xOjjq13xrjCQXtMmxKAVYgkfhPCi0rQsDTQeBJ5Wq1MurH3BjHCt0VIFosB95WKlsKDyVN0P0dFioakhQi2QgAa1pZDohprKbTjebrdYY8uk7gM6Yvf7g79az9ybqc0y0iYNEExSshC0dBUwjli5zm18tTI-0BI3vj8JrgvkaqzrG+TArPoEEGNBxhmBYEBWDYVitoobY0FoECyPW+jqDQrAaKhER-BUEifvUEgVrc9YrIg3wAAIqEMGDZh0uHpA+T6AQacARDRfpSGQD7tDQyzxBxhL6mKWIgMRZAYFCxAwlMvEAL7LPoGkQAkSQpFU2QCUJt6pOgNT3AAVjuDTQCZ3hiKgEQuO4HAUQRGhQWAKkALpAA + express: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbJjmVYnTJM6cKITIcAbnAA6Eeo1aduGOAA9Uoli179BwrqgCuZPE2MdzoiABM4defIDETAMpxhqKAHM4TYlRJUl0aQSYoJkIAGzEIJmiobGJTeUssXzgAfUCyFgAKGmNo6KyAdw5bMjYAXgAVOmM4AEonCFcAYVEoCgioqDpbJjJiKNIyKC5htn8jUwi7ANMTMnkK6osODEIB23zmxHkmY83t3ayZqHs6fNkwOo1hAEkIFaYAETgYYjvWiCOTp1ur0KOpDK95us2BESkwBDoOAAjWJwgawTwOFgA47pOZkLKgsi3eInUmVGp3ezfAmPO7mJiuABKcAAjpZRLZEBYIBw2bN7OQODQOA5saSElBEXBohSwJ9vkwHmCmC8VnTjkzWey4JyJVLosNaSTxUwpFBok1ZS8OJJzabzU11QymAB5IIcUjmrksCZCLg+e0WuTG8UVKq1O4AZgADNHUOona43cFoNEuR03G4mGHqmLSahEoQ4GxiNFrrKAKLkByG5UzUSJ13uz1ppgqYSEvMnKCmYgkfixCiy4wsBzQeCN5Me1NcxEMMqjugRXv9gsYphSthQKQexwh0ksVDS6KEGaEADWsrIjTk+A1TZTXo388XrCPJVPcAvG+L293Yr+MVXHeDhD0SHgBjEJgwiXap-EIYw6BsYQzSDMUAAEbGuDBOxDewaCiRDkKyVCmn2Q59xOUQyEQ+IaDuDoiMoFCHTgLkQDxDAqWIGkwX2ABfO55DAfiAF0gA + image: thumbnail.png --- :::{#example} diff --git a/components/inputs/text-box/thumbnail.png b/components/inputs/text-box/thumbnail.png new file mode 100644 index 00000000..ea2c02e1 Binary files /dev/null and b/components/inputs/text-box/thumbnail.png differ diff --git a/components/outputs/plot-seaborn/index.qmd b/components/outputs/plot-seaborn/index.qmd index b463b12e..262ab341 100644 --- a/components/outputs/plot-seaborn/index.qmd +++ b/components/outputs/plot-seaborn/index.qmd @@ -71,7 +71,3 @@ Follow these steps to display a Seaborn figure in your app: You can use a plot as an input widget, collecting the locations of user clicks, double clicks, hovers, and brushes. To do this, follow the instructions provided for [plots as inputs](plot-matplotlib.html#plots-as-inputs). -## Variations - -:::{#variations} -::: diff --git a/components/outputs/value-box/app-kitchensink-core.py b/components/outputs/value-box/app-kitchensink-core.py new file mode 100644 index 00000000..3af9fc30 --- /dev/null +++ b/components/outputs/value-box/app-kitchensink-core.py @@ -0,0 +1,134 @@ +import pandas as pd +import plotly.graph_objects as go +import shinywidgets as sw + +from shiny import App, ui + +# CSS for the beating heart animation +heart_beat_css = """ +@keyframes beat { + 0%, 100% { transform: scale(1); } + 50% { transform: scale(1.2); } +} + +.heart-beat { + animation: beat 1s infinite; + display: inline-block; /* Helps ensure transform works correctly */ +} +""" + +# Create custom icons, adding the 'heart-beat' class to the heart +chart_icon = ui.tags.i(class_="fa-solid fa-chart-simple", style="font-size: 6.5rem;") +chart_thumbs_up_icon = ui.tags.i( + class_="fa-solid fa-thumbs-up", style="font-size: 6.5rem;" +) +chart_star_icon = ui.tags.i(class_="fa-solid fa-star", style="font-size: 6.5rem;") + +# --- Add the heart-beat class here --- +chart_heart_icon = ui.tags.i( + class_="fa-solid fa-heart heart-beat", # Added 'heart-beat' class + style="font-size: 5rem; color: red;", # Optional: make it red +) +# --- --- + +chart_lightbulb_icon = ui.tags.i( + class_="fa-solid fa-lightbulb", style="font-size: 6.5rem;" +) + +data = pd.DataFrame( + {"Year": range(2018, 2024), "Revenue": [100, 120, 110, 122, 118, 130]} +) + +app_ui = ui.page_fluid( + # Add Font Awesome CSS and our custom animation CSS to the app head + ui.head_content( + ui.HTML( + '' + ), + ui.tags.style(heart_beat_css), # Include our animation CSS + ), + ui.br(), + ui.layout_column_wrap( + # 1. Basic value box + ui.value_box( + "Revenue", + "$5.2M", + "Up 12% from last month", + id="left_center_value_box", + showcase=chart_icon, + theme="primary", + ), + # 2. Value box top-right + ui.value_box( + "Active Users", + "2.4K", + "Daily active users", + id="top_right_value_box", + showcase=chart_thumbs_up_icon, + showcase_layout="top right", + theme="bg-gradient-purple-red", + ), + # 3. Value box with plot + ui.value_box( + "Conversion Rate", + "3.8%", + "Increased by 0.5%", + id="bottom_value_box", + showcase=sw.output_widget("graph"), + showcase_layout="bottom", + theme="text-success", + ), + # 4. Value box full screen + ui.value_box( + "Total Sales", + "8,742", + "Year to date performance", + id="full_screen_value_box", + showcase=chart_lightbulb_icon, + full_screen=True, + theme="bg-gradient-orange-red", + min_height="150px", + max_height="300px", + fill=True, + ), + # 5. Value box with beating heart showcase + ui.value_box( + "Pending Orders", + "156", + "Requires attention", + id="custom_bg_value_box", + showcase=chart_heart_icon, # Use the icon with the 'heart-beat' class + theme=None, + class_="bg-warning text-dark", + ), + width="300px", + ), +) + + +def server(input, output, session): + @sw.render_plotly + def graph(): + fig = go.Figure() + fig.add_trace( + go.Scatter( + x=data["Year"], + y=data["Revenue"], + mode="lines+markers", + line=dict(color="blue", width=2), + marker=dict(size=4), + ) + ) + fig.update_xaxes(visible=False, showgrid=False) + fig.update_yaxes(visible=False, showgrid=False) + fig.update_layout( + height=100, + hovermode="x", + margin=dict(t=0, r=0, l=0, b=0), + plot_bgcolor="rgba(0,0,0,0)", + paper_bgcolor="rgba(0,0,0,0)", + ) + return fig + + +app = App(app_ui, server) diff --git a/components/outputs/value-box/app-kitchensink-express.py b/components/outputs/value-box/app-kitchensink-express.py new file mode 100644 index 00000000..e02718e8 --- /dev/null +++ b/components/outputs/value-box/app-kitchensink-express.py @@ -0,0 +1,133 @@ +import pandas as pd +import plotly.graph_objects as go +import shinywidgets as sw + +from shiny.express import ui + +ui.page_opts(full_width=True) + +# CSS for the beating heart animation +heart_beat_css = """ +@keyframes beat { + 0%, 100% { transform: scale(1); } + 50% { transform: scale(1.2); } +} + +.heart-beat { + animation: beat 1s infinite; + display: inline-block; /* Helps ensure transform works correctly */ +} +""" + +# Create custom icons, adding the 'heart-beat' class to the heart +chart_icon = ui.tags.i(class_="fa-solid fa-chart-simple", style="font-size: 6.5rem;") +chart_thumbs_up_icon = ui.tags.i( + class_="fa-solid fa-thumbs-up", style="font-size: 6.5rem;" +) +chart_star_icon = ui.tags.i(class_="fa-solid fa-star", style="font-size: 6.5rem;") + +# --- Add the heart-beat class here --- +chart_heart_icon = ui.tags.i( + class_="fa-solid fa-heart heart-beat", # Added 'heart-beat' class + style="font-size: 5rem; color: red;", # Optional: make it red +) +# --- --- + +chart_lightbulb_icon = ui.tags.i( + class_="fa-solid fa-lightbulb", style="font-size: 6.5rem;" +) + +data = pd.DataFrame( + {"Year": range(2018, 2024), "Revenue": [100, 120, 110, 122, 118, 130]} +) + +# Add Font Awesome CSS to the app +ui.head_content( + ui.HTML( + '' + ), + ui.tags.style(heart_beat_css), # Include our animation CSS +) +ui.br() + +with ui.layout_column_wrap(width="300px"): + # 1. Basic value box with left-center showcase layout (default) + with ui.value_box(id="left_center_value_box", showcase=chart_icon, theme="primary"): + "Revenue" + "$5.2M" + "Up 12% from last month" + + # 2. Value box with top-right showcase layout + with ui.value_box( + id="top_right_value_box", + showcase=chart_thumbs_up_icon, + showcase_layout="top right", + theme="bg-gradient-purple-red", + # height="200px", + ): + "Active Users" + "2.4K" + "Daily active users" + + # 3. Value box with bottom showcase layout + with ui.value_box( + id="bottom_value_box", + showcase=sw.output_widget("graph"), + showcase_layout="bottom", + theme="text-success", + # height="200px", + ): + "Conversion Rate" + "3.8%" + "Increased by 0.5%" + with ui.hold(): + + @sw.render_plotly + def graph(): + fig = go.Figure() + fig.add_trace( + go.Scatter( + x=data["Year"], + y=data["Revenue"], + mode="lines+markers", + line=dict(color="blue", width=2), + marker=dict(size=4), + ) + ) + fig.update_xaxes(visible=False, showgrid=False) + fig.update_yaxes(visible=False, showgrid=False) + fig.update_layout( + height=100, + hovermode="x", + margin=dict(t=0, r=0, l=0, b=0), + plot_bgcolor="rgba(0,0,0,0)", + paper_bgcolor="rgba(0,0,0,0)", + ) + return fig + + # 4. Value box with full screen capability and custom theme + with ui.value_box( + id="full_screen_value_box", + showcase=chart_lightbulb_icon, + full_screen=True, + theme="bg-gradient-orange-red", + # height="600px", + min_height="150px", + max_height="300px", + fill=True, + ): + "Total Sales" + "8,742" + "Year to date performance" + + # 5. Value box with custom background color using class_ + with ui.value_box( + id="custom_bg_value_box", + showcase=chart_heart_icon, + theme=None, + # height="200px", + class_="bg-warning text-dark", + ): + "Pending Orders" + "156" + "Requires attention" diff --git a/components/outputs/value-box/index.qmd b/components/outputs/value-box/index.qmd index af90ea5f..eed9409d 100644 --- a/components/outputs/value-box/index.qmd +++ b/components/outputs/value-box/index.qmd @@ -85,6 +85,13 @@ listing: - styles.css - economics.csv shinylive: https://shinylive.io/py/editor/#code=NobwRAdghgtgpmAXAAjFADugdOgnmAGlQGMB7CAFzkqVQGJkB5da5ASwmQGcALD3ADZsAbnGQVS3OGKgATWWwptyUAcgBmbAXC4AdCPvUAnUjGTooFHkIBG7GOlJGKyAAqWe+-WwdOXFiFkoLmRg81lvX2dzAVIKAVwsOAAPdCMdELD0ZMjHaN5+AHc2WQBzOApMkK5CwxMzAohcezyXAEFMIgBXNi9oTAUjZABeNw8ACgB9Sc1taYBKHCh0yj6MdEmekeQepfKZtmS4WXH9ZHOdtiwOYgEu2ThJ4i4ucfXB5AB6ZF0wLgpBDosM89GB5gQzhddsJVF1HjZSMlTpwLqjfgAVOKqZAAZVUOnYnAAigAmX4QlGo86-AAkJKwABYAKwAWXJkKp3B4pEKxGCcGGNSwpC6FHQosmxTKFVOfwsRgA1kIIHBfuCOVTeDy+VxHgIoLgRRRhr8ERQJDB2ZTkOrrbN9TY5jBSDYtAL0UY4RT5n19A91FIjKIjOMOOKKEQjeGiLqXsoIPNEBqAAJClYPIySkrlCga-3ceVKjhwcaJjWouBkCCmNjPbboWRYdJyJ5cYRvAZsIbfX6V8g157Attq8sXTSlevJLDKkt96swWtcIjJE1gIJUcnIXCr9BcKDB3Ng0fncdYLoNyyPChGKDEHTIzmcmdPUixIyrugMgAMADYAKIAGIAIxWo+VLPlKVjDEBFJgai9qrhIABecAmLgoFwSeWgCGQb6rkYpQ2FA4w-gyBBAUBX4ECSDIwV+WAkj6hDHlS3LBhw6ikKu6HMdaqI+nxY5sKUZ4XlQkzJFARyvMIbBcGwjoCgBqi6jG3KFKURglMMykCLqAlgae57ro8uBSfesnyYpOkqXAak8pp2m6fpLFGWJeoGkaD6YcgPBwMJPDGpRVEsaibGoc6DyrjkvE+cgMDLKUHDDAoxAUOMxpUcg75ZQIwxZTY+W2nF6CxBQkw2KUuFOPhhHEVRDUEF+TGwT5FgsJmlXVe+vwEUR4yNQ1LUsQZj7pBQXRGJw46+v06DbB06AdhsPQxqhwYCYQqAAiwtBgFQyQUGAAC+RDgNA8B7f8gJcEOXBbWAVZUDQKBgAisjNCAkIWPIHClAAtBI6AoEB6QwAA3Pox19FgNhcLY-0wnccD-QiyTIDgZUJBjkVwERRj-U9UDFkMX0ogoXClQaKDViqkMQNDBgQFgjS4P9bB4FKOb-VGorIGT5wU1TuAoOo2jJPTJ7iyDyBAaEoqSAAhD4rRQJQkvIJBPAg1+X4AKT04z+gs3wTTs5z2YVDzorhsgAB8yAAFT85CQv6iLGjixrYspDLctQArGtazr+uGzDrPm7gXNW7zLgO878cu+TcnC6LXuQj7yR+-LEhByUVghwbUPh6bbMc1HlsUNbYp84nddO0ngsp+7acpN70uy53Ae55Cwey7rRcM-oD07Qgr0HUdp385AsBj6gc4DrdzzCA9T3UEdr0mQQ6B3tvpDoNve4HgQcIOPAsgnyqDixOhEAkrrX7-V+QFPzBP5MgAzEyWAf9RAAcX4ACcAB2H8BBv5kW-n-cBwCvx-30PfXWT8SSvwID+H8QFAFYGAf-CigCqIMiwNAn8WAYJMj-uQhBD8n4f1QegihRDcHfkAQQQhTI0EwI-h-KhSCvwMjoT+YBQFSG4Pfr-dhJCyEMj-iBO+1CvxMjobA4BWAwEkhkX-YBODCEsKgTAyhcjeE-iUQyD+WAWHqJJEBEkYCdHgOweA9+sjEGPy-MApRpERGWI-hQ+xJIOFMmAQyYBPDXF-yUYArBMFLFiL8Wgn+4CKHcMMa4wBdC-5-3pBYzJgCP7+LYXEpkP4SRMlCf9Si6SMkMX-nk5+rDVHxLIZ-BkZSKJ0PwfSMi6iP7Ml-gUyRjiP6ANaSgupP5AHMgcd08ZtjqlgKKT0nhL9n7tK0TUwB996nQL0T+L8JJkmIOWaMt+kS9HqNoh-bR5jGloLgcMwxyzaFjMAZo655yv5UW-r-EhYCMG0SWU-fhdTYHP2qec8hZD7EsOKUIgFCjUGwOCV4v+0jKL1IkQk4pNi4XGOBb+eiOD1FMl-PkrAEi0HSJaQ8p+7i8XAPpP4olH8gH2N+Yw9+f8Dm62WeE4FlE-5vIoYEqiJDiHXMRWSalQCEXP3pNAolKLf44JUf4oRDJJWHPKa4mC9K4GMn-rsl5BAzFkRUUq8ZVLNVtL5YIwVP4ekwUITqhxACvxcpWdYhFQEkWEr-u-WB6KCACv8ZkgxiDjleqCQk9RgiMk3IFWRDRGrdajOOQQelQEBW-xjZEyBjCs1BqsaUwxoynk6v2Sq-+Qj8FQqDfqzlfCeGjKBTq5lECq1DJwXogVLCKGRKbU-RRwLLFTM0cU75ZKCBYPYZy-tJan64tbZmsFmi-VkRIWRCiQahnutGbS1tAD9XqJkQo+xM7rmzq-AOuBCLvzCPYcej+uz7FkV7cyy1Kan5pOBUM6JGSMHbIcdOwtTJnGfoqcC0xBL-4ZIDd-HBWCwENpCfO61OrmRYN9YAyi8ygMJIoffAdnrgWgblf-XJQFxGTsQ0G0iV7DFloRZ-Mxf7AGgcA+wmjBH6OIKeWm4Bn9v7ZJAd61lU7J1+szTwp5Zb01MheUev+kSt1fPEzgihGTpOAoRcU6J+DrHsNU5RapGT1VafhcC4pAq9NuoZLh6BWDe1sZQ7xhdOngECrUfg8heawEUWozYn85n93puAT4sF+DMkioScZ3++mwNuqfrynVnKCkkmw24-xfn6IwQyYAoLDGv0Is5Q+7DeSyHVOMyGjZCXaEQZS5Mwl2HAl5t-sZxNYXk2JbQ+mpTNH0uZrcS+8i9Ff4UNAVp4jOqNlYMZRs3WgHN30UTR-ICLndYtoRS8lRXSasbPASNhpnLYE8KBWmgBmDGHpf2T+bZh2Q1AUEadmhqCAGgOohsopjrrlVaDQybDz2+GvbgZ5j7JItG6IScBmRJ3DFAqHblx7Zi5vpZAfYuLF6rFdaBYuoN3rK3pbyfs+x0Ct2ZL9YDkLmTl0WNyXZqjY2L2UYK4goFyWQMsY+5czBcTZvpsiTxjbRW6mcqsV43JIn6lgJo8AjZ62gf1e3VGrz6rmWBuh7+BL-Cesovvg09LDI7OzJgph-neTntTb+zIydBuLXxJYcB2XizDEI9e8E+ic3-uibMQh-VWiUU8KHedpk6WIugdPSa8TqqXmC4s7Jih4ybdsfUTgsx0uElaMuYH7TIvSLfy80yf7VFOcsNAfS7PFncukTMbT4VZEzGcZEaA0DFfceaJoldtjuS1HXNLyHj9Fmqc5KTwBnvIbGFBN-BX9nGS8lHvy4bqi9Jfeqp6cWxBQ7v25YyWc-LyjqIur90yT+2fFdKZsfr-LID-Gc9B0Ek-LvynLNy7kgVpXdWp4k5OgT6DT-nav5fkEqtsaofsquDvcogouqgt5lgvKiAqRFcuPmArAqRDwrimmvgvguLh5oXvUv4lEumpmgPrirJthiSPSHpgAs+oQuPsqplmgTnibmtoQnAeTo6nWqatYrHrigjlOkWuLiivliAdAm-mgjHgwb+NATRPRKwWFiwqahntyhISFrkuQZfn1mApHtAkIgJhIezqocInARsvaiAUhn7kAglrilvlOl-IQk1mxrgWnkGmgiivLsYorrkmFhFi8l-KYemtcoIuDgwT1q-h7sag-BMiAb2piu3sERgXZiwsyrZsXg4iohIqAl1vutAaBiQr-EkS1iAephnhRCzrrLShgYXqKuEXAnsvUrlpOuMkEYYrSqQeQt-DBMypRFYvUq+iIoIqtjwrSi2lOhgvBuEQZmRDQXWr8hQrHrSrwflqBgkp0dIn0nWllqAqUW4m5nUvlrankc-HIcIf4TguMrLoMTStAbAjRsyqzoUXWsqt6hAWUUllcZ-NcrcTYp-omhPr+PLrStYSAiAh8XspUSAeeo8bDogu4h4Zkqnnsm9iAT8aahWhcSEUpiotAsym2vXiInftIWiRgZFvqtiSnn4QmumnnjwsltAbksXm6sSpoUBpSRQtScgrSZRiSW6kIt9vUcqv9vLryqQV3lyUMkNj8cqpkl1rysMZEvlowu+hRN8eJqavaoKYOqgsFO8ViXwnkkqhPhekMuvgtjsTBJRJRCookXwsfrhpxkGoEsaTetsXUuaXwg4u+rLtAoQr0epp4WyU6WabrBMu6QotaccabhMj4v6dYcFKYpOm2syvIQ4r9hMhMmyR4flqNuEcfrgd-Owu1iNm4gPuEuiXrjqYEn6vEr0aTgolGYYiWRgWFtBsyrsnwlWYdvmdYhToYlvlcZygqSSnAvEv4sZjglwWGkGeybsZseEXRv4nmeRMImOeoi8jwt+qQUIqIS2eQoBiwtYjFj0tij2YwVOvSiwbOR5qcYwpyWaT4g-ogt+gsUEj2rOS8j8SOVMd6v9s8dKpIbsVQSCbqmymOZWvjm4muZcf+bRCGUAdCuRH5nZs-BBQGVOvlh0W4rduwnYo9jFqigPt+oCbPlybLnZrWmttecSkAhBRmatiCRopDpui+UBIJl1mkiERMvROwsyiipmmRbAeRCHpgtRUSQplaX6lwrWnrmacSquXIvVpqQ-IYeEbPhOtElRMxXwqURBmmsFMyg0omXsl2teY5gJRRFyhBrJsFEpiIomVjvYoSstgJffMmhBsMeafuVadhthgxFuhutRBQQJXksaRBrweacAYmU+lgrWemv5bhYIVQhBrjuaUsfXkAoXm-rUSQhYt-B+cEh+hBiFuaSiiGSApMuMmKvKvSG1syNYglWEgpeQcGuEaciolohihYmaXZtInVcLoGTRIkeaaAoyOgvEg5bhYEs8RUorpRO+u6TNZEuYuQvEmosIh+TkT1T1jNYXnNQomxtgqRMtdRNJXAmBlNTpW6hsjZRadbrAuwiotEsInuaYt1XJc-gpaYguatkArstggoV0veuRHeuZUcu9bAldRRJyZcsgfrsIreVFglY8gpcfpxcahRDYhAm2YSgDZRmFuttam5Qoq8poRRKYiQvsmKhYvRHuUaXjcsqFZrjfiUW4lgEOVlUdQ0pRkKgjaaSNvalUatmtt5eQfqYyp0uREMsUtzc6YGYImkajZgsCXwqXtGiOVDcDa8S6W4rrPpdYvfF8oIv4aLfqpzVJq9b1SNmFtZqjTRKHhRBVf5eLRMvAmbdNW4u8R0dYqRE6vJvEvKvRH5l-GmS7c-hbfJvGV2aHiHkqtRDIeLbcdzZbhafStUqtkkZhtYv4X7ZOpRkAuZRGprX6gFanZmixrLs4WWeROAXjamgpWxg3qjVwuFiAupuRKbl2ZRglaWrXUsViZRt+T-OMnWvmXztYkInnSeZRECXNU+raqPQ8a3SIp7XZp3RqZrflqDqnQ2mSozqTiZZ7bsivX+YGRMrkajXemkZEQQXrpujYhsofYVUAloind6lYgSpWU1eRfmejVpaMuzhRBtldYbmoQ6s4cujfcEqdaMjGThgDatl1SQkEtESOQKqTlYsxSvdNZPfxXA0kuYh5nWrvT9ljvlSgptWZfzRpdqSYW3aDlwQohgzpSTSjatlHcviHpXeRK1ZXels7ffJRq-JqVwWRiwz4tOmxvEm1notYhAwlXxoI-sjccxSHjlqYiTpw5VpgsSrIy9i6brfdajUUsUgxDRGRSon5o9kpto0Dro3rSScxTDkQsfu2eRWaWtgfXJU8qFdI4QsTfJv2e-OusmfoyUYXlY0lZ7Sg6jRgkIizeqr7Zw4uQJqdU8oVdYvKankjuQtgvgz8vBRo1wsFU8n-ZRqHozRyqNuDqNXk52eAVY9AzPR8RY7+KQiUvEzhTU1Cc-HVtqoubRNg2tnsgyleW1qfRDU+to2Q9ImY6jfSuoizTYsOeo4GZeRM4w6BpaTM7RPeqBs42aiNt+PlZtro6RuHQJrkuYsTsE+2l0XsglWdoI4Y8-W1WYrPv4ZIz9rZpNUCpZY9qo6trLuRffPqZulI26gAncxPQM-SMTQAtZVYtocbWMSArc3JfDoI8+XY5konsSndcbT41On2hC0fYuTDqjSip4sxaqsbS81OohUS6k36sw5muglVbdv4fmSXrsrw8-GzoIxMoQnkZmkpj7pWaBVklOvJl8+bXgoEnY2QTlUITtuLfqsYS5drj00I4K7ku8WFgoarUdgLhC5tXrcIvXpo54vfMrW1nFkAoLt6uUjpffMUqjaVZIoEv4X5uK5omtgla7i6ffKRatpEnM6RNDWOcjkGvguZUHpqffJkiSdCWwluhsx5bRpRL6zo2aUWgWrUvsm-dDTffaY2nJUOm5VYuc1iQG3sgxOI9M-5jOiHj+CPLgLtOPCkJPAALpAA +- id: kitchen-sink + template: ../../_partials/components-detail-kitchen-sink.ejs + contents: + - title: Value Box + core: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMASxlWICcyACVKCAEygGcXe2nADoQ6DZmwA2xMpOwYA5ozQALAPrEARgCs4hMnwELiIsU1Y8VNCNgDuNTgrgH+fHrZEiAZo2IwWltbYLGYSAILoeCwArjSeEADELADCAMqpLF5MLGQqcCyacFBk1goseVASHHTFNKQiFcxqhcVqhDx8ALwsQmC9-RAAAgDWcNg+sHB8LawgIiwsAAwApFEAjIsrLCA5yhA8WYwwiAGEUJJwABRrAJQA3CwAvvMsAKxbO2R7B0zHp+dXNYYABM9yeImeEBEGEaZAAtDNti9qjBaqQToi1nxrF5rDQKHcXpwaDxUJIoNgTtZJNY4AjpIRhg8APQAKhYAAk4JJUHxKDxoox8l8OD8jixbExhnwSIwhfo5CxWcyIZ4+ur4klkkLivlCNEeGQ-CESPsolBOMSIGVcvkAOSwhFFMh2liEckdHLEHJ5cpFZgiQgqSpkNQ0U0sbqxDBkKAKHgYGiXd28HhqTq9LxQOE8Yg0ziZbNBkM5sQXXpRQ3YC4ZsBZcilgBecBOADYMK8hTBCWAboHg01ctEYJo09FUGGI1GaDG4wmky8FimOunM9nc-nC3ChyOeHDxxWAmRq3Ba-X4TwaM22x2uz2RH2IMWmobKpPSJGYjPY-HE8mPWmZ7rnmDhbq+jCHlWNaZqQF5Xi2LDtp2cDdr0j4iEkcJYSwYSWj6+SOoiy58HkQosFhcL9iGaiwu+ECftGP7zpci5ugBq51sBm5ZnCsJ+iWMyHiwSS4ZwcAFg6-rwjMrrEaxUGnjBDaXtebx3m6eZMCcQqcD2UTCSwADyqAlKQ5wnKiowhKwOkPhh5HYRR8TPqGNIKCoZCaNEkiaHRDHfnOf6scRHE8RuoE8W5HleT5kHHtBdawU2CFIXeAzoVwxRQJ+qCcBgAAiWUAGLKPALH0QsSJgAAmv6vTaRwTiXMCixrAAHFELXAgALDcUS9AASnAABulDRHA9UsMAGyLOsLXrBsc3AgtHUsGsADMiwALqQhlaATrE-lYHGcBqF4kixJw5WVQZoksEVsE4bYUx+PkaQZBwBbEIKboGka-gomi9HvV6+H8Og-HCBVCzRhUnBtLBlBkNdN2VdGHIACoALIADIo6jqN2gAPDSEDDCwQqSLWCmWHAzi9OUQpeLWHlkLyiDMsyhCcBA2gJu632cOdlRwBgJAwMyUDaFAAAezI0qOzLnnCUDPbm8DMu2ADsIJcx0kuSJIGAwNYYsdL0AB8dqsTdfU22jAW-gply0TMbQdH1CxJAAkk+F1iSw32MPwoioqZwPpKxdvQ1+GCaIwlzRzd0bktg32hiQF0wBAai2MoqD46jSRAiwABCvDhiww3nONBTEDL9swzO1cXadmj14XBMLINI1jRN+CN6jvQACSvCCWMVoPN29AAqqga3AssmS+P4HqsDAsEqJPMddyEnC1hcXgZ0jcCMGoLfjc09fb7vN2WMQthnDwp4uXReBT5VtrwLWqCMDUjDYBvl3JOXckjAgwCwAAajXfI7cZZelQHCP+7kyCD2jBfNuHcP7dzAGEfQNBRosBns-RgPAgG3x6GAcB3UADS5Db69EKjQRUUB8GEINKfMhA8d5dwcLWI0E5kEeXPjAq+DduEUIWPfR+vAX4DlDDuUcahxxv2wQEFQD8n6nVTunfhxB55CNQRIyRX9FJgE0AoOESgLQ0CRnCVAgoyR0lssYgmICCZJHWhA6Brc67wPsLkKQMg0HN1EXAzuXdejJFIKNUhdR6IDV1PQ3evQvFtWWMkyJYBfaEB1M-AsmhgiLA7Bk1xt8+G9HbmQf6IjW5iMyQTaRWjOjuAwOnBxoZ7COGcCxMA1jUBb17O-HhjSNEyOfmoHR0QyC1iqf9BpqNTH8LgDLC80RCCECmFw4Zu93FFxYN1bxMC-GZG8pIU4QpKAhIwBgsRESCa9AxjIc4LBUgAm2Wo3oHUtbdWBAs6eNV-Sg24BQNgp9DioifP3HZkiKl1jOWoHguS6Y51uXA-5lUmmyM6K-KKnlvK+XDKQGFFCvAIqRZciAnQMaMHGiS2+SzKmWOscSOxTBGrOPEhihYJsc55BoCg2sax3ioHEfS3eqIZY0TgAKjytZNqLFFdyzIzCqY0rpYPPZN0khjygccuBEp8QqAKM6Uo-EJBYuftctFWCRlDzAAABUoFaMohlGBiVIcq3owrWxerAENAAjrEIUhhqlI3icquF+pDR+GaAoWpl90VlN3pauR1FaJEogPpJIxDhS+kzYawJtoWCSQEs6WSAE1FLIAHKkDgOKruIVZmWNsJUUQ1ocgrPhNwRgwwFlasql03I8rNhKrKdHDKIgxJeACKfWJlxrAdKiO06ZlYtnxJuIgVigxWlCi4KfNQZIZByFYtOlg-SVCJy3Xa3EZRujGAwEVAVgoriPl3rejAFp4Yik2fc1GD7UhnDDQnNRN0ZadBBVAYAvRaqVF6FtBtFDsAQaytB-1vcIDjXg4h2+G8xIH1pDwAA1KiXtnDlU3VJqeYk+hkyaUYLM1uh4h0qE6KCHDErKijAYzR5GKlTy9Q45VN9wDB4fvHCC06MtZZTEuMNEkNBNA1iKucZ+lYxlKD4SpyQz8RME3E7lXUahsAyZ4HJhTSnTzabU+oh+mn97WbgHp1GBnJOTIpOnP9N1+WCpmkJhYGjYl4bMWKtRpGFDWAg+GZGMzZoU06HFqmcXNAJYHQTI9oYLGZyYLWRgChNBQEuLNYreBFh9mTV3dgqAD1Zfo7l-LhWSvFfKzh5zN0hRkEFPRW98QRD7U-BEAu+1lE0DXYwWJj4wCPC2kAA + express: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMASxlWICcyACVKCAEygGcXe2nADoQ6DZmwA2xMpOwYA5ozQALAPrEARgCs4hMnwELiIsU1Y8VNCNgDuNTgrgH+fHrZEiAZo2IwWltbycAAeqIxwPHxmEgCuNJ4Q8VhQThqoBgAUXrGSkmr2nGQqALwAKoyxcACUiQDELADCAMrNLF5MLMVwLJpwUGTWCiwq-RIcdAM0pCKjUMxqfQNqhFEsJSxCYFs7EAACANZw2D6wkb39rCAiLCwADACkeCwAjHePLCBdyhA8HYwwRABQhQSRwTIvaoAbhYAF8biwAKwfL5kH5-JiA4Gg8EvDAAJmhcJE8IgIgwc2YAFollcERMYFNSEDaa9ohAvNYaBQoQjODQeKhJFBsEDrJJrHAadJCAcYQB6ABULAAEnBJKg+JQeLEIt8OBiASxbEwDnwSIwIvo5CxFfKSZ5tk76k0IgMeoRYjwyH4WDQSL9nlBOPyIMNuiwAOSUsg0y6RliEYVrH1dUYjMZkESEFTzMhqf2kdYsZJkVI8DA0TJJ3g8NQlLZeKBUnjECWcdrNnN5ltiMFbZ7e7BghtgDrkXsALzgQIAbBhEREYLywLUIN2FsVYjBNHXYqgCwHi6Xy5XMgjbjWovXG83W+3O1StzueFT9wOAmRh3BR+PYzwaGnOcFyXFcRDXDd829eZDyLDYTwUCsqyvOtfzvNsHEfaDGA-IcR0bUh-0AmcWHnRc4GXLY1xEBoqTolgAEEQzTHoYzjAZE2TPhRj1OiqWzXMFhjWCIGPGgMDLRCzwvTjaxvMd0IfJsqRjDMe1pD8WAaJjODgDto0zdiyATFCZLwn8CInACgKRUDEzbJggQiTgV2eLSWAAeQyaZoEkIFGSOP1WGc8CaJYPjwroxJILUCUFBUMhNFyTQRLEiTTyrGSUPk5T70w5S4oSpLJE0XCv3wsdCKnEiyNA3ZqK4AYoGLVBOAwAARJqADFlHgc9RNuT4tgATTGLYnI4JxMnxO4XgADmeGb8QAFmqZ4tgAJTgAA3SgqnGlhgDeO5nheGbTreU78XxC6FteABmO4AF1SQa7TmK6wjGNsSI-B6Fo2lTCM0FQERkjmTgVkIygyH6waS3ElUygAWQAGTh+HBsjAAeCUIAOFgIkkUdzMsOBnC2EYIi8UcErITVEHleVCE4CBtArJNiFiTgvGFCIMBIGB5SgbQoBCeUJV3eU-ypKAftbeB5XnAB2AlmaiYW8gwGBrAFqItgAPkjGS1pkhCK3MzJhNpFYojW24GgASXXSRuZ6LnGH4URGUGIsAdCpJxM0RhMga+xigRjBhWwLn8xIV2YAgAplFQTJCmKUdHruVAQioxAZIaPEWAAIV4f0WG20Eql6YgQmNbkVBYMEvFjQgYbgT3LGIWwQR4Hpo9jlhMl0ptcjINd4fDxvkkr124EWWvMgcUdm7j9vGDUWeqgX3P8ACFRu97n8YsLCBnm6eBR3CSZGGwPOZPhzadr2uBdkxwatgAEkRAlkbf9-NhgAAKqoFePiB47RfD+GTKwGAhEVC7ALiwfEGAWAADUq49E0LXeuEcfSoCpIwGg8ULAHx7rwfuIpY4ySnpHLe89sEhAxu-ZeWx8FqCISQzemCd4DgfoNLu5C+4lBis+Xcah9wiTwPw24gij6xSobEMgo58GE2IQlPhA134XwsmATQCgqRKGDDQGGVJUC6iFFKEK+AZHuVGOo5RWwZrZ13tIrRLBqj53cY-MADF9A0F2iwIBfdGA8H-u-JxGBloAGlwmYy2J1GgNooD+MCV6DuYTthkncQ0e6qCMFzxrnXWh2CyA+n8HIihTdFFZncbQmePDGHMMxqwvRMhyncLnrwmx3iBFkKPiUdwGBY7mPzIUJwsMthGNQAg1cbiAH70PhQhRMclGjlKeUzRCydEqNCP+WIhA276x6Qsho9iSGjmcTnLZg1PG2K2I0Ugu1Qk+RYBtd0cSfF5Lmg8T5H8wDO0IG6PuHZNDYHuAuX5WSFn1PEgfSQnBQ5eNsfDPYQyIhcA7moIUMg5AosGiPFg0yVBIvxe-TkwwNjGAwF1YhupwQTwWQAilGBgyQzRCk8EZKmXUuaCCMpHdmlMuFSwEIJRuBlmACNMaYAnrzJFQq7A4qmpSrAFtXaSRX6yvlQq4VcDdIr0lDwAA1IyRgRxQk3N1UyvGP5+T6GrA5Rg6y54fnTqUQkOrrUALNRa8V-pYbWR-KtL13qPHcvhoy61LL9wSvniEMWkRMjbQFDQTQI4uqgj7oOMhShl6ZskH3KNuqY2tXdGobAiaeDJtTemn8Bbs2LNsHmzgJQG01AjYNUtcaVmxyFd685CUSjHVDQO4gzz9W6NcZ29+ZqFDWH9Q65RJ1CYlBXcTFdmg12m16danF+Z9HxyYKORgChNBQEyCdK9eA7i1BOWGwa7BUBYsPU6k9Z6L3XqvXe0dwri0KoiGQXUokKWJHhg0Za+TMFFNwY3HIeRgQREoImNAUBNBJO5OCjgHZPTel9DomhDc6GNMXrY1p8H8g8CBeTJO9Dum-qbQMmKhVErJSkbYijagqNIYgOUSocAGM7K2Powxyh+SmKYJNKxekrWYzOXABxo5ZzvGufe2d1g1CDscWAF4yJVMMcZCETTCmLlbCzvpjjSTiYVCqF6u5u7AFlBkKCFgzQcSZPuWABaytlr4j+bcaV8wujEBYHGtgHd-iMnXFqsDg0Gg-3QdBxhsHExenKb0FJBwlBcy4PZaQnsvRDFkteQjEcGldKaWR1tWxcMdP0Z07ejDZPw0qcImKwlT6CdGJfAAcqQATtj5OKacSp6dDnsrrIMbYeYogwxdD2VSbg5rZP2YWVsAACpQUMwwPKMF0pa6FACti6dnP5wBW0ACO8QIiGAFeQHyuwwCwiekAA + image: valuebox.gif --- :::{#example} diff --git a/components/outputs/value-box/thumbnail.png b/components/outputs/value-box/thumbnail.png new file mode 100644 index 00000000..09900ff0 Binary files /dev/null and b/components/outputs/value-box/thumbnail.png differ diff --git a/components/outputs/value-box/valuebox.gif b/components/outputs/value-box/valuebox.gif new file mode 100644 index 00000000..5a96eab9 Binary files /dev/null and b/components/outputs/value-box/valuebox.gif differ diff --git a/images/plot.jpg b/images/plot.jpg new file mode 100644 index 00000000..dcce39ae Binary files /dev/null and b/images/plot.jpg differ