原则
设计新功能
动手做新东西之前要回答的问题,从最接近的模式到组件的流程,一份自查清单,以及什么时候该改设计系统本身。
每个新的屏幕、面板或流程,都从系统已有的东西出发:回答六个问题,找到最接近的模式,用 raft-ui 组件拼出来,再分清哪部分只属于一个产品、哪部分属于所有产品。做完后对照本页末尾的清单检查。只有当工作表明某条规则缺失或有错时,才去改系统本身,并且在同一个 pull request 里修改规范。
要回答的问题
在画任何东西、写任何东西之前,先回答这些问题。每个答案都决定一件具体的事。
- 是每个产品都需要,还是只有一个产品需要? 每个产品都需要的东西遵循模式;如果是新的,就把它变成一个模式。只有一个产品需要的东西,写在产品下该产品的页面里。无论哪种,先看产品现在是怎么做的:已上线的产品是结构上的参照。
- 它是内容、区域还是控件? 这决定它的表面和线:内容放在纸面上,用细线分隔;区域和相邻区域之间隔一条接缝线;控件有墨色边框(原则)。
- 屏幕的主操作是哪一个? 只有它是粉色,一个屏幕也可以没有主操作。如果不止一个操作都可能是主操作,说明层次错了:先想清楚这个屏幕是为哪个操作而存在的(Button)。
- 每种颜色是什么意思? 每种颜色都是一个身份、一个状态、一个信号(你、待办、这一项)或一个后果(打断、不可撤销)。如果某种颜色都不是,就去掉它(颜色)。
- 它在深色模式下、320px 宽度下、只用键盘时都能用吗? 按 390px 设计,并让所有东西在 320px 下都放得下(响应式布局)。人能用键盘到达的每个元素都显示焦点环(层级)。每个新组件都在两种模式下检查(深色模式)。
- 一个人盯着它看几个小时会不会累? 会的话,先去掉颜色,再去掉线,再去掉动效。显示状态的东西不能循环播放,也不能闪烁(动效)。
流程
1. 找到最接近的模式
大多数新工作都是系统里已有内容的变体。设计之前先把它找出来:
| 你要做的是 | 从这里开始 |
|---|---|
| 新的屏幕、面板或目的地 | 页面结构、导航和响应式布局 |
| agent 做的或展示的任何东西 | Agent 和 人和 agent |
| 消息、消息列、输入框 | 对话 |
| 任务及其状态 | 任务 |
| 表单或设置页 | 表单 |
| 结果、错误、加载状态或空状态 | 反馈 |
| 由几个现有部件组合成的东西 | 组合组件 |
然后阅读你所在区域对应的产品页面(Raft Chat 就看 Raft Chat),看看它在那里已经放了什么。
2. 选择组件
用 raft-ui 拼出这个功能。组件概览列出了现有的组件;当好几个看起来都合适时,选择组件帮你挑一个:哪种选择用哪个控件,哪种消息用哪种反馈,哪种用途用哪种浮层。
- 只要有合适的 raft-ui 组件就用它,徽标、标签片、分隔线、字段这类小部件也一样。手工复制的版本,在任何一方第一次改动时就会和原版走样。
- 用组件之前先读它的文档:「When to use」表格、规则和无障碍部分。
- 如果没有合适的,先在组合组件里找现有部件的组合。只有 raft-ui 里确实没有合适的才手写标记,并在 pull request 里说明,同时向 raft-ui 提议补上缺的部件,而不是保留一份本地副本。
- 每个值都用语义 token。不要用 Tailwind 的默认色板或原始颜色值。
raft-ui 的安装和配置见使用 raft-ui。
3. 分清共享的和产品特有的
把每条新规则写在它该在的地方,让下一个产品继承它该继承的,不多也不少:
| 如果规则是关于 | 写在 |
|---|---|
| 每个组件都遵循的值或规则 | 基础 |
| 某一个组件 | 该组件的文档 |
| 组件在任何产品中如何组合 | 模式 |
| 某个产品的目的地、屏幕以及什么放在哪里 | 该产品的页面 |
只对 Raft Chat 成立的规则(「手机标签栏显示哪四个目的地」)是产品规则。在 Tasks 或 Calendar 里也一样的规则(「某个面板出了问题,在它的标题栏下方显示一条提示」)是共享规则。拿不准时,问问第二个产品是否会出于同样的理由做同样的选择;如果会,这条规则就是共享的。
4. 写文案
标签、标题、空状态和错误信息遵循写作:人点击的东西用 Title Case,其余用 sentence case;agent 用描述队友的动词;按钮的标签和它打开的对话框标题保持一致。
自查清单
请人评审之前先过一遍这份清单。每一项都是评审者会检查的。
- 黄色只出现在外框上,以及表示「你」的东西上:导航中的选中项、打开的开关、提及你的地方、搜索命中。
- 屏幕上最多一个粉色按钮,用于这个屏幕存在的那个操作。
- 屏幕上的每种颜色都是一个身份、一个状态、一个信号或一个后果。红色只用于无法撤销的事。
- 每条线要么是内容里的细线,要么是区域之间的接缝线,要么是控件上的墨色边框;两个区域之间恰好共用一条线。
- 每块品牌色都有墨色边和墨色文字;柔和色调没有边;控件和卡片都没有阴影。
- 身份标识和圆点是方的;只有开关和单选按钮是圆的。
- 没有全大写的文字。可点击的文字用 Title Case;ID、时间、计数和事件行用 Space Mono。
- 显示状态的东西不循环、不闪烁,每个动画在
prefers-reduced-motion下都会停止。 - agent 和人使用同样的行、消息和头像,agent 正在做的事显示在它本来就出现的地方。
- 屏幕在深色模式下可用,贴纸不变并带有模切边。
- 所有东西在 320px 宽度下都放得下,触控目标至少 44px。
- 只用键盘就能完成所有操作,并且都显示焦点环。可点击的东西都是
<button>或带href的<a>,每个纯图标按钮都有aria-label。 - raft-ui 里有的部件都来自 raft-ui;手写的部件都在 pull request 里列出。
- 每个值都是语义 token。
- 每条新规则都写在它该在的基础、模式、组件文档或产品页面里。
修改设计系统
当新工作表明某条规则缺失或有错时,系统就该改。公开地改,并和工作放在同一个 pull request 里:
- 在同一个 pull request 里更新规范。 改变某样东西的外观或行为,就同时在代码和文档里更新它遵循的规则。如果系统对你要做的东西还没有规则,就在该在的地方写一条(见第 3 步)。raft-ui 和规范不一致时,改掉其中一个,不要让两者一直对不上。
- 只为重大的、跨领域的选择添加决策记录:改变一条原则、一种材质或一种颜色的含义,适用于多个产品,或推翻之前的记录。被推翻的记录标为
superseded。较小的改动只更新规范,不需要记录。模板见编写指南。 - 暂时做不了的选择,记在待定问题里,并写明做出决定之前使用的默认做法。
文档如何组织和编写见编写指南;pull request 需要满足什么见 CONTRIBUTING.md。
相关内容
- 原则:这些问题和清单所依据的规则。
- 为什么 Raft 长这样:这些规则背后的理由。
- 选择组件:每种情况对应一个组件。
- 决策:已经做出的重大选择,以及当时权衡过的其他方案。