orientation argument for glassTabsUI(): "vertical" stacks the
tab buttons in a left-hand rail beside the content pane. ArrowUp/ArrowDown
navigate in vertical mode, aria-orientation is set on the tablist, and
indicator = "underline" renders as a slim side bar adjacent to the
content. Falls back to stacked layout under 760px.tab_align argument for glassTabsUI(): "center" (default),
"left", or "right" aligns tab button text and icons.theme = "auto" preset bridges to Bootstrap 5 color modes: light
variables apply by default and dark variables apply under
data-bs-theme="dark", toggled live in the browser (works with
bslib::input_dark_mode() / toggle_dark_mode() with no server code).glassSelect() and glassMultiSelect() also support theme = "auto" so
their triggers and dropdown panels keep the glass look in both light and
dark Bootstrap 5 color modes.runGlassExample("indicators") demos the three indicator styles,
vertical orientation, and auto theming side by side.runGlassExample("connect-workflow") provides a Posit Connect-ready
workflow review page showing filters, badges, server-driven tab changes,
horizontal/vertical tabs, tab text alignment, and auto theming in one
deployable Shiny app.glassSelect() and
glassMultiSelect() fields remain readable when the page is in dark mode.glassSelect() and glassMultiSelect() dropdowns now clamp to
the viewport, so narrow browser widths no longer cut off the left or right
edge of the dropdown panel.indicator argument for glassTabsUI(): "glass" (default),
"solid" (flat opaque sliding pill, no backdrop-filter or shimmer -
lighter on the GPU and better suited to plain dashboards), and
"underline" (slim sliding bar under the active tab).clientLeft/clientTop), fixing a horizontal shift inside bordered
fallback containers such as bs4Dash .card-body.ResizeObserver re-aligns the halo whenever tab geometry changes
without a window resize: badge count updates, label changes via
renderUI, font swaps, or sidebar collapse.closeGlassSelect(), closeGlassMultiSelect(), and
closeAllGlassSelects() so apps can explicitly close dropdowns before tab
switches, modal changes, or dynamic UI replacement.glassSelect() and glassMultiSelect() now expose open state as
input$<inputId>_open.Released to CRAN.
glassSelect() and glassMultiSelect() gained a width argument
(passed to shiny::validateCssUnit()) so the widgets can fill a column or
match a fixed layout, like native selectizeInput().list(Fruit = c(Apple = "apple"), Veg = c(...))), rendering
non-interactive group headers. Search hides headers whose options are all
filtered out.disabled = TRUE greys out and blocks the whole
widget, and disabled_choices renders individual options as non-selectable.
Both are also reachable at runtime via updateGlassSelect() /
updateGlassMultiSelect() (disabled, disabled_choices). Disabled options
are skipped by "Select all".glassTabsUI() gained a shape argument ("rounded" default or
"square") so the tab bar and content corners can match
shape = "square" selects for a cohesive, selectize-style layout.shape argument to glassSelect() and glassMultiSelect(). The
default shape = "rounded" keeps the signature glass look, while
shape = "square" applies crisp, selectize-style corners so the widgets sit
flush next to native selectizeInput() controls without looking out of
place.updateGlassSelect() and updateGlassMultiSelect() gained a shape
argument so the corner style can be switched at runtime from the server
without re-rendering the widget (open dropdowns and selection state are
preserved).runGlassExample("square-corners") example app that demonstrates the
square shape live alongside native selectizeInput(), including a
runtime rounded-vs-square toggle via update*() and a light-theme variant.runGlassExample("bslib") example app that shows square
glassSelect() and glassMultiSelect() controls inside a Bootstrap 5
bslib layout.glassSelect() and
glassMultiSelect() choice sets via server = TRUE, glassSelectServer(),
and glassMultiSelectServer().runGlassExample("server-select") example and vignette
sections for server-backed single- and multi-select controls.updateGlassMultiSelect() updates being lost when a multi-select is
created or replaced by renderUI() in the same reactive flush. Dynamic
updates now target the replacement widget and retry briefly while it binds.selected values being interpreted as an empty selection by the
multi-select JavaScript binding.color-mix() usage from the shipped stylesheet. Select widget
alpha colors are now precomputed as CSS custom properties at render time for
better compatibility with older embedded browsers.glassSelect() and
glassMultiSelect(), with JavaScript keeping aria-expanded and
aria-selected in sync during interaction.glasstabs.csp_nonce option.forced-colors) CSS support and RTL layout
support for tabs and select widgets.glassTabsUI() inserted by renderUI() or
dashboard layouts after the initial page boot.glassTabCondition(id, value) — generates the correct JavaScript
condition string for [shiny::conditionalPanel()] without needing to remember
the input[["id-active_tab"]] key pattern.glasstabs_news() — prints the package changelog to the R console.ROADMAP.md tracking planned features and known limitations (not
shipped in the package).glass_tab_theme() and glass_select_theme() now have full @examples
with interactive app snippets..gt-container no longer forces max-width:960px or margin:48px auto —
the widget now behaves like a normal block element inside Shiny layouts.--gt-halo-shadow CSS variable, replacing the harsh dark drop shadow.runGlassExample() to launch any of the built-in example apps
directly from the R console (runGlassExample("smoke-test"), etc.).icon argument to glassTabPanel() — accepts any htmltools-compatible
tag (e.g. shiny::icon("table")). Renders with gt-tab-icon / gt-tab-label
spans so icon and text can be styled independently.disableGlassTab() and enableGlassTab() — gray out a tab without
hiding it. Completes the visibility/disabled/removal trio alongside
showGlassTab() / hideGlassTab().updateGlassTabBadge() — set a numeric count badge on any tab button.
Pass count = 0 or count = NA to hide the badge. Values above 99 display
as "99+".glassTabsServer() now integrates with Shiny's URL bookmarking: the active
tab is automatically saved and restored when enableBookmarking = "url" is
set on the app. Opt out per widget with bookmark = FALSE.glassTabsOutput() / renderGlassTabs() for server-driven tab
rendering. The JavaScript engine re-initialises automatically after each
render via a scoped shiny:value listener, so no manual glasstabs_reinit
calls are needed.glassTabsUI() now errors early on duplicate glassTabPanel() values,
reporting the offending value(s) by name.glassTabsUI() gains a compact = FALSE argument. Setting compact = TRUE
applies the .gt-compact CSS modifier which reduces margins, tab-link padding,
font size, and content area padding — ideal for embedding inside bs4Dash cards
or any tight dashboard layout.glassTabsServer() emits a warning() when the id argument contains "-",
which is the most common sign that ns("tabs") was passed instead of the bare
"tabs" id. The warning includes corrective guidance..gt-tab-disabled, .gt-tab-icon, .gt-tab-label, and
.gt-tab-badge rules. Badges adapt their background to the active halo colour
via the existing CSS custom property.var(--gt-xxx, fallback) instead
of being hardcoded — this was the root cause of light theme appearing invisible.
Light theme defaults were also strengthened for better contrast.shiny:value listener limits bootAll re-initialisation to outputs that
actually contain glasstabs elements, so ordinary Shiny outputs are unaffected.inst/cheatsheet/glasstabs-cheatsheet.tex — a printable four-column
LaTeX reference card covering the full API, module pattern, bs4Dash integration,
theming, and common gotchas.vignettes/cheatsheet.Rmd) extended with new sections:
"Tabs inside a Shiny module", "Dynamic tab values and selected",
"Tabs inside bs4Dash", and updated common gotchas.@examples, and cross-links.updateGlassTabsUI() for programmatic tab switching from the server.showGlassTab() and hideGlassTab() for dynamically showing and
hiding tabs at runtime.appendGlassTab() and removeGlassTab() for adding and removing tabs
at runtime.glassTabsUI() now validates selected against the available
glassTabPanel() values and errors early on invalid tab ids.glassTabsServer() is populated on first render.Opening a dropdown now closes any other open glasstabs dropdown, fixing a visual stacking issue where multiple dropdowns appeared simultaneously.
Improved widget lifecycle in dynamic UI (renderUI(), conditionalPanel()).
Widgets initialize more reliably and clean up properly when removed.
Widgets now emit their initial value to Shiny immediately after rendering,
fixing timing issues with conditionalPanel() and dynamic UI.
JavaScript engine refactored to use internal state instead of DOM scanning. No changes to the R API — all existing code works without modification.
Added scroll containers for long option lists, debounced search, and
.gt-loading / .gt-disabled CSS utility classes.
glassSelect(), an animated single-select dropdown for Shiny.updateGlassSelect() for server-side updates to choices and selection.glassSelectValue() as a convenience reactive helper for reading the selected value.updateGlassMultiSelect() for server-side updates to choices, selection, and checkbox style.glassMultiSelectValue() as a convenience reactive helper for reading selected values and active style.label support to glassMultiSelect().all_label support to control the trigger text shown when all choices are selected.glassSelect() and glassMultiSelect() more closely with standard Shiny input behavior.session$sendInputMessage() update patterns.glassMultiSelect() default behavior where selected = NULL initializes all choices as selected."filled" multi-select style.glassSelect().glassSelect().updateGlassMultiSelect() and glassMultiSelectValue().glassSelect(), updateGlassSelect(), and glassSelectValue().glassMultiSelect() server-side updates and helper utilities.Initial release.
glassTabsUI() — animated glassmorphism-style tab navigation with a sliding
glass halo and transfer trace between tabs.glassTabPanel() — defines a single tab button and its content pane.glassTabsServer() — reactive helper that tracks the active tab value.glass_tab_theme() — custom color theme for glassTabsUI() with eight
independent handles: tab_text, tab_active_text, halo_bg,
halo_border, content_bg, content_border, card_bg, card_text."dark" (default) and "light" presets for glassTabsUI().bs4Dash compatibility via wrap = FALSE.glassMultiSelect() — dropdown filter with live search,
select-all with indeterminate state, and three checkbox indicator styles:
"checkbox", "check-only", and "filled".glassFilterTags() — tag-pill display area that stays in sync with a
glassMultiSelect() automatically via JavaScript; clicking × on a pill
deselects that option.glass_select_theme() — custom color theme with four handles: bg_color,
border_color, text_color, accent_color."dark" and "light" presets for glassMultiSelect().show_style_switcher, show_select_all, show_clear_all flags to hide
UI chrome (all default TRUE)."filled" style via the hues argument
(auto-assigned if omitted).useGlassTabs() — injects CSS and JavaScript via
htmltools::htmlDependency, which is deduplicated automatically by Shiny.color-mix()), ensuring
compatibility with Shiny's embedded browser.id.