Design System 重构完成

This commit is contained in:
2026-02-10 03:54:09 +08:00
parent fe5e8533b5
commit 73d0b0d5fe
51 changed files with 4915 additions and 8 deletions

585
src/design-system/README.md Normal file
View File

@@ -0,0 +1,585 @@
# Design System
完整的设计系统,提供可复用的 UI 组件和设计令牌,确保整个应用的一致性。
## 目录结构
```
src/design-system/
├── tokens/ # 设计令牌(颜色、间距、字体等)
├── lib/ # 工具函数
├── base/ # 基础组件
│ ├── button/
│ ├── input/
│ ├── textarea/
│ ├── card/
│ ├── checkbox/
│ ├── radio/
│ ├── switch/
│ └── select/
├── feedback/ # 反馈组件
│ ├── alert/
│ ├── progress/
│ ├── skeleton/
│ └── toast/
├── overlay/ # 覆盖组件
│ └── modal/
├── data-display/ # 数据展示组件
│ ├── badge/
│ └── divider/
├── layout/ # 布局组件
│ ├── container/
│ ├── grid/
│ └── stack/
├── navigation/ # 导航组件
│ └── tabs/
└── index.ts # 统一导出
```
## 快速开始
### 安装依赖
```bash
pnpm add class-variance-authority clsx tailwind-merge
```
### 导入组件
```tsx
// 方式 1: 从主入口导入(简单但 tree-shaking 较差)
import { Button, Input, Card } from '@/design-system';
// 方式 2: 从子路径导入(更好的 tree-shaking
import { Button } from '@/design-system/base/button';
import { Input } from '@/design-system/base/input';
import { Card } from '@/design-system/base/card';
```
### 使用组件
```tsx
import { Button, Card } from '@/design-system';
export function MyComponent() {
return (
<Card>
<h1>标题</h1>
<p>内容</p>
<Button variant="primary">点击我</Button>
</Card>
);
}
```
## 组件列表
### 基础组件
| 组件 | 说明 | 状态 |
|------|------|------|
| [Button](#button) | 按钮 | ✅ |
| [Input](#input) | 输入框 | ✅ |
| [Textarea](#textarea) | 多行文本输入 | ✅ |
| [Card](#card) | 卡片容器 | ✅ |
| [Checkbox](#checkbox) | 复选框 | ✅ |
| [Radio](#radio) | 单选按钮 | ✅ |
| [Switch](#switch) | 开关 | ✅ |
| [Select](#select) | 下拉选择框 | ✅ |
### 反馈组件
| 组件 | 说明 | 状态 |
|------|------|------|
| [Alert](#alert) | 警告提示 | ✅ |
| [Progress](#progress) | 进度条 | ✅ |
| [Skeleton](#skeleton) | 骨架屏 | ✅ |
| [Toast](#toast) | 通知提示 | ✅ |
### 覆盖组件
| 组件 | 说明 | 状态 |
|------|------|------|
| [Modal](#modal) | 模态框 | ✅ |
### 数据展示组件
| 组件 | 说明 | 状态 |
|------|------|------|
| [Badge](#badge) | 徽章 | ✅ |
| [Divider](#divider) | 分隔线 | ✅ |
### 布局组件
| 组件 | 说明 | 状态 |
|------|------|------|
| [Container](#container) | 容器 | ✅ |
| [Grid](#grid) | 网格布局 | ✅ |
| [Stack](#stack) | 堆叠布局 | ✅ |
### 导航组件
| 组件 | 说明 | 状态 |
|------|------|------|
| [Tabs](#tabs) | 标签页 | ✅ |
## 组件 API
### Button
按钮组件,支持多种变体和尺寸。
```tsx
import { Button } from '@/design-system';
<Button variant="primary" size="md" onClick={handleClick}>
点击我
</Button>
```
**变体 (variant)**: `primary` | `secondary` | `success` | `warning` | `error` | `ghost` | `outline` | `link`
**尺寸 (size)**: `sm` | `md` | `lg`
**快捷组件**: `PrimaryButton`, `SecondaryButton`, `SuccessButton`, `WarningButton`, `ErrorButton`, `GhostButton`, `OutlineButton`, `LinkButton`
### Input
输入框组件。
```tsx
import { Input } from '@/design-system';
<Input
variant="bordered"
placeholder="请输入内容"
error={hasError}
/>
```
**变体 (variant)**: `default` | `bordered` | `filled` | `search`
**尺寸 (size)**: `sm` | `md` | `lg`
### Textarea
多行文本输入组件。
```tsx
import { Textarea } from '@/design-system';
<Textarea
variant="bordered"
placeholder="请输入内容"
rows={4}
/>
```
**变体 (variant)**: `default` | `bordered` | `filled`
### Card
卡片容器组件。
```tsx
import { Card, CardHeader, CardTitle, CardBody, CardFooter } from '@/design-system';
<Card>
<CardHeader>
<CardTitle>标题</CardTitle>
</CardHeader>
<CardBody>
<p>内容</p>
</CardBody>
<CardFooter>
<Button>确定</Button>
</CardFooter>
</Card>
```
**变体 (variant)**: `default` | `bordered` | `elevated` | `flat`
**内边距 (padding)**: `none` | `xs` | `sm` | `md` | `lg` | `xl`
### Checkbox
复选框组件。
```tsx
import { Checkbox } from '@/design-system';
<Checkbox checked={checked} onChange={setChecked}>
同意条款
</Checkbox>
```
### Radio
单选按钮组件。
```tsx
import { Radio, RadioGroup } from '@/design-system';
<RadioGroup name="choice" value={value} onChange={setValue}>
<Radio value="1">选项 1</Radio>
<Radio value="2">选项 2</Radio>
</RadioGroup>
```
### Switch
开关组件。
```tsx
import { Switch } from '@/design-system';
<Switch checked={enabled} onChange={setEnabled} />
```
### Alert
警告提示组件。
```tsx
import { Alert } from '@/design-system';
<Alert variant="success" title="成功">
操作成功完成
</Alert>
```
**变体 (variant)**: `info` | `success` | `warning` | `error`
### Progress
进度条组件。
```tsx
import { Progress } from '@/design-system';
<Progress value={60} showLabel />
```
### Skeleton
骨架屏组件。
```tsx
import { Skeleton, TextSkeleton, CardSkeleton } from '@/design-system';
<Skeleton className="h-4 w-32" />
<TextSkeleton lines={3} />
<CardSkeleton />
```
### Toast
通知提示组件(基于 sonner
```tsx
import { toast } from '@/design-system';
toast.success("操作成功!");
toast.error("发生错误");
toast.promise(promise, {
loading: "加载中...",
success: "加载成功",
error: "加载失败",
});
```
### Modal
模态框组件。
```tsx
import { Modal } from '@/design-system';
<Modal open={open} onClose={() => setOpen(false)}>
<Modal.Header>
<Modal.Title>标题</Modal.Title>
</Modal.Header>
<Modal.Body>
<p>内容</p>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={() => setOpen(false)}>
取消
</Button>
<Button variant="primary">确定</Button>
</Modal.Footer>
</Modal>
```
### Badge
徽章组件。
```tsx
import { Badge } from '@/design-system';
<Badge variant="success">成功</Badge>
<Badge dot />
```
**变体 (variant)**: `default` | `primary` | `success` | `warning` | `error` | `info`
### Divider
分隔线组件。
```tsx
import { Divider } from '@/design-system';
<Divider />
<Divider>或者</Divider>
<Divider orientation="vertical" />
```
### Container
容器组件。
```tsx
import { Container } from '@/design-system';
<Container size="lg" padding="xl">
<p>内容</p>
</Container>
```
### Grid
网格布局组件。
```tsx
import { Grid } from '@/design-system';
<Grid cols={3} gap={4}>
<div>项目 1</div>
<div>项目 2</div>
<div>项目 3</div>
</Grid>
```
### Stack
堆叠布局组件。
```tsx
import { Stack, VStack, HStack } from '@/design-system';
<VStack gap={4}>
<div>项目 1</div>
<div>项目 2</div>
</VStack>
```
### Tabs
标签页组件。
```tsx
import { Tabs } from '@/design-system';
<Tabs value={activeTab} onValueChange={setActiveTab}>
<Tabs.List>
<Tabs.Trigger value="tab1">标签 1</Tabs.Trigger>
<Tabs.Trigger value="tab2">标签 2</Tabs.Trigger>
</Tabs.List>
<Tabs.Content value="tab1">
<p>内容 1</p>
</Tabs.Content>
<Tabs.Content value="tab2">
<p>内容 2</p>
</Tabs.Content>
</Tabs>
```
## 设计令牌
### 颜色
```tsx
import { colors } from '@/design-system/tokens';
// 主色
colors.primary.500 // #35786f
// 语义色
colors.success.500 // #22c55e
colors.warning.500 // #f59e0b
colors.error.500 // #ef4444
colors.info.500 // #3b82f6
```
在组件中使用:
```tsx
<div className="bg-primary-500 text-white">主色背景</div>
<div className="text-success-600">成功文本</div>
```
### 间距
基于 8pt 网格系统:
```tsx
<div className="p-4"> // 16px
<div className="p-6"> // 24px
<div className="p-8"> // 32px
```
### 字体
```tsx
<div className="text-sm">小文本</div>
<div className="text-base">正常文本</div>
<div className="text-lg">大文本</div>
<div className="font-semibold">半粗体</div>
<div className="font-bold">粗体</div>
```
### 圆角
```tsx
<div className="rounded-lg"> // 8px
<div className="rounded-xl"> // 12px
<div className="rounded-2xl"> // 16px
```
### 阴影
```tsx
<div className="shadow-sm"> // 小阴影
<div className="shadow-md"> // 中阴影
<div className="shadow-lg"> // 大阴影
<div className="shadow-xl"> // 超大阴影
```
## 工具函数
### cn
合并 Tailwind CSS 类名的工具函数。
```tsx
import { cn } from '@/design-system';
const className = cn(
'base-class',
isActive && 'active-class',
'another-class'
);
```
## 最佳实践
### 1. 组件导入
对于更好的 tree-shaking建议从子路径导入
```tsx
// ✅ 推荐
import { Button } from '@/design-system/base/button';
// ❌ 不推荐(但也可以)
import { Button } from '@/design-system';
```
### 2. 样式覆盖
使用 `className` 属性覆盖样式:
```tsx
<Button className="w-full">全宽按钮</Button>
```
### 3. 组合组件
利用组件组合来构建复杂 UI
```tsx
<Card>
<CardHeader>
<CardTitle>标题</CardTitle>
</CardHeader>
<CardBody>
<VStack gap={4}>
<Input placeholder="输入框" />
<Button>提交</Button>
</VStack>
</CardBody>
</Card>
```
### 4. 可访问性
所有组件都内置了可访问性支持:
- 正确的 ARIA 属性
- 键盘导航支持
- 焦点管理
- 屏幕阅读器友好
## 迁移指南
### 从旧组件迁移
旧的组件路径:
```tsx
import { Button } from '@/components/ui/Button';
import { Input } from '@/components/ui/Input';
```
新的组件路径:
```tsx
import { Button } from '@/design-system/base/button';
import { Input } from '@/design-system/base/input';
```
### API 变化
大部分 API 保持兼容,但有以下变化:
1. **颜色不再使用硬编码值**
```tsx
// 旧
style={{ backgroundColor: '#35786f' }}
// 新
className="bg-primary-500"
```
2. **变体命名更加一致**
```tsx
// 旧
<Button variant="icon" />
// 新
<Button variant="ghost" />
```
3. **新增语义色变体**
```tsx
<Button variant="success">成功</Button>
<Button variant="warning">警告</Button>
<Button variant="error">错误</Button>
```
## 贡献
添加新组件时,请遵循以下规范:
1. 在对应的目录下创建组件
2. 使用 `cva` 定义变体样式
3. 使用 `forwardRef` 支持 ref 转发
4. 添加完整的 TypeScript 类型
5. 编写详细的 JSDoc 注释和示例
6. 在导出文件中添加导出
## 许可证
AGPL-3.0-only