glasstabs

Animated glass-morphism tab navigation and multi-select filter widgets for R Shiny

CRAN status R-CMD-check


Overview

glasstabs provides animated Shiny widgets built around a glass-morphism aesthetic:

All widgets are self-contained, themeable, and work in plain fluidPage(), bs4DashPage(), or other Shiny page wrappers.

Full documentation: https://prigasg.github.io/glasstabs/

Both widgets are self-contained, fully themeable, and work in plain fluidPage(), bs4DashPage(), or any other Shiny page wrapper.

Full documentation: https://prigasg.github.io/glasstabs/


Installation

# From CRAN
install.packages("glasstabs")

# From GitHub (development version)
pak::pak("prigasG/glasstabs")
# or
devtools::install_github("prigasG/glasstabs")

Quick start

library(shiny)
library(glasstabs)

ui <- fluidPage(
  useGlassTabs(),
  glassTabsUI(
    "main",
    glassTabPanel(
      "t1", "Overview", selected = TRUE,
      h3("Overview"),
      p("Content here."),
      glassFilterTags("cat")
    ),
    glassTabPanel(
      "t2", "Details",
      h3("Details"),
      p("More content."),
      glassFilterTags("cat")
    ),
    extra_ui = glassMultiSelect(
      "cat",
      c(A = "a", B = "b", C = "c"),
      show_style_switcher = FALSE
    )
  ),
  verbatimTextOutput("info")
)

server <- function(input, output, session) {
  tabs <- glassTabsServer("main")
  filt <- glassMultiSelectValue(input, "cat")

  output$info <- renderPrint({
    list(
      active_tab = tabs(),
      selected = filt$selected(),
      style = filt$style()
    )
  })
}

shinyApp(ui, server)

Note: useGlassTabs() must be called once somewhere in the UI before any glassTabsUI() or glassMultiSelect() call. It injects the shared CSS and JavaScript as a properly deduplicated htmltools dependency.


Function reference

Function Description
useGlassTabs() Inject package CSS and JavaScript, call once in the UI
glassTabsUI(id, ..., selected, wrap, extra_ui, theme) Animated tab bar with content area
glassTabPanel(value, label, ..., selected) Define one tab and its content
glassTabsServer(id) Reactive returning the active tab value
glassMultiSelect(inputId, choices, ...) Multi-select dropdown widget
updateGlassMultiSelect(session, inputId, ...) Update multi-select choices, selection, or style
glassMultiSelectValue(input, inputId) Reactive helper for multi-select value and style
glassSelect(inputId, choices, ...) Single-select dropdown widget
updateGlassSelect(session, inputId, ...) Update single-select choices, selection, or style
glassSelectValue(input, inputId) Reactive helper for selected value
glassFilterTags(inputId) Tag-pill display area synced to a multi-select
glass_tab_theme(...) Custom color theme for glassTabsUI()
glass_select_theme(...) Custom color theme for glassSelect() and glassMultiSelect()

Shiny inputs

Input Type Description
input[["<id>-active_tab"]] character Currently active tab value from glassTabsUI()
input$<inputId> character vector Selected values from glassMultiSelect()
input$<inputId>_style character Active selection style from glassMultiSelect()
input$<inputId> character or NULL Selected value from glassSelect()

Multi-select example

library(shiny)
library(glasstabs)

choices <- c(
  Apple  = "apple",
  Banana = "banana",
  Cherry = "cherry"
)

ui <- fluidPage(
  useGlassTabs(),
  glassMultiSelect("fruit", choices),
  glassFilterTags("fruit"),
  verbatimTextOutput("out")
)

server <- function(input, output, session) {
  output$out <- renderPrint(input$fruit)
}

shinyApp(ui, server)

Note: By default, glassMultiSelect() starts with all choices selected.

Server-side updates

server <- function(input, output, session) {
  observeEvent(input$clear, {
    updateGlassMultiSelect(
      session,
      "fruit",
      selected = character(0)
    )
  })

  observeEvent(input$fill_style, {
    updateGlassMultiSelect(
      session,
      "fruit",
      check_style = "filled"
    )
  })
}

Single-select example

```{r single-select} library(shiny) library(glasstabs)

choices <- c( North = “north”, South = “south”, East = “east”, West = “west” )

ui <- fluidPage( useGlassTabs(), glassSelect( “region”, choices, clearable = TRUE, check_style = “checkbox”, theme = “light” ), verbatimTextOutput(“out”) )

server <- function(input, output, session) { output\(out <- renderPrint(input\)region) }

shinyApp(ui, server)


## Server-side updates

```r
server <- function(input, output, session) {
  observeEvent(input$pick_south, {
    updateGlassSelect(
      session,
      "region",
      selected = "south"
    )
  })

  observeEvent(input$clear_region, {
    updateGlassSelect(
      session,
      "region",
      selected = character(0)
    )
  })
  
  observeEvent(input$fill_region, {
  updateGlassSelect(
    session,
    "region",
    check_style = "filled"
  )
})
}

Theming

All widgets default to "dark". You can switch to "light" or supply a custom theme object.

# Tab widget
glassTabsUI(
  "nav",
  glassTabPanel("a", "A", selected = TRUE, p("Content")),
  theme = glass_tab_theme(
    halo_bg = "rgba(251,191,36,0.15)",
    tab_active_text = "#fef3c7"
  )
)

# Multi-select
glassMultiSelect(
  "filter", choices,
  theme = glass_select_theme(
    mode = "dark",
    accent_color = "#f59e0b"
  )
)

# Single-select
glassSelect(
  "region", choices,
  theme = glass_select_theme(
    mode = "light",
    accent_color = "#2563eb"
  )
)

# Built-in light preset
glassTabsUI("nav", theme = "light", ...)
glassMultiSelect("f", choices, theme = "light", ...)
glassSelect("s", choices, theme = "light", ...)

glass_tab_theme() handles

Argument Controls
tab_text Inactive tab label color
tab_active_text Active tab label color
halo_bg Sliding glass halo fill
halo_border Sliding glass halo border
content_bg Tab content panel background
content_border Tab content panel border
card_bg Inner card background
card_text Inner card text color

glass_select_theme() handles

Argument Controls
mode Base preset, either "dark" or "light"
bg_color Dropdown panel and trigger background
border_color Border color
text_color Main text color
accent_color Ticks, badges, checked states, and clear controls
label_color Optional field label color

Checkbox styles

glassMultiSelect() and glassSelect() support three selection indicator styles:

Style Appearance
"checkbox" Ghost box with animated tick
"check-only" Tick only, no box
"filled" Solid colored box with no tick
glassMultiSelect(
  "f", choices,
  check_style = "filled",
  show_style_switcher = FALSE
)

glassSelect(
  "s", choices,
  check_style = "check-only"
)

Hues distribute automatically around the color wheel or can be set manually under multi-select:

glassMultiSelect("f", c(Apple = "apple", Banana = "banana", Cherry = "cherry"),
  check_style = "filled",
  hues = c(apple = 10L, banana = 50L, cherry = 340L)
)

bs4Dash compatibility

Pass wrap = FALSE when embedding inside a bs4Dash card.

bs4Card(
  glassTabsUI("dash",
    wrap     = FALSE,
    theme    = "light",
    extra_ui = glassMultiSelect("f", choices, theme = "light"),
    glassTabPanel("a", "Overview", selected = TRUE, p("Content")),
    glassTabPanel("b", "Details",  p("More"))
  )
)

Multiple instances

Multiple glassTabsUI() and glassMultiSelect() widgets on the same page work independently — each is scoped by its id, so CSS variables and JS event handlers never bleed across instances.


Articles

Full vignettes are available on the documentation site:

Article Description
Getting started Progressive walkthrough of both widgets
Animated tabs Full glassTabsUI() reference with theming and bs4Dash
Multi-select filter Full glassMultiSelect() reference with styles, tags and updates
Single-select filter Full glassSelect() reference with search, clear, and updates

Roadmap


License

MIT © glasstabs authors