design-shiny-ui
О программе
Этот навык помогает разработчикам создавать современные адаптивные пользовательские интерфейсы для приложений Shiny, используя bslib для тематического оформления, layout_columns для сеток и пользовательский CSS. Он идеально подходит для создания новых приложений с нуля или модернизации существующих приложений на fluidPage с улучшенной доступностью и согласованностью с брендом. Используйте его, когда вам нужно обеспечить адаптивность приложений Shiny на экранах разных размеров или применить профессиональное тематическое оформление.
Быстрая установка
Claude Code
Рекомендуетсяnpx skills add pjt222/agent-almanac -a claude-code/plugin add https://github.com/pjt222/agent-almanacgit clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/design-shiny-uiСкопируйте и вставьте эту команду в Claude Code для установки этого навыка
Документация
Shiny UI 之設
用 bslib 主題化、現代化佈局原語、自定義 CSS,設響應且可及之 Shiny 應用界面。
用時
- 自始構 Shiny 應用 UI
- 將既有 Shiny 應用由 fluidPage 現代化為 bslib
- 應用品牌主題(色、字)於 Shiny 應用
- 使 Shiny 應用於諸屏尺寸下響應
- 改 Shiny 應用之可及性
入
- 必要:應用之用與目標受眾
- 必要:佈局類型(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"))
)
)
得: 頁面佈局合應用之導航與內容之需。
敗則: 佈局不如所願則察用 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)
得: 應用以一致之品牌色、字、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_widthscard()— 內容容器,可選 header/footervalue_box()— KPI 顯示,帶圖示與主題layout_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...
)
)
)
得: 應用合 WCAG 2.1 AA 之色差、鍵盤導航、屏讀相容。
敗則: 以瀏覽器開發工具之可及性審計(Lighthouse)測。以 WebAIM 對比檢查器察色差比。確保諸交互元素可由鍵盤聚焦。
驗
- 頁面佈局於桌面與移動寬度下皆正渲染
- bslib 主題一致施於諸組件
- 值框以正確之主題與圖示顯示
- 卡片於響應式網格中正確縮放
- 自定義 CSS 用 Bootstrap 變量,非硬編碼
- 諸圖皆有屏讀者所用之替代文本
- 色對比合 WCAG AA(文本 4.5:1)
- 交互元素可由鍵盤訪問
陷
- 新舊 Shiny UI 相混:勿將
fluidPage()與 bslib 組件相混。專用page_sidebar()、page_navbar()或page_fillable() - CSS 中硬編碼色:用
var(--bs-primary)代#2c3e50。硬編碼色於主題變更時破 - 非填充行缺
fill = FALSE:值框行與摘要行常不宜填滿可用空間。設fill = FALSE - 離線環境用 Google Fonts:應用部署於隔離網絡則用系統字或自托管字文件代
font_google() - 略移動:以瀏覽器響應模式測。
layout_columns於窄屏自動堆疊,然自定義 CSS 或不能
參
scaffold-shiny-app— 初始應用搭建含主題設置build-shiny-module— 建模塊化 UI 組件optimize-shiny-performance— 注重性能之渲染review-web-design— 佈局、字體、色彩之視覺設計評議review-ux-ui— 可用性與可及性評議
GitHub репозиторий
Похожие навыки
content-collections
МетаЭтот навык предоставляет проверенную в продакшене настройку для Content Collections — TypeScript-ориентированного инструмента, который преобразует файлы Markdown/MDX в типобезопасные коллекции данных с валидацией Zod. Используйте его при создании блогов, сайтов документации или контентных приложений на Vite + React для обеспечения типобезопасности и автоматической проверки содержимого. Он охватывает всё: от настройки плагина Vite и компиляции MDX до оптимизации развертывания и валидации схем.
polymarket
МетаЭтот навык позволяет разработчикам создавать приложения на платформе прогнозных рынков Polymarket, включая интеграцию с API для торговли и получения рыночных данных. Он также обеспечивает потоковую передачу данных в реальном времени через WebSocket для отслеживания текущих сделок и рыночной активности. Используйте его для реализации торговых стратегий или создания инструментов, обрабатывающих обновления рынка в реальном времени.
creating-opencode-plugins
МетаЭтот навык помогает разработчикам создавать плагины OpenCode, которые подключаются к более чем 25 типам событий, таким как команды, файлы и операции LSP. Он предоставляет структуру плагина, спецификации API событий и шаблоны реализации для модулей на JavaScript/TypeScript. Используйте его, когда вам нужно перехватывать, отслеживать или расширять жизненный цикл ассистента OpenCode AI с помощью пользовательской событийно-ориентированной логики.
sglang
МетаSGLang — это высокопроизводительный фреймворк для обслуживания больших языковых моделей (LLM), специализирующийся на быстрой структурированной генерации JSON, regex и рабочих процессов агентов с использованием кэширования префиксов RadixAttention. Он обеспечивает значительно более высокую скорость вывода, особенно для задач с повторяющимися префиксами, что делает его идеальным для сложных структурированных результатов и многократных диалогов. Выбирайте SGLang вместо альтернатив, таких как vLLM, когда вам требуется ограниченное декодирование или вы создаете приложения с интенсивным совместным использованием префиксов.
