---
title: "Getting started with bslibdash"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Getting started with bslibdash}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(collapse = TRUE, comment = "#>")
```

bslibdash gives Shiny a Bootstrap 5 dashboard kit on top of
[bslib](https://rstudio.github.io/bslib/): a page shell, a sidebar
menu, and the cards, value boxes, dropdowns and toasts you reach for
in a KPI dashboard.

Because the kit is *just bslib*, a bslibdash app drops straight into the
modern Shiny ecosystem: [teal](https://insightsengineering.github.io/teal/)
modules, raw `bslib::page_*` layouts and any other Bootstrap 5 component
share its theme, dark mode and `bs_themer()` controls — no second styling
system to reconcile.

This vignette walks through the smallest dashboard you can build and
the changes you'll need to port an existing
[shinydashboard](https://rstudio.github.io/shinydashboard/) app. From
here, head to `vignette("components")` for the component tour and
`vignette("theming")` to restyle.

## Minimal dashboard skeleton

```{r eval = FALSE}
library(shiny)
library(bslibdash)

ui <- dashboardPage(
  header = dashboardHeader(title = "bslibdash demo"),
  sidebar = dashboardSidebar(
    sidebarMenu(
      id = "sidebarMenu",
      menuItem("Overview", tabName = "overview", icon = icon("house")),
      menuItem("Reports", tabName = "reports", icon = icon("bar-chart"))
    )
  ),
  body = dashboardBody(
    tabItems(
      tabItem(
        tabName = "overview",
        h2("Overview"),
        boxLayout(
          box("First card", title = "Status", width = 6),
          box("Second card", title = "Details", width = 6)
        )
      ),
      tabItem(
        tabName = "reports",
        h2("Reports"),
        box("Report content", title = "Quarterly")
      )
    )
  )
)

server <- function(input, output, session) {}
```

## Run the app

```{r eval = FALSE}
shinyApp(ui, server)
```

## Programmatic tab navigation

Use `updateTabItems()` from server logic when you need to move users to a
different tab based on an event:

```{r eval = FALSE}
observeEvent(input$go_reports, {
  updateTabItems(session, inputId = "sidebarMenu", selected = "reports")
})
```

## Migrating from shinydashboard

bslibdash deliberately mirrors **shinydashboard**'s function and parameter
names wherever the underlying concept is the same, so most apps port over
as a search-and-replace exercise. It is *not* a drop-in clone: there are
no deprecation shims or accepted-but-ignored arguments, and a handful of
legacy parameters that no longer make sense on Bootstrap 5 have been
removed. The sections below are the entire migration story.

### Function-name parity

The following functions accept the same names as their `shinydashboard`
counterparts and can be called the same way:

```
dashboardPage   dashboardHeader   dashboardSidebar   dashboardBody
dashboardFooter sidebarMenu        menuItem            menuSubItem
sidebarHeader   sidebarSearchForm  menuItemOutput      sidebarMenuOutput
renderMenu      box                updateBox           tabBox
tabItem         tabItems           updateTabItems      valueBox
valueBoxOutput  renderValueBox     infoBox             infoBoxOutput
renderInfoBox   dropdownMenu       dropdownMenuOutput  renderDropdownMenu
messageItem     notificationItem   taskItem            icon
```

### Behavioural differences to know about

- **`appName` is gone.** Use `title` instead in `dashboardPage()`
  (matches `shiny`/`shinydashboard`).
- **`box(collapsible)` defaults to `FALSE`** (matches shinydashboard).
  Pass `collapsible = TRUE` explicitly to get a collapse toggle.
- **Colour palette is Bootstrap, not shinydashboard.** bslibdash uses
  Bootstrap status names (`primary`, `success`, `info`, `warning`,
  `danger`, `secondary`, `dark`). See the mapping table below.

### Removed shinydashboard parameters

These shinydashboard arguments don't exist on the bslibdash equivalents
and will raise an `unused argument` error. The right-hand column shows the
recommended bslibdash approach.

| shinydashboard param | Where | bslibdash replacement |
|---|---|---|
| `solidHeader` | `box()`           | Use `status` + theming for visual emphasis. |
| `skin`        | `dashboardPage()` | Set `theme = brand_bs_theme(...)`. |
| `options`     | `dashboardPage()` | Not supported. |

### Accepted, but implemented differently

These shinydashboard arguments **are** accepted by bslibdash but their
implementation is bslib-native, so the visual result may differ slightly
from shinydashboard:

| shinydashboard param | Where | bslibdash behaviour |
|---|---|---|
| `disable`   | `dashboardSidebar()` | When `TRUE`, the sidebar is omitted entirely. |
| `width`     | `dashboardSidebar()` | Sets the `--app-sidebar-width` CSS variable. Prefer the bslib theme for global widths. |
| `collapsed` | `dashboardSidebar()` | Starts the sidebar collapsed via a CSS class. |

### Silently ignored — use these instead

The following shinydashboard arguments are absorbed by `...` and will
**not** error, but they have no effect. Use the bslibdash approach
instead:

| shinydashboard param | Where | bslibdash approach |
|---|---|---|
| `minified`, `expandOnHover` | `dashboardSidebar()` | Not supported. Style via `bs_theme()` if you need a similar effect. |
| `titleWidth`                | `dashboardHeader()`  | Styled by the theme. |
| `href`, `newtab`            | `menuItem()`         | Use `tags$a(href = ..., target = "_blank", text)` inside the sidebar instead of `menuItem()`. |

### Colour name mapping

shinydashboard ships its own palette (`aqua`, `green`, ...). bslibdash expects
Bootstrap status names. Use this table when porting `status=`, `color=`,
or `background=` arguments:

| shinydashboard | bslibdash (Bootstrap status) |
|---|---|
| `aqua`     | `info`     |
| `blue`     | `primary`  |
| `green`    | `success`  |
| `yellow`   | `warning`  |
| `red`      | `danger`   |
| `purple`   | `secondary` (or a theme accent) |
| `maroon`   | `danger` (closest) |
| `navy`     | `primary` (closest) |
| `teal`     | `info` |
| `olive`    | `success` |
| `lime`     | `success` |
| `orange`   | `warning` |
| `fuchsia`  | `secondary` |
| `black`    | `dark` |

Default-value differences worth calling out explicitly:

- `taskItem(color)`: shinydashboard `"aqua"` → bslibdash `"info"`.
- `menuItem(badgeColor)`: shinydashboard `"green"` → bslibdash `"success"`.
- `dropdownMenu(badgeStatus)`: matches (`"primary"`).

### Argument-ordering note

For functions shared with shinydashboard, bslibdash keeps the shinydashboard
parameters first (in shinydashboard's order) and pushes bslibdash-specific
extras (`appTag`, `copyright`, `rightUi`, `closable`, `maximizable`, `id`,
...) to the end with sensible defaults, so positional calls written for
shinydashboard keep working.
