The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
editor_options: markdown: wrap: 72 —
Animated tabs and select inputs that feel at home in a Shiny app.
glasstabs gives Shiny apps polished navigation and filtering without asking you to write custom JavaScript or CSS. The package includes:
glassTabsUI() for animated horizontal or vertical tab
navigationglassSelect() for a searchable single-select inputglassMultiSelect() for multi-select filters with
optional tag pillsThe widgets work in a regular fluidPage(), a
bslib app, or a bs4Dash dashboard. Each one
can use a dark, light, automatic, or custom colour theme.
Install the CRAN release:
install.packages("glasstabs")Or install the development version from GitHub:
pak::pak("prigasG/glasstabs")Call useGlassTabs() once in the UI, then compose the
widgets like ordinary Shiny controls. This app places a filter beside
two tabs and displays the current tab and selection.
library(shiny)
library(glasstabs)
choices <- c(Apple = "apple", Banana = "banana", Cherry = "cherry")
ui <- fluidPage(
useGlassTabs(),
glassTabsUI(
"main",
glassTabPanel(
"overview", "Overview", selected = TRUE,
h3("Fruit summary"),
glassFilterTags("fruit")
),
glassTabPanel(
"details", "Details",
h3("Selection details"),
verbatimTextOutput("selection")
),
extra_ui = glassMultiSelect(
"fruit",
choices,
show_style_switcher = FALSE
)
),
verbatimTextOutput("active_tab")
)
server <- function(input, output, session) {
active_tab <- glassTabsServer("main")
output$active_tab <- renderPrint(active_tab())
output$selection <- renderPrint(input$fruit)
}
if (interactive()) {
shinyApp(ui, server)
}glassMultiSelect() selects every choice by default. Use
selected = character(0) when the filter should start
empty.
Tabs are made from glassTabPanel() objects. The first
selected panel is shown when the app opens.
glassTabsUI(
"reports",
glassTabPanel("summary", "Summary", selected = TRUE, summary_ui),
glassTabPanel("table", "Table", tableOutput("results")),
glassTabPanel("notes", "Notes", textAreaInput("notes", NULL))
)A single-select behaves like a standard Shiny input. Its value is
available at input$region.
glassSelect(
"region",
c(North = "north", South = "south", East = "east", West = "west"),
label = "Region",
clearable = TRUE
)A multi-select returns a character vector and can display the selected values as tag pills anywhere in the UI.
glassMultiSelect(
"status",
c(Open = "open", Review = "review", Closed = "closed"),
selected = c("open", "review"),
label = "Status"
)
glassFilterTags("status")Use theme = "auto" in Bootstrap 5 or bslib
apps so the widgets follow the page’s light and dark modes. Use
shape = "square" when the controls sit next to native Shiny
inputs.
glassTabsUI(
"nav",
glassTabPanel("one", "One", selected = TRUE, p("First panel")),
glassTabPanel("two", "Two", p("Second panel")),
indicator = "underline",
theme = "auto"
)
glassSelect("region", choices, shape = "square", theme = "auto")
glassMultiSelect("filters", choices, shape = "square", theme = "auto")Tabs also support a vertical rail and three indicator styles:
glassTabsUI(
"workflow",
glassTabPanel("intake", "Intake", selected = TRUE, intake_ui),
glassTabPanel("review", "Review", review_ui),
glassTabPanel("approve", "Approve", approve_ui),
orientation = "vertical",
indicator = "solid",
tab_align = "left"
)For a custom accent, change only the fields your app needs:
glassTabsUI(
"nav",
glassTabPanel("a", "A", selected = TRUE, p("Content")),
glassTabPanel("b", "B", p("More content")),
theme = glass_tab_theme(
halo_bg = "rgba(37, 99, 235, 0.16)",
halo_border = "#2563eb"
)
)
glassSelect(
"region",
choices,
theme = glass_select_theme(mode = "light", accent_color = "#2563eb")
)Inside a bs4Dash card, compact = TRUE
reduces spacing and wrap = FALSE lets the card provide the
outer container.
bs4Dash::box(
width = 12,
glasstabs::glassTabsUI(
"dashboard",
glassTabPanel("summary", "Summary", selected = TRUE, summary_ui),
glassTabPanel("detail", "Detail", detail_ui),
compact = TRUE,
wrap = FALSE,
theme = "light"
)
)The widgets expose familiar Shiny inputs:
| Widget | Current value |
|---|---|
glassTabsUI("main", ...) |
input[["main-active_tab"]] |
glassSelect("region", ...) |
input$region |
glassMultiSelect("status", ...) |
input$status |
| An open select dropdown | input$region_open or
input$status_open |
Server helpers cover common programmatic changes:
server <- function(input, output, session) {
observeEvent(input$next_step, {
updateGlassTabsUI(session, "workflow", selected = "review")
updateGlassTabBadge(session, "workflow", "review", count = 3)
})
observeEvent(input$reset_filters, {
updateGlassSelect(session, "region", selected = character(0))
updateGlassMultiSelect(session, "status", selected = character(0))
})
}Use glassTabCondition() when a regular
conditionalPanel() should follow the active glass tab:
conditionalPanel(
condition = glassTabCondition("main", "details"),
p("This appears while the Details tab is active.")
)For hundreds or thousands of choices, keep the full vector on the server and send a small page of matches to the browser.
many_choices <- stats::setNames(
sprintf("value-%04d", 1:2000),
sprintf("Choice %04d", 1:2000)
)
ui <- fluidPage(
useGlassTabs(),
glassSelect("item", many_choices, server = TRUE, server_limit = 30),
glassMultiSelect("filters", many_choices, server = TRUE, server_limit = 30)
)
server <- function(input, output, session) {
glassSelectServer("item", many_choices, session = session, limit = 30)
glassMultiSelectServer("filters", many_choices, session = session, limit = 30)
}| Function | Description |
|---|---|
useGlassTabs() |
Inject package CSS and JavaScript—call once in the UI |
runGlassExample(example) |
Launch a built-in example app (runGlassExample() lists
all available apps) |
glasstabs_news() |
Print the package changelog to the R console |
Built-in examples include basic, bs4dash,
bslib, connect-workflow,
dashboard, indicators,
server-select, smoke-test, and
square-corners.
| Function | Description |
|---|---|
glassTabsUI(id, ..., selected, wrap, compact, shape, indicator, orientation, tab_align, extra_ui, theme) |
Animated tab bar with content area; use compact = TRUE
for dashboard cards |
glassTabPanel(value, label, ..., icon, selected) |
Define one tab and its content; icon accepts
shiny::icon() |
glassTabsServer(id, bookmark) |
Reactive returning the active tab; can bookmark the active tab in the URL |
glassTabsOutput(outputId) |
UI placeholder for a server-rendered tab widget |
renderGlassTabs({expr}) |
Render a glassTabsUI() reactively; JavaScript
reinitialises automatically |
glassTabCondition(id, value) |
JavaScript condition string for conditionalPanel() |
updateGlassTabsUI(session, id, selected) |
Switch the active tab from the server |
updateGlassTabBadge(session, id, value, count) |
Set a numeric badge on a tab button (0 hides it) |
showGlassTab(session, id, value) |
Show a hidden tab |
hideGlassTab(session, id, value) |
Hide a tab from the navigation bar |
disableGlassTab(session, id, value) |
Disable a tab while keeping it visible |
enableGlassTab(session, id, value) |
Re-enable a disabled tab |
appendGlassTab(session, id, tab, select) |
Add a new tab at runtime |
removeGlassTab(session, id, value) |
Remove a tab at runtime |
glass_tab_theme(...) |
Create a custom colour theme for glassTabsUI() |
| Function | Description |
|---|---|
glassMultiSelect(inputId, choices, ...) |
Multi-select dropdown widget |
glassMultiSelectServer(inputId, choices, ...) |
Server-side search for large multi-select choice sets |
updateGlassMultiSelect(session, inputId, ...) |
Update multi-select choices, selection, or style |
glassMultiSelectValue(input, inputId) |
Reactive helpers for multi-select value and style |
glassSelect(inputId, choices, ...) |
Single-select dropdown widget |
glassSelectServer(inputId, choices, ...) |
Server-side search for large single-select choice sets |
updateGlassSelect(session, inputId, ...) |
Update single-select choices, selection, or style |
glassSelectValue(input, inputId) |
Reactive helper for the selected value |
closeGlassSelect(session, inputId) |
Close one open single-select dropdown |
closeGlassMultiSelect(session, inputId) |
Close one open multi-select dropdown |
closeAllGlassSelects(session) |
Close every open glasstabs select dropdown |
glassFilterTags(inputId) |
Tag-pill display area synced to a multi-select |
glass_select_theme(...) |
Create a custom theme for glassSelect() and
glassMultiSelect() |
| Input | Type | Description |
|---|---|---|
input[["<id>-active_tab"]] |
character |
Active tab value from glassTabsUI() |
input$<inputId> |
character vector |
Selected values from glassMultiSelect() |
input$<inputId>_style |
character |
Active selection style from glassMultiSelect() |
input$<inputId>_open |
logical |
Whether a select dropdown is open |
input$<inputId> |
character or NULL |
Selected value from glassSelect() |
The glasstabs
website includes focused articles and a searchable function
reference. Release notes are available in NEWS.md or from R with
glasstabs_news().
If a widget does not fit naturally into your app, please open a GitHub issue with a small Shiny example. Questions, bug reports, and ideas for making the package easier to use are all welcome.
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.