shiny-bslib-theming by posit-dev/skills
npx skills add https://github.com/posit-dev/skills --skill shiny-bslib-theming使用 bslib 的 Bootstrap 5 主题系统自定义 Shiny 应用外观。从快速的 Bootswatch 主题到高级的 Sass 自定义和动态颜色模式切换。
"shiny" 预设(推荐的起点):
page_sidebar(
theme = bs_theme(), # 默认为 "shiny" 预设 — 经过打磨,不是普通的 Bootstrap
...
)
Bootswatch 主题(用于不同的视觉风格):
page_sidebar(
theme = bs_theme(preset = "zephyr"), # 或 "cosmo"、"minty"、"darkly" 等
...
)
自定义颜色和字体:
page_sidebar(
theme = bs_theme(
version = 5,
bg = "#FFFFFF",
fg = "#333333",
primary = "#2c3e50",
base_font = font_google("Lato"),
heading_font = font_google("Montserrat")
),
...
)
从 _brand.yml 自动获取品牌信息: 如果你的应用或项目目录中存在 _brand.yml 文件, 会自动发现并应用它。无需更改代码。需要 R 包。
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
bs_theme()brand.ymlbs_theme(brand = FALSE) # 禁用自动发现
bs_theme(brand = TRUE) # 要求 _brand.yml(如果未找到则报错)
bs_theme(brand = "path/to/brand.yml") # 显式指定路径
"shiny" 预设(默认)或与你期望外观接近的 Bootswatch 主题开始bg、fg、primary)font_google() 或其他字体辅助函数调整字体... 或 bs_add_variables() 使用 Bootstrap Sass 变量进行微调bs_add_rules() 添加自定义 Sass 规则thematic::thematic_shiny() 以使图表匹配主题bs_themer() 进行交互式预览示例:
theme <- bs_theme(preset = "minty") |>
bs_theme_update(
primary = "#1a9a7f",
base_font = font_google("Lato")
) |>
bs_add_rules("
.card { box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
")
创建 Bootstrap 主题的核心函数。返回一个 sass::sass_bundle() 对象。
bs_theme(
version = version_default(),
preset = NULL, # "shiny"(BS5+ 的默认值)、"bootstrap" 或 Bootswatch 名称
..., # Bootstrap Sass 变量覆盖
brand = NULL, # brand.yml:NULL(自动)、TRUE(要求)、FALSE(禁用)或路径
bg = NULL, fg = NULL,
primary = NULL, secondary = NULL,
success = NULL, info = NULL, warning = NULL, danger = NULL,
base_font = NULL, code_font = NULL, heading_font = NULL,
font_scale = NULL, # 基础字体大小的标量乘数(例如,1.5 = 150%)
bootswatch = NULL # preset 的别名
)
使用 bs_theme_update(theme, ...) 修改现有主题。使用 is_bs_theme(x) 测试对象是否为主题。
"shiny" 预设(推荐): 对于 Bootstrap 5+,bs_theme() 默认使用 preset = "shiny"。这是一个经过打磨、专门为 Shiny 应用设计的主题 — 它不是普通的 Bootstrap。它为卡片、侧边栏、数值框和其他 bslib 组件提供了具有精心选择默认值的专业样式。从这里开始,并在选择 Bootswatch 主题之前,先用颜色和字体进行自定义。
原生 Bootstrap: 使用 preset = "bootstrap" 来移除 "shiny" 预设,获得未修改的 Bootstrap 5 样式。
内置预设: builtin_themes() 列出 bslib 自己的预设。
Bootswatch 主题: bootswatch_themes() 列出所有可用的 Bootswatch 主题。选择一个适合应用目的和受众的主题 — 不要默认应用一个。
热门选项:"zephyr"(浅色,现代)、"cosmo"(简洁)、"minty"(清新的绿色)、"flatly"(扁平设计)、"litera"(清晰)、"darkly"(深色)、"cyborg"(深色)、"simplex"(极简主义)、"sketchy"(手绘风格)。
最具影响力的颜色 — 更改这些颜色会通过变量级联影响数百条 CSS 规则:
| 参数 | 描述 |
|---|---|
bg | 背景颜色 |
fg | 前景(文本)颜色 |
primary | 主品牌颜色(链接、导航激活状态、输入框焦点) |
secondary | 操作按钮的默认颜色 |
success | 正面/成功状态(通常为绿色) |
info | 信息性内容(通常为蓝绿色) |
warning | 警告(通常为黄色) |
danger | 错误/破坏性操作(通常为红色) |
bs_theme(
bg = "#202123", fg = "#B8BCC2",
primary = "#EA80FC", secondary = "#48DAC6"
)
颜色提示:
bg/fg:色调相似,亮度差异大(确保对比度以利于阅读)primary:与 bg 和 fg 都形成对比;用于超链接、导航、输入框焦点htmltools::parseCssColors() 理解的任何格式三个字体参数:base_font、heading_font、code_font。使用 font_scale 统一缩放所有字体大小(例如,1.5 表示 150%)。
每个参数接受单个字体、一个 font_collection() 或字体名称的字符向量。
在本地下载并缓存 Google 字体(默认 local = TRUE)。仅在首次下载时需要网络连接。
bs_theme(
base_font = font_google("Roboto"),
heading_font = font_google("Montserrat"),
code_font = font_google("Fira Code")
)
使用可变字重:font_google("Crimson Pro", wght = "200..900")
使用特定字重:font_google("Raleway", wght = c(300, 400, 700))
建议使用后备字体以避免在慢速连接上出现文本闪烁(FOIT):
bs_theme(
base_font = font_collection(
font_google("Lato", local = FALSE),
"Helvetica Neue", "Arial", "sans-serif"
)
)
字体配对资源:fontpair.co
用于自定义字体 URL 的 CSS 网络字体接口:
font_link("Crimson Pro",
href = "https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@200..900")
用于本地托管的字体文件,提供完整的 @font-face 控制:
font_face(
family = "Crimson Pro",
style = "normal",
weight = "200 900",
src = "url(fonts/crimson-pro.woff2) format('woff2')"
)
按回退顺序组合多个字体:
font_collection(font_google("Lato"), "Helvetica Neue", "Arial", "sans-serif")
用于超出 bs_theme() 命名参数的自定义。这些函数直接与 Bootstrap 的 Sass 层配合工作。
添加或覆盖 Bootstrap Sass 变量默认值:
theme <- bs_add_variables(
bs_theme(preset = "sketchy", primary = "orange"),
"body-bg" = "#EEEEEE",
"font-family-base" = "monospace",
"font-size-base" = "1.4rem",
"btn-padding-y" = ".16rem"
)
.where 参数控制在 Sass 编译顺序中的放置位置:
.where | 何时使用 |
|---|---|
"defaults"(默认) | 使用 !default 标志设置变量默认值。放置在 Bootstrap 自身默认值之前。 |
"declarations" | 引用其他 Bootstrap 变量(例如,$secondary)。放置在 Bootstrap 默认值之后。 |
"rules" | 放置在所有规则之后。很少需要。 |
引用 Bootstrap 变量:
# 这在 bs_theme() 中会失败,因为 $secondary 尚未定义:
# bs_theme("progress-bar-bg" = "$secondary")
# 改用 bs_add_variables 并设置 .where = "declarations":
bs_theme() |>
bs_add_variables("progress-bar-bg" = "$secondary", .where = "declarations")
添加可以引用 Bootstrap 变量和混合的自定义 Sass/CSS 规则:
theme <- bs_theme(primary = "#007bff") |>
bs_add_rules("
.custom-card {
background: mix($bg, $primary, 95%);
border: 1px solid $primary;
padding: $spacer;
@include media-breakpoint-up(md) {
padding: $spacer * 2;
}
}
")
来自外部文件:bs_add_rules(sass::sass_file("www/custom.scss"))
可用的 Sass 函数:lighten()、darken()、mix()、rgba()、color-contrast()。可用的 Bootstrap 混合:@include media-breakpoint-up()、@include box-shadow()、@include border-radius()。
向主题包添加自定义 Sass 函数或混合:
theme |>
bs_add_functions("@function my-tint($color) { @return mix(white, $color, 20%); }") |>
bs_add_rules(".highlight { background: my-tint($primary); }")
将 sass::sass_bundle() 对象附加到主题(用于打包可重用的主题扩展):
my_extension <- sass::sass_layer(
defaults = list("my-var" = "red !default"),
rules = ".my-class { color: $my-var; }"
)
theme <- bs_theme() |> bs_bundle(my_extension)
通过 bs_theme(...) 或 bs_add_variables() 传递任何 Bootstrap 5 Sass 变量。
常见变量:
bs_theme(
"border-radius" = "0.5rem",
"card-border-radius" = "1rem",
"card-bg" = "lighten($bg, 5%)",
"navbar-bg" = "$primary",
"link-color" = "$primary",
"font-size-base" = "1rem",
"spacer" = "1rem",
"btn-padding-y" = ".5rem",
"btn-padding-x" = "1rem",
"input-border-color" = "#dee2e6"
)
值可以是引用变量、函数和数学运算的 Sass 表达式。
有关详细信息,请参阅 sass-and-css-variables.md:
--bs-* CSS 自定义属性data-bs-theme 进行逐元素主题设置有关详细信息,请参阅 dark-mode.md:
data-bs-theme 属性)input_dark_mode() 和 toggle_dark_mode()session$setCurrentTheme() 进行服务器端主题切换bs_theme() 仅影响 CSS。R 图表输出(在服务器端渲染为图像)不会自动匹配。使用 thematic 包:
library(thematic)
thematic_shiny(font = "auto") # 在 shinyApp() 之前调用
shinyApp(ui, server)
font = "auto" 也会匹配来自 bs_theme() 的字体bs_themer() 配合使用,实现实时预览设置全局 ggplot2 主题以进一步提高一致性:
library(ggplot2)
theme_set(theme_minimal())
bslib-page-dashboard CSS 类在主内容区域后面添加浅灰色背景,使仪表板风格的应用具有精致的外观,卡片在背景上突出显示。这是一个主题细节 — 它不改变布局行为,只改变视觉处理。
对于 page_sidebar() 仪表板:
page_sidebar(
class = "bslib-page-dashboard",
title = "我的仪表板",
sidebar = sidebar(...),
...
)
对于具有仪表板导向页面的 page_navbar(): 将类应用于单个 nav_panel() 容器(而不是 page_navbar() 本身),以便只有仪表板导向的页面获得灰色背景:
page_navbar(
title = "分析",
nav_panel("仪表板", class = "bslib-page-dashboard",
layout_column_wrap(...)
),
nav_panel("报告",
# 没有仪表板类 — 用于文本/报告的标准白色背景
...
)
)
用于预览具有许多示例 UI 组件的主题的独立演示应用:
bslib::bs_theme_preview() # 默认主题
bslib::bs_theme_preview(bs_theme(preset = "darkly")) # 自定义主题
默认包含主题设置 UI(with_themer = TRUE)。
运行带有主题编辑器覆盖层的现有 Shiny 应用(而不是 shiny::runApp()):
run_with_themer(shinyApp(ui, server))
run_with_themer("path/to/app")
将主题编辑器添加到你自己应用的服务器函数中:
server <- function(input, output, session) {
bs_themer() # 在开发期间添加,生产时移除
# ...
}
所有三个工具都会将生成的 bs_theme() 代码打印到 R 控制台,便于复制粘贴。限制: 仅限 Bootstrap 5+,仅限 Shiny 应用和 runtime: shiny R Markdown,不影响不使用 bs_dependency_defer() 的第三方小部件。
检索计算出的 Sass 变量值:
vars <- c("body-bg", "body-color", "primary", "border-radius")
bs_get_variables(bs_theme(), varnames = vars)
bs_get_variables(bs_theme(preset = "darkly"), varnames = vars)
检查对比度(用于可访问性):
bs_get_contrast(bs_theme(), c("primary", "dark", "light"))
目标是符合 WCAG AA 标准:正常文本 4.5:1,大文本 3:1。
bs_theme() 而非自定义 CSS — 变量会自动级联到所有相关组件bs_theme(version = 5) 防止默认值更改时出现破坏font_collection() 以避免在慢速连接上出现 FOITbs_get_contrast() 和浏览器开发者工具theme.R 中组织复杂主题:# theme.R
app_theme <- function() {
bs_theme(
version = 5,
primary = "#2c3e50",
base_font = font_google("Lato"),
heading_font = font_google("Montserrat", wght = c(400, 700))
) |>
bs_add_rules(sass::sass_file("www/custom.scss"))
}
每周安装次数
90
代码库
GitHub 星标数
205
首次出现
2026年2月20日
安全审计
安装于
opencode80
github-copilot78
codex77
gemini-cli77
cursor77
claude-code76
Customize Shiny app appearance using bslib's Bootstrap 5 theming system. From quick Bootswatch themes to advanced Sass customization and dynamic color mode switching.
"shiny" preset (recommended starting point):
page_sidebar(
theme = bs_theme(), # "shiny" preset by default — polished, not plain Bootstrap
...
)
Bootswatch theme (for a different visual style):
page_sidebar(
theme = bs_theme(preset = "zephyr"), # or "cosmo", "minty", "darkly", etc.
...
)
Custom colors and fonts:
page_sidebar(
theme = bs_theme(
version = 5,
bg = "#FFFFFF",
fg = "#333333",
primary = "#2c3e50",
base_font = font_google("Lato"),
heading_font = font_google("Montserrat")
),
...
)
Auto-brand from_brand.yml: If a _brand.yml file exists in your app or project directory, bs_theme() automatically discovers and applies it. No code changes needed. Requires the brand.yml R package.
bs_theme(brand = FALSE) # Disable auto-discovery
bs_theme(brand = TRUE) # Require _brand.yml (error if not found)
bs_theme(brand = "path/to/brand.yml") # Explicit path
"shiny" preset (default) or a Bootswatch theme close to your desired lookbg, fg, primary)font_google() or other font helpers... or bs_add_variables()bs_add_rules() if neededthematic::thematic_shiny() so plots match the themebs_themer() during development for interactive previewExample:
theme <- bs_theme(preset = "minty") |>
bs_theme_update(
primary = "#1a9a7f",
base_font = font_google("Lato")
) |>
bs_add_rules("
.card { box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
")
Central function for creating Bootstrap themes. Returns a sass::sass_bundle() object.
bs_theme(
version = version_default(),
preset = NULL, # "shiny" (default for BS5+), "bootstrap", or Bootswatch name
..., # Bootstrap Sass variable overrides
brand = NULL, # brand.yml: NULL (auto), TRUE (require), FALSE (disable), or path
bg = NULL, fg = NULL,
primary = NULL, secondary = NULL,
success = NULL, info = NULL, warning = NULL, danger = NULL,
base_font = NULL, code_font = NULL, heading_font = NULL,
font_scale = NULL, # Scalar multiplier for base font size (e.g., 1.5 = 150%)
bootswatch = NULL # Alias for preset
)
Use bs_theme_update(theme, ...) to modify an existing theme. Use is_bs_theme(x) to test if an object is a theme.
The "shiny" preset (recommended): bs_theme() defaults to preset = "shiny" for Bootstrap 5+. This is a polished, purpose-built theme designed specifically for Shiny apps — it is not plain Bootstrap. It provides professional styling with well-chosen defaults for cards, sidebars, value boxes, and other bslib components. Start here and customize with colors and fonts before reaching for a Bootswatch theme.
Vanilla Bootstrap: Use preset = "bootstrap" to remove the "shiny" preset and get unmodified Bootstrap 5 styling.
Built-in presets: builtin_themes() lists bslib's own presets.
Bootswatch themes: bootswatch_themes() lists all available Bootswatch themes. Choose one that fits the app's purpose and audience — don't apply one by default.
Popular options: "zephyr" (light, modern), "cosmo" (clean), "minty" (fresh green), "flatly" (flat design), "litera" (crisp), "darkly" (dark), "cyborg" (dark), "simplex" (minimalist), "sketchy" (hand-drawn).
The most influential colors — changing these affects hundreds of CSS rules via variable cascading:
| Parameter | Description |
|---|---|
bg | Background color |
fg | Foreground (text) color |
primary | Primary brand color (links, nav active states, input focus) |
secondary | Default for action buttons |
success | Positive/success states (typically green) |
info | Informational content (typically blue-green) |
bs_theme(
bg = "#202123", fg = "#B8BCC2",
primary = "#EA80FC", secondary = "#48DAC6"
)
Color tips:
bg/fg: similar hue, large luminance difference (ensure contrast for readability)primary: contrasts with both bg and fg; used for hyperlinks, navigation, input focushtmltools::parseCssColors() understandsThree font arguments: base_font, heading_font, code_font. Use font_scale to uniformly scale all font sizes (e.g., 1.5 for 150%).
Each argument accepts a single font, a font_collection(), or a character vector of font names.
Downloads and caches Google Fonts locally (local = TRUE by default). Internet needed only on first download.
bs_theme(
base_font = font_google("Roboto"),
heading_font = font_google("Montserrat"),
code_font = font_google("Fira Code")
)
With variable weights: font_google("Crimson Pro", wght = "200..900")
With specific weights: font_google("Raleway", wght = c(300, 400, 700))
Recommend fallbacks to avoid Flash of Invisible Text (FOIT) on slow connections:
bs_theme(
base_font = font_collection(
font_google("Lato", local = FALSE),
"Helvetica Neue", "Arial", "sans-serif"
)
)
Font pairing resource: fontpair.co
CSS web font interface for custom font URLs:
font_link("Crimson Pro",
href = "https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@200..900")
For locally hosted font files with full @font-face control:
font_face(
family = "Crimson Pro",
style = "normal",
weight = "200 900",
src = "url(fonts/crimson-pro.woff2) format('woff2')"
)
Combine multiple fonts with fallback order:
font_collection(font_google("Lato"), "Helvetica Neue", "Arial", "sans-serif")
For customizations beyond bs_theme()'s named parameters. These work directly with Bootstrap's Sass layers.
Add or override Bootstrap Sass variable defaults:
theme <- bs_add_variables(
bs_theme(preset = "sketchy", primary = "orange"),
"body-bg" = "#EEEEEE",
"font-family-base" = "monospace",
"font-size-base" = "1.4rem",
"btn-padding-y" = ".16rem"
)
The.where parameter controls placement in the Sass compilation order:
.where | When to use |
|---|---|
"defaults" (default) | Set variable defaults with !default flag. Placed before Bootstrap's own defaults. |
"declarations" | Reference other Bootstrap variables (e.g., $secondary). Placed after Bootstrap's defaults. |
"rules" | Placed after all rules. Rarely needed. |
Referencing Bootstrap variables:
# This fails in bs_theme() because $secondary isn't defined yet:
# bs_theme("progress-bar-bg" = "$secondary")
# Use bs_add_variables with .where = "declarations" instead:
bs_theme() |>
bs_add_variables("progress-bar-bg" = "$secondary", .where = "declarations")
Add custom Sass/CSS rules that can reference Bootstrap variables and mixins:
theme <- bs_theme(primary = "#007bff") |>
bs_add_rules("
.custom-card {
background: mix($bg, $primary, 95%);
border: 1px solid $primary;
padding: $spacer;
@include media-breakpoint-up(md) {
padding: $spacer * 2;
}
}
")
From external file: bs_add_rules(sass::sass_file("www/custom.scss"))
Available Sass functions: lighten(), darken(), mix(), rgba(), color-contrast(). Available Bootstrap mixins: @include media-breakpoint-up(), @include box-shadow(), @include border-radius().
Add custom Sass functions or mixins to the theme bundle:
theme |>
bs_add_functions("@function my-tint($color) { @return mix(white, $color, 20%); }") |>
bs_add_rules(".highlight { background: my-tint($primary); }")
Append sass::sass_bundle() objects to a theme (for packaging reusable theme extensions):
my_extension <- sass::sass_layer(
defaults = list("my-var" = "red !default"),
rules = ".my-class { color: $my-var; }"
)
theme <- bs_theme() |> bs_bundle(my_extension)
Pass any Bootstrap 5 Sass variable through bs_theme(...) or bs_add_variables().
Finding variable names: https://rstudio.github.io/bslib/articles/bs5-variables/
Common variables:
bs_theme(
"border-radius" = "0.5rem",
"card-border-radius" = "1rem",
"card-bg" = "lighten($bg, 5%)",
"navbar-bg" = "$primary",
"link-color" = "$primary",
"font-size-base" = "1rem",
"spacer" = "1rem",
"btn-padding-y" = ".5rem",
"btn-padding-x" = "1rem",
"input-border-color" = "#dee2e6"
)
Values can be Sass expressions referencing variables, functions, and math.
See sass-and-css-variables.md for details on:
--bs-* CSS custom propertiesdata-bs-themeSee dark-mode.md for details on:
data-bs-theme attribute)input_dark_mode() and toggle_dark_mode() for user-controlled switchingsession$setCurrentTheme()bs_theme() only affects CSS. R plot output (rendered server-side as images) won't auto-match. Use the thematic package:
library(thematic)
thematic_shiny(font = "auto") # Call before shinyApp()
shinyApp(ui, server)
font = "auto" also matches fonts from bs_theme()bs_themer() for real-time previewSet global ggplot2 theme for further consistency:
library(ggplot2)
theme_set(theme_minimal())
The bslib-page-dashboard CSS class adds a light gray background behind the main content area, giving dashboard-style apps a polished look where cards stand out against the background. This is a theming detail — it doesn't change layout behavior, only the visual treatment.
Forpage_sidebar() dashboards:
page_sidebar(
class = "bslib-page-dashboard",
title = "My Dashboard",
sidebar = sidebar(...),
...
)
Forpage_navbar() with dashboard-focused pages: Apply the class to individual nav_panel() containers (not page_navbar() itself) so only dashboard-oriented pages get the gray background:
page_navbar(
title = "Analytics",
nav_panel("Dashboard", class = "bslib-page-dashboard",
layout_column_wrap(...)
),
nav_panel("Report",
# No dashboard class — standard white background for prose/reports
...
)
)
Standalone demo app for previewing a theme with many example UI components:
bslib::bs_theme_preview() # Default theme
bslib::bs_theme_preview(bs_theme(preset = "darkly")) # Custom theme
Includes the theming UI by default (with_themer = TRUE).
Run an existing Shiny app with the theme editor overlay (instead of shiny::runApp()):
run_with_themer(shinyApp(ui, server))
run_with_themer("path/to/app")
Add the theme editor to your own app's server function:
server <- function(input, output, session) {
bs_themer() # Add during development, remove for production
# ...
}
All three tools print the resulting bs_theme() code to the R console for easy copy-paste. Limitations: Bootstrap 5+ only, Shiny apps and runtime: shiny R Markdown only, doesn't affect 3rd-party widgets that don't use bs_dependency_defer().
Retrieve computed Sass variable values:
vars <- c("body-bg", "body-color", "primary", "border-radius")
bs_get_variables(bs_theme(), varnames = vars)
bs_get_variables(bs_theme(preset = "darkly"), varnames = vars)
Check contrast (for accessibility):
bs_get_contrast(bs_theme(), c("primary", "dark", "light"))
Aim for WCAG AA compliance: 4.5:1 for normal text, 3:1 for large text.
bs_theme() over custom CSS -- variables cascade to all related components automaticallybs_theme(version = 5) prevents breakage if defaults changefont_collection() to avoid FOIT on slow connectionsbs_get_contrast() and browser dev toolstheme.R:# theme.R
app_theme <- function() {
bs_theme(
version = 5,
primary = "#2c3e50",
base_font = font_google("Lato"),
heading_font = font_google("Montserrat", wght = c(400, 700))
) |>
bs_add_rules(sass::sass_file("www/custom.scss"))
}
Weekly Installs
90
Repository
GitHub Stars
205
First Seen
Feb 20, 2026
Security Audits
Gen Agent Trust HubPassSocketWarnSnykPass
Installed on
opencode80
github-copilot78
codex77
gemini-cli77
cursor77
claude-code76
ManimGL 最佳实践指南:场景、动画、3D 与交互式开发教程
867 周安装
Java 21+ 专家技能:现代 Java 开发、Spring Boot 3.x、JVM 性能优化与云原生架构
138 周安装
Tauri v2 权限配置指南:安全控制命令与系统资源访问
141 周安装
ASR语音转文本技能:使用z-ai-web-dev-sdk实现音频转录与语音识别
142 周安装
Web应用测试指南:Playwright自动化、E2E测试与视觉测试最佳实践
144 周安装
GitLab CLI 集成技能:使用 glab 命令行工具自动化 GitLab 任务
145 周安装
UI/UX 打磨迭代工作流:使用AI智能体进行10+次增量优化,打造世界级用户体验
144 周安装
warning | Warnings (typically yellow) |
danger | Errors/destructive actions (typically red) |