Design System构建指南

引言

Design System(设计系统)是产品设计与开发的"宪法"——它定义了视觉语言、交互规范、组件行为的统一标准,让团队在规模化协作中保持一致性。对于 AI 产品而言,设计系统还需要覆盖对话气泡、生成状态、置信度指示等独特模式。本文从架构到实施,系统阐述如何构建和维护一套可持续的设计系统。

一、设计系统架构

1.1 原子设计方法论

Brad Frost 的原子设计(Atomic Design)五层结构:

Layer 1: 原子(Atoms)
  颜色、字体、图标、间距、圆角、阴影
  → 最小不可再分的视觉单元

Layer 2: 分子(Molecules)
  按钮、输入框、标签、徽章、开关
  → 原子的有意义组合

Layer 3: 组织(Organisms)
  导航栏、侧边栏、卡片组、表单组、数据表格
  → 分子组成的功能区域

Layer 4: 模板(Templates)
  页面布局框架(无真实内容)
  → 定义内容区域的结构

Layer 5: 页面(Pages)
  填入真实内容的最终实例
  → 模板 + 真实数据

1.2 设计系统组成

┌──────────────────────────────────────────────┐
│              设计系统全景                       │
├──────────────────────────────────────────────┤
│                                              │
│  ┌────────────┐  ┌────────────┐             │
│  │ 设计令牌    │  │ 设计原则    │             │
│  │ (Tokens)   │  │ (Principles)│             │
│  └────────────┘  └────────────┘             │
│                                              │
│  ┌────────────┐  ┌────────────┐             │
│  │ 组件库      │  │ 模式库      │             │
│  │ (Components)│  │ (Patterns) │             │
│  └────────────┘  └────────────┘             │
│                                              │
│  ┌────────────┐  ┌────────────┐             │
│  │ 文档站      │  │ 工具链      │             │
│  │ (Docs)     │  │ (Tooling)  │             │
│  └────────────┘  └────────────┘             │
│                                              │
│  ┌────────────┐                              │
│  │ 治理流程    │                              │
│  │ (Governance)│                              │
│  └────────────┘                              │
└──────────────────────────────────────────────┘

二、设计令牌(Design Tokens)

2.1 令牌分层

Global Tokens(全局令牌):
  与语义无关的原始值
  --color-blue-500: #3B82F6;
  --font-size-16: 16px;
  --spacing-4: 16px;
  --radius-2: 8px;

Alias Tokens(语义令牌):
  赋予全局令牌以语义
  --color-primary: var(--color-blue-500);
  --color-text-body: var(--color-gray-700);
  --font-size-body: var(--font-size-16);
  --spacing-section: var(--spacing-4);

Component Tokens(组件令牌):
  组件级别的具体值
  --button-bg: var(--color-primary);
  --button-text: var(--color-white);
  --button-radius: var(--radius-2);
  --button-padding-x: var(--spacing-4);

2.2 令牌定义格式

{
  "color": {
    "primitive": {
      "blue": {
        "50":  { "value": "#EFF6FF" },
        "100": { "value": "#DBEAFE" },
        "200": { "value": "#BFDBFE" },
        "300": { "value": "#93C5FD" },
        "400": { "value": "#60A5FA" },
        "500": { "value": "#3B82F6" },
        "600": { "value": "#2563EB" },
        "700": { "value": "#1D4ED8" },
        "800": { "value": "#1E40AF" },
        "900": { "value": "#1E3A8A" }
      },
      "gray": {
        "50":  { "value": "#F9FAFB" },
        "100": { "value": "#F3F4F6" },
        "200": { "value": "#E5E7EB" },
        "300": { "value": "#D1D5DB" },
        "400": { "value": "#9CA3AF" },
        "500": { "value": "#6B7280" },
        "600": { "value": "#4B5563" },
        "700": { "value": "#374151" },
        "800": { "value": "#1F2937" },
        "900": { "value": "#111827" }
      }
    },
    "semantic": {
      "primary":   { "value": "{color.primitive.blue.600}" },
      "secondary": { "value": "{color.primitive.gray.500}" },
      "success":   { "value": "#059669" },
      "warning":   { "value": "#D97706" },
      "error":     { "value": "#DC2626" },
      "bg": {
        "primary":   { "value": "{color.primitive.gray.50}" },
        "secondary": { "value": "#FFFFFF" },
        "tertiary":  { "value": "{color.primitive.gray.100}" }
      },
      "text": {
        "primary":   { "value": "{color.primitive.gray.900}" },
        "secondary": { "value": "{color.primitive.gray.700}" },
        "tertiary":  { "value": "{color.primitive.gray.500}" },
        "inverse":   { "value": "#FFFFFF" }
      }
    }
  },
  "typography": {
    "fontFamily": {
      "sans":  { "value": "Inter, system-ui, sans-serif" },
      "mono":  { "value": "JetBrains Mono, monospace" }
    },
    "fontSize": {
      "xs":  { "value": "12px" },
      "sm":  { "value": "14px" },
      "base": { "value": "16px" },
      "lg":  { "value": "18px" },
      "xl":  { "value": "20px" },
      "2xl": { "value": "24px" },
      "3xl": { "value": "30px" },
      "4xl": { "value": "36px" }
    },
    "fontWeight": {
      "regular": { "value": "400" },
      "medium":  { "value": "500" },
      "semibold": { "value": "600" },
      "bold":    { "value": "700" }
    },
    "lineHeight": {
      "tight":  { "value": "1.25" },
      "normal": { "value": "1.5" },
      "relaxed": { "value": "1.75" }
    }
  },
  "spacing": {
    "0":  { "value": "0px" },
    "1":  { "value": "4px" },
    "2":  { "value": "8px" },
    "3":  { "value": "12px" },
    "4":  { "value": "16px" },
    "5":  { "value": "20px" },
    "6":  { "value": "24px" },
    "8":  { "value": "32px" },
    "10": { "value": "40px" },
    "12": { "value": "48px" },
    "16": { "value": "64px" }
  },
  "borderRadius": {
    "none": { "value": "0px" },
    "sm":   { "value": "4px" },
    "md":   { "value": "8px" },
    "lg":   { "value": "12px" },
    "xl":   { "value": "16px" },
    "full": { "value": "9999px" }
  },
  "shadow": {
    "sm":  { "value": "0 1px 2px rgba(0,0,0,0.05)" },
    "md":  { "value": "0 4px 6px rgba(0,0,0,0.07)" },
    "lg":  { "value": "0 10px 15px rgba(0,0,0,0.1)" },
    "xl":  { "value": "0 20px 25px rgba(0,0,0,0.1)" }
  }
}

2.3 令牌转换工具链

Style Dictionary 工作流:

tokens.json(单一事实源)
     │
     ▼
Style Dictionary(转换引擎)
     │
     ├─→ CSS Variables(Web)
     │     :root { --color-primary: #2563EB; }
     │
     ├─→ Tailwind Config(Tailwind CSS)
     │     theme: { colors: { primary: '#2563EB' } }
     │
     ├─→ SCSS Variables(Sass)
     │     $color-primary: #2563EB;
     │
     ├─→ Swift(iOS)
     │     extension Color { static let primary = Color(hex: "#2563EB") }
     │
     ├─→ XML(Android)
     │     <color name="primary">#2563EB</color>
     │
     └─→ JSON(设计工具 / PPT 模板)
           { "primary": "#2563EB" }

三、组件库设计

3.1 组件层级

基础组件(Foundation):
  Button, Input, Select, Checkbox, Radio, Switch,
  Badge, Tag, Avatar, Icon, Tooltip, Skeleton

布局组件(Layout):
  Container, Grid, Stack, Flex, Spacer, Divider,
  Card, Panel, Sidebar, Header, Footer

导航组件(Navigation):
  Navbar, Tabs, Breadcrumb, Pagination, Menu,
  Dropdown, CommandPalette

反馈组件(Feedback):
  Alert, Toast, Modal, Dialog, Drawer, Sheet,
  Progress, Spinner, EmptyState

数据展示(Data Display):
  Table, DataGrid, List, Tree, Timeline,
  Accordion, Carousel, Stat

AI 专用组件(AI-Specific):
  ChatBubble, TypingIndicator, ConfidenceBadge,
  SourceCitation, CodeBlock, MarkdownRenderer,
  StreamingText, ModelSelector, PromptInput

3.2 组件 API 设计原则

原则 1: 一致的 Props 命名
  size: "sm" | "md" | "lg"    (不用 small/medium/large)
  variant: "primary" | "secondary" | "ghost" | "destructive"
  disabled: boolean
  loading: boolean
  className: string            (允许覆盖样式)

原则 2: 组合优于继承
  正确:<Button variant="ghost" size="sm" />
  错误:<SmallGhostButton />

原则 3: 受控 + 非受控
  value + onChange    (受控)
  defaultValue        (非受控)

原则 4: 可访问性内置
  所有交互组件自带 ARIA 属性
  键盘导航内置(Tab / Enter / Escape)
  焦点管理自动处理

原则 5: 无样式内核(Headless)可选
  逻辑层(hooks)与视觉层(样式)分离
  允许完全自定义外观

3.3 组件文档模板

## Button

按钮用于触发操作或导航。

### 变体
| Variant | 用途 | 视觉权重 |
|---------|------|---------|
| primary | 主操作(每页 1 个) | 最高 |
| secondary | 次要操作 | 中 |
| ghost | 辅助操作 | 低 |
| destructive | 危险操作(删除等) | 高(红色) |

### 尺寸
| Size | Height | Font Size | Padding |
|------|--------|-----------|---------|
| sm | 32px | 14px | 12px 16px |
| md | 40px | 16px | 12px 20px |
| lg | 48px | 18px | 16px 24px |

### 状态
- Default → Hover → Active → Focus → Disabled → Loading

### 可访问性
- 角色:`role="button"`
- 键盘:`Enter` / `Space` 触发
- 禁用态:`aria-disabled="true"`
- 加载态:`aria-busy="true"` + 文字变为 "Loading..."

### 使用规范
- 每个页面/对话框最多 1 个 Primary Button
- Destructive Button 需要二次确认
- Loading 状态下禁用点击
- 按钮文案使用动词("保存"而非"确定")

四、模式库(Pattern Library)

4.1 交互模式

表单模式:
  1. 即时验证(blur 时校验)
  2. 错误提示在输入框下方(红色)
  3. 成功态用绿色勾号
  4. 必填字段用 * 标记
  5. 提交按钮在表单底部右侧

列表/表格模式:
  1. 空状态有插图 + 引导操作
  2. 加载中显示骨架屏(非转圈)
  3. 错误状态有重试按钮
  4. 分页 vs 无限滚动由数据量决定
  5. 排序/筛选在表头操作

导航模式:
  1. 桌面:侧边栏 + 顶部面包屑
  2. 移动:底部 Tab(3-5 项)
  3. 深层页面:返回箭头 + 页面标题
  4. 当前位置始终可见(高亮/加粗)

反馈模式:
  1. 操作成功:Toast(3 秒自消失)
  2. 操作失败:Alert(需手动关闭)+ 可操作建议
  3. 确认操作:Dialog(需明确确认/取消)
  4. 进度反馈:Progress Bar / Skeleton
  5. 后台任务:通知中心 + 状态标记

4.2 AI 交互模式

AI 对话模式:
  1. 流式输出(逐字显示,非等待后一次性显示)
  2. 思考状态用脉动点动画
  3. 长回复支持折叠/展开
  4. 代码块支持一键复制
  5. 引用来源可点击跳转

AI 生成确认模式:
  1. 预览 → 确认 → 应用
  2. 允许编辑 AI 生成的内容
  3. 支持"重新生成"
  4. 显示生成耗时和模型信息

AI 错误处理模式:
  1. 内容过长:提示"回复被截断" + 继续按钮
  2. 生成失败:显示错误原因 + 重试按钮
  3. 内容审核:显示"此内容无法生成" + 修改建议
  4. 额度不足:显示剩余额度 + 升级入口

五、文档站建设

5.1 文档站工具选型

工具 框架 组件展示 适合团队
Storybook 框架无关 强(交互式) 前端开发
Docusaurus React 中(MDX) 文档优先
VitePress Vue 中(Vue 组件) Vue 团队
Nextra Next.js 中(MDX) Next.js 团队
Chromatic Storybook 强(视觉测试) 需视觉回归

5.2 文档结构

设计系统文档站结构:

首页
├── 快速开始(Getting Started)
│   ├── 安装
│   ├── 主题配置
│   └── 第一个组件
├── 设计原则(Principles)
│   ├── 品牌指南
│   ├── 可访问性
│   └── 国际化
├── 设计令牌(Tokens)
│   ├── 颜色
│   ├── 字体
│   ├── 间距
│   └── 阴影
├── 组件(Components)
│   ├── 基础组件
│   ├── 布局组件
│   ├── 导航组件
│   ├── 反馈组件
│   ├── 数据展示
│   └── AI 专用组件
├── 模式(Patterns)
│   ├── 表单
│   ├── 列表
│   ├── 导航
│   └── AI 交互
├── 资源(Resources)
│   ├── Figma 库
│   ├── 图标库
│   └── 模板
└── 变更日志(Changelog)

六、治理与演进

6.1 贡献流程

新增/修改组件的标准流程:

1. 提案(RFC)
   - 描述需求场景
   - 列出现有组件无法满足的原因
   - 提出初步方案

2. 设计审查
   - 设计团队评审视觉方案
   - 确保与现有系统一致
   - 输出 Figma 组件稿

3. 开发实现
   - 按组件 API 规范开发
   - 编写单元测试 + 视觉测试
   - 编写组件文档

4. 代码审查
   - API 设计审查
   - 可访问性审查
   - 性能审查

5. 发布
   - Semver 版本号
   - 更新 Changelog
   - 通知使用者

6.2 版本管理

语义化版本(Semver):

Major(主版本):Breaking Changes
  - 删除组件或 Props
  - 修改默认行为
  - 更换设计令牌命名

Minor(次版本):New Features
  - 新增组件
  - 新增 Props(向后兼容)
  - 新增变体/尺寸

Patch(补丁版本):Bug Fixes
  - 修复样式问题
  - 修复可访问性问题
  - 修复文档错误

发布节奏建议:
  Patch:每周
  Minor:每两周
  Major:每季度(至多)

6.3 采用度衡量

设计系统健康指标:

覆盖率:
  - 组件覆盖率 = 使用系统组件的页面 / 总页面数
  - 令牌覆盖率 = 使用令牌的样式值 / 总样式值
  - 目标:>= 80%

一致性:
  - 视觉偏差数 = 不符合规范的实例数
  - 主题切换成功率 = 明暗模式正常切换的组件比例
  - 目标:偏差 < 5%

效率:
  - 新页面开发耗时(使用系统 vs 不使用)
  - 设计到开发交接时间
  - 目标:效率提升 30%+

满意度:
  - 开发者满意度(季度调研)
  - 设计师满意度(季度调研)
  - 目标:>= 4.0/5.0

总结

构建设计系统不是一次性工程,而是一个持续演进的过程。核心三层:令牌层(视觉决策的单一事实源)、组件层(可复用的 UI 构建块)、模式层(可复用的交互方案)。工具链选型推荐 Tokens Studio(令牌管理)+ Style Dictionary(令牌转换)+ shadcn/ui 或 Radix(组件基础)+ Storybook(文档站)。AI 产品需要在标准设计系统之上扩展 AI 专用组件(ChatBubble/StreamingText/ConfidenceBadge)和 AI 交互模式(流式输出/重新生成/来源引用)。设计系统的成功标志不是文档有多全,而是团队成员是否在日常工作中"自然地使用它"。


Maurice | maurice_wen@proton.me