Skip to content

Commit 7788a54

Browse files
committed
feat(docs): implement new demo system with build-time components, update documentation, and enhance demo registry
1 parent 8eb818c commit 7788a54

File tree

24 files changed

+1304
-32
lines changed

24 files changed

+1304
-32
lines changed

docs/DEMO_GUIDE.md

Lines changed: 303 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,303 @@
1+
# Demo 组件使用指南
2+
3+
本文档说明如何在文档中添加交互式代码演示。
4+
5+
## 🎯 方案对比
6+
7+
### ❌ 旧方案:LiveDemo(运行时编译)
8+
9+
```tsx
10+
<LiveDemo code={`...`} />
11+
```
12+
13+
**缺点:**
14+
- 客户端引入完整 Babel (~2MB)
15+
- 运行时编译,性能差
16+
- 使用 `new Function`,有安全隐患
17+
- 无法使用外部依赖
18+
19+
### ✅ 新方案:Demo(构建时方案)
20+
21+
```tsx
22+
<Demo demo="button-basic" />
23+
```
24+
25+
**优点:**
26+
- ✓ 零运行时开销
27+
- ✓ 真实的 TypeScript 文件
28+
- ✓ 完整的类型检查
29+
- ✓ 可以正常导入依赖
30+
- ✓ 自动代码分割
31+
32+
## 📝 快速开始
33+
34+
### 1. 创建 Demo 文件
35+
36+
`docs/demos/` 目录下创建组件文件:
37+
38+
```tsx
39+
// demos/button-basic.tsx
40+
import { Button } from '@/components/button';
41+
42+
export default function Demo() {
43+
return <Button>点击我</Button>;
44+
}
45+
```
46+
47+
**规范:**
48+
- 文件名使用 kebab-case:`button-basic.tsx`
49+
- 必须 `export default` 一个组件
50+
- 可以正常导入任何依赖
51+
52+
### 2. 注册到 Registry
53+
54+
编辑 `docs/lib/demo-registry.ts`
55+
56+
```ts
57+
export const demoRegistry = {
58+
'button-basic': '@/demos/button-basic.tsx',
59+
// ...
60+
} as const;
61+
```
62+
63+
### 3. 在 MDX 中使用
64+
65+
```mdx
66+
# Button 组件
67+
68+
## 基础用法
69+
70+
<Demo demo="button-basic" title="基础按钮" />
71+
```
72+
73+
## 🔧 使用方式
74+
75+
### 方式一:使用 Registry(推荐)
76+
77+
```mdx
78+
<Demo demo="button-basic" title="基础按钮" />
79+
```
80+
81+
**优点:**
82+
- 简洁,易于维护
83+
- 统一管理所有 demo
84+
- 自动提示(TypeScript)
85+
86+
### 方式二:直接路径
87+
88+
```mdx
89+
<Demo src="@/demos/button-basic.tsx" title="基础按钮" />
90+
```
91+
92+
**适用场景:**
93+
- 临时演示
94+
- 不需要复用的 demo
95+
96+
### 方式三:多文件 Demo
97+
98+
```mdx
99+
<Demo
100+
files={[
101+
{ src: '@/demos/multi/App.tsx', title: 'App' },
102+
{ src: '@/demos/multi/Button.tsx', title: 'Button' },
103+
{ src: '@/demos/multi/utils.ts', title: 'Utils' }
104+
]}
105+
entry="@/demos/multi/App.tsx"
106+
title="多文件示例"
107+
/>
108+
```
109+
110+
**特性:**
111+
- Tab 切换多个文件
112+
- 指定入口文件用于预览
113+
- 查看完整项目结构
114+
115+
## 📦 Props API
116+
117+
### Demo 组件
118+
119+
| 属性 | 类型 | 说明 |
120+
| --- | --- | --- |
121+
| demo | `DemoKey` | Registry 中的 demo key |
122+
| src | `string` | Demo 文件路径(直接模式) |
123+
| title | `string` | 标题 |
124+
| highlight | `string` | 高亮行,如 `"1,3-5"` |
125+
| files | `Array<{src, title}>` | 多文件模式的文件列表 |
126+
| entry | `string` | 多文件模式的入口文件 |
127+
128+
## 🎨 高级用法
129+
130+
### 代码高亮
131+
132+
高亮特定行:
133+
134+
```mdx
135+
<Demo
136+
demo="button-basic"
137+
highlight="3-5,7"
138+
title="高亮示例"
139+
/>
140+
```
141+
142+
### 复杂交互
143+
144+
Demo 可以包含状态、事件处理等:
145+
146+
```tsx
147+
// demos/counter.tsx
148+
import { Button } from '@/components/button';
149+
import { useState } from 'react';
150+
151+
export default function Demo() {
152+
const [count, setCount] = useState(0);
153+
154+
return (
155+
<div className="space-y-4">
156+
<div className="text-2xl font-bold">{count}</div>
157+
<div className="flex gap-2">
158+
<Button onClick={() => setCount(c => c + 1)}>+1</Button>
159+
<Button onClick={() => setCount(c => c - 1)}>-1</Button>
160+
<Button variant="outline" onClick={() => setCount(0)}>重置</Button>
161+
</div>
162+
</div>
163+
);
164+
}
165+
```
166+
167+
### 使用第三方库
168+
169+
正常导入即可:
170+
171+
```tsx
172+
// demos/with-library.tsx
173+
import { Button } from '@/components/button';
174+
import { motion } from 'framer-motion';
175+
176+
export default function Demo() {
177+
return (
178+
<motion.div
179+
initial={{ opacity: 0 }}
180+
animate={{ opacity: 1 }}
181+
>
182+
<Button>Animated Button</Button>
183+
</motion.div>
184+
);
185+
}
186+
```
187+
188+
## 🗂️ 目录结构
189+
190+
```
191+
docs/
192+
├── demos/ # 所有 demo 文件
193+
│ ├── button-basic.tsx
194+
│ ├── button-variants.tsx
195+
│ ├── input-basic.tsx
196+
│ └── multi/ # 多文件 demo
197+
│ ├── App.tsx
198+
│ ├── Button.tsx
199+
│ └── utils.ts
200+
├── lib/
201+
│ └── demo-registry.ts # Demo 注册表
202+
└── components/
203+
└── mdx-demo.tsx # MDX Demo 包装组件
204+
```
205+
206+
## 🚀 性能优化
207+
208+
Demo 组件使用 React 的 `lazy` 自动进行代码分割:
209+
210+
```tsx
211+
const Preview = lazy(() => import('@/demos/button-basic.tsx'));
212+
```
213+
214+
**好处:**
215+
- 只有查看 Demo 时才加载代码
216+
- 减小首次加载体积
217+
- 更快的页面渲染
218+
219+
## 🔄 迁移指南
220+
221+
### 从 ComponentPreview 迁移
222+
223+
**旧代码:**
224+
```mdx
225+
<ComponentPreview code={`import { Button } from '@skyroc/ui';
226+
227+
export default function Demo() {
228+
return <Button>Click</Button>;
229+
}`}>
230+
<Button>Click</Button>
231+
</ComponentPreview>
232+
```
233+
234+
**新代码:**
235+
236+
1. 创建 demo 文件 `demos/button-example.tsx`
237+
2. 注册到 registry
238+
3. 使用:
239+
```mdx
240+
<Demo demo="button-example" />
241+
```
242+
243+
### 从 LiveDemo 迁移
244+
245+
**旧代码:**
246+
```tsx
247+
<LiveDemo code={code} lang="tsx" />
248+
```
249+
250+
**新代码:**
251+
252+
1. 将代码保存为文件
253+
2. 使用 `<Demo src="..." />`
254+
255+
## 🐛 常见问题
256+
257+
### Q: Demo 不显示?
258+
259+
**A:** 检查:
260+
1. Demo 文件是否正确 export default
261+
2. Registry 中路径是否正确
262+
3. 是否有 TypeScript 错误
263+
264+
### Q: 如何调试 Demo?
265+
266+
**A:** Demo 是普通的 React 组件,可以:
267+
1. 直接在 demos/ 文件中添加 console.log
268+
2. 使用 React DevTools
269+
3. 检查浏览器控制台
270+
271+
### Q: 可以使用 Hooks 吗?
272+
273+
**A:** 可以!Demo 就是普通组件:
274+
```tsx
275+
export default function Demo() {
276+
const [state, setState] = useState(0);
277+
useEffect(() => { ... }, []);
278+
return ...;
279+
}
280+
```
281+
282+
### Q: 如何共享代码?
283+
284+
**A:** 创建共享的 utils:
285+
```tsx
286+
// demos/utils/common.tsx
287+
export const sharedStyles = "...";
288+
289+
// demos/button-basic.tsx
290+
import { sharedStyles } from './utils/common';
291+
```
292+
293+
## 📚 示例参考
294+
295+
查看现有 demos:
296+
- `demos/button-*.tsx` - 按钮示例
297+
- `demos/input-*.tsx` - 输入框示例
298+
- `demos/card-*.tsx` - 卡片示例
299+
300+
---
301+
302+
**享受编写文档的乐趣!** 🎉
303+

0 commit comments

Comments
 (0)