【免费下载链接】boardui
React design system for agentic interfaces. Every free BoardUI component as source, with a working AI chat app on your own model key as the homepage.
BoardUI 是一个面向 AI 智能体界面的 React 设计系统,它用一套 400+ 语义设计令牌(Design Token)架构,让深色模式切换与整站换肤几乎零成本:组件里不写任何dark:覆盖、不出现裸色值,换主题只是改 CSS 变量。本文带你看懂这套令牌体系的分层结构,以及"一键换肤"背后的 11 个 accent 变量。
什么是设计令牌,BoardUI 为什么需要 400 多个
设计令牌(Design Token)是把"设计决策"变成"代码变量":颜色、圆角、阴影、字号不再散落在各组件里,而是集中定义、按需引用。
BoardUI 的令牌体系集中在这几个文件中:
| 文件 | 职责 |
|---|---|
| styles/theme.css | 颜色原语、语义令牌、圆角、阴影、按钮渐变 |
| styles/typography.css | 完整字体排版体系,注册为text-*组合工具类 |
| styles/globals.css | 深色模式变体声明、基础重置与组件动画 |
README 中一句话概括了这个体系的价值:
One visual language. Figma first, 400+ semantic tokens, light and dark from the same classes.
也就是说,同一套类名,浅色和深色模式下都能正确工作——这是理解整个体系的钥匙。
令牌体系的四层架构
打开 styles/theme.css,文件开头的注释就把分层思路写清楚了:
/* Layered as Tailwind v4 expects: * @theme { ... } 原语 + 色阶覆盖 → Tailwind 工具类 * :root { ... } 语义令牌(浅色模式)— 引用原语 * .dark { ... } 语义覆盖(深色模式) * @theme inline {} 再导出语义令牌,使其成为工具类 */第一层:颜色原语与 accent 色阶
@theme { }块(theme.css#L13-L132)定义"原料":色板、字体、圆角、阴影。绝大部分色值直接复用 Tailwind v4 的 OKLCH 默认色阶,只有 4 处刻意覆盖(如--color-blue-400: #3392ff),保证与生态工具链兼容。
其中最关键的是accent 色阶(theme.css#L35-L45):
--color-accent-50: var(--color-blue-50); --color-accent-100: var(--color-blue-100); /* ... 共 11 级,直到 accent-950 ... */所有"交互与选中"类表面——主按钮渐变、幽灵按钮、复选框、单选、开关、滑块、Tab、侧边栏选中项、焦点环、日期范围选中——引用的都是accent-*而非具体色相。这意味着运行时覆盖这 11 个变量,整个系统就完成重新着色,即"一键换肤"。数据类蓝色(图表、状态芯片、日历事件)则刻意保持引用blue-*,换肤时不受影响,业务含义不跑偏。
第二层:语义令牌(:root 与 .dark 双份定义)
:root { }块(theme.css#L161-L421)定义浅色模式的语义令牌,全部通过var()引用原语,例如:
--color-text-primary: var(--color-neutral-950); --color-background-full: var(--color-white); --color-border-button-default: var(--color-neutral-200);.dark { }块(theme.css#L423-L632)为同名令牌提供深色值:
--color-text-primary: var(--color-neutral-50); --color-background-full: var(--color-neutral-925); --color-border-button-default: var(--color-neutral-700);命名遵循 Figma 变量名(如text/primary→--color-text-primary),设计稿与代码一一对应,400+ 个令牌按"前景 / 文本 / 背景 / 边框 / 状态 / 图表"分组,每个都覆盖 hover、active、disabled 等完整交互态。深色模式还有一处精调:暗色表面更容易"吃掉"低透明度阴影,所以.dark块在保持几何形状不变的前提下只提高黑色 alpha 值(theme.css#L512-L535),让卡片和侧边栏在深色下依然有清晰的层级。
第三层:@theme inline 让令牌"随主题而变"
Tailwind v4 的@theme默认在构建期展开变量值,主题切换就不会生效。BoardUI 用@theme inline { }(theme.css#L644-L832)把所有语义令牌再导出一次:
/* Re-export semantic tokens as Tailwind utilities. The `inline` form means * Tailwind reads the *current* computed value of the variable, so light↔dark * flips work without rebuild. */ @theme inline { --color-text-primary: var(--color-text-primary); ... }inline的语义是让 Tailwind 读取变量的当前计算值,于是text-text-primary、bg-background-primary-default这类工具类会自动跟随.dark翻转,无需重新构建,也不需要在组件里写第二套类名。
第四层:组件级"配方"令牌
有些视觉不是单个颜色,而是组合——比如主按钮的渐变。BoardUI 把它们也令牌化(theme.css#L412-L420):
--gradient-button-primary-default: linear-gradient(180deg, var(--color-accent-500) 0%, var(--color-accent-600) 100%);再配合 theme.css#L887-L920 的bg-button-primary工具类,把 default / hover / active / disabled 四种状态收敛成一个类名。因为渐变引用的是accent-*,换肤时按钮渐变也随之变化;color-mix()甚至能算出"accent 500 与 600 之间 63% 的位置"这类配方(如开关选中态 theme.css#L263-L264),换肤后依然成立。
深色模式如何做到零组件改动
策略在 styles/globals.css#L5-L17 中声明:
/* 基于 class 的深色变体:给 <html> 加 .dark 即激活 */ @custom-variant dark (&:where(.dark, .dark *));配套的铁律写在 AGENTS.md#L14-L22,项目连编码智能体都要求遵守:
Never use raw palette classes (
text-gray-500,bg-white,border-neutral-200) or hex/oklch literals. Every color rides a BoardUI semantic token, which also makes dark mode automatic.Do not write
dark:overrides with raw colors; if a token pair looks wrong in dark mode, pick a different token, not a literal.
规则很直白:组件里禁止裸色值和dark:覆盖,一切颜色走语义令牌。深色模式因此从"每个组件都改一遍"变成"给<html>加一个类"。
一键换肤:覆盖 11 个变量即可
由于所有交互色都指向 accent 色阶,换肤只需在客户项目中覆盖原语变量,或运行期设置data-accent属性。仓库里已有现成示例——贡献度热力图支持 9 种 accent 家族(globals.css#L576-L629):
.contributions-grid[data-accent="teal"] { --contribution-tier-1: var(--color-teal-200); /* ...每档都映射到 teal 色阶 */ } .dark .contributions-grid[data-accent="teal"] { --contribution-tier-1: var(--color-teal-950); /* 深色自动配套 */ }同一个data-accent机制还照顾了边界细节:非默认 accent 的/950在深色侧边栏上可能过亮,于是.dark[data-accent]单独把 NEW 徽章底色减半(theme.css#L637-L639)——细节令牌化的收益就在这里。
主题切换的"点击揭示"动画
换肤不仅是"换变量",体验也做足了。components/application/theme/theme-toggle.tsx 提供了手动明暗切换控件,几个值得借鉴的设计:
- 点击点揭示:基于 View Transition API,新主题从鼠标点击位置以模糊圆形扩散铺开(theme-toggle.tsx#L137-L183),过渡约 820ms;
- 本地持久化:选择写入
localStorage的boardui:theme,并广播boardui:theme-change事件,多标签页同步(theme-toggle.tsx#L98-L109); - 不依赖系统主题:永远尊重用户手动选择,避免"半夜自动变深色"的经典抱怨;
- 降级友好:不支持 View Transition 或用户开启"减少动态效果"时,直接瞬时切换。
上手实践:三条速记
- 颜色只用语义类名:
text-text-primary、bg-background-primary-default、border-border-button-default、图标text-foreground-icon-primary(AGENTS.md#L17-L21)。 - 文字用组合排版令牌:
text-body-medium一次设定字号、行高、字重、字距,禁止text-sm font-medium leading-5式拼装(styles/typography.css)。 - 合并类名走
cx():utils/cx.ts 是感知 BoardUI 组合文本样式的 tailwind-merge 封装,避免字符串拼接。
在已有项目中引入令牌体系只需一条命令:
npx boardui@latest add theme小结
BoardUI 的令牌体系可以浓缩成一句话:原语定义原料,语义层定义用途,inline 导出让工具类随主题翻转,accent 色阶保留换肤的"总开关"。400+ 语义令牌覆盖文本、前景、背景、边框、状态、图表六大族,深色模式是"加一个类",换肤是"改 11 个变量"——这正是它让深色模式与一键换肤零成本的全部秘密。
【免费下载链接】boardui
React design system for agentic interfaces. Every free BoardUI component as source, with a working AI chat app on your own model key as the homepage.
相关推荐
HyperDX 品牌主题系统深度解析:HyperDX 与 ClickStack 双品牌、明暗色模式与语义设计令牌架构
HyperDX 品牌主题系统深度解析:HyperDX 与 ClickStack 双品牌、明暗色模式与语义设计令牌架构 本文基于 HyperDX 开源仓库的 ag
可观测性云原生运维binwalk 固件分析工具:Docker / Cargo 完整安装与配置指南
binwalk 固件分析工具:Docker / Cargo 完整安装与配置指南 binwalk v3 是用 Rust 重写的固件分析工具,能识别并提取嵌在固件镜
固件嵌入式逆向工程Diagram Design 风格指南:语义令牌、排版系统与可换肤的视觉皮肤机制
Diagram Design 风格指南:语义令牌、排版系统与可换肤的视觉皮肤机制 本文围绕开源仓库 diagram design 的单一事实来源文档 style
AI 技能/插件
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考