The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
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[@]metanet.ch.
shinyreact apps do not render Shiny’s tag UI. The client is
www/ui.js, and shinyreact::page_react() drops
Bootstrap unless you pass theme.
glass_page_react() does that, and it also loads the Liquid
Glass React components so the client does not need its own glass
CSS.
library(shiny)
library(shinyreact)
library(shinyglass)
ui <- glass_page_react(
theme = glass_theme(preset = "auto", scene = "tahoe"),
title = "Liquid Glass"
)
server <- function(input, output, session) {
output$dist <- renderPlot({
pal <- glass_plot_colors(input = input)
hist(faithful$waiting, col = pal$fill, border = NA)
}, bg = "transparent")
}
shinyApp(ui, server)The matching www/ui.js reads the components from the
same global shinyreact already uses:
const { ReactDOM, useShinyInitialized, ShinyOutput } = window.shinyreact;
const {
useGlassTheme,
GlassPage,
GlassSidebar,
GlassSurface,
GlassButton
} = window.shinyglass;
const h = React.createElement;
function App() {
const ready = useShinyInitialized();
const theme = useGlassTheme();
if (!ready) return null;
return h(
GlassPage,
null,
h(
GlassSidebar,
null,
h(
GlassButton,
{
variant: theme.mode === "dark" ? "primary" : "secondary",
pressed: theme.mode === "dark",
onClick: () => theme.setMode(theme.mode === "dark" ? "light" : "dark")
},
theme.mode
)
),
h(GlassSurface, null, h(ShinyOutput, { id: "dist", className: "shiny-plot-output glass-plot" }))
);
}
ReactDOM.createRoot(document.body.appendChild(document.createElement("div"))).render(h(App));A full app ships at
system.file("examples/shinyreact-glass", package = "shinyglass").
It has no www/ui.css.
| Name | Element | Class |
|---|---|---|
GlassPage |
main |
.glass-page |
GlassMain |
div |
.glass-main |
GlassSidebar |
aside |
.glass-sidebar |
GlassSurface |
section |
.glass-surface |
GlassCard |
section |
.glass-surface.glass-card |
GlassStack |
div |
.glass-stack |
GlassButton |
button |
.glass-button-primary or
.glass-button-secondary |
GlassTitle |
h1 |
.glass-title |
GlassMuted |
p |
.glass-muted |
GlassRange |
input |
.glass-range |
GlassIntensitySlider |
div |
.glass-intensity-slider (Ultra Clear to Tinted, default
0.5) |
useGlassTheme() also reports refraction,
morph, press, scrollEdge,
minimizeTabs, iconStyle,
floatingSidebar, and reducedMotion. Setters
such as theme.setRefraction(false) and
theme.setIconStyle("color") call the same client API as
update_glass_theme(). GlassSidebar adds
.glass-sidebar-floating when floating is true
or the theme turned floating_sidebar on.
GlassButton takes variant
("primary" or "secondary") and
pressed. Primary fill follows --glass-accent /
--glass-on-primary. Secondary label ink follows
--glass-body-color. Sidebar, card, and page chrome use the
same surface tokens as bslib cards (blur, border, radius, shadow). Light
and dark packs swap those variables, so a button or panel written this
way tracks setPreset without a client stylesheet.
Plot and table hosts inside .glass-surface,
.glass-card, and .glass-sidebar stay
transparent, same as a plot inside .card. Ink for a base or
ggplot graphic is still drawn on the server. Use
glass_plot_colors(input = input) or
glass_resolved_preset(input) so the R graphic follows the
resolved pack. CSS variables are not available to the graphics
device.
The hook reads document.documentElement and subscribes
with a MutationObserver, so it sees the head script,
setPreset, and any other writer of the dataset.
| Field | Meaning |
|---|---|
mode |
"light", "dark", or
"auto" |
preset |
Resolved pack, "light" or "dark" |
scene |
Wallpaper scene |
material |
"regular" or "clear" ("clear"
is deprecated) |
intensity |
Number from 0 (ultra clear) to 1 (tinted). Default
0.5. |
reducedTransparency |
true when Reduce Transparency is on |
increasedContrast |
true when Increase Contrast is on |
forcedColors |
true when forced colors are active |
setMode, setScene,
setMaterial, and setIntensity call the
existing window.shinyglass mutators.
setMode("dark") is setPreset("dark").
setMaterial("clear") warns and maps to intensity
0.12. A later setIntensity() wins.
GlassIntensitySlider calls setIntensity and
labels the ends Ultra Clear and Tinted.
inst/js/shinyglass-react.js is an ES module attached as
the html dependency shinyglass-react (see
glass_react_dependency()). glass_page_react()
bundles it into the theme. bootstrapPage() emits theme
dependencies before www/ui.js, so the app module can
destructure window.shinyglass at top level. The file does
not touch window.shinyreact until a component renders,
because the theme module is earlier in the document than shinyreact’s
deferred script.
glass_theme_dependencies() appends the same dependency
for page_react_html(extra_deps = ). A plain
glass_theme() does not load it, so classic Shiny pages do
not download the React file.
page_react(theme = glass_theme()) still gets the CSS and
shiny-glass.js. Use glass_page_react(), or
pass glass_theme_dependencies(), when you want the
components.
This is not published as an npm package. shinyreact’s default app has
no build, and hooks must use the single React already on
window.shinyreact. A package that imported
react would load a second copy unless every app
externalized it. htmltools also serves the file at a versioned path, so
a hardcoded import in www/ui.js would break on each
shinyglass release. Named exports are there for a bundler
that can resolve the file itself. The supported no-build path is the
global, same as window.shinyreact.
Document class rules do not cross a shadow root.
--glass-* custom properties do. Call
window.shinyglass.adoptShadow(shadowRoot) from the
component that created the root. The example does this for a note inside
the page.
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.