为什么需要设计系统
当你的产品从 1 个页面增长到 100 个页面时,你会发现:按钮有 15 种不同的蓝色,间距有 7 种不同的值,字体大小完全没有规律。设计师和开发者之间反复沟通"这个颜色到底是什么",产品的一致性渐渐崩塌。设计系统就是解决这个问题的——它不是一套 UI 组件库,而是一套设计语言 + 编码规范 + 可复用组件的完整体系。
Design Token 架构
Design Token 是设计系统的原子单位。它将颜色、字体、间距、阴影等设计决策以平台无关的格式存储,然后自动转换为各平台可用的代码。一个典型的 Token 层级结构:
// tokens/color.json (源文件,平台无关)
{
"color": {
"blue": {
"50": { "value": "#EEF2FF" },
"500": { "value": "#4F46E5" },
"700": { "value": "#4338CA" }
}
},
"semantic": {
"primary": { "value": "{color.blue.500}" },
"primaryHover": { "value": "{color.blue.700}" },
"background": { "value": "{color.blue.50}" }
}
}
Token 分为三个层级:
- 原始 Token(Primitive):裸值,如
#4F46E5、16px - 语义 Token(Semantic):有意义的命名,如
color.primary、spacing.md - 组件 Token(Component):组件级别的 Token,如
button.primary.background
使用 Style Dictionary 同步 Token
Style Dictionary 是 Amazon 开源的工具,可以将 Design Token 转换为 CSS 变量、SCSS 变量、JavaScript 常量等多种格式:
// config.js
module.exports = {
source: ['tokens/**/*.json'],
platforms: {
css: {
transformGroup: 'css',
buildPath: 'dist/css/',
files: [{
destination: 'variables.css',
format: 'css/variables',
}],
},
js: {
transformGroup: 'js',
buildPath: 'dist/js/',
files: [{
destination: 'tokens.js',
format: 'javascript/es6',
}],
},
},
};
/* 生成的 CSS 变量 */
:root {
--color-blue-50: #EEF2FF;
--color-primary: #4F46E5;
--color-primary-hover: #4338CA;
}
这样,当设计师修改了一个 Token 值,只需要更新 JSON 文件,重新构建,所有平台的颜色自动同步。这是设计系统的"单一事实来源"。
Figma 组件与 Variant 设计
在 Figma 中构建组件时,使用 Variant 来管理组件的不同状态:
- 属性分类:Size(sm/md/lg)、Variant(primary/secondary/ghost)、State(default/hover/disabled/loading)
- 命名规范:使用
Property=Value格式,如Button / Size=md, Variant=primary, State=hover - Auto Layout:所有组件使用 Auto Layout,确保响应式行为和间距一致性
- 组件属性:使用 Figma 的 Component Properties 管理图标切换、文本内容、布尔显隐
关键原则:Figma 组件的结构和命名应该与代码组件的 props 保持一致。这样设计师和开发者能使用相同的语言沟通。
组件库开发
组件库是设计系统在代码层面的实现。以 React 为例:
// Button.tsx
import { type VariantProps, cva } from 'class-variance-authority';
const buttonVariants = cva(
'inline-flex items-center justify-center rounded-lg font-medium transition-colors',
{
variants: {
variant: {
primary: 'bg-[var(--color-primary)] text-white hover:bg-[var(--color-primary-hover)]',
secondary: 'bg-gray-100 text-gray-900 hover:bg-gray-200',
ghost: 'text-gray-600 hover:bg-gray-100',
},
size: {
sm: 'h-8 px-3 text-sm',
md: 'h-10 px-4 text-sm',
lg: 'h-12 px-6 text-base',
},
},
defaultVariants: {
variant: 'primary',
size: 'md',
},
}
);
interface ButtonProps extends VariantProps<typeof buttonVariants> {
children: React.ReactNode;
disabled?: boolean;
}
export function Button({ variant, size, children, disabled }: ButtonProps) {
return (
<button className={buttonVariants({ variant, size })} disabled={disabled}>
{children}
</button>
);
}
使用 CVA(class-variance-authority)可以让组件变体的管理与 Figma Variant 的概念完美对应。
Storybook 文档化
组件库必须有文档,否则只有你自己会用。Storybook 是行业标准:
// Button.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './Button';
const meta: Meta<typeof Button> = {
title: 'Components/Button',
component: Button,
argTypes: {
variant: { control: 'select', options: ['primary', 'secondary', 'ghost'] },
size: { control: 'select', options: ['sm', 'md', 'lg'] },
},
};
export default meta;
type Story = StoryObj<typeof Button>;
export const Primary: Story = { args: { variant: 'primary', children: '按钮' } };
export const Secondary: Story = { args: { variant: 'secondary', children: '取消' } };
export const Ghost: Story = { args: { variant: 'ghost', children: '了解更多' } };
Storybook 的价值:
- 开发者可以独立开发和测试组件,无需启动整个应用
- 设计师可以在 Storybook 中查看和验证组件实现
- 自动化的视觉回归测试可以捕获意外的样式变更
治理与版本管理
设计系统不是一次性工程,需要持续的维护和迭代:
- 语义化版本:组件库使用 SemVer。新增组件是小版本,破坏性变更是大版本
- 变更日志:每个版本发布时记录 CHANGELOG,说明新增、修改和废弃的内容
- 废弃策略:废弃的组件先标记 @deprecated,提供迁移指南,至少保留一个主要版本再移除
- 贡献流程:任何人都可以提议新增组件,但需要设计和技术双重审核
总结
构建设计系统建议分三步走:第一步,建立 Design Token 体系,让颜色和间距有统一来源;第二步,搭建组件库,从 Button、Input、Typography 等最基础的组件开始;第三步,用 Storybook 建立文档,让团队能够自助使用。记住:设计系统不是要"控制"设计师和开发者,而是要"赋能"他们——减少重复决策,让团队把精力放在产品创新上。