---
title: "Theming and Presets"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Theming and Presets}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

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

```{r setup}
library(bs4Dashkit)
```

`bs4Dashkit` themes dashboards using CSS custom properties (variables). This keeps
customisation lightweight: you set a small palette, and the styling propagates
across the navbar, sidebar, cards, and button utilities without rewriting many CSS
selectors.

---

## Recommended approach: `use_bs4Dashkit_core()`

The simplest way to theme an app is to pick a preset when calling
`use_bs4Dashkit_core()`.

```{r}
body = bs4DashBody(
  use_bs4Dashkit_core(ttl, preset = "professional"),  # default
  # ...
)
```

| Preset | Character |
|---|---|
| `"professional"` | Cool blue-grey, medium contrast, soft shadows |
| `"modern"` | Brighter neutrals with a stronger blue accent |
| `"dark-lite"` | Dark surfaces with lighter text and a violet accent |

If `preset = NULL`, `use_bs4Dashkit_core()` falls back to the option
`bs4Dashkit.theme_preset` (if set). If no option is set, it applies the base theme.

Each preset now carries a fuller set of theme tokens so the dashboard chrome
feels more intentional out of the box: navbar, sidebar, footer, muted text,
links, and status colors are all coordinated with the base palette instead of
only changing the main surface colors.

## Accent overrides

You can override the preset accent using the `accent` argument in
`use_bs4Dashkit_core()`:

```{r}
body = bs4DashBody(
  use_bs4Dashkit_core(ttl, preset = "professional", accent = "#2f6f8f"),
  # ...
)
```

This is the recommended way to change accent while still using a preset.

`use_bs4Dashkit_core()` also reads `options(bs4Dashkit.accent = ...)` when `accent`
is not supplied.

## Fine-grained overrides

When using a preset, you can supply additional CSS variable overrides via `...`.
These are passed through to `use_dash_theme_preset()`.

```{r}
body = bs4DashBody(
  use_bs4Dashkit_core(
    ttl,
    preset = "professional",
    accent = "#2f6f8f",
    radius = 14,
    shadow = "0 2px 8px rgba(0,0,0,0.08)"
  )
)

```

If you are not using a preset, you can apply the base theme directly:

```{r}
body = bs4DashBody(
  use_bs4Dashkit_core(ttl, preset = NULL, accent = "#2f6f8f"),
  # ...
)

```

Using `use_dash_theme()` directly

`use_dash_theme()` sets the base theme variables. Most users will not need this
directly, because `use_bs4Dashkit_core()` already applies either a preset theme
or the base theme.

Use `use_dash_theme()` if you want complete control without presets:

```{r}
body = bs4DashBody(
  use_bs4Dashkit_core(ttl, preset = NULL),
  use_dash_theme(
    bg      = "#f5f6f8",
    surface = "#ffffff",
    border  = "#e2e3e7",
    text    = "#1d1f23",
    muted   = "#6b6f76",
    accent  = "#2f6f8f",
    radius  = 12
  )
)

```

## `use_dash_theme_preset()`

Apply a preset independently (useful when switching themes at runtime):


```{r}
body = bs4DashBody(
  use_bs4Dashkit_core(ttl, preset = NULL),  # load core, no preset
  use_dash_theme_preset("modern"),         # apply preset explicitly
  # ...
)
```

## `bs4dashkit_theme_presets()`

List available presets and their CSS variable values:

```{r}
bs4dashkit_theme_presets()
bs4dashkit_theme_presets(values = TRUE)
```

This helper is useful for populating select controls, validating user
input, and avoiding guesswork about preset names while coding. With
`values = TRUE`, it also returns the underlying token lists so you can inspect
or programmatically reuse the shipped palette values.

## Example: user-selectable presets

```{r}
library(shiny)
library(bs4Dash)
library(bs4Dashkit)

ttl <- dash_titles("My App", icon = icon("palette"))

ui <- bs4DashPage(
  title   = ttl$app_name,
  header  = bs4DashNavbar(title = ttl$brand),
  sidebar = bs4DashSidebar(
    bs4SidebarMenu(
      bs4SidebarMenuItem("Home", tabName = "home", icon = icon("house"))
    )
  ),
  body = bs4DashBody(
    use_bs4Dashkit_core(ttl, preset = "professional"),
    selectInput(
      "theme_choice", "Theme",
      choices  = c("professional", "modern", "dark-lite"),
      selected = "professional"
    ),
    uiOutput("theme_css"),
    bs4TabItems(
      bs4TabItem(
        tabName = "home",
        bs4Card(title = "Theme Demo", width = 6, "Card content here.")
      )
    )
  )
)

server <- function(input, output, session) {
  output$theme_css <- renderUI({
    use_dash_theme_preset(input$theme_choice)
  })
}

shinyApp(ui, server)
```

## Notes on precedence

When you use presets, the effective theme follows this order:

`. Preset defaults (`use_dash_theme_preset()`)

2. `accent = ...` override (if provided)

3. Any `...` overrides (e.g., `radius`, `shadow`)

4. Base defaults when no preset is used

