knitr::opts_chunk$set(eval = FALSE)
Tabs often begin with three short labels and grow with the app. This article keeps that larger version comfortable on a phone, with a keyboard, and under system accessibility settings.
library(shiny) library(glasstabs) ui <- fluidPage( useGlassTabs(), glassTabsUI( "reports", glassTabPanel("summary", "Summary", selected = TRUE, h3("Summary"), p("A quick view of the current reporting period.") ), glassTabPanel("activity", "Recent activity", h3("Recent activity"), tableOutput("activity_table") ), glassTabPanel("quality", "Data quality", h3("Data quality"), plotOutput("quality_plot") ), glassTabPanel("settings", "Team settings", h3("Team settings"), textInput("team_name", "Team name") ), overflow = "scroll", theme = "auto" ) ) server <- function(input, output, session) { output$activity_table <- renderTable(head(mtcars)) output$quality_plot <- renderPlot(plot(mtcars$wt, mtcars$mpg)) } shinyApp(ui, server)
On a narrow screen, the labels remain in a touch-scrollable row. Keyboard focus follows the selected tab, and a server update brings its destination back into view.
"scroll" is a natural fit for most tab bars. "multiline" is useful when every
label should be visible at once. In a horizontal layout, "menu" keeps the
header compact and uses a native select control. Vertical tabs already have a
dedicated rail, so compact menu mode is not available there.
glassTabsUI( "wrapped", glassTabPanel("one", "First report", selected = TRUE, p("First")), glassTabPanel("two", "Second report", p("Second")), glassTabPanel("three", "Third report", p("Third")), overflow = "multiline" ) glassTabsUI( "menu", glassTabPanel("one", "First report", selected = TRUE, p("First")), glassTabPanel("two", "Second report", p("Second")), overflow = "menu" )
swipe = TRUE adds left and right gestures to ordinary panel content. Inputs,
links, buttons, Shiny outputs, HTML widgets, and horizontal scrollers keep
their own touch behavior.
glassTabsUI( "story", glassTabPanel("opening", "Opening", selected = TRUE, p("The first part.")), glassTabPanel("middle", "Middle", p("The middle part.")), glassTabPanel("ending", "Ending", p("The final part.")), swipe = TRUE )
Add data-gt-no-swipe to any custom region that should always keep its own
gesture:
tags$div(`data-gt-no-swipe` = "", custom_touch_component)
No R setting is needed for reduced motion. The browser preference removes the transfer trace and badge pulse, shortens CSS transitions, and shows the next panel without an animation delay.
Windows forced-colors mode uses system colors and visible focus outlines. When
backdrop blur is unsupported, the controls use solid surfaces instead of
losing contrast. Custom themes can set focus_ring in glass_tab_theme() and
glass_select_theme(); the colour follows select dropdowns when they move to
the document body, so search focus remains visible.
glassPage() keeps a small full-page app pleasantly short:
ui <- glassPage( title = "Operations", glassTabsUI( "main", glassTabPanel("overview", "Overview", selected = TRUE, overview_ui), glassTabPanel("alerts", "Alerts", alerts_ui), overflow = "scroll", theme = "auto" ) )
It is an experimental wrapper around bslib::page_fillable(). Plain
fluidPage(), page_fillable(), and dashboard layouts remain first-class
homes for every glasstabs widget.
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.