---
title: "Using shinyglass"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Using shinyglass}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

This vignette is installed with the package. Open it with `vignette("shinyglass")`. `browseVignettes("shinyglass")` lists it with the other vignettes. The same recipe is `help("shinyglass")`, also available as `help("shinyglass-package")`.

Intensity runs from `0` (Ultra Clear) to `1` (Tinted). The default is `0.5`. Do not pass `material = "clear"`; that argument is deprecated.

```{r}
library(shinyglass)
inherits(glass_theme(preset = "auto", intensity = 0.5), "bs_theme")
```

# Minimal app

`glass_page()` is the one-call page. It includes Light / Dark / Auto, the intensity slider, and accent wells, and it remembers the choices for that path. Call `observe_glass()` in the server.

```r
library(shiny)
library(shinyglass)

ui <- glass_page(
  title = "Hello, glass",
  sliderInput("n", "Bars", 5, 30, 15),
  plotOutput("plot")
)

server <- function(input, output, session) {
  observe_glass(input, session)
  output$plot <- renderPlot({
    pal <- glass_plot_colors(input = input)
    barplot(seq_len(input$n), col = pal$fill, border = NA, col.axis = pal$ink)
  }, bg = "transparent")
}

shinyApp(ui, server)
```

# Mobile support

The same app works on desktop and phone with no extra code. Controls are sized for touch, sidebars and popovers open and close as expected on a phone, and pages do not scroll sideways. On a desktop, each live demo has a Phone view button that shows it in a phone-sized frame.

```{r, echo=FALSE, out.width="280px", fig.alt="Basics demo in a phone-sized frame"}
knitr::include_graphics("../man/figures/phone-frame-demo.png")
```

# Add glass to an existing app

Keep the page you already have. bslib `page_sidebar()`, `page_fluid()`, `page_navbar()`, and `page_fillable()` take `theme`. So do `fluidPage()` and `navbarPage()`.

```r
library(shiny)
library(bslib)
library(shinyglass)

ui <- page_sidebar(
  title = "Existing app",
  theme = glass_theme(preset = "auto", intensity = 0.5),
  sidebar = sidebar(
    glass_theme_toggle(),
    glass_intensity_slider()
  ),
  card(
    card_header("Series"),
    plotOutput("plot")
  )
)

server <- function(input, output, session) {
  observe_glass(input, session)
  output$plot <- renderPlot({
    pal <- glass_plot_colors(input = input)
    barplot(seq_len(15), col = pal$fill, border = NA, col.axis = pal$ink)
  }, bg = "transparent")
}

shinyApp(ui, server)
```

The same theme works on `fluidPage()` and `navbarPage()`:

```r
ui <- fluidPage(
  theme = glass_theme(preset = "auto", intensity = 0.5),
  glass_theme_toggle(),
  glass_intensity_slider(),
  plotOutput("plot")
)
```

`glass_theme()` does not persist choices unless you set `persist = TRUE`. `glass_page()` turns persistence on for you.

# Key options

| Argument | Default | Allowed |
| --- | --- | --- |
| `preset` | `"light"` on `glass_theme()`, `"auto"` on `glass_page()` | `"light"`, `"dark"`, `"auto"` |
| `intensity` | `0.5` | `0` to `1` |
| `primary` | `"#007AFF"` | hex, `rgb()`, or a name from `glass_system_colors()` |
| `plot_surface` | `"clear"` | `"clear"`, `"opaque"` |
| `scene` | `"default"` (`"tahoe"` on `glass_page()`) | `names(glass_scenes())` |
| `persist` | `FALSE` (`TRUE` on `glass_page()`) | `TRUE` or `FALSE` |
| `icon_style` | `"clear"` | `"clear"`, `"color"`, `"all"` |
| `floating_sidebar` | `FALSE` | `TRUE` or `FALSE` |
| `refraction`, `morph`, `press`, `scroll_edge`, `minimize_tabs` | `TRUE` | `TRUE` or `FALSE` |

`update_glass_theme(session, ...)` changes these in a running app. Leave an argument `NULL` to keep the current value. Under Auto, color plots with `glass_resolved_preset(input)`, not the string `"auto"`.

# Migrating to 0.5.0

`vignette("migrating")` is the full note. The short version:

- Default intensity moved from `0.45` to `0.5`.
- Delete `material = "clear"`. Pass `intensity` instead. If you omit `intensity`, clear still maps to `0.12` and warns. Write `intensity = 0.12` to keep that clearer look.
- Specular highlights are static top and bottom bands. `specular = FALSE` hides them. They do not follow the pointer.
- `refraction`, `morph`, `press`, `scroll_edge`, `minimize_tabs`, and clear icon ink are on. `floating_sidebar` stays off until you set it to `TRUE`.
- Existing page functions and click targets keep working.

# Plots, chat, and React

Transparent plots need `bg = "transparent"` and ink from `glass_plot_colors(input = input)`. When a chart is hard to read on the wallpaper, set `plot_surface = "opaque"`, or add `glass_plot_surface_input()` and `observe_glass_plot_surface()`. ggplot2, plotly, gt, and DT helpers are `theme_glass()`, `plotly_glass()`, `gt_theme_glass()`, and `dt_options_glass()`.

shinychat: `page_chat(theme = glass_theme())`. A sources panel can be `bslib::offcanvas()`.

shinyreact: the theme argument must be named, or the compiled CSS is dropped.

```r
ui <- glass_page_react(theme = glass_theme(preset = "auto"))
```

`shinyreact::page_react_html()` has no `theme` argument. Pass `extra_deps = glass_theme_dependencies()`. Build the client from `window.shinyglass` (`GlassPage`, `GlassCard`, `GlassButton`, `GlassIntensitySlider`, `useGlassTheme`). Do not bundle a second React.

# Pitfalls and fixes

| What you see | Fix |
| --- | --- |
| Cards or text ignore the glass colors | Remove app CSS that sets those colors. Use `glass_css_tokens()` or `glass_theme(tokens = list(blur = "28px"))`. |
| The plot is a solid rectangle, or the series disappears on the wallpaper | `renderPlot(..., bg = "transparent")` and `glass_plot_colors()`. Or `plot_surface = "opaque"`. |
| The toggle or slider does nothing | Call `observe_glass(input, session)` in the server. Custom ids need the matching `observe_glass_*()` helper. `observe_glass()` only watches `glass_toggle`, `glass_intensity`, and `glass_accent`. |
| Plot colors stay on one mode while Auto is selected | Use `glass_resolved_preset(input)`, which is `"light"` or `"dark"`. |
| Warning about `material = "clear"` | Delete `material`. Pass `intensity` from `0` to `1`. Use `0.12` for the old clear look. |
| shinyreact page has no glass CSS | Pass `theme = glass_theme()` by name. |
| Blur makes a screenshot or PDF muddy | `glass_flatten(session, TRUE)` or open the app with `?glass_flatten=1`. |
| The glass is solid even though intensity is low | The OS setting for reduced transparency, increased contrast, or forced colors is on. That override is intentional. |
