跳到主要内容
menumenu tanreiexpand_morecontrasttranslate
tanreiexpand_more
开始使用WebReactSwiftUIJetpack ComposeFlutterReact Native预设你自己的设计系统与 AI 代理一起使用 Tanrei品牌设计令牌设计系统与定制Theme Studio颜色字体排印图标形状层级动效交互状态行为布局无障碍文字颜色令牌字阶令牌形状令牌层级令牌动效令牌状态令牌间距与度量令牌组件按钮主操作按钮分段按钮按钮组带菜单的按钮工具栏复制按钮复选框单选按钮开关纸片(Chip)菜单滑块滑块字段日历DateTimePicker字段组单选组复选框组下拉选择框下拉选择字段菜单栏文件上传文件选择器 进阶放置区文本输入框 进阶文本字段纸片字段字段组合框 进阶组合框字段数字输入框 进阶数字字段颜色输入框 进阶颜色字段一次性验证码输入框 进阶一次性验证码字段嵌入式文本输入框 进阶聊天输入栏卡片分隔线模态层 进阶对话框列表列表行底部面板侧边面板轮播代码块表格弹出框步骤折叠面板描述列表图示应用外壳页头树视图时间线图片预览调整手柄可调整大小的框滚动区域徽标进度指示器计量条数字滚动器加载指示器消息条(Snackbar)工具提示键盘快捷键标签(Tag)行内代码提示块(Callout)头像空状态标签组(Tag group)骨架屏文件项色块跑马灯文本标签页标签页视图应用栏导航栏导航抽屉搜索链接分页上一页/下一页链接步骤条面包屑目录链接卡片FAB 菜单状态Tanrei 是如何构建的参与贡献许可与致谢
首页项目Tanrei 是如何构建的

Tanrei 是如何构建的

两个唯一可信来源、规格先行的工作流,以及让五个平台、文档和状态矩阵保持一致的漂移检查。

content_copy以 Markdown 格式查看

Tanrei 从一个仓库把一套设计系统交付到五个平台。要让这种方式行得通,仓库本身必须让人很难出错:在一处所做的修改,要么传播到所有地方,要么明明白白地失败。本页介绍做到这一点的那套机制。

两个唯一可信来源

只有两个目录包含决策:

目录 内容 格式
tokens/ 每一个设计值 Design Tokens Community Group 格式,2025.10
specs/ 每一个组件的契约 JSON,由 specs/component.schema.json 校验

其余一切都是推导出来的:为各平台生成的令牌文件、各平台的实现、这份文档中的表格和状态矩阵。当推导出的东西与唯一可信来源不一致时,按定义,错的是推导出的东西。

规格包含什么

组件规格与平台无关。它记录组件的构成、属性、插槽、事件和状态;以带编号的需求写成的行为;无障碍契约,包括角色、键盘操作表和标注方式;它所绑定的令牌分组;一组测试样例(fixtures),即每个平台都以相同 ID 截取快照的基准渲染;以及一个 platforms 块,把中立的名称映射到各平台的惯用写法。

行为以 EARS 形式书写,这是一种受约束的句式,便于据此编写测试:

WHEN the user activates the button by pointer, touch, Enter or Space
THE button SHALL emit click exactly once.

每条需求都有一个类似 BTN-1 的 ID,各平台上的测试都引用这些 ID。

工作流

  1. 提议。 编写或修改规格,必要时也修改令牌。新组件和破坏性变更由维护者在修改规格之前决定。
  2. 校验。 pnpm validate 检查 schema、对令牌做 lint,并针对每个主题和对比度级别验证对比度不变式。
  3. 生成。 pnpm generate 重新构建令牌输出、脚手架和状态矩阵。
  4. 实现。 在规格列出的每个平台上实现,并附带单元测试、快照测试和无障碍测试。
  5. 检查。 pnpm check 按顺序运行全部检查,包括漂移检查,并且必须全部通过。
  6. 记录。 添加 changeset。所有包的版本同步推进,因为对等本身就是产品。

任何平台的公开接口,都不得在规格没有在同一次提交中做出相同修改的情况下发生变化。

漂移就是构建失败

  • 重新生成的差异。 CI 会重新生成所有派生文件,只要结果与已提交的内容不同就失败。手工改动生成的文件是留不住的。
  • 对等检查。 对规格声明的每个平台,检查器都要求有实现、有测试、每个测试样例都有快照,并且有该组件的英文和日文文档页面。站点的其他各语言必须有哪些页面,由文档站点另行检查。状态矩阵由同样的事实计算得出,因此它所声称的不可能多于实际存在的。
  • 对比度不变式。 对比度不达标的配色方案根本不会被输出。
  • 快照纪律。 快照出现差异就是一项发现。只有当视觉变化正是规格或令牌变更的预期结果时,基准图才会更新。

对等的定义

对等意味着相同的令牌、等效的视觉结果、相同的状态和相同的无障碍语义,并不意味着完全相同的 API。Compose 接受 enabled,Flutter 用值为 null 的 onPressed 来禁用按钮,SwiftUI 使用 .disabled(_:)。每一处对应关系都写在规格的 platforms 块中,并显示在每个组件页面上。

对代理而言安全的工作流

同样的规则同时约束人和 AI 代理,并且其中尽可能多的规则由工具强制执行,而不是依靠信任。

  • 分层的规则。 根目录一份简短的 AGENTS.md 写明项目的根本规则;嵌套的文件为令牌、规格和各个包补充本地规则。嵌套的规则可以在根规则之上追加,但绝不能削弱它们。
  • 分道。 平台相关的工作被限制在该平台的包内。实现 SwiftUI 的代理没有理由去碰 Compose。
  • 钩子。 对生成目录的编辑、--no-verify 以及更新快照基准图的操作,都在工具层面被拦截;会话结束时还会运行漂移检查。
  • 技能。 添加组件或令牌这类反复出现的流程,被写成按步骤执行的技能,因此每次的做法都一样。
  • 不做发布。 向注册表发布由维护者决定。任何自动化的执行者都不得进行发布。

注意

这份文档也遵循同样的规则。状态、令牌参考和组件规格表格都在构建时由仓库数据渲染而来。只有正文是手写的。