返回技能列表

design-shiny-ui

pjt222
更新于 6 days ago
18 次查看
17
2
17
在 GitHub 上查看
design

关于

This skill helps developers build modern Shiny app UIs using bslib for theming and responsive layouts. It covers creating grids with layout_columns, implementing value boxes/cards, and applying custom CSS/SCSS for branding. Use it when starting a new Shiny app, modernizing from fluidPage, or improving responsiveness and accessibility.

快速安装

Claude Code

推荐
主要方式
npx skills add pjt222/agent-almanac -a claude-code
插件命令备选方式
/plugin add https://github.com/pjt222/agent-almanac
Git 克隆备选方式
git clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/design-shiny-ui

在 Claude Code 中复制并粘贴此命令以安装该技能

技能文档

設 Shiny UI

以 bslib 題、現代布局原、自定 CSS 設響、可訪 Shiny 介。

  • 從始建新 Shiny UI
  • 舊 app 由 fluidPage 現代化至 bslib
  • 施品題(色、字)於 Shiny
  • 使 Shiny 於諸屏響
  • 改 Shiny 可訪

  • :app 用與目眾
  • :布類(sidebar、navbar、fillable、dashboard)
  • :品色與字
  • :用自定 CSS/SCSS(默:僅 bslib)
  • :可訪求(WCAG 級)

一:擇頁布

bslib 供諸頁構:

# Sidebar layout — most common for data apps
ui <- page_sidebar(
  title = "My App",
  sidebar = sidebar("Controls here"),
  "Main content here"
)

# Navbar layout — for multi-page apps
ui <- page_navbar(
  title = "My App",
  nav_panel("Tab 1", "Content 1"),
  nav_panel("Tab 2", "Content 2"),
  nav_spacer(),
  nav_item(actionButton("help", "Help"))
)

# Fillable layout — content fills available space
ui <- page_fillable(
  card(
    full_screen = TRUE,
    plotOutput("plot")
  )
)

# Dashboard layout — grid of value boxes and cards
ui <- page_sidebar(
  title = "Dashboard",
  sidebar = sidebar(open = "closed", "Filters"),
  layout_columns(
    fill = FALSE,
    value_box("Revenue", "$1.2M", theme = "primary"),
    value_box("Users", "4,521", theme = "success"),
    value_box("Uptime", "99.9%", theme = "info")
  ),
  layout_columns(
    card(plotOutput("chart1")),
    card(plotOutput("chart2"))
  )
)

得:布符 app 之導航與內容需。

敗:布不適→查用 page_sidebar() / page_navbar()(bslib),非 fluidPage() / navbarPage()(base shiny)。bslib 默認更佳且支題。

二:配 bslib 題

my_theme <- bslib::bs_theme(
  version = 5,                      # Bootstrap 5
  bootswatch = "flatly",            # Optional preset theme
  bg = "#ffffff",                   # Background color
  fg = "#2c3e50",                   # Foreground (text) color
  primary = "#2c3e50",              # Primary brand color
  secondary = "#95a5a6",            # Secondary color
  success = "#18bc9c",
  info = "#3498db",
  warning = "#f39c12",
  danger = "#e74c3c",
  base_font = bslib::font_google("Source Sans Pro"),
  heading_font = bslib::font_google("Source Sans Pro", wght = 600),
  code_font = bslib::font_google("Fira Code"),
  "navbar-bg" = "#2c3e50"
)

ui <- page_sidebar(
  theme = my_theme,
  title = "Themed App",
  # ...
)

開發時用互動題編:

bslib::bs_theme_preview(my_theme)

得:app 以一致品色、字、Bootstrap 5 組件現。

敗:字不載→查網(Google Fonts 需之)或換系字:font_collection("system-ui", "-apple-system", "Segoe UI")。題變量不施→查 theme 傳至頁函。

三:以卡與列建布

ui <- page_sidebar(
  theme = my_theme,
  title = "Analysis Dashboard",
  sidebar = sidebar(
    width = 300,
    title = "Filters",
    selectInput("dataset", "Dataset", choices = c("iris", "mtcars")),
    sliderInput("sample", "Sample %", 10, 100, 100, step = 10),
    hr(),
    actionButton("refresh", "Refresh", class = "btn-primary w-100")
  ),

  # KPI row — non-filling
  layout_columns(
    fill = FALSE,
    col_widths = c(4, 4, 4),
    value_box(
      title = "Observations",
      value = textOutput("n_obs"),
      showcase = bsicons::bs_icon("table"),
      theme = "primary"
    ),
    value_box(
      title = "Variables",
      value = textOutput("n_vars"),
      showcase = bsicons::bs_icon("columns-gap"),
      theme = "info"
    ),
    value_box(
      title = "Missing",
      value = textOutput("n_missing"),
      showcase = bsicons::bs_icon("exclamation-triangle"),
      theme = "warning"
    )
  ),

  # Main content row
  layout_columns(
    col_widths = c(8, 4),
    card(
      card_header("Distribution"),
      full_screen = TRUE,
      plotOutput("main_plot")
    ),
    card(
      card_header("Summary"),
      tableOutput("summary_table")
    )
  )
)

諸布原:

  • layout_columns() — 響格,含 col_widths
  • card() — 內容器,可選頭/尾
  • value_box() — KPI 顯,含徽與題
  • layout_sidebar() — 卡內嵌 sidebar
  • navset_card_tab() — 有頁標之卡

得:響格布應屏尺。

敗:寬屏列意外堆→查 col_widths 和為 12(Bootstrap 格)。卡重疊→非填列宜 fill = FALSE

四:添動 UI 素

server <- function(input, output, session) {
  output$dynamic_filters <- renderUI({
    data <- current_data()
    tagList(
      selectInput("col", "Column", choices = names(data)),
      if (is.numeric(data[[input$col]])) {
        sliderInput("range", "Range",
          min = min(data[[input$col]], na.rm = TRUE),
          max = max(data[[input$col]], na.rm = TRUE),
          value = range(data[[input$col]], na.rm = TRUE)
        )
      } else {
        selectInput("values", "Values",
          choices = unique(data[[input$col]]),
          multiple = TRUE
        )
      }
    )
  })

  # Conditional panels (no server round-trip)
  # In UI:
  # conditionalPanel(
  #   condition = "input.show_advanced == true",
  #   numericInput("alpha", "Alpha", 0.05)
  # )
}

得:UI 素依使擇及數動更。

敗:動 UI 閃→用 conditionalPanel()(CSS 基)代 renderUI()。動入於再渲失值→加 session$sendInputMessage() 復態。

五:添自定 CSS/SCSS(可選)

求 bslib 題變量外之樣:

# Inline CSS
ui <- page_sidebar(
  theme = my_theme,
  tags$head(tags$style(HTML("
    .sidebar { border-right: 2px solid var(--bs-primary); }
    .card-header { font-weight: 600; }
    .value-box .value { font-size: 2.5rem; }
  "))),
  # ...
)

# External CSS file (place in www/ directory)
ui <- page_sidebar(
  theme = my_theme,
  tags$head(tags$link(rel = "stylesheet", href = "custom.css")),
  # ...
)

SCSS 與 bslib 整合:

my_theme <- bslib::bs_theme(version = 5) |>
  bslib::bs_add_rules(sass::sass_file("www/custom.scss"))

得:自定樣施而不破 bslib 題。

敗:自定 CSS 與 bslib 衝→用 Bootstrap CSS 變量(var(--bs-primary))代硬編色→題變則自定樣傳播。

六:保可訪

# Add ARIA labels to inputs
selectInput("category", "Category",
  choices = c("A", "B", "C")
) |> tagAppendAttributes(`aria-describedby` = "category-help")

# Add alt text to plots
output$plot <- renderPlot({
  plot(data(), main = "Distribution of Values")
}, alt = "Histogram showing the distribution of selected values")

# Ensure sufficient color contrast in theme
my_theme <- bslib::bs_theme(
  version = 5,
  bg = "#ffffff",      # White background
  fg = "#212529"       # Dark text — 15.4:1 contrast ratio
)

# Use semantic HTML
tags$main(
  role = "main",
  tags$h1("Dashboard"),
  tags$section(
    `aria-label` = "Key Performance Indicators",
    layout_columns(
      # value boxes...
    )
  )
)

得:app 符 WCAG 2.1 AA 之色對、鍵導、屏讀相容。

敗:用瀏覽器開發工具 Lighthouse 可訪審試。以 WebAIM 對比查色對。保諸互動素可鍵焦。

  • 頁布於桌與手寬皆正渲
  • bslib 題一致施於諸組件
  • value box 以正題及徽顯
  • 卡於響格正縮
  • 自定 CSS 用 Bootstrap 變量,非硬編
  • 諸圖有 alt 文為屏讀
  • 色對符 WCAG AA(文 4.5:1)
  • 互動素可鍵訪

  • 混新舊 Shiny UI:勿混 fluidPage() 與 bslib 組件→專用 page_sidebar()page_navbar()、或 page_fillable()
  • CSS 硬編色:用 var(--bs-primary)#2c3e50→硬編色題變則破
  • 非填列忘 fill = FALSE:value box 列與摘列常不宜伸→設 fill = FALSE
  • 離網境之 Google Fonts:部至隔網→用系字或自寓字檔代 font_google()
  • 略手機:以瀏覽器響模試。layout_columns 窄屏自動堆,自定 CSS 則或否

  • scaffold-shiny-app
  • build-shiny-module
  • optimize-shiny-performance
  • review-web-design
  • review-ux-ui

GitHub 仓库

pjt222/agent-almanac
路径: i18n/wenyan-ultra/skills/design-shiny-ui
0
agentsagentskillsai-assisted-developmentclaude-codeskillsteams

相关推荐技能

content-collections

Content Collections 是一个 TypeScript 优先的构建工具,可将本地 Markdown/MDX 文件转换为类型安全的数据集合。它专为构建博客、文档站和内容密集型 Vite+React 应用而设计,提供基于 Zod 的自动模式验证。该工具涵盖从 Vite 插件配置、MDX 编译到生产环境部署的完整工作流。

查看技能

polymarket

这个Claude Skill为开发者提供完整的Polymarket预测市场开发支持,涵盖API调用、交易执行和市场数据分析。关键特性包括实时WebSocket数据流,可监控实时交易、订单和市场动态。开发者可用它构建预测市场应用、实施交易策略并集成实时市场预测功能。

查看技能

creating-opencode-plugins

该Skill帮助开发者创建OpenCode插件,用于接入命令、文件、LSP等25+种事件。它提供了插件结构、事件API规范和JavaScript/TypeScript实现模式,适合需要拦截操作、扩展功能或自定义事件处理的场景。开发者可通过它快速构建响应式模块来增强OpenCode AI助手的能力。

查看技能

sglang

SGLang是一个专为LLM设计的高性能推理框架,特别适用于需要结构化输出的场景。它通过RadixAttention前缀缓存技术,在处理JSON、正则表达式、工具调用等具有重复前缀的复杂工作流时,能实现极速生成。如果你正在构建智能体或多轮对话系统,并追求远超vLLM的推理性能,SGLang是理想选择。

查看技能