--- title: "Single-Select Dropdown with glasstabs" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Single-Select Dropdown with glasstabs} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} editor_options: markdown: wrap: 72 --- ```{r setup, include=FALSE} knitr::opts_chunk$set(eval = FALSE) ``` ## Overview `glassSelect()` is an animated single-select dropdown for Shiny. It behaves like a standard Shiny input: `input$` stores the selected value as a single character string, or `NULL` when nothing is selected. It supports: - optional labels - search and clear controls - built-in dark and light themes - custom theming with `glass_select_theme()` - selectable marker styles via `check_style` - server-side updates with `updateGlassSelect()` ## Basic usage ```{r basic} library(shiny) library(glasstabs) fruits <- c( Apple = "apple", Banana = "banana", Cherry = "cherry", Mango = "mango" ) ui <- fluidPage( useGlassTabs(), glassSelect("pick", fruits), verbatimTextOutput("out") ) server <- function(input, output, session) { output$out <- renderPrint(input$pick) } shinyApp(ui, server) ``` ## Initial selection ```{r initial} # No selection (default) glassSelect("f", fruits) # Pre-select one value glassSelect("f", fruits, selected = "banana") ``` ## Optional label ```{r label} glassSelect("f", fruits, label = "Choose a fruit") ``` ## Selection styles `glassSelect()` supports three selection marker styles: - `"checkbox"` (default) - `"check-only"` - `"filled"` ```{r styles} glassSelect("f1", fruits, check_style = "checkbox") glassSelect("f2", fruits, check_style = "check-only") glassSelect("f3", fruits, check_style = "filled") ``` ## Searchable and clearable Search is enabled by default. You can also enable a clear control. ```{r search-clear} glassSelect( "f", fruits, searchable = TRUE, clearable = TRUE ) ``` To hide the search box: ```{r no-search} glassSelect( "f", fruits, searchable = FALSE ) ``` ## Explicit “All” option You can prepend an explicit “All” option: ```{r include-all} glassSelect( "f", fruits, include_all = TRUE, all_choice_label = "All fruits", all_choice_value = "__all__" ) ``` This is useful when you want the UI to distinguish between: - no selection - a deliberate “All” selection ## Server-side access Read the current value directly from `input$`: ```{r server-direct} server <- function(input, output, session) { observe({ message("Selected: ", if (is.null(input$pick)) "NULL" else input$pick) }) } ``` ## Reactive helper If you want a small convenience wrapper, use `glassSelectValue()`: ```{r server-helper} server <- function(input, output, session) { pick <- glassSelectValue(input, "pick") observe({ print(pick()) }) } ``` ## Updating choices and selection from the server `updateGlassSelect()` can update: - available choices - current selection - selection marker style ```{r style selection} observeEvent(input$filled, { updateGlassSelect( session, "pick", check_style = "filled" ) }) ``` It follows Shiny-style update semantics: - `choices = NULL` leaves choices unchanged - `selected = NULL` leaves selection unchanged - `selected = character(0)` clears the selection ```{r updates} ui <- fluidPage( useGlassTabs(), actionButton("subset", "Keep first 2 fruits"), actionButton("banana", "Select banana"), actionButton("clear", "Clear"), actionButton("filled", "Use filled style"), glassSelect("pick", fruits, clearable = TRUE), verbatimTextOutput("out") ) server <- function(input, output, session) { output$out <- renderPrint(input$pick) observeEvent(input$subset, { updateGlassSelect( session, "pick", choices = fruits[1:2] ) }) observeEvent(input$banana, { updateGlassSelect( session, "pick", selected = "banana" ) }) observeEvent(input$clear, { updateGlassSelect( session, "pick", selected = character(0) ) }) } shinyApp(ui, server) ``` When `choices` is updated without `selected`, the widget keeps the current value if it still exists in the new set of choices. ## Theming ### Built-in presets ```{r presets} glassSelect("f", fruits, theme = "dark") glassSelect("f", fruits, theme = "light") ``` ### Custom theme with `glass_select_theme()` ```{r custom-theme} glassSelect( "f", fruits, theme = glass_select_theme( mode = "dark", accent_color = "#f59e0b" ) ) glassSelect( "f", fruits, theme = glass_select_theme( bg_color = "#1a0a2e", border_color = "#a855f7", text_color = "#ede9fe", accent_color = "#a855f7" ) ) #other themes glassSelect( "f", fruits, theme = glass_select_theme( mode = "light", accent_color = "#2563eb" ) ) #more themes glassSelect( "f", fruits, theme = glass_select_theme( mode = "light", bg_color = "#ffffff", border_color = "rgba(0,0,0,0.15)", text_color = "#111111", accent_color = "#111111", label_color = "#111111" ) ) ``` ## Standalone usage `glassSelect()` can be used without the tab widget. You only need `useGlassTabs()` to load the package CSS and JavaScript assets: ```{r standalone} ui <- fluidPage( useGlassTabs(), glassSelect("region", c(North = "North", South = "South", East = "East")), verbatimTextOutput("out") ) server <- function(input, output, session) { output$out <- renderPrint(input$region) } shinyApp(ui, server) ```