ds-markdown 0.0.10-beta.4 → 0.0.11-beta.0

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 CHANGED
@@ -1,36 +1,105 @@
1
1
  # ds-markdown
2
2
 
3
- > 🚀 一个高性能的 React Markdown 打字动画组件,完美复刻 DeepSeek 聊天界面效果
3
+ > 🚀 高性能 React Markdown 打字动画组件,完美复刻 DeepSeek 聊天界面效果
4
4
 
5
- `ds-markdown` 是一个专为现代 Web 应用设计的 React 组件,提供流畅的打字动画效果和完整的 Markdown 渲染能力。
5
+ **🇨🇳 中文 | [🇺🇸 English](./README.en.md) | [🇯🇵 日本語](./README.ja.md) | [🇰🇷 한국어](./README.ko.md)**
6
+
7
+ 一个专为现代 AI 应用设计的 React 组件,提供流畅的实时打字动画和完整的 Markdown 渲染能力。
6
8
 
7
9
  [![npm version](https://img.shields.io/npm/v/ds-markdown)](https://www.npmjs.com/package/ds-markdown)
8
10
  [![npm downloads](https://img.shields.io/npm/dm/ds-markdown.svg)](https://www.npmjs.com/package/ds-markdown)
9
11
  [![bundle size](https://img.shields.io/bundlephobia/minzip/ds-markdown)](https://bundlephobia.com/package/ds-markdown)
10
12
  [![React](https://img.shields.io/badge/React-16.8+-blue)](https://react.dev)
13
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue)](https://www.typescriptlang.org/)
11
14
 
12
15
  [📖 在线演示](https://onshinpei.github.io/ds-markdown/) | [🔧 StackBlitz 体验](https://stackblitz.com/edit/vitejs-vite-ddfw8avb?file=src%2FApp.tsx)
13
16
 
14
- ## ✨ 特性
17
+ ---
18
+
19
+ ## ✨ 核心特性
20
+
21
+ ### 🎯 **完美还原**
22
+
23
+ - 1:1 复刻 [DeepSeek 官网](https://chat.deepseek.com/) 聊天响应效果
24
+ - 支持思考过程 (`thinking`) 和回答内容 (`answer`) 双模式
25
+ - 原生 Markdown 语法支持,包括代码高亮、表格、列表等
26
+
27
+ ### ⚡ **极致性能**
28
+
29
+ - 智能分批处理,大文档渲染零卡顿
30
+ - 双模式定时器:`requestAnimationFrame` + `setTimeout`
31
+ - 内置流式语法缓冲,避免不完整 Markdown 渲染错误
15
32
 
16
- - 🎯 **1:1 还原** - 完美复刻 [DeepSeek 官网](https://chat.deepseek.com/) 聊天响应效果
17
- - ⚡ **高性能** - 智能分批处理,大文档渲染无卡顿
18
- - 🎬 **流畅动画** - 双模式定时器,支持高频打字效果
19
- - 🎨 **完整渲染** - 内置常用 Markdown 格式支持
20
- - 🔧 **灵活配置** - 声明式 + 命令式双重 API 设计
21
- - 📱 **现代兼容** - 支持 React 16.8+ 和现代浏览器
33
+ ### 🎬 **流畅动画**
22
34
 
23
- ## 📦 安装
35
+ - 高频打字支持(`requestAnimationFrame`模式下打字间隔最低可接近于`0ms`)
36
+ - 帧同步渲染,与浏览器 60fps 完美配合
37
+ - 智能字符批量处理,视觉效果更自然
38
+
39
+ ### 🔧 **灵活易用**
40
+
41
+ - **声明式 API**:适合简单场景,React 风格
42
+ - **命令式 API**:适合流式数据,性能更优
43
+ - **TypeScript 原生支持**:完整类型提示
44
+
45
+ ---
46
+
47
+ ## 📦 快速安装
24
48
 
25
49
  ```bash
50
+ # npm
26
51
  npm install ds-markdown
27
- # or
52
+
53
+ # yarn
28
54
  yarn add ds-markdown
29
- # or
55
+
56
+ # pnpm
30
57
  pnpm add ds-markdown
31
58
  ```
32
59
 
33
- ## 🚀 快速开始
60
+ ### 通过 ESM CDN 使用
61
+
62
+ 无需安装,直接在浏览器中使用:
63
+
64
+ ```html
65
+ <!-- 引入样式 -->
66
+ <link rel="stylesheet" href="https://esm.sh/ds-markdown/style.css" />
67
+
68
+ <!-- 引入组件 -->
69
+ <script type="importmap">
70
+ {
71
+ "imports": {
72
+ "react": "https://esm.sh/react@19.1.0",
73
+ "react-dom/client": "https://esm.sh/react-dom@19.1.0/client",
74
+ "ds-markdown": "https://esm.sh/ds-markdown@0.0.10"
75
+ }
76
+ }
77
+ </script>
78
+ <script type="module" src="https://esm.sh/tsx"></script>
79
+
80
+ <script type="text/babel">
81
+ import { createRoot } from 'react-dom/client';
82
+ import DsMarkdown from 'ds-markdown';
83
+
84
+ const markdown = `
85
+ # Hello ds-markdown
86
+
87
+ 这是一个**高性能**的打字动画组件!
88
+
89
+ ## 特性
90
+ - ⚡ 零延迟流式处理
91
+ - 🎬 流畅打字动画
92
+ - 🎯 完美语法支持
93
+ `;
94
+
95
+ const root = createRoot(document.getElementById('root'));
96
+ root.render(<DsMarkdown interval={20}>{markdown}</DsMarkdown>);
97
+ </script>
98
+ ```
99
+
100
+ ## 🚀 5分钟上手
101
+
102
+ ### 基础用法
34
103
 
35
104
  ```tsx
36
105
  import DsMarkdown from 'ds-markdown';
@@ -38,59 +107,128 @@ import 'ds-markdown/style.css';
38
107
 
39
108
  function App() {
40
109
  return (
41
- <DsMarkdown timerType="requestAnimationFrame" interval={20} answerType="answer">
42
- # Hello World 这是一个**打字动画**示例!
110
+ <DsMarkdown interval={20} answerType="answer">
111
+ # Hello ds-markdown 这是一个**高性能**的打字动画组件! ## 特性 - ⚡ 零延迟流式处理 - 🎬 流畅打字动画 - 🎯 完美语法支持
43
112
  </DsMarkdown>
44
113
  );
45
114
  }
46
115
  ```
47
116
 
48
- ## 📚 API 文档
117
+ ### AI 对话场景
49
118
 
50
- ### 默认导出 (声明式 API)
119
+ ```tsx
120
+ function ChatDemo() {
121
+ const [thinking, setThinking] = useState('');
122
+ const [answer, setAnswer] = useState('');
123
+
124
+ const handleAsk = () => {
125
+ setThinking('🤔 正在思考您的问题...');
126
+
127
+ setTimeout(() => {
128
+ setAnswer(`# 关于 React 19
129
+
130
+ React 19 带来了许多激动人心的新特性:
131
+
132
+ ## 🚀 主要更新
133
+ 1. **React Compiler** - 自动优化性能
134
+ 2. **Actions** - 简化表单处理
135
+ 3. **Document Metadata** - 内置 SEO 支持
136
+
137
+ 让我们一起探索这些新功能!`);
138
+ }, 2000);
139
+ };
140
+
141
+ return (
142
+ <div>
143
+ <button onClick={handleAsk}>询问 AI</button>
144
+
145
+ {thinking && (
146
+ <DsMarkdown answerType="thinking" interval={30}>
147
+ {thinking}
148
+ </DsMarkdown>
149
+ )}
51
150
 
52
- | 属性名 | 类型 | 说明 | 默认值 |
53
- | ------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------- | ------------------------- |
54
- | `interval` | `number` | 打字间隔时间 (毫秒) | `30` |
55
- | `timerType` | `'setTimeout'` \| `'requestAnimationFrame'` | 定时器类型,详见下方说明 | `'requestAnimationFrame'` |
56
- | `answerType` | `'thinking'` \| `'answer'` | 内容类型,影响样式主题 | `'answer'` |
57
- | `onEnd` | `(data: { str: string; answerType: AnswerType }) => void` | 打字结束回调 **(可能触发多次)** | - |
58
- | `onStart` | `(data: { currentIndex: number; currentChar: string; answerType: AnswerType; prevStr: string }) => void` | 打字开始回调 **(可能触发多次)** | - |
59
- | `onTypedChar` | `(data: { currentIndex: number; currentChar: string; answerType: AnswerType; prevStr: string }) => void` | 每个字符打字回调 | - |
151
+ {answer && (
152
+ <DsMarkdown answerType="answer" interval={15}>
153
+ {answer}
154
+ </DsMarkdown>
155
+ )}
156
+ </div>
157
+ );
158
+ }
159
+ ```
60
160
 
61
- #### 🎛️ timerType 模式详解
161
+ ---
62
162
 
63
- ##### `requestAnimationFrame` 模式 (推荐) 🌟
163
+ ## 📚 完整 API 文档
164
+
165
+ ### 声明式 API (推荐新手)
166
+
167
+ | 属性 | 类型 | 说明 | 默认值 |
168
+ | ------------- | ------------------------------------------- | ----------------------- | ----------------------------------------------------------- |
169
+ | `interval` | `number` | 打字间隔 (毫秒) | `30` |
170
+ | `timerType` | `'setTimeout'` \| `'requestAnimationFrame'` | 定时器类型 | 当前默认值是`setTimeout`,后期会改为`requestAnimationFrame` |
171
+ | `answerType` | `'thinking'` \| `'answer'` | 内容类型 (影响样式主题) | `'answer'` |
172
+ | `onEnd` | `(data: EndData) => void` | 打字结束回调 | - |
173
+ | `onStart` | `(data: StartData) => void` | 打字开始回调 | - |
174
+ | `onTypedChar` | `(data: CharData) => void` | 每字符打字回调 | - |
175
+
176
+ ### 命令式 API (推荐流式场景)
64
177
 
65
178
  ```typescript
66
- // 特性
67
- - 🎯 时间驱动:基于真实经过时间计算字符数量
68
- - 📊 批量处理:单帧内可处理多个字符
69
- - 🎬 帧同步:与浏览器 60fps 刷新率同步
70
- - ⚡ 高频优化:完美支持 interval < 16ms 的高速打字
179
+ import { MarkdownCMD, MarkdownRef } from 'ds-markdown';
71
180
 
72
- // 适用场景
73
- - 追求流畅动画效果
74
- - 高频打字 (interval: 5-15ms)
181
+ interface MarkdownRef {
182
+ push: (content: string, answerType: AnswerType) => void;
183
+ clear: () => void;
184
+ triggerWholeEnd: () => void;
185
+ flushBuffer: (answerType?: AnswerType) => void;
186
+ }
187
+ ```
188
+
189
+ | 方法 | 参数 | 说明 |
190
+ | ----------------- | ------------------------------------------- | ------------------ |
191
+ | `push` | `(content: string, answerType: AnswerType)` | 添加内容并开始打字 |
192
+ | `clear` | - | 清空所有内容和状态 |
193
+ | `triggerWholeEnd` | - | 手动触发完成回调 |
194
+ | `flushBuffer` | `answerType?: AnswerType` | 强制刷新缓冲区内容 |
195
+
196
+ ---
197
+
198
+ ## 🎛️ 定时器模式详解
199
+
200
+ ### `requestAnimationFrame` 模式 🌟 (推荐)
201
+
202
+ ```typescript
203
+ // 🎯 特性
204
+ - 时间驱动:基于真实经过时间计算字符数量
205
+ - 批量处理:单帧内可处理多个字符
206
+ - 帧同步:与浏览器 60fps 刷新率同步
207
+ - 高频优化:完美支持 interval < 16ms 的高速打字
208
+
209
+ // 🎯 适用场景
75
210
  - 现代 Web 应用的默认选择
211
+ - 追求流畅动画效果
212
+ - 高频打字 (interval > 0 即可)
213
+ - AI 实时对话场景
76
214
  ```
77
215
 
78
- ##### `setTimeout` 模式 (传统) 📟
216
+ ### `setTimeout` 模式 📟 (兼容)
79
217
 
80
218
  ```typescript
81
- // 特性
82
- - 单字符:每次精确处理一个字符
83
- - 🕐 固定间隔:严格按设定时间执行
84
- - 🎵 节拍感:经典打字机的节奏感
85
- - 🎯 精确控制:适合特定时序要求
219
+ // 🎯 特性
220
+ - 单字符:每次精确处理一个字符
221
+ - 固定间隔:严格按设定时间执行
222
+ - 节拍感:经典打字机的节奏感
223
+ - 精确控制:适合特定时序要求
86
224
 
87
- // 适用场景
225
+ // 🎯 适用场景
88
226
  - 需要精确时间控制
89
227
  - 营造复古打字机效果
90
228
  - 兼容性要求较高的场景
91
229
  ```
92
230
 
93
- ##### 📊 性能对比
231
+ ### 📊 性能对比
94
232
 
95
233
  | 特性 | requestAnimationFrame | setTimeout |
96
234
  | ------------ | ---------------------------- | ---------------- |
@@ -100,280 +238,243 @@ function App() {
100
238
  | **视觉效果** | 🎬 流畅动画感 | ⚡ 精确节拍感 |
101
239
  | **性能开销** | 🟢 低 (帧同步) | 🟡 中等 (定时器) |
102
240
 
103
- ## 💡 使用示例
104
-
105
- ### 📝 声明式用法 (推荐)
106
-
107
- ```tsx
108
- import { useState } from 'react';
109
- import DsMarkdown from 'ds-markdown';
110
- import 'ds-markdown/style.css';
111
-
112
- const markdown = `# ds-markdown
113
-
114
- \`ds-markdown\` 是一个高性能的 React Markdown 打字动画组件
115
-
116
- ## ✨ 特性
117
-
118
- - 🎯 **1:1 还原** - 完美复刻 DeepSeek 聊天界面效果
119
- - ⚡ **高性能** - 智能分批处理,大文档渲染无卡顿
120
- - 🎬 **流畅动画** - 双模式定时器,支持高频打字效果
121
- `;
122
-
123
- function App() {
124
- const [thinkingContent, setThinkingContent] = useState('');
125
- const [answerContent, setAnswerContent] = useState('');
126
-
127
- const handleStart = () => {
128
- // 清空之前的内容
129
- setThinkingContent('🤔 正在分析您的问题...\n\n分析完成,准备回答');
130
- };
131
-
132
- return (
133
- <div>
134
- <button onClick={handleStart}>开始演示</button>
135
-
136
- {/* 思考过程 */}
137
- <DsMarkdown
138
- answerType="thinking"
139
- interval={15}
140
- timerType="requestAnimationFrame"
141
- onEnd={() => {
142
- console.log('思考完成');
143
- setAnswerContent(markdown);
144
- }}
145
- >
146
- {thinkingContent}
147
- </DsMarkdown>
148
-
149
- {/* 回答内容 */}
150
- {answerContent && (
151
- <DsMarkdown answerType="answer" interval={10} timerType="requestAnimationFrame">
152
- {answerContent}
153
- </DsMarkdown>
154
- )}
155
- </div>
156
- );
157
- }
158
-
159
- export default App;
160
- ```
241
+ 高频推荐`requestAnimationFrame`,低频推荐 `setTimeout`
161
242
 
162
- [🔗 在线体验](https://stackblitz.com/edit/vitejs-vite-ddfw8avb?file=src%2FApp.tsx)
243
+ ---
163
244
 
164
- ### 命令式用法 (流式场景)
245
+ ## 💡 实战示例
165
246
 
166
- 适用于实时流式数据场景,减少组件重渲染,提升性能。
247
+ ### 📝 AI 流式对话
167
248
 
168
- ```tsx
249
+ ````tsx
169
250
  import { useRef } from 'react';
170
- import { MarkdownCMD } from 'ds-markdown';
171
- import 'ds-markdown/style.css';
251
+ import { MarkdownCMD, MarkdownRef } from 'ds-markdown';
172
252
 
173
253
  function StreamingChat() {
174
- const markdownRef = useRef<any>();
254
+ const markdownRef = useRef<MarkdownRef>(null);
175
255
 
176
- // 模拟流式数据接收
177
- const simulateStreaming = async () => {
256
+ // 模拟 AI 流式响应
257
+ const simulateAIResponse = async () => {
178
258
  markdownRef.current?.clear();
179
259
 
180
- // 显示思考过程
181
- markdownRef.current?.push('🤔 正在分析您的问题...\n\n分析完成,准备回答', 'thinking');
260
+ // 思考阶段
261
+ markdownRef.current?.push('🤔 正在分析您的问题...', 'thinking');
262
+ await delay(1000);
263
+ markdownRef.current?.push('\n\n✅ 分析完成,开始回答', 'thinking');
182
264
 
183
- // 模拟流式回答
265
+ // 流式回答
184
266
  const chunks = [
185
- '# 关于 ds-markdown\n\n',
186
- '`ds-markdown` 是一个专为现代 Web 应用设计的组件。\n\n',
187
- '## 主要特性\n\n',
188
- '- 高性能渲染\n',
189
- '- 🎬 流畅动画\n',
190
- '- 🎯 精确控制\n\n',
191
- '希望这个回答对您有帮助!',
267
+ '# React 19 新特性解析\n\n',
268
+ '## 🚀 React Compiler\n',
269
+ 'React 19 最大的亮点是引入了 **React Compiler**:\n\n',
270
+ '- 🎯 **自动优化**:无需手动 memo 和 useMemo\n',
271
+ '- **性能提升**:编译时优化,运行时零开销\n',
272
+ '- 🔧 **向后兼容**:现有代码无需修改\n\n',
273
+ '## 📝 Actions 简化表单\n',
274
+ '新的 Actions API 让表单处理变得更简单:\n\n',
275
+ '```tsx\n',
276
+ 'function ContactForm({ action }) {\n',
277
+ ' const [state, formAction] = useActionState(action, null);\n',
278
+ ' return (\n',
279
+ ' <form action={formAction}>\n',
280
+ ' <input name="email" type="email" />\n',
281
+ ' <button>提交</button>\n',
282
+ ' </form>\n',
283
+ ' );\n',
284
+ '}\n',
285
+ '```\n\n',
286
+ '希望这个解答对您有帮助!🎉',
192
287
  ];
193
288
 
194
289
  for (const chunk of chunks) {
195
- await new Promise((resolve) => setTimeout(resolve, 500));
290
+ await delay(100);
196
291
  markdownRef.current?.push(chunk, 'answer');
197
292
  }
198
293
  };
199
294
 
200
295
  return (
201
- <div>
202
- <button onClick={simulateStreaming}>开始流式演示</button>
203
- <MarkdownCMD
204
- ref={markdownRef}
205
- interval={10}
206
- timerType="requestAnimationFrame"
207
- onEnd={(data) => {
208
- console.log('段落完成:', data);
209
- }}
210
- />
296
+ <div className="chat-container">
297
+ <button onClick={simulateAIResponse}>🤖 询问 React 19 新特性</button>
298
+
299
+ <MarkdownCMD ref={markdownRef} interval={10} timerType="requestAnimationFrame" onEnd={(data) => console.log('段落完成:', data)} />
211
300
  </div>
212
301
  );
213
302
  }
214
- ```
215
303
 
216
- [🔗 在线体验](https://stackblitz.com/edit/vitejs-vite-2ri8kex3?file=src%2FApp.tsx)
304
+ const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
305
+ ````
217
306
 
218
- ### 命令式 API
307
+ ### 🔄 流式 Markdown 语法处理
219
308
 
220
- ```typescript
221
- interface MarkdownRef {
222
- push: (content: string, answerType: 'thinking' | 'answer') => void;
223
- clear: () => void;
224
- triggerWholeEnd: () => void;
225
- flushBuffer: (answerType?: AnswerType) => void;
226
- }
227
- ```
309
+ **核心问题**:流式输出时,不完整的 Markdown 语法会导致渲染错误
228
310
 
229
- | 方法 | 参数 | 说明 |
230
- | ----------------- | ------------------------------------------- | ------------------------- |
231
- | `push` | `(content: string, answerType: AnswerType)` | 添加内容并开始打字 |
232
- | `clear` | - | 清空所有内容和状态 |
233
- | `triggerWholeEnd` | - | 手动触发完成回调 |
234
- | `flushBuffer` | `answerType?: AnswerType` | 强制刷新缓冲区内容 (新增) |
311
+ ```tsx
312
+ // 🚨 问题场景
313
+ push('#'); // "# "
314
+ push(' '); // "# "
315
+ push('标题'); // "# 标题"
316
+ push('\n'); // "# 标题\n"
317
+ push('1'); // "# 标题\n1" ← 这里会被误解析为段落
318
+ push('.'); // "# 标题\n1." ← 形成正确的列表
319
+ push(' 项目'); // "# 标题\n1. 项目"
320
+ ```
235
321
 
236
- ### 4. 类型安全
322
+ **✅ 智能解决方案**:组件内置同步缓冲机制
237
323
 
238
324
  ```tsx
239
- import { MarkdownRef } from 'ds-markdown';
325
+ // 组件会智能处理语法边界
326
+ const handleStreamingMarkdown = () => {
327
+ const chunks = ['#', ' ', '使用', '技能', '\n', '1', '.', ' ', '技能1', '\n', '2', '.', ' 技能2'];
240
328
 
241
- const ref = useRef<MarkdownRef>(null);
242
- // 现在具有完整的类型提示和新增的 flushBuffer 方法
329
+ chunks.forEach((chunk) => {
330
+ markdownRef.current?.push(chunk, 'answer');
331
+ // 无需延迟,组件内部智能缓冲
332
+ });
333
+
334
+ // 可选:手动刷新剩余缓冲内容
335
+ markdownRef.current?.flushBuffer();
336
+ };
337
+
338
+ // 🧠 智能处理流程:
339
+ // 1. 实时检测 "# 使用技能\n1" 语法不完整
340
+ // 2. 智能缓冲,等待更多字符
341
+ // 3. 收到 "." 形成 "1." 后立即处理
342
+ // 4. 零延迟,纯同步处理
243
343
  ```
244
344
 
245
- ## 🎨 样式定制
345
+ **缓冲机制特性**:
246
346
 
247
- ```css
248
- /* 自定义思考区域样式 */
249
- .ds-markdown-thinking {
250
- background: rgba(255, 193, 7, 0.1);
251
- border-left: 3px solid #ffc107;
252
- padding: 12px;
253
- border-radius: 4px;
254
- }
347
+ - ⚡ **零延迟**:无 setTimeout,纯同步实时处理
348
+ - 🧠 **智能边界**:基于 Markdown 语法规则的边界检测
349
+ - 🔄 **实时分割**:遇到完整语法立即处理,不完整时智能缓冲
350
+ - 🛡️ **安全保障**:提供 `flushBuffer()` 方法处理剩余内容
255
351
 
256
- /* 自定义回答区域样式 */
257
- .ds-markdown-answer {
258
- color: #333;
259
- line-height: 1.6;
260
- }
352
+ **支持的语法检测**:
261
353
 
262
- /* 自定义代码块样式 */
263
- .ds-markdown pre {
264
- background: #f8f9fa;
265
- border-radius: 6px;
266
- padding: 16px;
267
- }
268
- ```
354
+ ````typescript
355
+ // 完整语法 (立即处理)
356
+ '## 标题'; // 完整标题
357
+ '1. 列表项'; // 完整列表项
358
+ '- 项目'; // 完整无序列表
359
+ '> 引用内容'; // 完整引用
360
+ '```javascript'; // 代码块开始
361
+ '```'; // 代码块结束
362
+ '内容以换行结尾\n'; // 换行边界
363
+
364
+ // 🔄 不完整语法 (智能缓冲)
365
+ '##'; // 只有标题符号
366
+ '1'; // 只有数字
367
+ '```java'; // 可能的代码块开始
368
+ ````
369
+
370
+ ---
269
371
 
270
372
  ## 🔧 最佳实践
271
373
 
272
- ### 1. 性能优化建议
374
+ ### 1. 性能优化
273
375
 
274
376
  ```tsx
275
- // ✅ 推荐:使用 requestAnimationFrame + 适中的 interval
377
+ // ✅ 推荐配置
276
378
  <DsMarkdown
277
379
  timerType="requestAnimationFrame"
278
380
  interval={15} // 15-30ms 为最佳体验
279
381
  />
280
382
 
281
- // ❌ 避免:过小的 interval 值
383
+ // ❌ 避免过小间隔
282
384
  <DsMarkdown interval={1} /> // 可能导致性能问题
283
385
  ```
284
386
 
285
387
  ### 2. 流式数据处理
286
388
 
287
389
  ```tsx
288
- // ✅ 推荐:使用命令式 API
289
- const ref = useRef();
390
+ // ✅ 推荐:命令式 API
391
+ const ref = useRef<MarkdownRef>(null);
290
392
  useEffect(() => {
291
- // 实时接收数据时使用 push 方法
292
393
  ref.current?.push(newChunk, 'answer');
293
394
  }, [newChunk]);
294
395
 
295
- // ❌ 避免:频繁更新 children prop
396
+ // ❌ 避免:频繁更新 children
296
397
  const [content, setContent] = useState('');
297
398
  // 每次更新都会重新解析整个内容
298
399
  ```
299
400
 
300
- ### 3. 流式 Markdown 语法处理
301
-
302
- **问题场景**: 流式输出时,不完整的 Markdown 语法会导致渲染错误
401
+ ### 3. 类型安全
303
402
 
304
403
  ```tsx
305
- // 🚨 问题示例:逐字符推送导致的解析错误
306
- push('#'); // "# "
307
- push(' '); // "# "
308
- push('标题'); // "# 标题"
309
- push('\n'); // "# 标题\n"
310
- push('1'); // "# 标题\n1" ← 这里会被误解析
311
- push('.'); // "# 标题\n1." ← 形成正确的列表
312
- push(' 列表项'); // "# 标题\n1. 列表项"
404
+ import { MarkdownRef } from 'ds-markdown';
405
+
406
+ const ref = useRef<MarkdownRef>(null);
407
+ // 完整的 TypeScript 类型提示
313
408
  ```
314
409
 
315
- **✅ 解决方案**: 组件内置**同步智能缓冲机制**
410
+ ### 4. 样式定制
316
411
 
317
- ```tsx
318
- // 组件会实时检测并缓冲不完整的语法
319
- const streamingDemo = async () => {
320
- const chunks = ['#', ' ', '使用', '技能', '\n', '1', '.', ' ', '技能1', '\n', '2', '.', ' 技能2'];
412
+ ```css
413
+ /* 思考区域样式 */
414
+ .ds-markdown-thinking {
415
+ background: rgba(255, 193, 7, 0.1);
416
+ border-left: 3px solid #ffc107;
417
+ padding: 12px;
418
+ border-radius: 6px;
419
+ margin: 8px 0;
420
+ }
321
421
 
322
- for (const chunk of chunks) {
323
- markdownRef.current?.push(chunk, 'answer');
324
- // 无需延迟,组件内部智能处理
325
- }
422
+ /* 回答区域样式 */
423
+ .ds-markdown-answer {
424
+ color: #333;
425
+ line-height: 1.6;
426
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
427
+ }
326
428
 
327
- // 手动刷新剩余缓冲内容 (可选)
328
- markdownRef.current?.flushBuffer();
329
- };
429
+ /* 代码块样式 */
430
+ .ds-markdown pre {
431
+ background: #f8f9fa;
432
+ border-radius: 8px;
433
+ padding: 16px;
434
+ overflow-x: auto;
435
+ }
330
436
 
331
- // 组件会同步智能处理:
332
- // 1. 实时检测 "# 使用技能\n1" 语法不完整
333
- // 2. 智能缓冲,等待更多字符
334
- // 3. 收到 "." 形成 "1." 后立即处理
335
- // 4. 零延迟,纯同步处理
336
- ```
437
+ /* 表格样式 */
438
+ .ds-markdown-table {
439
+ border-collapse: collapse;
440
+ width: 100%;
441
+ margin: 16px 0;
442
+ }
337
443
 
338
- **同步缓冲机制特性**:
444
+ .ds-markdown-table th,
445
+ .ds-markdown-table td {
446
+ border: 1px solid #ddd;
447
+ padding: 8px 12px;
448
+ text-align: left;
449
+ }
450
+ ```
339
451
 
340
- - ⚡ **零延迟**: 无 setTimeout,纯同步实时处理
341
- - 🧠 **智能边界**: 基于 Markdown 语法规则的边界检测
342
- - 🔄 **实时分割**: 遇到完整语法立即处理,不完整时智能缓冲
343
- - 🛡️ **安全保障**: 提供 `flushBuffer()` 方法处理剩余内容
452
+ ---
344
453
 
345
- **支持的语法检测**:
454
+ ## 🌐 兼容性
346
455
 
347
- ````typescript
348
- // 完整语法模式 (立即处理)
349
- '## 标题'; // 完整标题
350
- '1. 列表项'; // 完整列表项
351
- '- 项目'; // 完整无序列表
352
- '> 引用内容'; // 完整引用
353
- '```javascript'; // 代码块开始
354
- '```'; // 代码块结束
355
- '内容以换行结尾\n'; // 换行边界
456
+ | 环境 | 版本要求 | 说明 |
457
+ | -------------- | ----------------------------------- | --------------- |
458
+ | **React** | 16.8.0+ | 需要 Hooks 支持 |
459
+ | **TypeScript** | 4.0+ | 可选,但推荐 |
460
+ | **浏览器** | Chrome 60+, Firefox 55+, Safari 12+ | 现代浏览器 |
461
+ | **Node.js** | 14.0+ | 构建环境 |
356
462
 
357
- // 不完整语法 (智能缓冲)
358
- '##'; // 只有标题符号
359
- '1'; // 只有数字
360
- '```java'; // 可能的代码块开始
361
- ````
463
+ ---
362
464
 
363
- **新增 API**:
465
+ ## 🤝 贡献指南
364
466
 
365
- | 方法 | 参数 | 说明 |
366
- | ------------- | ------------------------- | ------------------ |
367
- | `flushBuffer` | `answerType?: AnswerType` | 强制刷新缓冲区内容 |
467
+ 欢迎提交 Issue Pull Request!
368
468
 
369
- ## 🌐 兼容性
469
+ 1. Fork 本仓库
470
+ 2. 创建特性分支:`git checkout -b feature/amazing-feature`
471
+ 3. 提交更改:`git commit -m 'Add amazing feature'`
472
+ 4. 推送分支:`git push origin feature/amazing-feature`
473
+ 5. 提交 Pull Request
370
474
 
371
- - **React**: 16.8.0+
372
- - **TypeScript**: 4.0+
373
- - **浏览器**: Chrome 60+, Firefox 55+, Safari 12+
374
- - **Node.js**: 14.0+
475
+ ---
375
476
 
376
- ## 📄 License
477
+ ## 📄 开源协议
377
478
 
378
479
  MIT © [onshinpei](https://github.com/onshinpei)
379
480
 
@@ -381,4 +482,10 @@ MIT © [onshinpei](https://github.com/onshinpei)
381
482
 
382
483
  <div align="center">
383
484
  <strong>如果这个项目对你有帮助,请给个 ⭐️ Star 支持一下!</strong>
485
+
486
+ <br><br>
487
+
488
+ [🐛 报告问题](https://github.com/onshinpei/ds-markdown/issues) |
489
+ [💡 功能建议](https://github.com/onshinpei/ds-markdown/issues) |
490
+ [📖 查看文档](https://onshinpei.github.io/ds-markdown/)
384
491
  </div>