ds-markdown 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -666
- package/README.zh.md +39 -840
- package/es/components/CodeComponent/BlockWrap/index.css +0 -13
- package/es/components/CodeComponent/CodeBlockWrap/index.css +24 -0
- package/es/components/CodeComponent/CodeBlockWrap/index.d.ts +1 -0
- package/es/components/CodeComponent/CodeBlockWrap/index.d.ts.map +1 -1
- package/es/components/CodeComponent/CodeBlockWrap/index.js +1 -0
- package/es/components/CodeComponent/CodeBlockWrap/index.js.map +1 -1
- package/es/components/CodeComponent/index.css +0 -24
- package/es/style.css +0 -1004
- package/package.json +2 -2
package/README.zh.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# ds-markdown
|
|
2
2
|
|
|
3
|
+
> 🚀 React Markdown 打字动画组件,提供现代聊天界面效果
|
|
4
|
+
|
|
3
5
|
<p align="center">
|
|
4
6
|
<img src="./assets/images/favicon.png" alt="ds-markdown logo" width="120" />
|
|
5
7
|
</p>
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
**🇨🇳 中文 | [🇺🇸 English](./README.en.md)**
|
|
9
|
+
**🇨🇳 中文 | [🇺🇸 English](./README.md)**
|
|
10
10
|
|
|
11
11
|
一个专为现代 AI 应用设计的 React 组件,提供流畅的实时打字动画和完整的 Markdown 渲染能力。
|
|
12
12
|
|
|
@@ -16,21 +16,9 @@
|
|
|
16
16
|
[](https://react.dev)
|
|
17
17
|
[](https://www.typescriptlang.org/)
|
|
18
18
|
|
|
19
|
-
- [使用文档](https://onshinpei.github.io/ds-markdown/)
|
|
20
|
-
- 使用示例
|
|
21
|
-
- [基本用法](https://stackblitz.com/edit/vitejs-vite-ddfw8avb?file=src%2FApp.tsx)
|
|
22
|
-
- [流式数据用法](https://stackblitz.com/edit/vitejs-vite-2ri8kex3?file=src%2FApp.tsx)
|
|
23
|
-
- [mermaid图表](https://stackblitz.com/edit/vitejs-vite-iqbyta3j?file=index.html)
|
|
24
|
-
- [数学公式demo1](https://stackblitz.com/edit/vitejs-vite-iqbyta3j?file=index.html)
|
|
25
|
-
- [数学公式demo2](https://stackblitz.com/edit/vitejs-vite-xk9lxagc?file=src%2FApp.tsx)
|
|
26
|
-
|
|
27
|
-
如果你想要一个纯净的`react markdown` 打字组件,可以使用[react-markdown-typer](https://github.com/onshinpei/react-markdown-typer)
|
|
28
|
-
|
|
29
|
-
---
|
|
30
|
-
|
|
31
19
|
## 为什么要用 ds-markdown?
|
|
32
20
|
|
|
33
|
-
###
|
|
21
|
+
### **解决的核心问题**
|
|
34
22
|
|
|
35
23
|
- **流式数据打字卡顿问题**
|
|
36
24
|
传统打字机组件在处理 AI 后端流式数据时,由于每个 chunk 包含多个字符,会出现卡顿、跳字等问题。ds-markdown 智能拆分每个 chunk,确保每个字符都流畅打字。
|
|
@@ -38,7 +26,7 @@
|
|
|
38
26
|
- **Markdown 渲染与打字动画割裂**
|
|
39
27
|
大多数打字机组件只支持纯文本,无法在打字过程中实时渲染 Markdown 语法、数学公式、图表等富媒体内容。
|
|
40
28
|
|
|
41
|
-
###
|
|
29
|
+
### **带来的价值**
|
|
42
30
|
|
|
43
31
|
- **提升用户沉浸感**
|
|
44
32
|
提供专业级 AI 聊天体验,让用户感受到真实的 AI 交互过程,极大提升产品专业度和用户满意度。
|
|
@@ -46,77 +34,37 @@
|
|
|
46
34
|
- **开箱即用,降低开发复杂度**
|
|
47
35
|
完整的解决方案,无需额外配置即可支持流式数据、Markdown 渲染、数学公式、图表等复杂功能。
|
|
48
36
|
|
|
49
|
-
|
|
50
|
-
从 AI 聊天机器人到教育内容展示,从技术文档到产品演示,一个组件满足多种需求。
|
|
51
|
-
|
|
52
|
-
---
|
|
53
|
-
|
|
54
|
-
## 目录
|
|
55
|
-
|
|
56
|
-
- [核心特性](#-核心特性)
|
|
57
|
-
- [快速安装](#-快速安装)
|
|
58
|
-
- [5分钟上手](#-5分钟上手)
|
|
59
|
-
- [基础用法](#基础用法)
|
|
60
|
-
- [禁用打字动画](#禁用打字动画)
|
|
61
|
-
- [数学公式支持](#数学公式支持)
|
|
62
|
-
- [AI 对话场景](#ai-对话场景)
|
|
63
|
-
- [代码块功能 🆕](#代码块功能-)
|
|
64
|
-
- [Mermaid图表支持](#mermaid图表支持)
|
|
65
|
-
- [完整 API 文档](#-完整-api-文档)
|
|
66
|
-
- [插件系统](#-插件系统)
|
|
67
|
-
- [内置插件](#内置插件)
|
|
68
|
-
- [KaTeX 数学公式插件](#katex-数学公式插件)
|
|
69
|
-
- [Mermaid 图表插件 🆕](#mermaid-图表插件-)
|
|
70
|
-
- [自定义插件](#自定义插件)
|
|
71
|
-
- [多语言配置](#多语言配置)
|
|
72
|
-
- [实战示例](#-实战示例)
|
|
73
|
-
- [最佳实践](#-最佳实践)
|
|
74
|
-
|
|
75
|
-
## 核心特性
|
|
76
|
-
|
|
77
|
-
### 🤖 **AI 对话场景**
|
|
78
|
-
|
|
79
|
-
- 专业级 AI 聊天响应效果,媲美主流 AI 平台体验
|
|
80
|
-
- 支持思考过程 (`thinking`) 和回答内容 (`answer`) 双模式
|
|
81
|
-
- 流式数据完美适配,零延迟响应用户输入
|
|
82
|
-
|
|
83
|
-
### 📊 **内容展示场景**
|
|
84
|
-
|
|
85
|
-
- 完整 Markdown 语法支持,包括代码高亮、表格、列表等
|
|
86
|
-
- 数学公式渲染 (KaTeX),支持 `$...$` 和 `\[...\]` 语法
|
|
87
|
-
- Mermaid 图表支持,包括流程图、序列图、甘特图、类图等 🆕
|
|
88
|
-
- 支持亮色/暗色主题,适配不同产品风格
|
|
89
|
-
- 插件化架构,支持 remark/rehype 插件扩展
|
|
37
|
+
## 文档
|
|
90
38
|
|
|
91
|
-
|
|
39
|
+
**👉 [完整文档](https://onshinpei.github.io/ds-markdown/)**
|
|
92
40
|
|
|
93
|
-
-
|
|
94
|
-
-
|
|
95
|
-
-
|
|
41
|
+
- [快速开始](https://onshinpei.github.io/ds-markdown/#get-started)
|
|
42
|
+
- [API 文档](https://onshinpei.github.io/ds-markdown/#docs)
|
|
43
|
+
- [在线示例](https://onshinpei.github.io/ds-markdown/#examples)
|
|
44
|
+
- [马上试试](https://onshinpei.github.io/ds-markdown/#try)
|
|
96
45
|
|
|
97
|
-
|
|
46
|
+
## stackblitz 示例
|
|
98
47
|
|
|
99
|
-
-
|
|
100
|
-
-
|
|
101
|
-
-
|
|
102
|
-
-
|
|
48
|
+
- [基本用法](https://stackblitz.com/edit/vitejs-vite-ddfw8avb?file=src%2FApp.tsx)
|
|
49
|
+
- [流式数据用法](https://stackblitz.com/edit/vitejs-vite-2ri8kex3?file=src%2FApp.tsx)
|
|
50
|
+
- [mermaid图表](https://stackblitz.com/edit/vitejs-vite-iqbyta3j?file=index.html)
|
|
51
|
+
- [数学公式demo1](https://stackblitz.com/edit/vitejs-vite-iqbyta3j?file=index.html)
|
|
52
|
+
- [数学公式demo2](https://stackblitz.com/edit/vitejs-vite-xk9lxagc?file=src%2FApp.tsx)
|
|
103
53
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
- 双模式定时器优化,支持`requestAnimationFrame`和`setTimeout`模式
|
|
107
|
-
- 高频打字支持(`requestAnimationFrame`模式下打字间隔最低可接近于`0ms`)
|
|
108
|
-
- 帧同步渲染,与浏览器刷新完美配合
|
|
109
|
-
- 智能字符批量处理,视觉效果更自然
|
|
110
|
-
- **动态速度控制** 🆕:根据剩余字符数量自动调整打字速度,流式数据场景下提供更自然的阅读体验
|
|
111
|
-
|
|
112
|
-
### ⚡ **性能优化**
|
|
54
|
+
## 核心特性
|
|
113
55
|
|
|
114
|
-
-
|
|
115
|
-
-
|
|
56
|
+
- 🤖 **AI 对话就绪** - 专业的 AI 流式响应打字动画
|
|
57
|
+
- 📝 **完整 Markdown 支持** - 代码高亮、表格、列表等
|
|
58
|
+
- 🔢 **数学公式** - KaTeX 支持,`$...$` 和 `$$...$$` 语法
|
|
59
|
+
- 📊 **Mermaid 图表** - 流程图、序列图、甘特图等
|
|
60
|
+
- 🎨 **可定制** - 亮色/暗色主题,可配置打字速度
|
|
61
|
+
- ⚡ **高性能** - 轻量级,流畅动画
|
|
62
|
+
- 🔌 **可扩展** - 插件系统,支持自定义功能
|
|
63
|
+
- 📦 **TypeScript** - 完整类型支持
|
|
116
64
|
|
|
117
65
|
---
|
|
118
66
|
|
|
119
|
-
##
|
|
67
|
+
## 安装
|
|
120
68
|
|
|
121
69
|
```bash
|
|
122
70
|
# npm
|
|
@@ -129,13 +77,7 @@ yarn add ds-markdown
|
|
|
129
77
|
pnpm add ds-markdown
|
|
130
78
|
```
|
|
131
79
|
|
|
132
|
-
##
|
|
133
|
-
|
|
134
|
-
> ✅ v1.0+版本开始,无需再手动 `import 'ds-markdown/style.css'`,组件会自动注入所需的基础样式。
|
|
135
|
-
|
|
136
|
-
### 基础用法
|
|
137
|
-
|
|
138
|
-
[DEMO](https://stackblitz.com/edit/vitejs-vite-z94syu8j?file=src%2FApp.tsx)
|
|
80
|
+
## 快速开始
|
|
139
81
|
|
|
140
82
|
```tsx
|
|
141
83
|
import DsMarkdown from 'ds-markdown';
|
|
@@ -149,170 +91,9 @@ function App() {
|
|
|
149
91
|
}
|
|
150
92
|
```
|
|
151
93
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
```tsx
|
|
155
|
-
import DsMarkdown from 'ds-markdown';
|
|
156
|
-
|
|
157
|
-
function StaticDemo() {
|
|
158
|
-
const [disableTyping, setDisableTyping] = useState(false);
|
|
159
|
-
|
|
160
|
-
return (
|
|
161
|
-
<div>
|
|
162
|
-
<button onClick={() => setDisableTyping(!disableTyping)}>{disableTyping ? '开启' : '关闭'}打字机效果</button>
|
|
163
|
-
|
|
164
|
-
<DsMarkdown interval={20} answerType="answer" disableTyping={disableTyping}>
|
|
165
|
-
# 静态展示模式 当 `disableTyping` 为 `true` 时,内容会立即全部显示,无打字动画效果。 这在某些场景下非常有用: - 📄 静态文档展示 - 🔄 切换显示模式 - ⚡ 快速预览内容
|
|
166
|
-
</DsMarkdown>
|
|
167
|
-
</div>
|
|
168
|
-
);
|
|
169
|
-
}
|
|
170
|
-
```
|
|
94
|
+
## 核心API文档
|
|
171
95
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
```tsx
|
|
175
|
-
import DsMarkdown from 'ds-markdown';
|
|
176
|
-
// 如果需要展示公式,则需要引入公式转换插件
|
|
177
|
-
import { katexPlugin } from 'ds-markdown/plugins';
|
|
178
|
-
import 'ds-markdown/style.css';
|
|
179
|
-
// 如果需要展示公式,则需要引入数学公式样式
|
|
180
|
-
import 'ds-markdown/katex.css';
|
|
181
|
-
|
|
182
|
-
function MathDemo() {
|
|
183
|
-
return (
|
|
184
|
-
<DsMarkdown interval={20} answerType="answer" plugins={[katexPlugin]} math={{ splitSymbol: 'dollar' }}>
|
|
185
|
-
# 勾股定理 在直角三角形中,斜边的平方等于两条直角边的平方和: $a^2 + b^2 = c^2$ 其中: - $a$ 和 $b$ 是直角边 - $c$ 是斜边 对于经典的"勾三股四弦五": $c = \sqrt{3 ^ (2 + 4) ^ 2} = \sqrt{25} = 5$
|
|
186
|
-
</DsMarkdown>
|
|
187
|
-
);
|
|
188
|
-
}
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
### AI 对话场景
|
|
192
|
-
|
|
193
|
-
```tsx
|
|
194
|
-
function ChatDemo() {
|
|
195
|
-
const [thinking, setThinking] = useState('');
|
|
196
|
-
const [answer, setAnswer] = useState('');
|
|
197
|
-
|
|
198
|
-
const handleAsk = () => {
|
|
199
|
-
setThinking('🤔 正在思考您的问题...');
|
|
200
|
-
|
|
201
|
-
setTimeout(() => {
|
|
202
|
-
setAnswer(`# 关于 React 19
|
|
203
|
-
|
|
204
|
-
React 19 带来了许多激动人心的新特性:
|
|
205
|
-
|
|
206
|
-
## 🚀 主要更新
|
|
207
|
-
1. **React Compiler** - 自动优化性能
|
|
208
|
-
2. **Actions** - 简化表单处理
|
|
209
|
-
3. **Document Metadata** - 内置 SEO 支持
|
|
210
|
-
|
|
211
|
-
让我们一起探索这些新功能!`);
|
|
212
|
-
}, 2000);
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
return (
|
|
216
|
-
<div>
|
|
217
|
-
<button onClick={handleAsk}>询问 AI</button>
|
|
218
|
-
|
|
219
|
-
{thinking && (
|
|
220
|
-
<DsMarkdown answerType="thinking" interval={30}>
|
|
221
|
-
{thinking}
|
|
222
|
-
</DsMarkdown>
|
|
223
|
-
)}
|
|
224
|
-
|
|
225
|
-
{answer && (
|
|
226
|
-
<DsMarkdown answerType="answer" interval={15}>
|
|
227
|
-
{answer}
|
|
228
|
-
</DsMarkdown>
|
|
229
|
-
)}
|
|
230
|
-
</div>
|
|
231
|
-
);
|
|
232
|
-
}
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
### 代码块功能 🆕
|
|
236
|
-
|
|
237
|
-
```tsx
|
|
238
|
-
import DsMarkdown from 'ds-markdown';
|
|
239
|
-
|
|
240
|
-
function CodeBlockDemo() {
|
|
241
|
-
const codeContent = `# Hello World
|
|
242
|
-
|
|
243
|
-
\`\`\`javascript
|
|
244
|
-
function greet(name) {
|
|
245
|
-
console.log(\`Hello, \${name}!\`);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
greet('ds-markdown');
|
|
249
|
-
\`\`\`
|
|
250
|
-
|
|
251
|
-
支持代码高亮、复制和下载功能!`;
|
|
252
|
-
|
|
253
|
-
return (
|
|
254
|
-
<DsMarkdown
|
|
255
|
-
interval={20}
|
|
256
|
-
answerType="answer"
|
|
257
|
-
codeBlock={{
|
|
258
|
-
headerActions: true, // 启用代码块头部操作按钮
|
|
259
|
-
}}
|
|
260
|
-
>
|
|
261
|
-
{codeContent}
|
|
262
|
-
</DsMarkdown>
|
|
263
|
-
);
|
|
264
|
-
}
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
### Mermaid图表支持
|
|
268
|
-
|
|
269
|
-
[DEMO](https://stackblitz.com/edit/vitejs-vite-iqbyta3j?file=README.md)
|
|
270
|
-
|
|
271
|
-
```tsx
|
|
272
|
-
import DsMarkdown from 'ds-markdown';
|
|
273
|
-
import { ConfigProvider } from 'ds-markdown';
|
|
274
|
-
import mermaidPlugin from 'ds-markdown-mermaid-plugin';
|
|
275
|
-
import 'ds-markdown/style.css';
|
|
276
|
-
|
|
277
|
-
function MermaidDemo() {
|
|
278
|
-
const chartContent = `以下是简化版的学习开车流程图,仅保留 **最核心步骤**,适合快速掌握关键节点:
|
|
279
|
-
|
|
280
|
-
\`\`\`mermaid
|
|
281
|
-
graph TD
|
|
282
|
-
A[开始] --> B[科目一: 理论考试]
|
|
283
|
-
B --> C[科目二: 场地五项]
|
|
284
|
-
C --> D[科目三: 路考]
|
|
285
|
-
D --> E[科目四: 安全笔试]
|
|
286
|
-
E --> F[拿驾照]
|
|
287
|
-
F --> G[实际驾驶练习]
|
|
288
|
-
\`\`\`
|
|
289
|
-
|
|
290
|
-
### 极简说明:
|
|
291
|
-
1. **理论先行**:先通过交通规则笔试(科目一)。
|
|
292
|
-
2. **场地基础**:练习倒车、坡起等(科目二)。
|
|
293
|
-
3. **上路实战**:实际道路驾驶考试(科目三)。
|
|
294
|
-
4. **安全收尾**:通过科目四即可领证。
|
|
295
|
-
5. **持续熟练**:拿证后继续练习适应真实路况。
|
|
296
|
-
|
|
297
|
-
### 可视化建议:
|
|
298
|
-
- 用手机备忘录或白纸手绘时,按 **箭头顺序** 写步骤即可。
|
|
299
|
-
- 想更直观?用圆形便签贴出每个科目,连线成流程。`;
|
|
300
|
-
|
|
301
|
-
return (
|
|
302
|
-
<ConfigProvider>
|
|
303
|
-
<DsMarkdown interval={20} answerType="answer" plugins={[mermaidPlugin]}>
|
|
304
|
-
{chartContent}
|
|
305
|
-
</DsMarkdown>
|
|
306
|
-
</ConfigProvider>
|
|
307
|
-
);
|
|
308
|
-
}
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-

|
|
312
|
-
|
|
313
|
-
---
|
|
314
|
-
|
|
315
|
-
## 📚 完整 API 文档
|
|
96
|
+
详细文档可查看:[完整文档](https://onshinpei.github.io/ds-markdown/#get-started)
|
|
316
97
|
|
|
317
98
|
### 默认导出 DsMarkdown 和 MarkdownCMD 的 props
|
|
318
99
|
|
|
@@ -327,7 +108,7 @@ import DsMarkdown, { MarkdownCMD } from 'ds-markdown';
|
|
|
327
108
|
| `answerType` | `'thinking'` \| `'answer'` | 内容类型 (影响样式主题),不支持动态修改 | `'answer'` |
|
|
328
109
|
| `theme` | `'light'` \| `'dark'` | 主题类型 | `'light'` |
|
|
329
110
|
| `plugins` | `IMarkdownPlugin[]` | 插件配置 | `[]` |
|
|
330
|
-
| `math` |
|
|
111
|
+
| `math` | `IMarkdownMath` | 数学公式配置 | `{ splitSymbol: 'dollar' }` |
|
|
331
112
|
| `onEnd` | `(data: EndData) => void` | 打字结束回调 | - |
|
|
332
113
|
| `onStart` | `(data: StartData) => void` | 打字开始回调 | - |
|
|
333
114
|
| `onBeforeTypedChar` | `(data: IBeforeTypedChar) => Promise<void>` | 字符打字前的回调,支持异步操作,会阻塞之后的打字 | - |
|
|
@@ -338,601 +119,19 @@ import DsMarkdown, { MarkdownCMD } from 'ds-markdown';
|
|
|
338
119
|
|
|
339
120
|
> 注意:打字进行中将 `disableTyping` 从 `true` 改为 `false` 只会从当前位置继续,不会回放已跳过的动画;若需从头播放,请调用实例方法 `restart()`。
|
|
340
121
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
| 属性 | 类型 | 说明 | 默认值 |
|
|
344
|
-
| -------------- | ------------ | ---------------------------- | ------ |
|
|
345
|
-
| `currentIndex` | `number` | 当前字符在整个字符串中的索引 | `0` |
|
|
346
|
-
| `currentChar` | `string` | 当前即将打字的字符 | - |
|
|
347
|
-
| `answerType` | `AnswerType` | 内容类型 (thinking/answer) | - |
|
|
348
|
-
| `prevStr` | `string` | 当前类型内容的前缀字符串 | - |
|
|
349
|
-
| `percent` | `number` | 打字进度百分比 (0-100) | `0` |
|
|
350
|
-
|
|
351
|
-
### ITypedChar
|
|
352
|
-
|
|
353
|
-
| 属性 | 类型 | 说明 | 默认值 |
|
|
354
|
-
| -------------- | ------------ | ---------------------------- | ------ |
|
|
355
|
-
| `currentIndex` | `number` | 当前字符在整个字符串中的索引 | `0` |
|
|
356
|
-
| `currentChar` | `string` | 当前已打字的字符 | - |
|
|
357
|
-
| `answerType` | `AnswerType` | 内容类型 (thinking/answer) | - |
|
|
358
|
-
| `prevStr` | `string` | 当前类型内容的前缀字符串 | - |
|
|
359
|
-
| `currentStr` | `string` | 当前类型内容的完整字符串 | - |
|
|
360
|
-
| `percent` | `number` | 打字进度百分比 (0-100) | `0` |
|
|
361
|
-
|
|
362
|
-
#### IntervalConfig 🆕
|
|
363
|
-
|
|
364
|
-
| 属性 | 类型 | 说明 | 默认值 |
|
|
365
|
-
| --------- | ---------------------------------------------------------------------------------------------------------- | -------------------------------------- | -------- |
|
|
366
|
-
| `max` | `number` | 最大间隔时间 (毫秒),剩余字符多时使用 | - |
|
|
367
|
-
| `min` | `number` | 最小间隔时间 (毫秒),剩余字符少时使用 | - |
|
|
368
|
-
| `curveFn` | `(x: number) => number` | 自定义曲线函数,x 为剩余字符占比 [0,1] | - |
|
|
369
|
-
| `curve` | `'ease'` \| `'ease-in'` \| `'ease-out'` \| `'ease-in-out'` \| `'linear'` \| `'step-start'` \| `'step-end'` | 预设曲线函数,curveFn 存在时无效 | `'ease'` |
|
|
370
|
-
|
|
371
|
-
**动态速度控制说明:**
|
|
372
|
-
|
|
373
|
-
- **剩余字符越多,打字越快**:当后端流式推送大量字符时,组件会自动加快打字速度
|
|
374
|
-
- **剩余字符越少,打字越慢**:接近完成时,打字速度会逐渐放缓,提供更好的阅读体验
|
|
375
|
-
- **流式数据适配**:自动适应流式场景中字符数量的动态变化
|
|
376
|
-
- **曲线函数**:通过 `curve` 或 `curveFn` 控制速度变化曲线
|
|
377
|
-
|
|
378
|
-
**使用示例:**
|
|
379
|
-
|
|
380
|
-
```tsx
|
|
381
|
-
// 固定间隔
|
|
382
|
-
<DsMarkdown interval={20}>内容</DsMarkdown>
|
|
383
|
-
|
|
384
|
-
// 动态速度控制
|
|
385
|
-
<DsMarkdown
|
|
386
|
-
interval={{
|
|
387
|
-
min: 10, // 最快 10ms
|
|
388
|
-
max: 50, // 最慢 50ms
|
|
389
|
-
curve: 'ease-out' // 减速曲线
|
|
390
|
-
}}
|
|
391
|
-
>
|
|
392
|
-
内容
|
|
393
|
-
</DsMarkdown>
|
|
394
|
-
|
|
395
|
-
// 自定义曲线
|
|
396
|
-
<DsMarkdown
|
|
397
|
-
interval={{
|
|
398
|
-
min: 5,
|
|
399
|
-
max: 100,
|
|
400
|
-
curveFn: (x) => x * x // 二次函数曲线
|
|
401
|
-
}}
|
|
402
|
-
>
|
|
403
|
-
内容
|
|
404
|
-
</DsMarkdown>
|
|
405
|
-
```
|
|
406
|
-
|
|
407
|
-
#### IMarkdownMath
|
|
408
|
-
|
|
409
|
-
| 属性 | 类型 | 说明 | 默认值 |
|
|
410
|
-
| ------------- | ------------------------- | ------------------ | ---------- |
|
|
411
|
-
| `splitSymbol` | `'dollar'` \| `'bracket'` | 数学公式分隔符类型 | `'dollar'` |
|
|
412
|
-
|
|
413
|
-
**分隔符说明:**
|
|
414
|
-
|
|
415
|
-
- `'dollar'`:使用 `$...$` 和 `$$...$$` 语法
|
|
416
|
-
- `'bracket'`:使用 `\(...\)` 和 `\[...\]` 语法
|
|
417
|
-
|
|
418
|
-
#### IMarkdownCode 🆕
|
|
419
|
-
|
|
420
|
-
| 属性 | 类型 | 说明 | 默认值 |
|
|
421
|
-
| --------------- | --------- | -------------------- | ------ |
|
|
422
|
-
| `headerActions` | `boolean` | 是否显示头部操作按钮 | `true` |
|
|
423
|
-
|
|
424
|
-
#### IMarkdownPlugin
|
|
425
|
-
|
|
426
|
-
| 属性 | 类型 | 说明 | 默认值 |
|
|
427
|
-
| -------------- | ---------------------------------------------- | ----------------- | ------ |
|
|
428
|
-
| `remarkPlugin` | `Pluggable` | remark 插件 | - |
|
|
429
|
-
| `rehypePlugin` | `Pluggable` | rehype 插件 | - |
|
|
430
|
-
| `type` | `'buildIn'` \| `'custom'` | 插件类型 | - |
|
|
431
|
-
| `id` | `any` | 插件唯一标识 | - |
|
|
432
|
-
| `components` | `Record<string, React.ComponentType<unknown>>` | 自定义组件映射 🆕 | - |
|
|
433
|
-
|
|
434
|
-
### 组件暴露的方法
|
|
435
|
-
|
|
436
|
-
#### 默认导出 DsMarkdown
|
|
437
|
-
|
|
438
|
-
| 方法 | 参数 | 说明 |
|
|
439
|
-
| --------- | ---- | -------------------------------------- |
|
|
440
|
-
| `start` | - | 开始打字动画 |
|
|
441
|
-
| `stop` | - | 暂停打字动画 |
|
|
442
|
-
| `resume` | - | 恢复打字动画 |
|
|
443
|
-
| `restart` | - | 重新开始打字动画,从头开始播放当前内容 |
|
|
444
|
-
|
|
445
|
-
#### MarkdownCMD 暴露的方法
|
|
446
|
-
|
|
447
|
-
| 方法 | 参数 | 说明 |
|
|
448
|
-
| ----------------- | ------------------------------------------- | -------------------------------------- |
|
|
449
|
-
| `push` | `(content: string, answerType: AnswerType)` | 添加内容并开始打字 |
|
|
450
|
-
| `clear` | - | 清空所有内容和状态 |
|
|
451
|
-
| `triggerWholeEnd` | - | 手动触发完成回调 |
|
|
452
|
-
| `start` | - | 开始打字动画 |
|
|
453
|
-
| `stop` | - | 暂停打字动画 |
|
|
454
|
-
| `resume` | - | 恢复打字动画 |
|
|
455
|
-
| `restart` | - | 重新开始打字动画,从头开始播放当前内容 |
|
|
456
|
-
|
|
457
|
-
**用法示例:**
|
|
458
|
-
|
|
459
|
-
```tsx
|
|
460
|
-
markdownRef.current?.start(); // 开始动画
|
|
461
|
-
markdownRef.current?.stop(); // 暂停动画
|
|
462
|
-
markdownRef.current?.resume(); // 恢复动画
|
|
463
|
-
markdownRef.current?.restart(); // 重新开始动画
|
|
464
|
-
```
|
|
465
|
-
|
|
466
|
-
---
|
|
467
|
-
|
|
468
|
-
## 🔌 插件系统
|
|
469
|
-
|
|
470
|
-
### 内置插件
|
|
471
|
-
|
|
472
|
-
#### KaTeX 数学公式插件
|
|
473
|
-
|
|
474
|
-
[DEMO](https://stackblitz.com/edit/vitejs-vite-iqbyta3j?file=index.html)
|
|
475
|
-
|
|
476
|
-
```tsx
|
|
477
|
-
import { katexPlugin } from 'ds-markdown/plugins';
|
|
478
|
-
|
|
479
|
-
// 启用数学公式支持
|
|
480
|
-
<DsMarkdown plugins={[katexPlugin]}>数学公式:$E = mc^2$</DsMarkdown>;
|
|
481
|
-
```
|
|
482
|
-
|
|
483
|
-
#### Mermaid 图表插件 🆕
|
|
484
|
-
|
|
485
|
-
**安装 Mermaid 插件:**
|
|
486
|
-
|
|
487
|
-
```bash
|
|
488
|
-
npm install ds-markdown-mermaid-plugin
|
|
489
|
-
```
|
|
490
|
-
|
|
491
|
-
**基础用法:**
|
|
492
|
-
|
|
493
|
-
```tsx
|
|
494
|
-
import { ConfigProvider, Markdown } from 'ds-markdown';
|
|
495
|
-
import mermaidPlugin from 'ds-markdown-mermaid-plugin';
|
|
122
|
+
详细文档可查看:[完整文档](https://onshinpei.github.io/ds-markdown/#get-started)
|
|
496
123
|
|
|
497
|
-
|
|
498
|
-
const content = `
|
|
499
|
-
# 流程图示例
|
|
500
|
-
|
|
501
|
-
\`\`\`mermaid
|
|
502
|
-
flowchart TD
|
|
503
|
-
A[开始] --> B{判断条件}
|
|
504
|
-
B -->|是| C[处理A]
|
|
505
|
-
B -->|否| D[处理B]
|
|
506
|
-
C --> E[结束]
|
|
507
|
-
D --> E
|
|
508
|
-
\`\`\`
|
|
509
|
-
`;
|
|
124
|
+
## 相关项目
|
|
510
125
|
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
<Markdown plugins={[mermaidPlugin]}>{content}</Markdown>
|
|
514
|
-
</ConfigProvider>
|
|
515
|
-
);
|
|
516
|
-
}
|
|
517
|
-
```
|
|
518
|
-
|
|
519
|
-
**支持的图表类型:**
|
|
126
|
+
- **[react-markdown-typer](https://github.com/onshinpei/react-markdown-typer)** - 如果你需要一个轻量级的 markdown 打字组件
|
|
127
|
+
- **[ds-markdown-mermaid-plugin](https://github.com/onshinpei/ds-markdown-mermaid-plugin)** - Mermaid 图表支持插件
|
|
520
128
|
|
|
521
|
-
|
|
522
|
-
- 📋 **序列图** (Sequence Diagram) - 展示对象间的交互时序
|
|
523
|
-
- 📅 **甘特图** (Gantt Chart) - 项目计划和时间线
|
|
524
|
-
- 🏗️ **类图** (Class Diagram) - 面向对象设计
|
|
525
|
-
- 🥧 **饼图** (Pie Chart) - 数据比例展示
|
|
526
|
-
- 🔀 **状态图** (State Diagram) - 状态转换流程
|
|
527
|
-
- 📊 **Git图** (Git Graph) - 代码分支历史
|
|
528
|
-
- 🗺️ **用户旅程图** (User Journey) - 用户体验流程
|
|
129
|
+
## 许可证
|
|
529
130
|
|
|
530
|
-
|
|
131
|
+
MIT © [onshinpei](https://github.com/onshinpei)
|
|
531
132
|
|
|
532
|
-
|
|
533
|
-
import { ConfigProvider } from 'ds-markdown';
|
|
534
|
-
|
|
535
|
-
const mermaidConfig = {
|
|
536
|
-
theme: 'default', // 主题:default, neutral, dark, forest
|
|
537
|
-
flowchart: {
|
|
538
|
-
useMaxWidth: true,
|
|
539
|
-
htmlLabels: true,
|
|
540
|
-
},
|
|
541
|
-
sequence: {
|
|
542
|
-
diagramMarginX: 50,
|
|
543
|
-
diagramMarginY: 10,
|
|
544
|
-
},
|
|
545
|
-
};
|
|
546
|
-
|
|
547
|
-
return (
|
|
548
|
-
<ConfigProvider mermaidConfig={mermaidConfig}>
|
|
549
|
-
<Markdown plugins={[mermaidPlugin]}>{chartContent}</Markdown>
|
|
550
|
-
</ConfigProvider>
|
|
551
|
-
);
|
|
552
|
-
```
|
|
553
|
-
|
|
554
|
-
**相关链接:**
|
|
555
|
-
|
|
556
|
-
- [ds-markdown-mermaid-plugin GitHub](https://github.com/onshinpei/ds-markdown-mermaid-plugin)
|
|
557
|
-
- [Mermaid 官方文档](https://mermaid.js.org/)
|
|
558
|
-
|
|
559
|
-
### 自定义插件
|
|
560
|
-
|
|
561
|
-
```tsx
|
|
562
|
-
import { createBuildInPlugin } from 'ds-markdown/plugins';
|
|
563
|
-
|
|
564
|
-
// 创建自定义插件
|
|
565
|
-
const customPlugin = createBuildInPlugin({
|
|
566
|
-
remarkPlugin: yourRemarkPlugin,
|
|
567
|
-
rehypePlugin: yourRehypePlugin,
|
|
568
|
-
id: Symbol('custom-plugin'),
|
|
569
|
-
components: {
|
|
570
|
-
// 自定义组件映射 🆕
|
|
571
|
-
CustomComponent: MyCustomComponent,
|
|
572
|
-
},
|
|
573
|
-
});
|
|
574
|
-
|
|
575
|
-
// 使用自定义插件
|
|
576
|
-
<DsMarkdown plugins={[katexPlugin, customPlugin]}>内容</DsMarkdown>;
|
|
577
|
-
```
|
|
578
|
-
|
|
579
|
-
---
|
|
580
|
-
|
|
581
|
-
## 🎨 UI组件系统 🆕
|
|
582
|
-
|
|
583
|
-
ds-markdown 提供了丰富的UI组件,可以单独使用或与markdown组件配合。
|
|
584
|
-
|
|
585
|
-
### 核心组件
|
|
586
|
-
|
|
587
|
-
```tsx
|
|
588
|
-
import {
|
|
589
|
-
Button,
|
|
590
|
-
IconButton,
|
|
591
|
-
ToolTip,
|
|
592
|
-
Segmented,
|
|
593
|
-
CopyButton,
|
|
594
|
-
DownloadButton
|
|
595
|
-
} from 'ds-markdown';
|
|
596
|
-
|
|
597
|
-
// 按钮组件
|
|
598
|
-
<Button icon={<span>📄</span>} onClick={() => {}}>
|
|
599
|
-
点击按钮
|
|
600
|
-
</Button>
|
|
601
|
-
|
|
602
|
-
// 工具提示
|
|
603
|
-
<ToolTip title="提示信息">
|
|
604
|
-
<IconButton icon={<span>📋</span>} onClick={() => {}} />
|
|
605
|
-
</ToolTip>
|
|
606
|
-
|
|
607
|
-
// 分段控制器
|
|
608
|
-
<Segmented
|
|
609
|
-
Segmented={[
|
|
610
|
-
{ label: '图表', value: 'diagram' },
|
|
611
|
-
{ label: '代码', value: 'code' }
|
|
612
|
-
]}
|
|
613
|
-
value={value}
|
|
614
|
-
onChange={setValue}
|
|
615
|
-
/>
|
|
616
|
-
|
|
617
|
-
// 代码块操作
|
|
618
|
-
<CopyButton codeContent="console.log('Hello')" />
|
|
619
|
-
<DownloadButton codeContent="console.log('Hello')" language="javascript" />
|
|
620
|
-
```
|
|
621
|
-
|
|
622
|
-
### 样式定制
|
|
623
|
-
|
|
624
|
-
```css
|
|
625
|
-
:root {
|
|
626
|
-
--ds-button-bg-color: #f5f5f5;
|
|
627
|
-
--ds-button-hover-color: #e0e0e0;
|
|
628
|
-
--ds-tooltip-bg-color: rgba(0, 0, 0, 0.8);
|
|
629
|
-
}
|
|
630
|
-
```
|
|
631
|
-
|
|
632
|
-
---
|
|
633
|
-
|
|
634
|
-
## 多语言配置
|
|
635
|
-
|
|
636
|
-
```tsx
|
|
637
|
-
import { ConfigProvider } from 'ds-markdown';
|
|
638
|
-
import zhCN from 'ds-markdown/i18n/zh';
|
|
639
|
-
import enUS from 'ds-markdown/i18n/en';
|
|
640
|
-
|
|
641
|
-
// 中文
|
|
642
|
-
<ConfigProvider locale={zhCN}>
|
|
643
|
-
<DsMarkdown {...props} />
|
|
644
|
-
</ConfigProvider>
|
|
645
|
-
|
|
646
|
-
// 英文
|
|
647
|
-
<ConfigProvider locale={enUS}>
|
|
648
|
-
<DsMarkdown {...props} />
|
|
649
|
-
</ConfigProvider>
|
|
650
|
-
```
|
|
133
|
+
## 贡献
|
|
651
134
|
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
## 📚 ConfigProvider API
|
|
655
|
-
|
|
656
|
-
`ConfigProvider` 是一个全局配置提供者,用于为 ds-markdown 组件提供多语言、Mermaid 图表和 KaTeX 数学公式的配置。
|
|
657
|
-
|
|
658
|
-
### Props 类型
|
|
659
|
-
|
|
660
|
-
```tsx
|
|
661
|
-
interface ConfigProviderProps {
|
|
662
|
-
locale?: Locale; // 语言包配置
|
|
663
|
-
mermaidConfig?: IMarkdownMermaidConfig; // Mermaid 图表配置
|
|
664
|
-
katexConfig?: IMarkdownKatexConfig; // KaTeX 数学公式配置
|
|
665
|
-
children: React.ReactNode; // 子组件
|
|
666
|
-
}
|
|
667
|
-
```
|
|
668
|
-
|
|
669
|
-
### 配置选项详解
|
|
670
|
-
|
|
671
|
-
#### 1. 多语言配置 (locale)
|
|
672
|
-
|
|
673
|
-
```tsx
|
|
674
|
-
import { ConfigProvider } from 'ds-markdown';
|
|
675
|
-
import zhCN from 'ds-markdown/i18n/zh';
|
|
676
|
-
import enUS from 'ds-markdown/i18n/en';
|
|
677
|
-
|
|
678
|
-
<ConfigProvider locale={zhCN}>
|
|
679
|
-
<DsMarkdown {...props} />
|
|
680
|
-
</ConfigProvider>;
|
|
681
|
-
```
|
|
682
|
-
|
|
683
|
-
#### 2. Mermaid 图表配置 (mermaidConfig)
|
|
684
|
-
|
|
685
|
-
```tsx
|
|
686
|
-
const mermaidConfig = {
|
|
687
|
-
theme: 'dark', // 主题:'default' | 'forest' | 'dark' | 'neutral'
|
|
688
|
-
fontFamily: 'Arial', // 字体
|
|
689
|
-
logLevel: 'warn', // 日志级别
|
|
690
|
-
securityLevel: 'strict', // 安全级别
|
|
691
|
-
startOnLoad: true, // 页面加载时自动启动
|
|
692
|
-
// ... 更多 Mermaid 配置选项
|
|
693
|
-
};
|
|
694
|
-
|
|
695
|
-
<ConfigProvider mermaidConfig={mermaidConfig}>
|
|
696
|
-
<DsMarkdown {...props} />
|
|
697
|
-
</ConfigProvider>;
|
|
698
|
-
```
|
|
699
|
-
|
|
700
|
-
#### 3. KaTeX 数学公式配置 (katexConfig)
|
|
701
|
-
|
|
702
|
-
```tsx
|
|
703
|
-
const katexConfig = {
|
|
704
|
-
throwOnError: false, // 错误时不抛出异常
|
|
705
|
-
errorColor: '#cc0000', // 错误颜色
|
|
706
|
-
macros: {
|
|
707
|
-
// 自定义宏
|
|
708
|
-
'\\RR': '\\mathbb{R}',
|
|
709
|
-
'\\NN': '\\mathbb{N}',
|
|
710
|
-
},
|
|
711
|
-
minRuleThickness: 0.05, // 最小规则厚度
|
|
712
|
-
colorIsTextColor: false, // 颜色是否为文本颜色
|
|
713
|
-
// ... 更多 KaTeX 配置选项
|
|
714
|
-
};
|
|
715
|
-
|
|
716
|
-
<ConfigProvider katexConfig={katexConfig}>
|
|
717
|
-
<DsMarkdown {...props} />
|
|
718
|
-
</ConfigProvider>;
|
|
719
|
-
```
|
|
720
|
-
|
|
721
|
-
### 使用 Hooks
|
|
722
|
-
|
|
723
|
-
#### useConfig
|
|
724
|
-
|
|
725
|
-
获取完整的配置上下文:
|
|
726
|
-
|
|
727
|
-
```tsx
|
|
728
|
-
import { useConfig } from 'ds-markdown';
|
|
729
|
-
|
|
730
|
-
function MyComponent() {
|
|
731
|
-
const { locale, mermaidConfig, katexConfig } = useConfig();
|
|
732
|
-
|
|
733
|
-
return (
|
|
734
|
-
<div>
|
|
735
|
-
<p>当前语言: {locale.language}</p>
|
|
736
|
-
<p>Mermaid 主题: {mermaidConfig?.theme}</p>
|
|
737
|
-
</div>
|
|
738
|
-
);
|
|
739
|
-
}
|
|
740
|
-
```
|
|
741
|
-
|
|
742
|
-
#### useLocale
|
|
743
|
-
|
|
744
|
-
仅获取语言包配置:
|
|
745
|
-
|
|
746
|
-
```tsx
|
|
747
|
-
import { useLocale } from 'ds-markdown';
|
|
748
|
-
|
|
749
|
-
function MyComponent() {
|
|
750
|
-
const locale = useLocale();
|
|
751
|
-
|
|
752
|
-
return (
|
|
753
|
-
<div>
|
|
754
|
-
<p>当前语言: {locale.language}</p>
|
|
755
|
-
<p>复制按钮文本: {locale.copyButton}</p>
|
|
756
|
-
</div>
|
|
757
|
-
);
|
|
758
|
-
}
|
|
759
|
-
```
|
|
760
|
-
|
|
761
|
-
### 完整配置示例
|
|
762
|
-
|
|
763
|
-
```tsx
|
|
764
|
-
import { ConfigProvider } from 'ds-markdown';
|
|
765
|
-
import zhCN from 'ds-markdown/i18n/zh';
|
|
766
|
-
|
|
767
|
-
const mermaidConfig = {
|
|
768
|
-
theme: 'dark',
|
|
769
|
-
fontFamily: 'Consolas, monospace',
|
|
770
|
-
logLevel: 'warn',
|
|
771
|
-
};
|
|
772
|
-
|
|
773
|
-
const katexConfig = {
|
|
774
|
-
throwOnError: false,
|
|
775
|
-
errorColor: '#cc0000',
|
|
776
|
-
macros: {
|
|
777
|
-
'\\RR': '\\mathbb{R}',
|
|
778
|
-
},
|
|
779
|
-
};
|
|
780
|
-
|
|
781
|
-
function App() {
|
|
782
|
-
return (
|
|
783
|
-
<ConfigProvider locale={zhCN} mermaidConfig={mermaidConfig} katexConfig={katexConfig}>
|
|
784
|
-
<DsMarkdown content="# Hello World" />
|
|
785
|
-
</ConfigProvider>
|
|
786
|
-
);
|
|
787
|
-
}
|
|
788
|
-
```
|
|
789
|
-
|
|
790
|
-
---
|
|
791
|
-
|
|
792
|
-
## 💡 实战示例
|
|
793
|
-
|
|
794
|
-
### 🚀 动态速度控制 🆕
|
|
795
|
-
|
|
796
|
-
```tsx
|
|
797
|
-
import DsMarkdown from 'ds-markdown';
|
|
798
|
-
|
|
799
|
-
function DynamicSpeedDemo() {
|
|
800
|
-
const content = `# 动态速度控制示例
|
|
801
|
-
|
|
802
|
-
这是一个演示动态速度控制的示例。当剩余字符较多时,打字速度会加快;
|
|
803
|
-
当剩余字符较少时,打字速度会放缓,提供更好的阅读体验。
|
|
804
|
-
|
|
805
|
-
## 流式数据场景
|
|
806
|
-
|
|
807
|
-
在 AI 流式对话中,后端可能会一次性推送大量文本,使用动态速度控制可以:
|
|
808
|
-
- 快速处理大量文本,减少等待时间
|
|
809
|
-
- 在接近完成时放缓速度,让用户有时间阅读
|
|
810
|
-
- 提供更自然的打字体验`;
|
|
811
|
-
|
|
812
|
-
return (
|
|
813
|
-
<DsMarkdown
|
|
814
|
-
interval={{
|
|
815
|
-
min: 8, // 最快 8ms(剩余字符多时)
|
|
816
|
-
max: 80, // 最慢 80ms(剩余字符少时)
|
|
817
|
-
curve: 'ease-out', // 减速曲线
|
|
818
|
-
}}
|
|
819
|
-
timerType="requestAnimationFrame"
|
|
820
|
-
>
|
|
821
|
-
{content}
|
|
822
|
-
</DsMarkdown>
|
|
823
|
-
);
|
|
824
|
-
}
|
|
825
|
-
```
|
|
826
|
-
|
|
827
|
-
### 📝 AI 流式对话
|
|
828
|
-
|
|
829
|
-
[DEMO: 🔧 StackBlitz 体验](https://stackblitz.com/edit/vitejs-vite-2ri8kex3?file=src%2FApp.tsx)
|
|
830
|
-
|
|
831
|
-
```tsx
|
|
832
|
-
import { useRef } from 'react';
|
|
833
|
-
import { MarkdownCMD, MarkdownCMDRef } from 'ds-markdown';
|
|
834
|
-
|
|
835
|
-
function StreamingChat() {
|
|
836
|
-
const markdownRef = useRef<MarkdownCMDRef>(null);
|
|
837
|
-
const answerRef = useRef<MarkdownCMDRef>(null);
|
|
838
|
-
const [isShowAnswer, setIsShowAnswer] = useState(false);
|
|
839
|
-
|
|
840
|
-
// 模拟 AI 流式响应
|
|
841
|
-
const simulateAIResponse = async () => {
|
|
842
|
-
markdownRef.current?.clear();
|
|
843
|
-
answerRef.current?.clear();
|
|
844
|
-
|
|
845
|
-
// 思考阶段
|
|
846
|
-
markdownRef.current?.push('🤔 正在分析您的问题...', 'thinking');
|
|
847
|
-
await delay(1000);
|
|
848
|
-
markdownRef.current?.push('\n\n✅ 分析完成,开始回答', 'thinking');
|
|
849
|
-
setIsShowAnswer(true);
|
|
850
|
-
// 流式回答
|
|
851
|
-
const chunks = [
|
|
852
|
-
'# React 19 新特性解析\n\n',
|
|
853
|
-
'## 🚀 React Compiler\n',
|
|
854
|
-
'React 19 最大的亮点是引入了 **React Compiler**:\n\n',
|
|
855
|
-
'- 🎯 **自动优化**:无需手动 memo 和 useMemo\n',
|
|
856
|
-
'- ⚡ **性能提升**:编译时优化,运行时零开销\n',
|
|
857
|
-
'- 🔧 **向后兼容**:现有代码无需修改\n\n',
|
|
858
|
-
'希望这个解答对您有帮助!🎉',
|
|
859
|
-
];
|
|
860
|
-
|
|
861
|
-
for (const chunk of chunks) {
|
|
862
|
-
await delay(100);
|
|
863
|
-
answerRef.current?.push(chunk, 'answer');
|
|
864
|
-
}
|
|
865
|
-
};
|
|
866
|
-
|
|
867
|
-
const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
868
|
-
|
|
869
|
-
return (
|
|
870
|
-
<div className="chat-container">
|
|
871
|
-
<button onClick={simulateAIResponse}>🤖 询问 React 19 新特性</button>
|
|
872
|
-
<MarkdownCMD answerType="thinking" ref={markdownRef} interval={10} timerType="requestAnimationFrame" />
|
|
873
|
-
{isShowAnswer && <MarkdownCMD answerType="answer" ref={answerRef} interval={10} timerType="requestAnimationFrame" />}
|
|
874
|
-
</div>
|
|
875
|
-
);
|
|
876
|
-
}
|
|
877
|
-
```
|
|
878
|
-
|
|
879
|
-
## 🔧 最佳实践
|
|
880
|
-
|
|
881
|
-
### 1. 性能优化
|
|
882
|
-
|
|
883
|
-
```tsx
|
|
884
|
-
// ✅ 推荐配置
|
|
885
|
-
<DsMarkdown
|
|
886
|
-
timerType="requestAnimationFrame"
|
|
887
|
-
interval={15} // 15-30ms 为最佳体验
|
|
888
|
-
/>
|
|
889
|
-
|
|
890
|
-
// ✅ 流式数据推荐配置
|
|
891
|
-
<DsMarkdown
|
|
892
|
-
timerType="requestAnimationFrame"
|
|
893
|
-
interval={{
|
|
894
|
-
min: 8, // 快速处理大量文本
|
|
895
|
-
max: 60, // 接近完成时放缓
|
|
896
|
-
curve: 'ease-out' // 自然减速
|
|
897
|
-
}}
|
|
898
|
-
/>
|
|
899
|
-
```
|
|
900
|
-
|
|
901
|
-
### 2. 流式数据处理
|
|
902
|
-
|
|
903
|
-
```tsx
|
|
904
|
-
// ✅ 推荐:命令式 API
|
|
905
|
-
const ref = useRef<MarkdownCMDRef>(null);
|
|
906
|
-
useEffect(() => {
|
|
907
|
-
ref.current?.push(newChunk);
|
|
908
|
-
}, [newChunk]);
|
|
909
|
-
```
|
|
910
|
-
|
|
911
|
-
### 3. 数学公式优化
|
|
912
|
-
|
|
913
|
-
```tsx
|
|
914
|
-
// ✅ 推荐:按需加载
|
|
915
|
-
import { katexPlugin } from 'ds-markdown/plugins';
|
|
916
|
-
import 'ds-markdown/katex.css'; // 仅在需要时引入
|
|
917
|
-
|
|
918
|
-
<DsMarkdown plugins={[katexPlugin]}>数学公式内容</DsMarkdown>;
|
|
919
|
-
```
|
|
920
|
-
|
|
921
|
-
### 4. Mermaid图表最佳实践 🆕
|
|
922
|
-
|
|
923
|
-
```tsx
|
|
924
|
-
// ✅ 推荐:独立安装插件
|
|
925
|
-
npm install ds-markdown-mermaid-plugin
|
|
926
|
-
|
|
927
|
-
// ✅ 推荐:配置适合的主题
|
|
928
|
-
const mermaidConfig = {
|
|
929
|
-
theme: 'default', // 根据应用主题选择
|
|
930
|
-
flowchart: { useMaxWidth: true },
|
|
931
|
-
};
|
|
932
|
-
|
|
933
|
-
<ConfigProvider mermaidConfig={mermaidConfig}>
|
|
934
|
-
<DsMarkdown plugins={[mermaidPlugin]} />
|
|
935
|
-
</ConfigProvider>
|
|
936
|
-
```
|
|
135
|
+
欢迎贡献、提问和功能请求!
|
|
937
136
|
|
|
938
137
|
[](https://visitorbadge.io/status?path=https%3A%2F%2Fgithub.com%2Fonshinpei%2Fds-markdown)
|