基础
Token
每组 token 及其在两种模式下的值,token 名怎么构成,tokens.json 放在哪里、foundation.css 如何由它生成,以及如何迁移弃用的名称。
token 是一个有名字的值:一种颜色、一种阴影、一个尺寸。组件和产品只用名字,从不直接用值,所以一个值只需在一处修改,所有界面在两种模式下都会跟着变。本页是所有 token 的参考。在 token 之间如何选择的规则,归属于各组 token 所属的基础页面,下面每一节都附有链接。
原则
- 只有一个来源。
tokens.json里的每个 token 只在那里写一次。foundation.css由它生成,其他任何地方都不定义 token 的值。 - 名字说明角色,不说明颜色。 写
attention,不写粉色;写layer-canvas,不写白色。值变了,token 的名字不变;深色模式的值也放在同一个名字下。 - 先用角色 token,再用调色板。 只有在没有合适角色时才用
palette-*;见颜色。 - 一个值用到第三次就变成 token。 只用一次的值可以内联,写成一个墨色阶或一个
oklch()字面量;用到第三次时,添加一个 token。
token 放在哪里
| 文件 | 内容 |
|---|---|
packages/ui/src/tokens.json | 颜色、阴影、焦点环和尺寸类 token 的来源,采用 Design Tokens Community Group 格式(2025.10)。以 @botiverse/raft-ui/tokens.json 发布,供 CSS 以外的工具使用。 |
packages/ui/src/foundation.css | 由 tokens.json 生成:每个 token 都是一个 CSS 自定义属性,分别用于浅色模式、深色模式和跟随系统设置。以 @botiverse/raft-ui/foundation.css 发布,供纯 CSS 使用。 |
packages/ui/src/styles.css | Tailwind 入口。它引入 foundation.css,把 token 映射成工具类(bg-layer-canvas、text-foreground-muted、shadow-float),并定义只作为 Tailwind 主题值存在的 token:圆角、文字样式和 ease-slide。 |
packages/ui/src/fonts.css | 字体族:Space Grotesk、Space Mono 和 CJK 后备字体(默认简体中文;繁体中文、日文和韩文在各自的 lang 下)。 |
使用 Tailwind 的应用引入 @botiverse/raft-ui/styles.css。不用 Tailwind 的页面引入 @botiverse/raft-ui/foundation.css,读取自定义属性:var(--layer-canvas)。
foundation.css 如何生成
packages/ui/scripts/build-tokens.mjs 读取 tokens.json,写出 foundation.css。不要手动编辑 foundation.css。
vp run @botiverse/raft-ui#build:tokens # write src/foundation.css
node packages/ui/scripts/build-tokens.mjs --check # exit 1 if it is out of date- 在
tokens.json里改一个值,运行build:tokens,然后两个文件一起提交。foundation.css与tokens.json不一致时,测试(foundation.generated.test.ts)会失败。 - token 的路径就是它的属性名:
{layer.canvas}对应--layer-canvas。$root表示分组本身:{foreground.$root}对应--foreground。引用("{palette.cyan.800}")会变成var(--palette-cyan-800)。 - 这个格式没有表示模式的字段,所以
tokens.json加了一个扩展build.botiverse.raft:
| 字段 | 含义 |
|---|---|
modes.dark | 深色模式的值。没有这一项的 token 在两种模式下值相同 |
desktop | 桌面端的值:从 768px 起(桌面布局从这里开始),并使用鼠标或触控板(间距);此时 token 自身的值是手机和触屏的值。用于 field-font-size 这类尺寸 token |
scope: "root" | 不随模式变化的值,比如调色板:只在 :root 上声明一次 |
scope: "every-mode" | 随模式变化的 token 的别名:在每个模式的作用域里再声明一次,这样它解析的是该模式下的值 |
css: true | 保留为 CSS 表达式的值,格式中没有对应的类型:color-mix()、多层阴影 |
static: true | 不随模式变化的值的弃用别名 |
生成的文件依次包含:
- 调色板,在
:where(:root)上; - 浅色模式,在
:where(:root)和.light上; - 深色模式,在
.dark上; - 再写一遍深色模式,放在
@media (prefers-color-scheme: dark)下,针对没有.light或.dark的根节点,这样在应用设置 class 之前页面的颜色就是对的; - 在每个模式中都声明的别名,然后是弃用的名称;
- 桌面端的值,放在
@media (width >= 48rem) and (pointer: fine)下(也是styles.css中桌面字号用的查询),选择器与它们所替换的值相同。
深色页面里的 .light 元素是一个浅色孤岛,用于预览或传送门(portal);styles.css 中的 dark: 变体跟随最近的模式 class。见深色模式。
token 命名规则
名字由几个部分组成,所以即使是没见过的名字,你也能看出它是做什么的。
| 类别 | 模式 | 示例 |
|---|---|---|
| 中性角色 | {role}(-{purpose})(-{intensity}) | layer-canvas、foreground-hint、line-seam、fill-medium、foreground-on-hud |
| 颜色角色 | {family}(-{slot}) | brand、brand-soft、danger-strong、info-muted |
| 墨色阶 | ink-{alpha} | ink-8、ink-40 |
| 调色板 | palette-{color}-{step} | palette-yellow-400、palette-lavender-800 |
| 状态 | task-status-{status}(-soft|-strong)、presence-{state} | task-status-in-review-soft、presence-busy |
| 贴纸 | sticker-{part} | sticker-ink、sticker-edge、sticker-medium |
| 阴影 | elevation-{level}、focus-ring | elevation-float、elevation-sticker |
| 尺寸 | {part}-{property} | field-font-size、card-title-line-height |
中性角色。 角色是以下四种之一:
foreground-*:文字和图标;layer-*:表面,按叠放顺序排列(外框、侧边栏、画布、卡片、弹出层);line-*:线;fill-*:铺在表面里或表面上的填充。
用途说明 token 用在哪里:frame、sidebar、canvas、card、popover、code、hud、on-frame、on-hud、link、field。强度从不带后缀的名字往下到 -muted,文字再往下是 -hint;线则从 -hairline 经 -seam 到 -strong。
颜色角色。 色系是 brand、attention、info、success、warning、danger 或 inactive 之一。槽位说明是哪个色阶:
| 槽位 | 含义 |
|---|---|
不带后缀(info) | 实色:贴纸的填充 |
-strong | 深色阶,可作为文字阅读 |
-muted | 较浓的淡色 |
-soft | 很淡的淡色,不带边框;见柔和淡色 |
-foreground | 实色上的文字,仅限有自己文字色的色系 |
-hover、-active | 实色填充在悬停和按下时用的一对值。一个色系要么两个都有,要么都没有 |
-50 到 -950 | 带编号的色阶。只有 brand 和 attention 有 |
不透明度。 除了两个遮罩 layer-backdrop 和 layer-backdrop-nested,所有 layer token 都是不透明的。fill-muted 和 fill-strong 是不透明的。fill-subtle、fill-medium、fill-frame-medium 和 sticker-medium 是半透明的:它们是悬停层级,叠在控件或行上面(悬停浮层)。
工具类。 Tailwind 工具类由属性前缀加 token 名构成:bg-layer-card、text-foreground-muted、border-line-strong。阴影另有命名:elevation-float 对应 shadow-float,elevation-sticker 对应 shadow-sticker,focus-ring 对应 shadow-focus。带编号的调色板色阶只有自定义属性,没有工具类;不带编号的 bg-palette-yellow 及同类是例外。
token 分组
下面每个区块都由 tokens.json 生成,显示浅色和深色两种值。
调色板
角色所指向的原始颜色。直接使用它们的规则见颜色。
| Token | 浅色 | 深色 |
|---|---|---|
| palette-yellow-50 | ||
| palette-yellow-100 | ||
| palette-yellow-200 | ||
| palette-yellow-300 | ||
| palette-yellow-400 | ||
| palette-yellow-500 | ||
| palette-yellow-600 | ||
| palette-yellow-700 | ||
| palette-yellow-800 | ||
| palette-yellow-900 | ||
| palette-yellow-950 | ||
| palette-lavender-50 | ||
| palette-lavender-100 | ||
| palette-lavender-200 | ||
| palette-lavender-300 | ||
| palette-lavender-400 | ||
| palette-lavender-500 | ||
| palette-lavender-600 | ||
| palette-lavender-700 | ||
| palette-lavender-800 | ||
| palette-lavender-900 | ||
| palette-lavender-950 | ||
| palette-pink-50 | ||
| palette-pink-100 | ||
| palette-pink-200 | ||
| palette-pink-300 | ||
| palette-pink-400 | ||
| palette-pink-500 | ||
| palette-pink-600 | ||
| palette-pink-700 | ||
| palette-pink-800 | ||
| palette-pink-900 | ||
| palette-pink-950 | ||
| palette-cyan-50 | ||
| palette-cyan-100 | ||
| palette-cyan-200 | ||
| palette-cyan-300 | ||
| palette-cyan-400 | ||
| palette-cyan-500 | ||
| palette-cyan-600 | ||
| palette-cyan-700 | ||
| palette-cyan-800 | ||
| palette-cyan-900 | ||
| palette-cyan-950 | ||
| palette-orange-50 | ||
| palette-orange-100 | ||
| palette-orange-200 | ||
| palette-orange-300 | ||
| palette-orange-400 | ||
| palette-orange-500 | ||
| palette-orange-600 | ||
| palette-orange-700 | ||
| palette-orange-800 | ||
| palette-orange-900 | ||
| palette-orange-950 | ||
| palette-lime-50 | ||
| palette-lime-100 | ||
| palette-lime-200 | ||
| palette-lime-300 | ||
| palette-lime-400 | ||
| palette-lime-500 | ||
| palette-lime-600 | ||
| palette-lime-700 | ||
| palette-lime-800 | ||
| palette-lime-900 | ||
| palette-lime-950 | ||
| palette-red-50 | ||
| palette-red-100 | ||
| palette-red-200 | ||
| palette-red-300 | ||
| palette-red-400 | ||
| palette-red-500 | ||
| palette-red-600 | ||
| palette-red-700 | ||
| palette-red-800 | ||
| palette-red-900 | ||
| palette-red-950 | ||
| palette-stone-50 | ||
| palette-stone-100 | ||
| palette-stone-200 | ||
| palette-stone-300 | ||
| palette-stone-400 | ||
| palette-stone-500 | ||
| palette-stone-600 | ||
| palette-stone-700 | ||
| palette-stone-800 | ||
| palette-stone-900 | ||
| palette-stone-950 | ||
| palette-cream-50 | ||
| palette-cream-100 | ||
| palette-cream-200 | ||
| palette-cream-300 | ||
| palette-cream-400 | ||
| palette-cream-500 | ||
| palette-cream-600 | ||
| palette-cream-700 | ||
| palette-cream-800 | ||
| palette-cream-900 | ||
| palette-cream-950 |
文字和图标
foreground 及其各层级,以及外框和 HUD 上的文字颜色。用法和对比度:颜色、字体排印。
| Token | 浅色 | 深色 |
|---|---|---|
| foreground | ||
| foreground-muted | ||
| foreground-hint | ||
| foreground-disabled | ||
| foreground-inverse | ||
| foreground-on-hud | ||
| foreground-on-hud-mutedSecondary text on the HUD: the shortcut in a tooltip, the detail line of a toast. | ||
| foreground-on-frame | ||
| foreground-on-frame-muted | ||
| foreground-on-frame-active | ||
| foreground-link | ||
| foreground-active | ||
| foreground-hover |
表面
用法:颜色。
| Token | 浅色 | 深色 |
|---|---|---|
| layer-canvas | ||
| layer-sidebar | ||
| layer-popover | ||
| layer-backdrop | ||
| layer-backdrop-nested | ||
| layer-card | ||
| layer-hud | ||
| layer-frame | ||
| layer-frame-active | ||
| layer-code |
填充
| Token | 浅色 | 深色 |
|---|---|---|
| fill-muted | ||
| fill-strong | ||
| fill-subtleHover tier subtle (light): hover on large things people read, a row, a message, a readable card, and a row whose menu is open. About 2.5 to 3 OKLab dE in both modes, on paper, the sidebar and cards alike, under every selection tint, so text keeps its contrast. | ||
| fill-mediumHover tier medium: hover on small controls (buttons, icon buttons, chips, tabs, segment items) and press on everything, on paper-coloured surfaces. About 5.5 to 6.5 OKLab dE; dark is lighter than light because the same ink alpha shows more on a dark surface. | ||
| fill-frame-mediumHover tier medium on the frame (rail items, on-frame buttons, the workspace button): hover and press. Its own alphas because ink shows differently on the yellow and on the near-black frame: 10% on the yellow and 6% on the dark frame land on the medium step, about 6 OKLab dE. |
线
| Token | 浅色 | 深色 |
|---|---|---|
| line-strong | ||
| line-seam | ||
| line-hairline | ||
| line-frame-active | ||
| line-fieldThe frame of a field and the composer: the ink and width of line-strong, drawn 1.5px. | ||
| line-field-hover |
墨色阶
半透明的墨色阶梯,线、次要文字和浮层都由它构成。请用角色 token;只有一次性的淡色铺底才用墨色阶。
| Token | 浅色 | 深色 |
|---|---|---|
| ink-2 | ||
| ink-4 | ||
| ink-6 | ||
| ink-8 | ||
| ink-10 | ||
| ink-16 | ||
| ink-20 | ||
| ink-30 | ||
| ink-40 | ||
| ink |
颜色角色
每种颜色的含义:颜色的含义。
| Token | 浅色 | 深色 |
|---|---|---|
| brand-50 | ||
| brand-100 | ||
| brand-200 | ||
| brand-300 | ||
| brand-400 | ||
| brand-500 | ||
| brand-600 | ||
| brand-700 | ||
| brand-800 | ||
| brand-900 | ||
| brand-950 | ||
| brand-strong | ||
| brand-soft | ||
| brand-edge | ||
| brand-glow | ||
| brand-hoverHovering or pressing a sticker lays sticker-medium (10% ink) over its colour. | ||
| brand-active |
| Token | 浅色 | 深色 |
|---|---|---|
| attention-50 | ||
| attention-100 | ||
| attention-200 | ||
| attention-300 | ||
| attention-400 | ||
| attention-500 | ||
| attention-600 | ||
| attention-700 | ||
| attention-800 | ||
| attention-900 | ||
| attention-950 | ||
| attention-strong | ||
| attention-soft | ||
| attention-hover | ||
| attention-active |
| Token | 浅色 | 深色 |
|---|---|---|
| infoEvery solid is a sticker: ink type on the colour in both modes. | ||
| info-strong | ||
| info-muted | ||
| info-soft | ||
| info-hover | ||
| info-active |
| Token | 浅色 | 深色 |
|---|---|---|
| success | ||
| success-foreground | ||
| success-strong | ||
| success-muted | ||
| success-soft |
| Token | 浅色 | 深色 |
|---|---|---|
| warning | ||
| warning-foreground | ||
| warning-strong | ||
| warning-muted | ||
| warning-soft | ||
| warning-hover | ||
| warning-active |
| Token | 浅色 | 深色 |
|---|---|---|
| dangerdanger = the destructive sticker (red fill, ink type); danger-strong is the error ink for invalid fields and destructive menu items. | ||
| danger-foreground | ||
| danger-strong | ||
| danger-muted | ||
| danger-soft | ||
| danger-hover | ||
| danger-active |
| Token | 浅色 | 深色 |
|---|---|---|
| inactive | ||
| inactive-foreground | ||
| inactive-soft |
状态
任务状态和在线状态灯:状态。
| Token | 浅色 | 深色 |
|---|---|---|
| task-status-todo | ||
| task-status-todo-soft | ||
| task-status-todo-strong | ||
| task-status-in-progress | ||
| task-status-in-progress-soft | ||
| task-status-in-progress-strong | ||
| task-status-in-review | ||
| task-status-in-review-soft | ||
| task-status-in-review-strong | ||
| task-status-done | ||
| task-status-done-soft | ||
| task-status-done-strong | ||
| task-status-closed | ||
| task-status-closed-soft | ||
| task-status-closed-strong |
| Token | 浅色 | 深色 |
|---|---|---|
| presence-online | ||
| presence-busy | ||
| presence-error | ||
| presence-offline | ||
| presence-external |
贴纸
用法:贴纸。
| Token | 浅色 | 深色 |
|---|---|---|
| sticker-ink | ||
| sticker-paper | ||
| sticker-edge | ||
| sticker-mediumHover tier medium on a colour sticker (primary, warning and danger buttons, colour badges, the selected segment on press): hover and press, 10% ink in both modes. |
阴影和焦点环
| Token | 浅色 | 深色 |
|---|---|---|
| elevation-floatControls never cast a shadow; only overlays float. | ||
| elevation-sticker |
| Token | 浅色 | 深色 |
|---|---|---|
| focus-ringThe focus indicator. It shows only after keyboard navigation: styles.css empties it while the root carries data-input-modality="pointer", which installInputModality sets after a click or a tap. |
尺寸
输入框和卡片标题与旁边并排部件共用的文字尺寸。用法:字体排印。
| Token | 浅色 | 深色 | 桌面端 |
|---|---|---|---|
| field-font-size | |||
| field-font-weight | |||
| field-line-height |
| Token | 浅色 | 深色 | 桌面端 |
|---|---|---|---|
| card-title-font-size | |||
| card-title-font-weight | |||
| card-title-line-height |
控件尺寸:默认控件的高度、它的图标和点击区域,以及嵌在外框里的控件保持的值:control-embedded-inset,即它到外框外边缘和到相邻控件的距离;control-embedded-size,即输入框里标签或按钮的高度(间距、形状)。
| Token | 浅色 | 深色 | 桌面端 |
|---|---|---|---|
| control-heightA default control: a field, a Button at lg, an icon button at icon-lg. A finger's 44px on a phone, Feishu's 32px on a desktop. | |||
| control-height-ctaThe full-width call to action across a sign-in, sign-up or setup form (Button xl). | |||
| control-icon-sizeThe icon in a control-height icon button. | |||
| control-hit-insetHow far a control-height button's hit area reaches past its top and bottom, to keep 44px. | |||
| control-embedded-insetHow far a chip or a button embedded in a field, the composer or a corner sits inside its frame's outer edge, and from its sibling. | |||
| control-embedded-sizeA chip or a button embedded in a field: the control height less the embedded inset above and below, so the field keeps its height. |
时间线节奏:对话里各行之间的消息档和分段档,以及每行在文字周围保留的行内距(间距)。
| Token | 浅色 | 深色 |
|---|---|---|
| timeline-gap-messageThe message step of a timeline: from the last line of one turn to the first line of the next (a sender line, an event line). Every row keeps the row inset above and below its text; the first row of a turn adds the rest above it. | ||
| timeline-gap-sectionThe section step of a timeline, one step wider than the message step: either side of a date line, from the top of the list to the first line, and from the last line to the composer, so a boundary reads as one and the last message never sits on the composer. | ||
| timeline-row-insetHow far a timeline row's hover and selected highlight reaches above and below its text. Two rows of one turn sit two insets apart. |
在 styles.css 中定义的 token
这些是 styles.css 里的 Tailwind 主题值,不是 tokens.json 中的条目,所以没有生成的表格。
| Token | 归属 |
|---|---|
radius-sticker、radius-chip、radius-control、radius-container、radius-dialog | 形状 |
text-hero 到 text-label、text-mono-meta、text-mono-code、text-control,各有手机和桌面端两个值 | 字体排印 |
ease-slide | 动效 |
spacing-timeline-message、spacing-timeline-section、spacing-timeline-row(时间线 token 对应的间距工具类),以及由它们推出的 spacing-timeline-turn、spacing-timeline-lead、spacing-timeline-start、spacing-timeline-end。产品只用 timeline-start 和 timeline-end | 间距 |
font-sans、font-heading、font-mono | 字体排印 |
弃用的名称
旧名称作为别名保留到 raft-ui 1.0,放在 tokens.json 的 deprecated 分组里。每个别名都指向应改用的 token,这样旧代码在迁移期间仍能正常工作。
| Token | 浅色 | 深色 |
|---|---|---|
| fill-pressed | ||
| fill-frame-pressed | ||
| fill-row-hover | ||
| fill-row-open | ||
| fill-message-hover | ||
| sticker-pressed | ||
| layer-panel | ||
| layer-inset | ||
| layer-canvas-muted | ||
| layer-hud-foreground | ||
| foreground-strong | ||
| foreground-icon | ||
| foreground-placeholder | ||
| line | ||
| line-muted | ||
| primary-50 | ||
| primary-100 | ||
| primary-200 | ||
| primary-300 | ||
| primary-400 | ||
| primary-500 | ||
| primary-600 | ||
| primary-700 | ||
| primary-800 | ||
| primary-900 | ||
| primary-950 | ||
| primary-strong | ||
| primary-soft | ||
| primary-edge | ||
| primary-glow | ||
| primary-hover | ||
| primary-active | ||
| accent-50 | ||
| accent-100 | ||
| accent-200 | ||
| accent-300 | ||
| accent-400 | ||
| accent-500 | ||
| accent-600 | ||
| accent-700 | ||
| accent-800 | ||
| accent-900 | ||
| accent-950 | ||
| accent-strong | ||
| accent-soft | ||
| accent-hover | ||
| accent-active | ||
| theme-shadow-xs | ||
| theme-shadow-sm | ||
| theme-shadow-md | ||
| theme-shadow-lg | ||
| theme-shadow-xl | ||
| theme-shadow-float | ||
| theme-shadow-sticker | ||
| theme-focus-ring | ||
| color-brutal-yellow-50 | ||
| color-brutal-yellow-100 | ||
| color-brutal-yellow-200 | ||
| color-brutal-yellow-300 | ||
| color-brutal-yellow-400 | ||
| color-brutal-yellow-500 | ||
| color-brutal-yellow-600 | ||
| color-brutal-yellow-700 | ||
| color-brutal-yellow-800 | ||
| color-brutal-yellow-900 | ||
| color-brutal-yellow-950 | ||
| color-brutal-purple-50 | ||
| color-brutal-purple-100 | ||
| color-brutal-purple-200 | ||
| color-brutal-purple-300 | ||
| color-brutal-purple-400 | ||
| color-brutal-purple-500 | ||
| color-brutal-purple-600 | ||
| color-brutal-purple-700 | ||
| color-brutal-purple-800 | ||
| color-brutal-purple-900 | ||
| color-brutal-purple-950 | ||
| color-brutal-pink-50 | ||
| color-brutal-pink-100 | ||
| color-brutal-pink-200 | ||
| color-brutal-pink-300 | ||
| color-brutal-pink-400 | ||
| color-brutal-pink-500 | ||
| color-brutal-pink-600 | ||
| color-brutal-pink-700 | ||
| color-brutal-pink-800 | ||
| color-brutal-pink-900 | ||
| color-brutal-pink-950 | ||
| color-brutal-cyan-50 | ||
| color-brutal-cyan-100 | ||
| color-brutal-cyan-200 | ||
| color-brutal-cyan-300 | ||
| color-brutal-cyan-400 | ||
| color-brutal-cyan-500 | ||
| color-brutal-cyan-600 | ||
| color-brutal-cyan-700 | ||
| color-brutal-cyan-800 | ||
| color-brutal-cyan-900 | ||
| color-brutal-cyan-950 | ||
| color-brutal-orange-50 | ||
| color-brutal-orange-100 | ||
| color-brutal-orange-200 | ||
| color-brutal-orange-300 | ||
| color-brutal-orange-400 | ||
| color-brutal-orange-500 | ||
| color-brutal-orange-600 | ||
| color-brutal-orange-700 | ||
| color-brutal-orange-800 | ||
| color-brutal-orange-900 | ||
| color-brutal-orange-950 | ||
| color-brutal-lime-50 | ||
| color-brutal-lime-100 | ||
| color-brutal-lime-200 | ||
| color-brutal-lime-300 | ||
| color-brutal-lime-400 | ||
| color-brutal-lime-500 | ||
| color-brutal-lime-600 | ||
| color-brutal-lime-700 | ||
| color-brutal-lime-800 | ||
| color-brutal-lime-900 | ||
| color-brutal-lime-950 | ||
| color-brutal-red-50 | ||
| color-brutal-red-100 | ||
| color-brutal-red-200 | ||
| color-brutal-red-300 | ||
| color-brutal-red-400 | ||
| color-brutal-red-500 | ||
| color-brutal-red-600 | ||
| color-brutal-red-700 | ||
| color-brutal-red-800 | ||
| color-brutal-red-900 | ||
| color-brutal-red-950 | ||
| color-brutal-stone-50 | ||
| color-brutal-stone-100 | ||
| color-brutal-stone-200 | ||
| color-brutal-stone-300 | ||
| color-brutal-stone-400 | ||
| color-brutal-stone-500 | ||
| color-brutal-stone-600 | ||
| color-brutal-stone-700 | ||
| color-brutal-stone-800 | ||
| color-brutal-stone-900 | ||
| color-brutal-stone-950 | ||
| color-brutal-cream-50 | ||
| color-brutal-cream-100 | ||
| color-brutal-cream-200 | ||
| color-brutal-cream-300 | ||
| color-brutal-cream-400 | ||
| color-brutal-cream-500 | ||
| color-brutal-cream-600 | ||
| color-brutal-cream-700 | ||
| color-brutal-cream-800 | ||
| color-brutal-cream-900 | ||
| color-brutal-cream-950 | ||
| secondary-50 | ||
| secondary-100 | ||
| secondary-200 | ||
| secondary-300 | ||
| secondary-400 | ||
| secondary-500 | ||
| secondary-600 | ||
| secondary-700 | ||
| secondary-800 | ||
| secondary-900 | ||
| secondary-950 |
重命名遵循几种模式:
primary-* -> brand-*
accent-* -> attention-*
color-brutal-{color}-{n} -> palette-{color}-{n} (purple -> lavender)
secondary-{n} -> palette-stone-{n}
layer-panel -> layer-canvas
layer-canvas-muted -> layer-sidebar
layer-inset -> fill-muted
layer-hud-foreground -> foreground-on-hud
foreground-strong -> foreground
foreground-icon -> foreground-muted
foreground-placeholder -> foreground-hint
line -> line-seam
line-muted -> line-hairline
theme-shadow-float/lg/xl -> elevation-float (utility: shadow-float)
theme-shadow-sticker -> elevation-sticker (utility: shadow-sticker)
theme-focus-ring -> focus-ring (utility: shadow-focus)
theme-shadow-xs/sm/md -> none: controls cast no shadow, drop the classCodemod
raft-ui 附带一个 codemod,可以改写 Tailwind 工具类(bg-…、hover:border-…/50)和 CSS 自定义属性(var(--…))中的旧名称:
node node_modules/@botiverse/raft-ui/codemods/token-names.mjs <dir-or-file>... [--dry]- 它改写
.ts、.tsx、.js、.jsx、.mjs、.cjs、.css和.html文件,跳过node_modules、dist和build。--dry列出它会修改的文件。 - 它只重命名引用,不动声明,所以运行两次也是安全的。
- 人工检查结果。原本禁止旧名称的防护(lint 规则、测试、允许列表)现在会禁止新名称;由片段拼出的模式,比如针对 class 名的正则表达式,仍保留旧名称。
- 文档从不使用弃用的名称:页面中出现时,
scripts/check-docs.mjs会报错。
修改 token
- 只在
tokens.json里添加或修改值,并在同一次改动中重新生成foundation.css。 - 新 token 的名字要遵循上面的命名规则;如果组件需要,在
styles.css里加上它的工具类。 - 重命名 token 时,把旧名称保留在
deprecated分组里并指向新名称,同时把这次重命名加进 codemod。只在大版本中删除别名。 - 文字、表面或淡色的值变化时,在两种模式下重新核对颜色中的对比度保证。
- 在同一个 pull request 里更新这个 token 所属的基础页面(编写指南)。