返回博客列表
设计开发
设计系统构建指南
2025-09-05
15 分钟阅读
设计系统UI/UX组件库

设计系统构建指南
设计系统是现代产品开发中不可或缺的一部分。它不仅能提高开发效率,还能确保产品的一致性和可维护性。
什么是设计系统?
设计系统是一套完整的设计标准,包括:
- 设计原则:指导设计决策的核心价值观
- 视觉语言:颜色、字体、图标、间距等视觉元素
- 组件库:可复用的 UI 组件
- 设计规范:使用指南和最佳实践
- 工具链:支持设计和开发的工具
设计原则
1. 一致性 (Consistency)
保持整个产品的一致性,包括视觉风格、交互模式和用户体验。
2. 可访问性 (Accessibility)
确保所有用户都能使用产品,包括残障用户。
3. 可扩展性 (Scalability)
设计系统应该能够适应不同规模和复杂度的项目。
4. 效率 (Efficiency)
通过复用组件和规范,提高设计和开发效率。
视觉语言设计
颜色系统
:root {
/* 主色调 */
--primary-50: #eff6ff;
--primary-100: #dbeafe;
--primary-500: #3b82f6;
--primary-600: #2563eb;
--primary-900: #1e3a8a;
/* 中性色 */
--gray-50: #f9fafb;
--gray-100: #f3f4f6;
--gray-500: #6b7280;
--gray-900: #111827;
/* 语义色 */
--success: #10b981;
--warning: #f59e0b;
--error: #ef4444;
--info: #3b82f6;
}
字体系统
:root {
/* 字体族 */
--font-sans: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
--font-mono: 'Fira Code', 'Monaco', 'Consolas', monospace;
/* 字体大小 */
--text-xs: 0.75rem; /* 12px */
--text-sm: 0.875rem; /* 14px */
--text-base: 1rem; /* 16px */
--text-lg: 1.125rem; /* 18px */
--text-xl: 1.25rem; /* 20px */
--text-2xl: 1.5rem; /* 24px */
/* 行高 */
--leading-tight: 1.25;
--leading-normal: 1.5;
--leading-relaxed: 1.75;
}
间距系统
:root {
--space-1: 0.25rem; /* 4px */
--space-2: 0.5rem; /* 8px */
--space-3: 0.75rem; /* 12px */
--space-4: 1rem; /* 16px */
--space-6: 1.5rem; /* 24px */
--space-8: 2rem; /* 32px */
--space-12: 3rem; /* 48px */
--space-16: 4rem; /* 64px */
}
组件库构建
1. 基础组件
// Button 组件
interface ButtonProps {
variant?: 'primary' | 'secondary' | 'outline'
size?: 'sm' | 'md' | 'lg'
disabled?: boolean
children: React.ReactNode
onClick?: () => void
}
export function Button({
variant = 'primary',
size = 'md',
disabled = false,
children,
onClick
}: ButtonProps) {
const baseClasses = 'inline-flex items-center justify-center rounded-md font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2'
const variantClasses = {
primary: 'bg-primary text-primary-foreground hover:bg-primary/90',
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
outline: 'border border-input bg-background hover:bg-accent'
}
const sizeClasses = {
sm: 'h-9 px-3 text-sm',
md: 'h-10 px-4 py-2',
lg: 'h-11 px-8 text-lg'
}
return (
<button
className={cn(
baseClasses,
variantClasses[variant],
sizeClasses[size],
disabled && 'opacity-50 cursor-not-allowed'
)}
disabled={disabled}
onClick={onClick}
>
{children}
</button>
)
}
2. 复合组件
// Card 组件
interface CardProps {
children: React.ReactNode
className?: string
}
export function Card({ children, className }: CardProps) {
return (
<div className={cn('rounded-lg border bg-card text-card-foreground shadow-sm', className)}>
{children}
</div>
)
}
interface CardHeaderProps {
children: React.ReactNode
className?: string
}
export function CardHeader({ children, className }: CardHeaderProps) {
return (
<div className={cn('flex flex-col space-y-1.5 p-6', className)}>
{children}
</div>
)
}
interface CardContentProps {
children: React.ReactNode
className?: string
}
export function CardContent({ children, className }: CardContentProps) {
return (
<div className={cn('p-6 pt-0', className)}>
{children}
</div>
)
}
3. 表单组件
// Input 组件
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
label?: string
error?: string
helperText?: string
}
export function Input({ label, error, helperText, className, ...props }: InputProps) {
return (
<div className="space-y-2">
{label && (
<label className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
{label}
</label>
)}
<input
className={cn(
'flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
error && 'border-destructive focus-visible:ring-destructive',
className
)}
{...props}
/>
{error && (
<p className="text-sm text-destructive">{error}</p>
)}
{helperText && !error && (
<p className="text-sm text-muted-foreground">{helperText}</p>
)}
</div>
)
}
设计规范文档
1. 组件使用指南
# Button 组件使用指南
## 基本用法
```tsx
<Button>点击我</Button>
<Button variant="secondary">次要按钮</Button>
<Button variant="outline">轮廓按钮</Button>
尺寸
<Button size="sm">小按钮</Button>
<Button size="md">中等按钮</Button>
<Button size="lg">大按钮</Button>
状态
<Button disabled>禁用按钮</Button>
最佳实践
- 主要操作使用 primary 变体
- 次要操作使用 secondary 或 outline 变体
- 危险操作使用 error 变体
- 按钮文字应该简洁明了
### 2. 设计原则文档
```markdown
# 设计原则
## 一致性
- 使用统一的颜色、字体和间距
- 保持相同的交互模式
- 遵循既定的视觉层次
## 可访问性
- 确保足够的颜色对比度
- 提供键盘导航支持
- 使用语义化的 HTML 标签
## 响应式设计
- 移动优先的设计方法
- 灵活的布局系统
- 适配不同屏幕尺寸
工具链建设
1. Storybook 集成
// .storybook/main.js
module.exports = {
stories: ['../src/**/*.stories.@(js|jsx|ts|tsx)'],
addons: [
'@storybook/addon-essentials',
'@storybook/addon-a11y',
'@storybook/addon-docs'
],
framework: '@storybook/react',
typescript: {
check: false,
reactDocgen: 'react-docgen-typescript'
}
}
2. 自动化测试
// Button.test.tsx
import { render, screen, fireEvent } from '@testing-library/react'
import { Button } from './Button'
describe('Button', () => {
it('renders correctly', () => {
render(<Button>Click me</Button>)
expect(screen.getByRole('button')).toBeInTheDocument()
})
it('handles click events', () => {
const handleClick = jest.fn()
render(<Button onClick={handleClick}>Click me</Button>)
fireEvent.click(screen.getByRole('button'))
expect(handleClick).toHaveBeenCalledTimes(1)
})
it('is disabled when disabled prop is true', () => {
render(<Button disabled>Click me</Button>)
expect(screen.getByRole('button')).toBeDisabled()
})
})
3. 设计令牌管理
// design-tokens.js
export const tokens = {
colors: {
primary: {
50: '#eff6ff',
100: '#dbeafe',
500: '#3b82f6',
600: '#2563eb',
900: '#1e3a8a'
}
},
spacing: {
xs: '0.25rem',
sm: '0.5rem',
md: '1rem',
lg: '1.5rem',
xl: '2rem'
},
typography: {
fontFamily: {
sans: ['Inter', 'sans-serif'],
mono: ['Fira Code', 'monospace']
},
fontSize: {
xs: '0.75rem',
sm: '0.875rem',
base: '1rem',
lg: '1.125rem',
xl: '1.25rem'
}
}
}
实施策略
1. 渐进式实施
- 从核心组件开始
- 逐步扩展到复杂组件
- 持续迭代和改进
2. 团队协作
- 设计师和开发者密切合作
- 建立清晰的沟通机制
- 定期审查和更新
3. 版本管理
{
"name": "@company/design-system",
"version": "1.2.0",
"description": "Company Design System",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"scripts": {
"build": "tsc",
"test": "jest",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
}
}
最佳实践
1. 组件设计
- 单一职责原则
- 可组合性
- 可配置性
- 可访问性
2. 文档维护
- 及时更新文档
- 提供使用示例
- 记录变更历史
3. 质量保证
- 自动化测试
- 代码审查
- 性能监控
总结
设计系统是一个持续演进的过程,需要团队协作、工具支持和最佳实践。通过建立完善的设计系统,我们可以:
- 提高开发效率
- 确保产品一致性
- 降低维护成本
- 改善用户体验
记住,设计系统不是一成不变的,需要根据项目需求和用户反馈不断优化和改进。