mcpField
O
opendesign-tokens

opendesign-tokens

github.com/finch-poiデザイン・UI164 回インストール9 週間前に更新
リポジトリ

opendesign-tokens について

opendesign-tokensは、OpenDesignコンポーネントライブラリ向けのデザイントークンガイドです。デザイナーやフロントエンド開発者を対象に、Pixsoのデザイン属性をCSS Tokenへ対応付けます。6種類のテーマ、ライト・ダークモード、レスポンシブトークンの選び方を扱います。

主な機能

  1. 016種類のテーマとモード切り替えの説明
  2. 02意味別に整理されたカラーToken
  3. 03レスポンシブな文字サイズと間隔Token
  4. 04Pixso属性からCSS Tokenへの対応付け
  5. 05バージョン要件と無効な名前の注意

活用シーン

  1. 01Pixsoのデザイン属性をCSS Tokenに変換
  2. 02ページ用のレスポンシブ文字サイズと間隔の選択
  3. 03コンポーネントに意味色や境界線Tokenを適用
  4. 04テーマ設定とTokenのバージョン確認

MCP 対応

Pixso MCPのデザインノード属性をCSS Tokenに対応付ける説明があり、デザイン属性の読み取り後のToken選択に使えます。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/finch-poi/opendesign-skills --skill opendesign-tokens

インストール後、Claude Code で/opendesign-tokensを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

CHANGELOG.md
references/
tokens-ascend.md
tokens-kunpeng.md
tokens-mindspore.md
tokens-openeuler.md
tokens-opengauss.md
tokens-openubmc.md
tokens.md
scripts/
bin.mjs
check-tokens.mjs
package.json
scripts/lib/
convert.mjs
file-scan.mjs
lookup.mjs
package-resolver.mjs
registry.mjs
shared.mjs

詳細

OpenDesign デザイントークンガイド

本 Skill は @opensig/opendesign-token v0.1.1(2026-06 生成)に対応しています。最低依存バージョンは ≥0.1.1 です。

@opensig/opendesign-token は OpenDesign コンポーネントライブラリのデザイントークンパッケージで、すべての token に --o- プレフィックスが付いています。プロジェクトで以前のバージョン(<0.1.1)を使用している場合、トークン(7 段階のフォントウェイト、オンデマンドインポート、ラテン文字/中国語の分離など)が一部存在しない可能性があります。Skill が推奨するトークンを使用する際は、まずプロジェクトの package.json でこのパッケージのバージョンを確認してください。0.1.1 未満の場合は、ユーザーにアップグレードを促してください。個々のトークンがどのバージョンで追加・変更・削除されたかは、 ReleaseNote を確認してください。

コンポーネントライブラリには、独立した6種類のテーマ(openEuler/Ascend/Kunpeng/Mindspore/openGauss/openUBMC)があります。 各コミュニティプロジェクトは初期化時に1種類を選択し、実行時に6種類のテーマを切り替えることはありません。テーマを選択した後は、ライトモードとダークモードの切り替えのみ行います。


各コミュニティテーマの使用方法

各コミュニティプロジェクトは初期化時に1種類のテーマを選択し、エントリーファイル(main.ts)で対応するテーマ CSS をインポートします。HarmonyOS フォント(HarmonyOS Sans SC)を有効にする場合は、テーマ CSS の後にフォント CSS(@opensig/opendesign-token/fonts/css)をインポートしてください。詳細は第6節「フォント Token」を参照してください。

openEuler テーマ(e)
// main.ts 引入(必须在组件样式之前)
import '@opensig/opendesign-token/themes/e.token.css'

実行時に light/dark を切り替える場合(<html> または <body> に設定します):

document.documentElement.setAttribute('data-o-theme', 'e.light') // 浅色
document.documentElement.setAttribute('data-o-theme', 'e.dark')  // 深色

ブランドカラー: Klein Blue(ブランドブルー)。コントロールのホバー時にはブランドカラーの明るい色調を使用します。


Ascend テーマ(a)
// main.ts 引入
import '@opensig/opendesign-token/themes/a.token.css'

実行時に light/dark を切り替える場合:

document.documentElement.setAttribute('data-o-theme', 'a.light') // 浅色
document.documentElement.setAttribute('data-o-theme', 'a.dark')  // 深色

ブランドカラー: Ascend ブランドカラー。コントロールのホバー時にはニュートラルなグレーの色調を使用します。


Kunpeng テーマ(k)
// main.ts 引入
import '@opensig/opendesign-token/themes/k.token.css'

実行時に light/dark を切り替える場合:

document.documentElement.setAttribute('data-o-theme', 'k.light') // 浅色
document.documentElement.setAttribute('data-o-theme', 'k.dark')  // 深色

ブランドカラー: Kunpeng ブランドカラー。コントロールのホバー時にはニュートラルなグレーの色調を使用します。


Mindspore テーマ(m)
// main.ts 引入
import '@opensig/opendesign-token/themes/m.token.css'

実行時に light/dark を切り替える場合:

document.documentElement.setAttribute('data-o-theme', 'm.light') // 浅色
document.documentElement.setAttribute('data-o-theme', 'm.dark')  // 深色

ブランドカラー: Vivid Blue(鮮やかなブルー)。コントロールのホバー時にはブランドブルーの明るい色調を使用します。


openGauss テーマ(g)
// main.ts 引入
import '@opensig/opendesign-token/themes/g.token.css'

実行時に light/dark を切り替える場合:

document.documentElement.setAttribute('data-o-theme', 'g.light') // 浅色
document.documentElement.setAttribute('data-o-theme', 'g.dark')  // 深色

ブランドカラー: Purple(パープル)。コントロールのホバー時にはブランドパープルの明るい色調を使用します。


openUBMC テーマ(u)
// main.ts 引入
import '@opensig/opendesign-token/themes/u.token.css'

実行時に light/dark を切り替える場合:

document.documentElement.setAttribute('data-o-theme', 'u.light') // 浅色
document.documentElement.setAttribute('data-o-theme', 'u.dark')  // 深色

ブランドカラー: Azure Blue(スカイブルー)。コントロールのホバー時にはブランドブルーの明るい色調を使用します。


Token システムのアーキテクチャ

6種類のテーマで token 名は完全に共通しており、色の値(ブランドカラー、角丸など)のみが異なります。

基础 Token(调色板)        →  语义 Token(颜色意义)         →  组件级 Token
--o-kleinblue-6            →  --o-color-primary1             →  --btn-color
--o-green-6                →  --o-color-success1             →  --input-border-color
--o-mixedgray-*            →  --o-color-info1                →  ...

使用原則:

  • セマンティック token の使用を推奨します(--o-color-*、--o-gap-* など)。light/dark に応じて自動的に適応します。
  • パレット token(--o-kleinblue-*、--o-green-* など)を直接使用しないでください。これらは内部実装用です。

Pixso MCP デザインデータから Token へのマッピングガイド

Pixso MCP でデザインデータのノード属性を読み取る際は、この節を使って Pixso の視覚的な値を対応する CSS Token にマッピングし、ハードコードされた値を置き換えてください。

マッチング手順
Pixso 节点属性值(颜色 / 字号 / 间距 / 圆角 / 阴影 / 宽度)
  ↓
① 识别属性类型 → 查「属性类型速查表」定位到对应章节
  ↓
② 判断使用响应式 token(--o-r-*)还是静态 token(--o-*)
  ↓
③ 颜色类:确认是通用功能色(直接反查)还是主题特有色(查 reference)
  ↓
④ 输出 CSS 变量:var(--o-xxx)
属性タイプ早見表
Pixso 属性判定ルール推奨 Token参照する節
Fill color(塗りつぶし色)背景色、カード/ブロックの塗りつぶし--o-color-fill*第1節
Fill color(塗りつぶし色)機能色(緑/オレンジ/赤/ブランド色)--o-color-success/warning/danger/primary*第1節
Fill color(塗りつぶし色)ブランドのメインカラー、Primary — テーマ固有対応するテーマの reference を確認テーマ reference
Stroke / Border colorコントロールの枠線--o-color-control*第1節
Text color(文字色)主要・副次・補助テキスト(透明度指定)--o-color-info1 ~ info4第1節
Font size(フォントサイズ)ページタイトル、本文、ヒントテキスト--o-r-font_size-*(優先)第2節
Font size(フォントサイズ)コンポーネント内部の固定フォントサイズ--o-font_size-*第6節
Line height(行の高さ)ページレベルのテキスト--o-r-line_height-*(優先)第2節
Padding / Gap(余白/間隔)ページのブロック、モジュール間の間隔--o-r-gap-*(優先)第2節
Padding / Gap(余白/間隔)コンポーネント内部の固定間隔--o-gap-*第4節
Frame width(列幅)複数列レイアウト、サイドバー+メインコンテンツ--o-r-grid-N(第3節のピクセル対応表で N を確認)第3節
Auto-layout gapモジュールの水平方向の間隔(グリッドのガター)--o-r-grid-column-gutter第3節
Corner radius(角丸)カード、コンテナの角丸--o-radius-*第5節
Corner radius(角丸)ボタン、入力欄などのコントロールの角丸--o-radius_control-*第5節
Drop shadow(ドロップシャドウ)カード、ダイアログ--o-shadow-*第7節
Opacity の低下(約 0.4)無効状態コンポーネントの disabled prop。token ではありません—
色の識別優先順位
Pixso 颜色值
  ↓
1. 是否为功能色(绿/橙/红)或文字透明度色(rgba 黑/白)?
   → 直接用文末「通用色值反查表」
  ↓ 否
2. 是否为品牌主色 / Primary / Fill / 圆角?
   → 主题特有,查对应主题 reference 末尾「反查速查表」
  ↓
3. 替换为 var(--o-xxx)
画板尺寸 → 断点对照

响应式 token 的实际值取决于画板所在断点,读取 Pixso 画板宽度时按此对应:

Pixso 画板宽度对应断点响应式 token 实际值参考列
≤840pxPhone第 2 节表格 Phone 列
841–1200pxPad第 2 节表格 Pad 列
1201–1680pxLaptop第 2 节表格 Laptop 列
>1680pxDesktop第 2 节表格 Desktop 列(= 静态 token 值)

从 Pixso 读到字号 22px 且画板宽度为 1440px(Laptop 断点)→ 查第 2 节 Laptop 列 → 对应 --o-r-font_size-h3(Laptop: 18px)或 --o-r-font_size-display3(Laptop: 32px)中选最接近的。


1. 语义颜色 Token(推荐使用)

主色系(Primary)
Token用途light 示例值dark 示例值
--o-color-primary1常规主色rgb(0, 47, 167)rgb(72, 116, 220)
--o-color-primary2悬浮主色rgb(81, 119, 202)rgb(40, 68, 149)
--o-color-primary3激活主色rgb(0, 39, 147)rgb(0, 39, 147)
--o-color-primary4禁用主色rgb(132, 161, 220)rgb(27, 48, 113)
--o-color-primary1-light主色浅色(背景)rgb(190, 206, 237)—
--o-color-primary2-light主色浅色(悬浮背景)rgb(132, 161, 220)—
--o-color-primary3-light主色浅色(激活背景)rgb(81, 119, 202)—
--o-color-primary4-light主色浅色(禁用背景)rgb(227, 234, 246)—

注:以上颜色值为 openEuler 主题的 light 模式示例,其他主题的品牌色会有所不同。

成功色(Success)
Token用途
--o-color-success1常规成功色(rgb(11, 177, 81) light)
--o-color-success2悬浮成功色
--o-color-success3激活成功色
--o-color-success4禁用成功色
--o-color-success1-light成功色浅色(背景)
--o-color-success2-light成功色悬浮浅色
--o-color-success3-light成功色激活浅色
--o-color-success4-light成功色禁用浅色
告警色(Warning)
Token用途
--o-color-warning1常规告警色(rgb(250, 115, 5) light)
--o-color-warning2悬浮告警色
--o-color-warning3激活告警色
--o-color-warning4禁用告警色
--o-color-warning1-light告警色浅色(背景)
--o-color-warning2-light ~ --o-color-warning4-light其他状态浅色
危险色(Danger)
Token用途
--o-color-danger1常规危险色(rgb(230, 0, 18) light)
--o-color-danger2悬浮危险色
--o-color-danger3激活危险色
--o-color-danger4禁用危险色
--o-color-danger1-light危险色浅色(背景)
--o-color-danger2-light ~ --o-color-danger4-light其他状态浅色
信息色 / 文字颜色(Info)
Token用途说明
--o-color-info1一级文字标题、强调文本(不透明)
--o-color-info2二级文字正文(80% 不透明度)
--o-color-info3三级文字辅助信息(60% 不透明度)
--o-color-info4四级文字禁用/占位文本(40% 不透明度)
--o-color-info1-inverse反色一级文字深色背景上的白色文字
--o-color-info2-inverse反色二级文字深色背景上的次要白色文字
--o-color-info3-inverse反色三级文字—
--o-color-info4-inverse反色四级文字—
填充色 / 背景色(Fill)
Token用途说明
--o-color-fill1一级填充页面背景
--o-color-fill2二级填充区块/卡片背景(最常用)
--o-color-fill3三级填充嵌套卡片背景

背景色选择规则:

/* 页面背景 */
background-color:

var
(
--o-color-fill1

)
;

/* 卡片/区块背景(最常用) */
background-color:

var
(
--o-color-fill2

)
;

/* 嵌套卡片背景 */
background-color:

var
(
--o-color-fill3

)
;

/* 纯白色(极少使用,特殊场景) */
background-color:

var
(
--o-color-white

)
;

⚠️ 不存在的 token 命名——严禁使用:

错误写法正确替换说明
var(--o-color-bg1)var(--o-color-fill2)bg1 不存在,在 token CSS 中无定义,解析为 transparent
var(--o-color-bg2)var(--o-color-fill2)bg2 不存在,同上
var(--o-color-bg3)var(--o-color-fill3)bg3 不存在,同上

bg* 命名是其他设计系统(Bootstrap、Element Plus 等)的惯例,opendesign 不��用此命名。背景色统一用 fill*。

控件色(Control)
Token用途
--o-color-control1常规边框色(25% 透明度)
--o-color-control2悬浮边框色(60% 透明度)
--o-color-control3激活边框色(80% 透明度)
--o-color-control4禁用边框色(10% 透明度)
--o-color-control1-light常规控件背景
--o-color-control2-light悬浮控件背景
--o-color-control3-light激活控件背景
--o-color-control4-light禁用控件背景
--o-color-control-light很浅控件色(常用于表格背景)
链接色(Link)
Token用途
--o-color-link1常规链接色
--o-color-link2悬浮链接色
--o-color-link3激活链接色
--o-color-link4禁用链接色
遮罩色(Mask)
Token用途
--o-color-mask1全局遮罩(40% 透明)
--o-color-mask2局部遮罩(20% 透明)
基础色(Base)
Token用途
--o-color-white纯白色 rgb(255, 255, 255)(极少直接使用)
--o-color-black纯黑色 rgb(0, 0, 0)(极少直接使用)

2. 响应式 Token(Responsive)— 页面级首选

优先使用响应式 Token。对于字号、行高、间距,响应式变量(--o-r-*)会根据视口自动缩放,是纠正硬编码值的首选。静态 Token( --o-font_size-*、--o-gap-*)仅在需要固定不变的场景下使用。

响应式变量前缀为 --o-r-,引入主题 CSS 后自动生效,无需额外导入。共 4 个断点:

断点视口范围典型设备
Phone≤840px手机、平板竖屏
Pad841–1200px平板横屏
Laptop1201–1680px笔记本
Desktop>1680px桌面大屏
响应式字号 + 行高
语义Token 名称PhonePadLaptopDesktop
一级数据展示--o-r-font_size-display1 / line_height22/3040/5648/6456/80
二级数据展示--o-r-font_size-display2 / line_height20/2832/4440/5648/64
三级数据展示--o-r-font_size-display3 / line_height18/2624/3232/4440/56
一级标题--o-r-font_size-h1 / line_height18/2620/2820/2832/44
二级标题--o-r-font_size-h2 / line_height16/2418/2620/2824/32
三级标题--o-r-font_size-h3 / line_height16/2416/2418/2622/30
四级标题--o-r-font_size-h4 / line_height16/2416/2418/2620/28
大号正文--o-r-font_size-text2 / line_height14/2214/2216/2418/26
常规正文--o-r-font_size-text1 / line_height14/2214/2214/2216/24
提示文本1--o-r-font_size-tip1 / line_height12/1812/1814/2214/22
提示文本2--o-r-font_size-tip2 / line_height10/1612/1812/1812/18

单位均为 px。Token 名称中 font_size 和 line_height 共享后缀(如 --o-r-font_size-h1 配 --o-r-line_height-h1)。

响应式间距
Token 名称PhonePadLaptopDesktop
--o-r-gap-1032px40px56px72px
--o-r-gap-924px32px48px64px
--o-r-gap-816px24px40px48px
--o-r-gap-712px16px24px40px
--o-r-gap-612px16px24px32px
--o-r-gap-512px12px16px24px
--o-r-gap-48px8px12px16px
--o-r-gap-38px8px8px12px
--o-r-gap-28px8px8px8px
--o-r-gap-14px4px4px4px

对照关系:--o-r-gap-N 的 Desktop 值 = --o-gap-N 的静态值。响应式变量在小屏上自动压缩间距。

响应式 vs 静态 Token 选择
场景推荐原因
页面标题、正文、区块间距--o-r-*(响应式)随视口自动适配,无需写 media query
组件内部固定尺寸(如图标旁 4px 间距)--o-gap-*(静态)尺寸不应随视口变化
设计稿硬编码的字号/间距纠正--o-r-*(响应式)首选,确保多端一致

字号/行高的引用方式:① 字号 + 行高成对输出到当前元素时,使用 font.scss mixin(@include h1;),保证配对且调用简洁;② 只需单独引用某一项时,直接使用 var(--o-r-font_size-*) + var(--o-r-line_height-*) 响应式变量。mixin 的全局注入配置与完整用法详见 opendesign-application skill → styles-infrastructure 第 4 节。


3. 栅格系统 Token(Grid)— 页面级模块布局

栅格系统用于页面级布局,是控制页面各模块在水平方向(X 轴)上宽度与间距的核心配置形式。多栏布局、侧边栏 + 主内容区、模块间的水平分割均应优先使用栅格变量,而非手动写死宽度或 padding。

24 列响应式栅格,共 6 个断点。引入主题 CSS 后自动生效。

断点视口范围列数留白(单侧)水槽
超大屏>1920px2464px32px
桌面1441–1920px2464px32px
小桌面1201–1440px2440px24px
平板横屏841–1200px1232px16px
平板竖屏601–840px832px16px
手机≤600px424px12px

关键变量:--o-r-grid-1 ~ --o-r-grid-24(N 列宽度),--o-r-grid-column-gutter(水槽宽度),--o-r-grid-full(全栅格宽度), --o-r-grid-padding(栅格外侧留白),--o-r-grid-section-width(楼层宽度),--o-r-grid-section-padding(楼层边缘到视口边缘距离)。

栅格容器:直接使用 .o-r-grid-container 类即可( display:flex; max-width:1920px; margin:0 auto; padding:var(--o-r-grid-padding))。

/* 使用栅格列宽变量 */
.column-6 {
    width: var(--o-r-grid-6);
}

.column-8 {
    width: var(--o-r-grid-8);
}

.column-12 {
    width: var(--o-r-grid-12);
}

/* 并排元素间距使用水槽 */
.row {
    display: flex;
    gap: 0 var(--o-r-grid-column-gutter);
}
Pixso 画板 → grid-N 像素对照表

从 Pixso 读到 frame 宽度后,在对应画板宽度的行中找最接近的值,即可确定应使用 --o-r-grid-N。

列宽公式:col = (画板宽 - 2×留白 - (最大列数-1)×水槽) / 最大列数 grid-N 宽度:grid-N = N × col + (N-1) × 水槽

画板宽度断点col水槽grid-4grid-6grid-8grid-12grid-16grid-18
1920px超大屏44px32px272px424px576px880px1184px1336px
1680px桌面34px32px232px364px496px760px1024px1156px
1440px小桌面~33.7px24px~207px~322px~437px~668px~899px~1014px
1200px平板横屏80px16px368px560px752px1136px(超出12列)(超出12列)
840px平板竖屏83px16px380px578px776px(超出8列)——
375px手机~72.75px12px327px(超出4列)————

说明:平板横屏最多 12 列,超出部分等于全宽(grid-12 值);平板竖屏最多 8 列;手机最多 4 列。

水槽分隔原则(核心规则)

X 轴方向上相邻的大块元素(Card、楼层区块、内容模块等)之间的间距 固定为 1 个水槽(--o-r-grid-column-gutter),不使用 gap token。

列数分配约束:N 个并排块的列数之和 = 当前断点的总列数。

grid-N₁ + gutter + grid-N₂ + gutter + ... + grid-Nₙ = 内容区全宽
即:N₁ + N₂ + ... + Nₙ = 总列数(24 / 12 / 8 / 4,取决于断点)

等宽 N 块:每块列数 = 总列数 ÷ N

并排块数超大屏/桌面/小桌面(24列)平板横屏(12列)平板竖屏(8列)手机(4列)
2 块等宽grid-12 + grid-12grid-6 + grid-6grid-4 + grid-4grid-2 + grid-2
3 块等宽grid-8 × 3grid-4 × 3— (不整除)—
4 块等宽grid-6 × 4grid-3 × 4grid-2 × 4—
6 块等宽grid-4 × 6grid-2 × 6——
楼层栅格适配规范

楼层(页面整体区块)的宽度应居中显示,两侧留出适当空白。以下变量已在 token 包中预定义,无需手动创建:

变量名用途
--o-r-grid-section-width楼层宽度
--o-r-grid-section-padding从视口边缘到楼层边缘的总距离

各断点宽度规则:

断点楼层宽度一侧空白栅格数
>1680pxvar(--o-r-grid-20)2 列
1201–1680pxvar(--o-r-grid-22)1 列
≤1200pxvar(--o-r-grid-full)0 列(占满)

使用方式:

.floor {
  width: var(--o-r-grid-section-width);
  margin: 0 auto;
}

布局示意:

|<-- section-padding -->|<--- section-width --->|<-- section-padding -->|

Desktop (>1680px):    grid-padding + 2×(col+gutter) | grid-20 | ...

Laptop (1201-1680px): grid-padding + 1×(col+gutter) | grid-22 | ...

Pad及以下 (≤1200px):  grid-padding               | grid-full | grid-padding
从 Pixso frame 宽度判断 grid-N 的步骤
① 读取 Pixso 画板宽度 → 确定断点行
② 读取 frame.width
③ 在对照表中找最接近的列值 → 得到 N
   (误差在 ±5px 以内可认为是同一列,因设计工具精度或子像素造成)
④ 若 frame 占满内容区(全宽减两侧留白)→ 使用 .o-r-grid-container 包裹即可,无需 grid-N
⑤ 代入:width: var(--o-r-grid-N)

示例:Pixso 画板 1440px,frame 宽度 322px → 查表 "1440px 行,grid-6 ≈ 322px" → 使用 width: var(--o-r-grid-6)。

表单组件栅格规则

OForm 及输入类组件(OInput、OSelect、OTextarea 等)在多列表单布局中,每个表单项的宽度应对齐到栅格列,行间距遵循设计规范值。

多列表单:每行项数与列宽分配

断点总列数每行项数每项宽度 Token标签位置
Desktop >1680px244 项/行--o-r-grid-6左置水平
Laptop 1201–1680px244 项/行--o-r-grid-6左置水平
Pad 841–1200px123 项/行--o-r-grid-4左置水平
Phone ≤840px41 项/行全宽上置堆叠

验证(桌面端,4 项×grid-6):4×grid-6 + 3×gutter = 4×424 + 3×32 = 1696 + 96 = 1792px = 24列内容区 ✓ 验证(平板横屏,3 项×grid-4):3×grid-4 + 2×gutter = 3×368 + 2×16 = 1104 + 32 = 1136px = 12列内容区(1200px画板)✓

行间距(form item 垂直方向)

断点每行 form item 间距
>840px(水平标签)32px
≤840px(堆叠标签)12px

标签宽度与内部间距

区域>840px(PC 水平模式)≤840px(手机堆叠模式)
标签区域宽度固定 96px全宽(100%)
标签到输入框间距4px(标签文字到冒号间距)8px(标签文字到输入框)
Hint/帮助文字位置输入框右侧,右侧留 24px输入框下方,间距 12px

分组约束

  • 多列表单中,单个表单分组(section)建议包含 2–7 个表单项
  • 跨全行的宽项(文本域、文件上传等)单独占满一行(width = 容器全宽)
  • 并排项的列数之和须等于当前断点总列数(同「水槽分隔原则」)

示例:桌面端 4 列表单布局(>1200px)

/* 每个 form item 宽度 = grid-6 */
.form-item {
  width: var(--o-r-grid-6);
}

/* 多列 form 行容器:flex + gutter 间距 */
.form-row {
  display: flex;
  flex-wrap: wrap;
  gap: 32px var(--o-r-grid-column-gutter);
  /* ↑ row-gap=32px(PC),column-gap=水槽 */
}
/* 平板横屏(841-1200px):3 列,每项 grid-4 */
@media (max-width: 1200px) {
  .form-item { width: var(--o-r-grid-4); }
  .form-row  { gap: 12px var(--o-r-grid-column-gutter); }
}

/* 手机(≤840px):1 列,全宽 */
@media (max-width: 840px) {
  .form-item { width: 100%; }
  .form-row  { gap: 12px 0; }
}

4. 间距 Token(Gap)— 静态值

页面级间距推荐使用响应式 token --o-r-gap-*(见第 2 节),以下静态 token 适用于不随视口变化的固定间距场景。

间距 token 适用于 gap、padding、margin 等属性。

Token值用途
--o-gap-14px最小间距(紧凑元素内部)
--o-gap-28px小间距(组件内部元素)
--o-gap-312px中小间距(相关元素之间)
--o-gap-416px常规间距(默认,最常用)
--o-gap-524px中等间距(区块之间)
--o-gap-632px大间距(页面级布局)
--o-gap-740px较大间距
--o-gap-848px很大间距
--o-gap-964px超大间距
--o-gap-1072px最大间距

5. 圆角 Token(Radius)

⚠️ 圆角值因主题而异:以下 值 列是通用参考值,实际值取决于主题。例如 openEuler 主题所有圆角均为 4px(接近直角风格),而 Mindspore 主题则更圆润。使用时请查阅对应主题 reference 文件中的圆角表格。 也不存在 --o-r-radius-1 等带 r- 前缀的圆角变量,圆角 token 没有响应式变体。

内容圆角(用于卡片、容器等)
Token通用参考值用途
--o-radius-xs4px超小圆角
--o-radius-s8px小圆角
--o-radius-m12px中等圆角
--o-radius-l16px大圆角
--o-radius-xl24px超大圆角(一般用于卡片)
控件圆角(用于按钮、输入框等组件)
Token通用参考值用途
--o-radius_control-xs4px超小控件圆角
--o-radius_control-s8px小控件圆角
--o-radius_control-m12px中等控件圆角
--o-radius_control-l16px大控件圆角

6. 字体 Token(Font)

页面级文字推荐使用响应式 token --o-r-font_size-* / --o-r-line_height-*(见第 2 节),以下静态 token 适用于不随视口变化的固定字号场景。

字体族(Font Family)— 鸿蒙字体

OpenDesign 默认使用 HarmonyOS Sans SC(鸿蒙黑体简体)作为中文字体族,并以 HarmonyOS Sans 作为拉丁字体族。字体文件随 @opensig/opendesign-token 包发布,需在入口文件显式引入后,--o-font_family 才会真正指向鸿蒙字体。

⚠️ 0.1.1 破坏性变更:

  • @font-face 注册的字体族由旧版 "HarmonyOS" / HarmonyOS-Hans 更名为 'HarmonyOS Sans SC'(中文)与 'HarmonyOS Sans'(拉丁)。若项目中硬编码了旧字体族名,需改为 'HarmonyOS Sans SC',或直接使用变量 var(--o-font_family)(推荐)。
  • 旧版引入字体文件后会自动对 body 应用 var(--o-font_family),本版不再自动应用,仅注册 @font-face 。升级后需自行在根容器设置字体:
    :root { font-family: var(--o-font_family); }
    
  • --o-font_weight-bold 由 600 改为 700(对应 SansSC_Bold 字体文件);旧版 600 现有独立的 --o-font_weight-semibold 变量对应。设计师通常使用 semibold(600)作为加粗,请确认加粗效果符合预期。
// main.ts(在主题 CSS 之后引入)
import '@opensig/opendesign-token/themes/e.token.css' // 主题 CSS
import '@opensig/opendesign-token/fonts/css'          // 鸿蒙字体(仅注册 @font-face,不自动应用)

若只需某一字重,可按需引入以减小体积(sc- 为中文字体,sans- 为拉丁字体;中文无斜体源文件,故仅有 7 个非斜体目录):

// 仅引入中文常规字重(400)
import '@opensig/opendesign-token/fonts/sc-regular/font.min.css'
// 仅引入拉丁常规字重(400)
import '@opensig/opendesign-token/fonts/sans-regular/font.min.css'
Token值说明
--o-font_family'HarmonyOS Sans', 'HarmonyOS Sans SC', Inter, -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif默认字体族
--o-font_family-codeSFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', monospace等宽代码字体族

字体族自动分流:--o-font_family 将 'HarmonyOS Sans'(拉丁族)排在 'HarmonyOS Sans SC'(中文族)之前。浏览器逐族匹配:拉丁字符命中 'HarmonyOS Sans'(含独立 italic 面,font-style: italic 可直接渲染真斜体);中文字符在 'HarmonyOS Sans' 字体文件中无对应 glyph(该字体仅含拉丁字形),浏览器自动穿透到下一族 'HarmonyOS Sans SC'。中文无源文件斜体,font-style: italic 会合成伪斜体。

字体应用与加载

引入字体 CSS 后仅完成 @font-face 注册, 不会自动应用到任何元素。需在根容器手动应用字体变量:

/* 全局应用鸿蒙字体(推荐在根容器设置) */
:root {
    font-family: var(--o-font_family);
}

code, pre {
    font-family: var(--o-font_family-code);
}

⚠️ 仅设置 font-family: var(--o-font_family) 不会自动加载字体文件,必须在入口文件 import '@opensig/opendesign-token/fonts/css'。中文字体(HarmonyOS Sans SC)按 unicode-range 分片,仅按需加载实际用到的字符;拉丁字体( HarmonyOS Sans)不分片,但文件体量小(~28KB/字重),整体按需加载影响不大。

字重(Font Weight)

鸿蒙字体共七档字重,与 @font-face 注册的七个字面一一对应(CSS font-weight 数值与字面精确匹配,无需就近匹配)。

Token值说明
--o-font_weight-thin250极细
--o-font_weight-light300细体
--o-font_weight-regular400常规
--o-font_weight-medium500中等
--o-font_weight-semibold600半粗(标题、强调)
--o-font_weight-bold700加粗
--o-font_weight-black900超粗

实际开发:日常使用以 --o-font_weight-regular(400)和 --o-font_weight-semibold(600)两档为主,前者用于正文,后者用于标题、强调等场景。

.title {
  font-family: var(--o-font_family);
  font-weight: var(--o-font_weight-semibold); /* 600,标题加粗 */
}
字体大小(Font Size)
Token值用途
--o-font_size-display156px一级数据展示
--o-font_size-display248px二级数据展示
--o-font_size-display340px三级数据展示
--o-font_size-h132px一级标题
--o-font_size-h224px二级标题
--o-font_size-h322px三级标题
--o-font_size-h420px四级标题
--o-font_size-text218px大号正文
--o-font_size-text116px常规正文(最常用)
--o-font_size-tip114px提示文本(小字)
--o-font_size-tip212px辅助提示文本(最小)
行高(Line Height)
Token值配套字号
--o-line_height-display180pxdisplay1
--o-line_height-display264pxdisplay2
--o-line_height-display356pxdisplay3
--o-line_height-h144pxh1
--o-line_height-h232pxh2
--o-line_height-h330pxh3
--o-line_height-h428pxh4
--o-line_height-text226pxtext2
--o-line_height-text124pxtext1
--o-line_height-tip122pxtip1
--o-line_height-tip218pxtip2

字体和行高应配套使用:

/* 响应式(推荐,自动适配多端) */
.title {
    font-size: var(--o-r-font_size-h3);
    line-height: var(--o-r-line_height-h3);
}

/* 需要字号 + 行高成对输出时,可用 font.scss mixin */
/* 全局注入配置与完整用法见 opendesign-application skill → styles-infrastructure §4 */
.title {
    @include h3;
}

/* 静态(仅在需要固定值时使用) */
.fixed-label {
    font-size: var(--o-font_size-tip1);
    line-height: var(--o-line_height-tip1);
}

7. 阴影 Token(Shadow)

Token值用途
--o-shadow-10 3px 8px rgba(..., 0.08)卡片、小弹窗、楼层阴影
--o-shadow-20 2px 24px rgba(..., 0.15)卡片悬浮阴影
--o-shadow-30 8px 40px rgba(..., 0.1)大弹窗、抽屉阴影

8. 动画 Token(Animation)

持续时间(Duration)
Token值用途
--o-duration-s200ms退出屏幕的动画
--o-duration-m1250msstandard-in 曲线进入动画
--o-duration-m2300msstandard 曲线开始/结束动画
--o-duration-m3400msemphasized-in 曲线进入动画
--o-duration-l500msemphasized 曲线开始/结束动画
--o-duration-xl1000ms轮播切换动画
缓动曲线(Easing)
Token值用途
--o-easing-linearcubic-bezier(0, 0, 1, 1)线性
--o-easing-standardcubic-bezier(0.2, 0, 0, 1)标准(组件动画,推荐)
--o-easing-standard-incubic-bezier(0, 0, 0, 1)标准进入
--o-easing-standard-outcubic-bezier(0.3, 0, 1, 1)标准退出
--o-easing-emphasizedcubic-bezier(0.2, 0, 0, 1)强调(大卡片/场景切换)
--o-easing-emphasized-incubic-bezier(0.3, 0, 0.8, 0.15)强调进入
--o-easing-emphasized-outcubic-bezier(0.05, 0.7, 0.1, 1)强调退出
/* 推荐的动画写法 */
transition: all

var
(
--o-duration-m1

)
var
(
--o-easing-standard

)
;

9. 组件尺寸 Token(Control Size)

Token值用途
--o-control_size-2xs14px超超小控件
--o-control_size-xs16px超小控件
--o-control_size-s24px小控件
--o-control_size-m32px中等控件
--o-control_size-l40px大控件
--o-control_size-xl48px超大控件
--o-control_size-2xl56px超超大控件

10. 图标尺寸 Token(Icon Size)

独立图标
Token值
--o-icon_size-xs16px
--o-icon_size-s20px
--o-icon_size-m24px
--o-icon_size-l32px
--o-icon_size-xl40px
--o-icon_size-2xl48px
--o-icon_size-3xl56px
--o-icon_size-4xl64px
控件内图标(组件使用)
Token值
--o-icon_size_control-xs16px
--o-icon_size_control-s20px
--o-icon_size_control-m24px
--o-icon_size_control-l32px
--o-icon_size_control-xl40px

11. 调色板 Token(参考,不推荐直接使用)

调色板 token 是原始颜色值,为语义 token 提供基础, 不应在业务代码中直接使用。

每个色系均有 10 个色阶(1=最浅,10=最深),light/dark 模式下颜色相反。

色系Token 前缀主色代表用途
品牌蓝--o-kleinblue-*#002FA7主色/链接色
绿色--o-green-*#0BB151成功色
橘红色--o-orange-*#FA7305告警色
红色--o-red-*#E60012危险色
黄色--o-yellow-*#F0BC06辅助色
琥珀色--o-amber-*#E78900辅助色
黄绿色--o-lime-*#A7C900辅助色
浅绿色--o-light-green-*#70B31B辅助色
蓝绿色--o-teal-*#00B385辅助色
青色--o-cyan-*#00A7B3辅助色
浅蓝色--o-light-blue-*#009CE5辅助色
蓝色--o-blue-*#1075E8辅助色
紫罗兰--o-violet-*#5E12CB辅助色
紫色--o-purple-*#8702B3辅助色
粉红色--o-pink-*#E00070辅助色
白色--o-white#FFFFFF基础
黑色--o-black#000000基础

最佳实践

OpenDesign 组件样式原则

使用 @opensig/opendesign 组件库中的组件时, 组件应作为一个整体使用,不应修改组件内部样式(除非有明确的特殊需求并经过确认)。组件的视觉表现由 Token 体系统一控制:

  • 通过切换主题(data-o-theme)改变组件的品牌色和圆角风格
  • 通过组件暴露的 props 控制尺寸、颜色变体等
  • 不要通过 CSS 覆盖组件内部的 class 样式(如 .o-btn__text)
  • 不要通过 ::v-deep / :deep() 穿透修改组件内部结构

Token 变量主要用于 自定义业务区域的样式(如页面布局、自定义卡片、业务容器等),而非覆盖组件内部。

✅ 推荐做法

⚠️ 边框规则: 只在设计稿 DSL 中有 strokes 属性时才加边框,绝对不要默认给卡片/容器加边框。 设计稿没有描边就不写 border。

.card {
  background-color: var(--o-color-fill2);        /* 卡片背景 */
  /* ⚠️ border 只有在 DSL strokes 非空时才加 */
  /* border: 1px solid var(--o-color-control1); */
  border-radius: var(--o-radius-m);              /* 圆角 */
  padding: var(--o-r-gap-4);                     /* 内边距(响应式) */
  box-shadow: var(--o-shadow-1);                 /* 阴影(有 DSL effects 时才加) */
}

.title {
  font-size: var(--o-r-font_size-h3);            /* 响应式字号 */
  line-height: var(--o-r-line_height-h3);        /* 响应式行高 */
  color: var(--o-color-info1);                   /* 标题文字 */
}

.body-text {
  font-size: var(--o-r-font_size-text1);         /* 响应式字号 */
  line-height: var(--o-r-line_height-text1);     /* 响应式行高 */
  color: var(--o-color-info2);                   /* 正文 */
}

.section-gap {
  padding: var(--o-r-gap-6) var(--o-r-gap-4);   /* 响应式间距 */
}

.caption {
  font-size: var(--o-r-font_size-tip1);
  color: var(--o-color-info3);                   /* 辅助信息 */
}

.button:hover {
  transition: all var(--o-duration-m1) var(--o-easing-standard);
  box-shadow: var(--o-shadow-2);
}

.link {
  color: var(--o-color-link1);
}
.link:hover {
  color: var(--o-color-link2);
}
❌ 不推荐做法
/* 不要使用调色板 token */
.card {
  background-color: rgb(var(--o-white));        /* ❌ 应使用 var(--o-color-fill2) */
  border: 1px solid rgb(var(--o-grey-5));       /* ❌ 应使用 var(--o-color-control1) */
}

/* 不要硬编码字号/间距——应使用响应式 token */
.title {
  font-size: 22px;                              /* ❌ 应使用 var(--o-r-font_size-h3) */
  line-height: 30px;                            /* ❌ 应使用 var(--o-r-line_height-h3) */
}
.card {
  padding: 16px;                                /* ❌ 应使用 var(--o-r-gap-4) */
  border-radius: 12px;                          /* ❌ 应使用 var(--o-radius-m) */
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.08);  /* ❌ 应使用 var(--o-shadow-1) */
}
.section {
  gap: 32px;                                    /* ❌ 应使用 var(--o-r-gap-6) */
}

/* 不要用静态 token 代替响应式 token(除非确实需要固定值) */
.page-title {
  font-size: var(--o-font_size-h1);             /* ⚠️ 应使用 var(--o-r-font_size-h1),自动适配多端 */
}

使用场景速查

背景色
场景Token
页面背景--o-color-fill1
卡片/区块背景--o-color-fill2(最常用)
嵌套卡片--o-color-fill3
纯白(特殊)--o-color-white
文字颜色
场景Token
标题/强调--o-color-info1
正文--o-color-info2
辅助信息--o-color-info3
禁用/占位--o-color-info4
深色背景白字--o-color-info1-inverse
边框颜色
场景Token
默认边框--o-color-control1
悬浮边框--o-color-control2
激活/聚焦边框--o-color-primary1 或 --o-color-control3
禁用边框--o-color-control4
间距

页面级间距优先使用响应式 token --o-r-gap-*,组件内部固定间距可用静态 --o-gap-*。

场景Token(响应式优先)Desktop 值
图标与文字间距--o-r-gap-1 / --o-gap-14px
组件内部元素--o-r-gap-2 / --o-gap-28px
相关元素间--o-r-gap-312px
默认内边距--o-r-gap-416px
区块间距--o-r-gap-524px
页面布局--o-r-gap-632px
字号

字号和行高优先使用响应式 token --o-r-font_size-* / --o-r-line_height-*。

场景Token(响应式优先)Desktop 值
页面大标题--o-r-font_size-h1 + --o-r-line_height-h132/44px
区块标题--o-r-font_size-h3 + --o-r-line_height-h322/30px
正文--o-r-font_size-text1 + --o-r-line_height-text116/24px
辅助/提示--o-r-font_size-tip1 + --o-r-line_height-tip114/22px

色值反查(设计稿写死色值 → Token)

设计稿中可能存在写死色值(如 #002FA7、rgba(0,0,0,0.25))的情况,需要反向匹配为对应 CSS 变量。

操作流程
1. 确认截取色值时的模式(light / dark)
2. 确认项目使用的主题(e / a / k / m / g / u)
3. 用 CLI 自动反查:node scripts/bin.mjs convert '#XXX' -t <主题> -m <模式>
   或在下方通用表 / 对应主题 reference 中手动查找
4. 将写死的值替换为 var(--o-xxx)
5. 字号/行高/间距优先替换为响应式 token var(--o-r-xxx)

CLI convert 命令从 @opensig/opendesign-token 的 CSS 产物动态构建反向表, 匹配结果始终与实际包版本同步,无需维护静态映射表。下方表格为离线速查参考。

注意:同一 token 在 light 和 dark 模式下对应不同色值,确保对应正确的模式。


通用色值反查(六套主题相同)

以下 token 的色值在六套主题中 完全相同,可直接反查。

功能色(Light 模式)
HexRGBToken语义
#0BB151rgb(11, 177, 81)--o-color-success1成功色
#54D07Frgb(84, 208, 127)--o-color-success2成功悬浮
#07984Argb(7, 152, 72)--o-color-success3成功激活
#80E09Ergb(128, 224, 158)--o-color-success4成功禁用
#B1EFC3rgb(177, 239, 195)--o-color-success1-light成功浅色背景
#FA7305rgb(250, 115, 5)--o-color-warning1告警色
#FCB05Frgb(252, 176, 95)--o-color-warning2告警悬浮
#CF5803rgb(207, 88, 3)--o-color-warning3告警激活
#FDCA8Crgb(253, 202, 140)--o-color-warning4告警禁用
#FEE2BArgb(254, 226, 186)--o-color-warning1-light告警浅色背景
#E60012rgb(230, 0, 18)--o-color-danger1危险色
#F0575Argb(240, 87, 90)--o-color-danger2危险悬浮
#C00016rgb(192, 0, 22)--o-color-danger3危险激活
#F58886rgb(245, 136, 134)--o-color-danger4危险禁用
#FAB9B6rgb(250, 185, 182)--o-color-danger1-light危险浅色背景
文字色(透明度写法,Light 模式)
设计稿常见写法Token语义
rgba(0,0,0,1) 或 #000000--o-color-info1一级文字/标题
rgba(0,0,0,0.8) 或 #000000 80%--o-color-info2二级文字/正文
rgba(0,0,0,0.6) 或 #000000 60%--o-color-info3三级文字/辅助
rgba(0,0,0,0.4) 或 #000000 40%--o-color-info4四级文字/禁用
rgba(255,255,255,1)--o-color-info1-inverse深色背景白字
rgba(255,255,255,0.8)--o-color-info2-inverse深色背景次要白字
遮罩和边框(Light 模式)
设计稿常见写法Token语义
rgba(0,0,0,0.4)--o-color-mask1全局遮罩
rgba(255,255,255,0.2)--o-color-mask2局部遮罩
rgba(0,0,0,0.25)--o-color-control1默认边框
rgba(0,0,0,0.1)--o-color-control4禁用边框
间距(六套主题完全相同)

硬编码间距应优先替换为响应式 token --o-r-gap-*。

硬编码值响应式 Token(推荐)静态 Token
4px--o-r-gap-1--o-gap-1
8px--o-r-gap-2--o-gap-2
12px--o-r-gap-3--o-gap-3
16px--o-r-gap-4--o-gap-4
24px--o-r-gap-5--o-gap-5
32px--o-r-gap-6--o-gap-6
40px--o-r-gap-7--o-gap-7
48px--o-r-gap-8--o-gap-8
64px--o-r-gap-9--o-gap-9
72px--o-r-gap-10--o-gap-10

注意:上表硬编码值对应的是 Desktop 断点(>1680px)的响应式值。小屏下响应式 token 会自动缩小。

字号 / 行高(六套主题完全相同)

硬编码字号应优先替换为响应式 token --o-r-font_size-* + --o-r-line_height-*。

硬编码 font-size响应式 Token(推荐)静态 Token
56px--o-r-font_size-display1--o-font_size-display1
48px--o-r-font_size-display2--o-font_size-display2
40px--o-r-font_size-display3--o-font_size-display3
32px--o-r-font_size-h1--o-font_size-h1
24px--o-r-font_size-h2--o-font_size-h2
22px--o-r-font_size-h3--o-font_size-h3
20px--o-r-font_size-h4--o-font_size-h4
18px--o-r-font_size-text2--o-font_size-text2
16px--o-r-font_size-text1--o-font_size-text1
14px--o-r-font_size-tip1--o-font_size-tip1
12px--o-r-font_size-tip2--o-font_size-tip2

主题特有色值反查

品牌色、Primary 色、Fill 色、圆角等因主题而异,请查阅对应 reference 文件:


Token CLI(校验 + 反查)

写代码前先看这里:本仓库自带一个零依赖的 Node.js CLI,用于检验代码中使用的 var(--o-*) 变量是否真实存在于 @opensig/opendesign-token 包中,并将设计稿中的 hex/rgb 色值、px/ms 尺寸等反向匹配为对应 token。 大模型生成 OpenDesign 相关代码后,强烈建议用此工具扫描一遍,剔除捏造的变量名(如把 --o-color-fill2 误写成 --o-color-bg2、把 --o-r-font_size-h4 误写成 --o-r-font_size-h5)。

为什么要校验

OpenDesign 的 token 命名遵循自身规范,与 Bootstrap / Element Plus / Tailwind 等其他设计系统 不一致:

常见错误(捏造)实际不存在的原因正确替换
--o-color-bg1 / --o-color-bg2 / --o-color-bg3opendesign 用 fill 不用 bg--o-color-fill1 / fill2 / fill3
--o-color-border1边框用 control 不用 border--o-color-control1
--o-r-font_size-h5 / --o-r-font_size-h6响应式标题只有 h1–h4--o-r-font_size-h4
--o-color-text1 / --o-color-text2文字用 info 不用 text--o-color-info1 / info2
--o-radius-medium / --o-radius-large圆角用尺寸缩写(xs/s/m/l/xl)--o-radius-m / --o-radius-l
--o-color-primary5主色只有 1–4 档--o-color-primary4
--o-r-gap-11 / --o-r-gap-12响应式间距只有 1–10 档--o-r-gap-10

这些错误变量名在 CSS 中会解析为 transparent / 0 / initial,导致样式静默失效,很难排查。

CLI 位置
skills/opendesign-tokens/scripts/
├── bin.mjs               ← 统一入口(所有命令)
├── check-tokens.mjs      ← 向后兼容入口(等价于 bin.mjs)
├── lib/
│   ├── package-resolver.mjs  ← npm 包解析 + 下载 + 缓存
│   ├── registry.mjs          ← CSS 解析 + token 注册表
│   ├── lookup.mjs            ← token 查找 + 归一化 + 建议
│   ├── convert.mjs           ← 值→token 反向映射(动态构建)
│   ├── file-scan.mjs         ← 文件扫描
│   └── shared.mjs            ← 注册表单例 + 输出格式化
└── package.json

零外部依赖(仅用 Node.js ≥ 18 内置模块),首次运行时从 npm registry 下载 @opensig/opendesign-token tarball 并缓存到 ~/.cache/opendesign-token-cache/(Windows: %LOCALAPPDATA%/opendesign-token-cache/),后续运行直接用缓存。 两个入口文件等价——check-tokens.mjs 向后兼容旧调用方式,bin.mjs 是统一入口(含 convert 等新命令)。

真值源:CSS 产物,非 JSON 源码

CLI 以 themes/*.css 产物为唯一真值源——变量存在性、值、响应式各断点值全部从 CSS 解析(@media 块追踪 + JSDoc 注释 @group/@description/@type 提取)。tokens/*.json 仅作为可选富化(补充 CSS 注释里缺失的 @name、断点标签映射等), JSON schema 变更或缺失不影响核心功能。这样设计的理由:CSS 变量名是面向使用者的稳定契约,而 JSON 是包内部的中间产物,不同版本 schema 可能不同(如 v0.0.3 无 responsive-token.json,v0.0.4 前文件名大小写不一致)。

包解析:本地优先,下载兜底

CLI 按以下优先级确定用哪个版本的包做校验:

  1. --version <ver> 显式指定(如 --version 0.0.3)→ 下载或用缓存中该版本
  2. 就近查找本地 node_modules → 从被扫描文件的目录开始 逐层向上查找 node_modules/@opensig/opendesign-token/ ,找到则直接用该本地包(无需联网、无需缓存)
  3. 本地没找到 + --offline → 用缓存中最高版本
  4. 以上都没找到 → 从 npm registry 下载 latest(首次下载后缓存)

就近查找是核心策略——不依赖 process.cwd(),而是从被扫描文件的位置开始查找。这天然支持 monorepo:

  • pnpm workspace:包通常 symlink 在子包的 node_modules/,真实文件在 root 的 .pnpm/ 下
  • npm/yarn hoisting:包在 monorepo root 的 node_modules/,子包目录逐层向上可找到

scan src/App.vue 时,CLI 从 src/App.vue 所在目录开始向上查找,无论 CLI 是从项目根还是从 monorepo 外调起,都能正确定位项目依赖的包版本。

若项目装的是 v0.0.3(无响应式 token),--o-r-font_size-h1 会被判为不存在——这正是期望的行为。

命令速查
# ① 校验单个 token(接受三种输入形式)
node skills/opendesign-tokens/scripts/bin.mjs check --o-color-fill2
node skills/opendesign-tokens/scripts/bin.mjs check "var(--o-color-bg1)"
node skills/opendesign-tokens/scripts/bin.mjs check color-primary1

# ② 扫描文件/目录,找出所有捏造的 var(--o-*) 用法
node skills/opendesign-tokens/scripts/bin.mjs scan src/App.vue
node skills/opendesign-tokens/scripts/bin.mjs scan src/ --theme e --strict
node skills/opendesign-tokens/scripts/bin.mjs scan src/components/ --json

# ③ 列出所有 token(支持 glob 模式)
node skills/opendesign-tokens/scripts/bin.mjs list "--o-color-*"
node skills/opendesign-tokens/scripts/bin.mjs list "--o-r-*" --json

# ④ 查看单个 token 的完整信息(跨主题 light/dark 值)
node skills/opendesign-tokens/scripts/bin.mjs info --o-brand-6

# ⑤ 设计稿值 → token 反查(颜色 / 尺寸 / 时长 / 缓动 / 阴影)
node skills/opendesign-tokens/scripts/bin.mjs convert '#FFFFFF'
node skills/opendesign-tokens/scripts/bin.mjs convert 'rgb(0, 47, 167)'
node skills/opendesign-tokens/scripts/bin.mjs convert 16px
node skills/opendesign-tokens/scripts/bin.mjs convert 200ms
node skills/opendesign-tokens/scripts/bin.mjs convert 'cubic-bezier(0.2, 0, 0, 1)' --all
node skills/opendesign-tokens/scripts/bin.mjs convert '0 3px 8px rgba(var(--o-grey-14), 0.08)'

# ⑥ 列出包的所有版本
node skills/opendesign-tokens/scripts/bin.mjs versions

# ⑦ 清空本地缓存
node skills/opendesign-tokens/scripts/bin.mjs clear-cache

check-tokens.mjs 向后兼容旧调用方式(node check-tokens.mjs check ...),与 bin.mjs 等价。

常用选项
选项说明默认值
-V, --version <ver>指定包版本自动解析
-t, --theme <e|a|k|m|g|u>主题e
-m, --mode <light|dark>模式light
--json输出 JSON(便于 LLM 程序化消费)关
--offline仅用缓存,不联网关
--strictscan 时发现无效 token 则退出码 1关
--no-suggest不计算建议关
-v, --verbose详细输出关
--colorconvert 专用:强制按颜色解析关
--valueconvert 专用:强制按普通值解析关
--tolerance <n>convert 专用:颜色容差5
--allconvert 专用:显示全部匹配关
工作流建议
  1. 生成代码后立即扫描:写完一段含 var(--o-*) 的样式后,用 scan 命令检查所在文件。
    node skills/opendesign-tokens/scripts/bin.mjs scan path/to/your.vue --theme e
    
  2. CI / git hook:加 --strict 让扫描发现无效 token 时非零退出,阻断提交。
    node skills/opendesign-tokens/scripts/bin.mjs scan src/ --theme e --strict
    
  3. 不确定某个 token 名时:用 check 单查;CLI 会给出最接近的 3 个真实 token 作为建议。
    node skills/opendesign-tokens/scripts/bin.mjs check --o-color-bg2
    # ❌ --o-color-bg2 does not exist
    #    💡 closest: --o-color-fill2 (d=4), --o-color-info2 (d=4), ...
    
  4. 设计稿值 → token 反查:从 Pixso/Figma 取到色值或尺寸后,用 convert 反查对应 token。CLI 会从 @opensig/opendesign-token 的 CSS 产物动态构建反向表,匹配结果始终与实际包版本同步。
    # 色值反查
    node skills/opendesign-tokens/scripts/bin.mjs convert '#FFFFFF'
    # → var(--o-color-fill2) [fill] 二级填充:区块、卡片
    
    # 尺寸反查(响应式 token 优先)
    node skills/opendesign-tokens/scripts/bin.mjs convert 16px
    # → var(--o-r-font_size-text1) [font_size] 响应式常规正文
    
    # 缓动曲线反查
    node skills/opendesign-tokens/scripts/bin.mjs convert 'cubic-bezier(0.2, 0, 0, 1)'
    # → var(--o-easing-emphasized) [easing] 用于大卡片、场景切换
    
    # 显示全部匹配(一个值可能对应多个 token)
    node skills/opendesign-tokens/scripts/bin.mjs convert 16px --all
    
  5. JSON 模式:加 --json 可把结果结构化输出,便于其他工具或 LLM 解析。
  6. 离线环境:首次运行需联网下载包;之后 --offline 即可离线校验。
主题特异性注意

部分 token 不是所有主题都定义。例如 --o-brand-1 ~ --o-brand-10 仅在 e/m/g/u 四套主题中存在;Ascend (a) 和 Kunpeng (k) 只定义了 --o-brand-6。用 -t 指定主题时,CLI 会按该主题校验:

node skills/opendesign-tokens/scripts/check-tokens.mjs check --o-brand-1 -t e  # ✅ exists
node skills/opendesign-tokens/scripts/check-tokens.mjs check --o-brand-1 -t a  # ❌ not in theme a
CLI 不做的事
  • 不修改你的代码:只读文件、只输出报告;不会自动替换变量名。
  • 不校验 SCSS mixin:只校验 var(--o-*) 形式的 CSS 变量引用。@include h1; 这类 mixin 调用不在扫描范围内(mixin 的合法性由 opendesign-application skill 的 styles-infrastructure 约束)。

コメント