shiny-bslib

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Modern Shiny Apps with bslib

基于bslib的现代化Shiny应用

Build professional Shiny dashboards using bslib's Bootstrap 5 components and layouts. This skill focuses on modern UI/UX patterns that replace legacy Shiny approaches.
使用bslib的Bootstrap 5组件与布局构建专业级Shiny仪表盘。本技能聚焦于可替代传统Shiny方案的现代化UI/UX模式。

Quick Start

快速开始

Single-page dashboard:
r
library(shiny)
library(bslib)

ui <- page_sidebar(
  title = "My Dashboard",
  theme = bs_theme(version = 5),  # "shiny" preset by default
  sidebar = sidebar(
    selectInput("variable", "Variable", choices = names(mtcars))
  ),
  layout_column_wrap(
    width = 1/3,
    fill = FALSE,
    value_box(title = "Users", value = "1,234", theme = "primary"),
    value_box(title = "Revenue", value = "$56K", theme = "success"),
    value_box(title = "Growth", value = "+18%", theme = "info")
  ),
  card(
    full_screen = TRUE,
    card_header("Plot"),
    plotOutput("plot")
  )
)

server <- function(input, output, session) {
  output$plot <- renderPlot({
    hist(mtcars[[input$variable]], main = input$variable)
  })
}

shinyApp(ui, server)
Multi-page dashboard:
r
ui <- page_navbar(
  title = "Analytics Platform",
  theme = bs_theme(version = 5),
  nav_panel("Overview", overview_ui),
  nav_panel("Analysis", analysis_ui),
  nav_panel("Reports", reports_ui)
)
单页仪表盘:
r
library(shiny)
library(bslib)

ui <- page_sidebar(
  title = "My Dashboard",
  theme = bs_theme(version = 5),  # "shiny" preset by default
  sidebar = sidebar(
    selectInput("variable", "Variable", choices = names(mtcars))
  ),
  layout_column_wrap(
    width = 1/3,
    fill = FALSE,
    value_box(title = "Users", value = "1,234", theme = "primary"),
    value_box(title = "Revenue", value = "$56K", theme = "success"),
    value_box(title = "Growth", value = "+18%", theme = "info")
  ),
  card(
    full_screen = TRUE,
    card_header("Plot"),
    plotOutput("plot")
  )
)

server <- function(input, output, session) {
  output$plot <- renderPlot({
    hist(mtcars[[input$variable]], main = input$variable)
  })
}

shinyApp(ui, server)
多页仪表盘:
r
ui <- page_navbar(
  title = "Analytics Platform",
  theme = bs_theme(version = 5),
  nav_panel("Overview", overview_ui),
  nav_panel("Analysis", analysis_ui),
  nav_panel("Reports", reports_ui)
)

Core Concepts

核心概念

Page Layouts

页面布局

  • page_sidebar()
    -- Single-page dashboard with sidebar (most common)
  • page_navbar()
    -- Multi-page app with top navigation bar
  • page_fillable()
    -- Viewport-filling layout for custom arrangements
  • page_fluid()
    -- Scrolling layout for long-form content
See page-layouts.md for detailed guidance.
  • page_sidebar()
    -- 带侧边栏的单页仪表盘(最常用)
  • page_navbar()
    -- 带顶部导航栏的多页应用
  • page_fillable()
    -- 可填充视口的自定义布局
  • page_fluid()
    -- 适用于长内容的滚动布局
详见page-layouts.md获取详细指导。

Grid Systems

网格系统

  • layout_column_wrap()
    -- Uniform grid with auto-wrapping (recommended for most cases)
  • layout_columns()
    -- 12-column Bootstrap grid with precise control
See grid-layouts.md for detailed guidance.
  • layout_column_wrap()
    -- 支持自动换行的统一网格(大多数场景推荐使用)
  • layout_columns()
    -- 可精确控制的12列Bootstrap网格
详见grid-layouts.md获取详细指导。

Cards

卡片

Primary container for dashboard content. Support headers, footers, multiple body sections, and full-screen expansion.
See cards.md for detailed guidance.
仪表盘内容的主要容器,支持页眉、页脚、多主体区域以及全屏展开功能。
详见cards.md获取详细指导。

Value Boxes

数值框

Display key metrics and KPIs with optional icons, sparklines, and built-in theming.
See value-boxes.md for detailed guidance.
展示关键指标与KPI,支持可选图标、迷你折线图及内置主题。
详见value-boxes.md获取详细指导。

Navigation

导航

  • Page-level:
    page_navbar()
    for multi-page apps
  • Component-level:
    navset_card_underline()
    ,
    navset_tab()
    ,
    navset_pill()
    for tabbed content
See navigation.md for detailed guidance.
  • 页面级
    page_navbar()
    用于多页应用
  • 组件级
    navset_card_underline()
    navset_tab()
    navset_pill()
    用于标签页内容
详见navigation.md获取详细指导。

Sidebars

侧边栏

  • Page-level:
    page_sidebar()
    or
    page_navbar(sidebar = ...)
  • Component-level:
    layout_sidebar()
    within cards
  • Supports conditional content, dynamic open/close, accordions
See sidebars.md for detailed guidance.
  • 页面级
    page_sidebar()
    page_navbar(sidebar = ...)
  • 组件级:卡片内的
    layout_sidebar()
  • 支持条件内容、动态展开/折叠、折叠面板
详见sidebars.md获取详细指导。

Filling Layouts

填充布局

The fill system controls how components resize to fill available space. Key concepts: fillable containers, fill items, fill carriers. Fill activates when containers have defined heights.
See filling.md for detailed guidance.
填充系统控制组件如何调整大小以填充可用空间,核心概念包括可填充容器、填充项、填充载体。当容器定义高度时,填充功能激活。
详见filling.md获取详细指导。

Theming

主题设置

  • bs_theme()
    with Bootswatch themes for quick styling
  • Custom colors:
    bg
    ,
    fg
    ,
    primary
    affect hundreds of CSS rules
  • Fonts:
    font_google()
    for typography
  • Dynamic theming:
    input_dark_mode()
    +
    session$setCurrentTheme()
See theming.md for detailed guidance.
  • bs_theme()
    结合Bootswatch主题实现快速样式设置
  • 自定义颜色
    bg
    fg
    primary
    可影响数百条CSS规则
  • 字体
    font_google()
    用于排版设置
  • 动态主题
    input_dark_mode()
    +
    session$setCurrentTheme()
详见theming.md获取详细指导。

UI Components

UI组件

  • Accordions -- Collapsible sections, especially useful in sidebars
  • Tooltips -- Hover-triggered help text
  • Popovers -- Click-triggered containers for secondary UI/inputs
  • Toasts -- Temporary notification messages
See accordions.md, tooltips-popovers.md, and toasts.md.
  • 折叠面板 -- 可折叠区域,在侧边栏中尤为实用
  • 工具提示 -- 悬停触发的帮助文本
  • 弹出框 -- 点击触发的次级UI/输入容器
  • 通知提示 -- 临时通知消息
详见accordions.mdtooltips-popovers.mdtoasts.md

Icons

图标

Recommended:
bsicons
package
(Bootstrap Icons, designed for bslib):
r
bsicons::bs_icon("graph-up")
bsicons::bs_icon("people", size = "2em")
Alternative:
fontawesome
package:
r
fontawesome::fa("envelope")
Accessibility for icon-only triggers: When an icon is used as the sole trigger for a tooltip, popover, or similar interactive element (no accompanying text), it must be accessible to screen readers. By default, icon packages mark icons as decorative (
aria-hidden="true"
), which hides them from assistive technology.
  • bsicons::bs_icon()
    : Provide
    title
    — this automatically sets
    a11y = "sem"
    r
    tooltip(
      bs_icon("info-circle", title = "More information"),
      "Tooltip content here"
    )
  • fontawesome::fa()
    : Set
    a11y = "sem"
    and provide
    title
    r
    tooltip(
      fa("circle-info", a11y = "sem", title = "More information"),
      "Tooltip content here"
    )
The
title
should describe the purpose of the trigger (e.g., "More information", "Settings"), not the icon itself (e.g., not "info circle icon").
推荐使用:
bsicons
(为bslib设计的Bootstrap Icons):
r
bsicons::bs_icon("graph-up")
bsicons::bs_icon("people", size = "2em")
替代方案:
fontawesome
包:
r
fontawesome::fa("envelope")
**纯图标触发器的可访问性:**当图标作为工具提示、弹出框或类似交互元素的唯一触发器(无伴随文本)时,必须支持屏幕阅读器访问。默认情况下,图标包会将图标标记为装饰性(
aria-hidden="true"
),这会使其对辅助技术不可见。
  • bsicons::bs_icon()
    :提供
    title
    参数——这会自动设置
    a11y = "sem"
    r
    tooltip(
      bs_icon("info-circle", title = "更多信息"),
      "工具提示内容"
    )
  • fontawesome::fa()
    :设置
    a11y = "sem"
    并提供
    title
    参数
    r
    tooltip(
      fa("circle-info", a11y = "sem", title = "更多信息"),
      "工具提示内容"
    )
title
应描述触发器的用途(如“更多信息”、“设置”),而非图标本身(如不要用“信息圆形图标”)。

Special Inputs

特殊输入组件

  • input_switch()
    -- Toggle switch (modern checkbox alternative)
  • input_dark_mode()
    -- Dark mode toggle
  • input_task_button()
    -- Button for long-running operations
  • input_code_editor()
    -- Code editor with syntax highlighting
  • input_submit_textarea()
    -- Textarea with explicit submission
See inputs.md for detailed guidance.
  • input_switch()
    -- 切换开关(现代化复选框替代方案)
  • input_dark_mode()
    -- 深色模式切换器
  • input_task_button()
    -- 用于长时间运行操作的按钮
  • input_code_editor()
    -- 带语法高亮的代码编辑器
  • input_submit_textarea()
    -- 带显式提交功能的文本域
详见inputs.md获取详细指导。

Common Workflows

常见工作流

Building a Dashboard

构建仪表盘

  1. Choose page layout:
    page_sidebar()
    (single-page) or
    page_navbar()
    (multi-page)
  2. Add theme with
    bs_theme()
    (consider Bootswatch for quick start)
  3. Create sidebar with inputs for filtering/controls
  4. Add value boxes at top for key metrics (set
    fill = FALSE
    on container)
  5. Arrange cards with
    layout_column_wrap()
    or
    layout_columns()
  6. Enable
    full_screen = TRUE
    on all visualization cards
  7. Add
    thematic::thematic_shiny()
    for plot theming
  1. 选择页面布局:
    page_sidebar()
    (单页)或
    page_navbar()
    (多页)
  2. 使用
    bs_theme()
    添加主题(可考虑Bootswatch快速上手)
  3. 创建包含筛选/控制输入的侧边栏
  4. 在顶部添加数值框展示关键指标(在容器上设置
    fill = FALSE
  5. 使用
    layout_column_wrap()
    layout_columns()
    排列卡片
  6. 为所有可视化卡片启用
    full_screen = TRUE
  7. 添加
    thematic::thematic_shiny()
    实现图表主题同步

Modernizing an Existing App

改造现有应用

See migration.md for a complete mapping of legacy patterns to modern equivalents. Key steps:
  1. Replace
    fluidPage()
    with
    page_sidebar()
    or
    page_navbar()
  2. Replace
    fluidRow()
    /
    column()
    with
    layout_columns()
  3. Wrap outputs in
    card(full_screen = TRUE)
  4. Add
    theme = bs_theme(version = 5)
  5. Convert key metrics to
    value_box()
    components
  6. Replace
    tabsetPanel()
    with
    navset_card_underline()
详见migration.md获取传统模式与现代方案的完整映射。核心步骤:
  1. page_sidebar()
    page_navbar()
    替换
    fluidPage()
  2. layout_columns()
    替换
    fluidRow()
    /
    column()
  3. 将输出包裹在
    card(full_screen = TRUE)
  4. 添加
    theme = bs_theme(version = 5)
  5. 将关键指标转换为
    value_box()
    组件
  6. navset_card_underline()
    替换
    tabsetPanel()

Guidelines

指导原则

  1. Prefer bslib page functions (
    page_sidebar()
    ,
    page_navbar()
    ,
    page_fillable()
    ,
    page_fluid()
    ) over legacy equivalents (
    fluidPage()
    ,
    navbarPage()
    )
  2. Use
    layout_column_wrap()
    or
    layout_columns()
    for grid layouts instead of
    fluidRow()
    /
    column()
    , which don't support filling layouts
  3. Wrap outputs in
    card(full_screen = TRUE)
    when building dashboards -- full-screen expansion is a high-value feature
  4. Set
    fill = FALSE
    on
    layout_column_wrap()
    containers holding value boxes (they shouldn't stretch to fill height)
  5. Pin Bootstrap version: include
    theme = bs_theme(version = 5)
    or a preset theme
  6. Use
    thematic::thematic_shiny()
    in the server so base R and ggplot2 plots match the app theme
  7. Use responsive widths like
    width = "250px"
    in
    layout_column_wrap()
    for auto-adjusting columns
  8. Group sidebar inputs with
    accordion()
    when sidebars have many controls
  9. See migration.md for mapping legacy Shiny patterns to modern bslib equivalents
  1. 优先使用bslib页面函数
    page_sidebar()
    page_navbar()
    page_fillable()
    page_fluid()
    )而非传统等价函数(
    fluidPage()
    navbarPage()
  2. **使用
    layout_column_wrap()
    layout_columns()
    **实现网格布局,而非不支持填充布局的
    fluidRow()
    /
    column()
  3. 将输出包裹在
    card(full_screen = TRUE)
    构建仪表盘——全屏展开是高价值功能
  4. 在承载数值框的
    layout_column_wrap()
    容器上设置
    fill = FALSE
    (数值框不应拉伸填充高度)
  5. 固定Bootstrap版本:包含
    theme = bs_theme(version = 5)
    或预设主题
  6. **在server中使用
    thematic::thematic_shiny()
    **使基础R图表与ggplot2图表匹配应用主题
  7. 使用响应式宽度,如在
    layout_column_wrap()
    中设置
    width = "250px"
    实现列自动调整
  8. 当侧边栏包含大量控件时,用
    accordion()
    对输入进行分组
  9. **查看migration.md**获取传统Shiny模式到现代bslib等价方案的映射

Avoid Common Errors

避免常见错误

  1. Avoid directly nesting
    card()
    containers.
    navset_card_*()
    functions are already cards;
    nav_panel()
    content goes directly inside them without wrapping in
    card()
  2. Only use
    layout_columns()
    and
    layout_column_wrap()
    for laying out multiple elements. Single children should be passed directly to their container functions.
  3. Never nest
    page_*()
    functions. Only use one top-level page function per app.
  1. 避免直接嵌套
    card()
    容器。
    navset_card_*()
    函数本身已是卡片;
    nav_panel()
    内容应直接传入,无需包裹在
    card()
  2. 仅在布局多个元素时使用
    layout_columns()
    layout_column_wrap()
    。单个子元素应直接传入其容器函数
  3. 切勿嵌套
    page_*()
    函数。每个应用仅使用一个顶级页面函数

Reference Files

参考文档

  • migration.md -- Legacy Shiny to modern bslib migration guide
  • page-layouts.md -- Page-level layout functions and patterns
  • grid-layouts.md -- Multi-column grid systems
  • cards.md -- Card components and features
  • value-boxes.md -- Value boxes for metrics and KPIs
  • navigation.md -- Navigation containers and patterns
  • sidebars.md -- Sidebar layouts and organization
  • filling.md -- Fillable containers and fill items
  • theming.md -- Basic theming (colors, fonts, Bootswatch). See shiny-bslib-theming skill for advanced theming
  • accordions.md -- Collapsible sections and sidebar organization
  • tooltips-popovers.md -- Hover tooltips and click-triggered popovers
  • toasts.md -- Temporary notification messages
  • inputs.md -- Special bslib input widgets
  • best-practices.md -- bslib-specific patterns and common gotchas
  • migration.md -- 传统Shiny到现代bslib的迁移指南
  • page-layouts.md -- 页面级布局函数与模式
  • grid-layouts.md -- 多列网格系统
  • cards.md -- 卡片组件与特性
  • value-boxes.md -- 用于指标与KPI的数值框
  • navigation.md -- 导航容器与模式
  • sidebars.md -- 侧边栏布局与组织
  • filling.md -- 可填充容器与填充项
  • theming.md -- 基础主题设置(颜色、字体、Bootswatch)。高级主题设置请查看shiny-bslib-theming技能
  • accordions.md -- 可折叠区域与侧边栏组织
  • tooltips-popovers.md -- 悬停工具提示与点击触发的弹出框
  • toasts.md -- 临时通知消息
  • inputs.md -- 特殊bslib输入组件
  • best-practices.md -- bslib专属模式与常见陷阱