ds-markdown 0.1.10-beta.1 โ†’ 0.1.10-beta.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.en.md CHANGED
@@ -9,66 +9,72 @@ A React component designed specifically for modern AI applications, providing sm
9
9
  [![npm version](https://img.shields.io/npm/v/ds-markdown)](https://www.npmjs.com/package/ds-markdown)
10
10
  [![npm downloads](https://img.shields.io/npm/dm/ds-markdown.svg)](https://www.npmjs.com/package/ds-markdown)
11
11
  [![bundle size](https://img.shields.io/bundlephobia/minzip/ds-markdown)](https://bundlephobia.com/package/ds-markdown)
12
- [![React](https://img.shields.io/badge/React-16.8+-blue)](https://react.dev)
12
+ [![React](https://img.shields.io/badge/React-18.0.0+-blue)](https://react.dev)
13
13
  [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue)](https://www.typescriptlang.org/)
14
14
 
15
- [๐Ÿ“– Live Demo](https://onshinpei.github.io/ds-markdown/)
15
+ - [Documentation](https://onshinpei.github.io/ds-markdown/)
16
+ - Usage Examples
17
+ - [Basic Usage](https://stackblitz.com/edit/vitejs-vite-ddfw8avb?file=src%2FApp.tsx)
18
+ - [Streaming Data Usage](https://stackblitz.com/edit/vitejs-vite-2ri8kex3?file=src%2FApp.tsx)
19
+ - [Mermaid Charts](https://stackblitz.com/edit/vitejs-vite-iqbyta3j?file=index.html)
20
+ - [Math Formula Demo 1](https://stackblitz.com/edit/vitejs-vite-iqbyta3j?file=index.html)
21
+ - [Math Formula Demo 2](https://stackblitz.com/edit/vitejs-vite-xk9lxagc?file=src%2FApp.tsx)
16
22
 
17
- [DEMO๏ผš๐Ÿ”ง StackBlitz Experience](https://stackblitz.com/edit/vitejs-vite-ddfw8avb?file=src%2FApp.tsx)
18
-
19
- **If you want a pure react markdown typing component, you can use [react-markdown-typer](https://github.com/onshinpei/react-markdown-typer)**
20
-
21
- ---
22
-
23
- ## ๐Ÿ“‹ Table of Contents
24
-
25
- - [โœจ Core Features](#-core-features)
26
- - [๐Ÿ“ฆ Quick Installation](#-quick-installation)
27
- - [๐Ÿš€ 5-Minute Quick Start](#-5-minute-quick-start)
28
- - [Basic Usage](#basic-usage)
29
- - [Disable Typing Animation](#disable-typing-animation)
30
- - [Mathematical Formula Support](#mathematical-formula-support)
31
- - [AI Conversation Scenario](#ai-conversation-scenario)
32
- - [๐ŸŽฏ Advanced Callback Control](#-advanced-callback-control)
33
- - [๐Ÿ”„ Restart Animation Demo](#-restart-animation-demo)
34
- - [โ–ถ๏ธ Manual Start Animation Demo](#๏ธ-manual-start-animation-demo)
35
- - [๐Ÿ“š Complete API Documentation](#-complete-api-documentation)
36
- - [๐Ÿงฎ Mathematical Formula Usage Guide](#-mathematical-formula-usage-guide)
37
- - [๐Ÿ”Œ Plugin System](#-plugin-system)
38
- - [๐ŸŽ›๏ธ Timer Mode Details](#๏ธ-timer-mode-details)
39
- - [๐Ÿ’ก Practical Examples](#-practical-examples)
40
- - [๐Ÿ”ง Best Practices](#-best-practices)
41
- - [ConfigProvider Internationalization (i18n)](<#ConfigProvider-Internationalization-(i18n)>)
23
+ If you want a pure `react markdown` typing component, you can use [react-markdown-typer](https://github.com/onshinpei/react-markdown-typer)
42
24
 
43
25
  ---
44
26
 
45
27
  ## โ“ Why use ds-markdown?
46
28
 
47
29
  - **Ultimate AI Chat Experience**
48
- Faithfully recreates the typing animation and streaming response of leading AI chat interfaces (like DeepSeek), delivering a truly immersive "AI is thinking/answering" experience.
30
+ 1:1 recreation of DeepSeek and other mainstream AI chat interface typing animations and streaming responses, delivering an authentic "AI is thinking/answering" experience that greatly enhances user immersion.
49
31
 
50
32
  - **Perfect for Streaming Backend Data**
51
- Many AI/LLM backends (OpenAI, DeepSeek, etc.) send data chunks containing multiple characters at once.
52
- **ds-markdown automatically splits each chunk into single characters and animates them one by one, ensuring smooth typing even if the backend sends several characters at a time.**
33
+ Many AI/LLM backend interfaces (like OpenAI, DeepSeek, etc.) push data chunks containing multiple characters at once, which can cause stuttering and character jumping issues with ordinary typewriter implementations.
34
+ **ds-markdown automatically splits each chunk into single characters and renders them one by one with smooth animations, ensuring fluent typing regardless of how many characters the backend pushes at once.**
35
+
36
+ - **Complete Markdown & Math Formula, Diagram Support**
53
37
 
54
- - **Full Markdown & Math Formula Support**
55
- Built-in KaTeX, supports all major Markdown syntax and math formulasโ€”ideal for technical Q&A, education, and knowledge bases.
38
+ - Built-in KaTeX, supporting all mainstream Markdown syntax and math formulas, suitable for technical Q&A, education, knowledge bases, and other content-rich applications.
39
+ - Support for `Diagram` rendering through the [mermaid-plugin](https://github.com/onshinpei/ds-markdown-mermaid-plugin)
56
40
 
57
41
  - **Excellent Developer Experience**
58
- Rich imperative API, supports streaming data, async callbacks, and plugin extensions for flexible animation and content control.
42
+ Rich imperative API, supporting streaming data, async callbacks, and plugin extensions, allowing developers to flexibly control animations and content.
59
43
 
60
44
  - **Lightweight & High Performance**
61
- Small bundle size, fast, mobile and desktop ready. The only core dependency is [react-markdown](https://github.com/remarkjs/react-markdown) (a widely used, mature Markdown renderer). No other heavy dependenciesโ€”works out of the box.
45
+ Small size, excellent performance, compatible with mobile and desktop. Core dependency is [react-markdown](https://github.com/remarkjs/react-markdown) (industry mainstream, mature Markdown rendering library), with no other heavyweight dependencies - works out of the box.
62
46
 
63
47
  - **Multi-theme & Plugin Architecture**
64
- Light/dark theme switching, remark/rehype plugin compatibility, and advanced extensibility.
48
+ Support for light/dark theme switching, compatible with remark/rehype plugins, meeting personalized and advanced extension needs.
49
+
50
+ - **Rich UI Component System** ๐Ÿ†•
51
+ Built-in UI components: Button, IconButton, ToolTip, Segmented, etc., supporting code block copy, download, and other interactive features.
65
52
 
66
53
  - **Wide Range of Use Cases**
67
54
  - AI chatbots/assistants
68
55
  - Real-time Q&A/knowledge bases
69
- - Education/math/programming content
70
- - Product demos, interactive docs
71
- - Any scenario needing "typewriter" animation and streaming Markdown rendering
56
+ - Education/math/programming content display
57
+ - Product demos, interactive documentation
58
+ - Any scenario requiring "typewriter" animation and streaming Markdown rendering
59
+
60
+ ---
61
+
62
+ ## ๐Ÿ“‹ Table of Contents
63
+
64
+ - [โœจ Core Features](#-core-features)
65
+ - [๐Ÿ“ฆ Quick Installation](#-quick-installation)
66
+ - [๐Ÿš€ 5-Minute Quick Start](#-5-minute-quick-start)
67
+ - [Basic Usage](#basic-usage)
68
+ - [Disable Typing Animation](#disable-typing-animation)
69
+ - [Mathematical Formula Support](#mathematical-formula-support)
70
+ - [AI Conversation Scenario](#ai-conversation-scenario)
71
+ - [Code Block Features](#code-block-features) ๐Ÿ†•
72
+ - [Mermaid Chart Support](#mermaid-chart-support) ๐Ÿ†•
73
+ - [๐Ÿ“š Complete API Documentation](#-complete-api-documentation)
74
+ - [๐Ÿ”Œ Plugin System](#-plugin-system)
75
+ - [๐ŸŽจ UI Component System](#-ui-component-system) ๐Ÿ†•
76
+ - [๐Ÿ’ก Practical Examples](#-practical-examples)
77
+ - [๐Ÿ”ง Best Practices](#-best-practices)
72
78
 
73
79
  ---
74
80
 
@@ -84,13 +90,21 @@ A React component designed specifically for modern AI applications, providing sm
84
90
 
85
91
  - Complete Markdown syntax support, including code highlighting, tables, lists, etc.
86
92
  - Mathematical formula rendering (KaTeX), supporting `$...$` and `\[...\]` syntax
87
- - Light/dark theme support, adapting to different product styles
93
+ - Mermaid chart support, including flowcharts, sequence diagrams, Gantt charts, class diagrams, etc. ๐Ÿ†•
94
+ - Support for light/dark themes, adapting to different product styles
88
95
  - Plugin architecture supporting remark/rehype plugin extensions
89
96
 
97
+ ### ๐ŸŽจ **UI Component System** ๐Ÿ†•
98
+
99
+ - Built-in rich UI components: Button, IconButton, ToolTip, Segmented, etc.
100
+ - Code block enhancement features: copy, download, language identification
101
+ - Complete interactive experience and accessibility support
102
+
90
103
  ### ๐Ÿ”ง **Developer Experience**
91
104
 
92
105
  - Support for typing interruption `stop` and resume `resume`
93
- - Support for disabling and enabling typing
106
+ - Support for enabling and disabling typing
107
+ - Complete TypeScript type support
94
108
 
95
109
  ### ๐ŸŽฌ **Smooth Animation**
96
110
 
@@ -238,223 +252,81 @@ Let's explore these new features together!`);
238
252
  }
239
253
  ```
240
254
 
241
- ### ๐ŸŽฏ Advanced Callback Control
255
+ ### Code Block Features ๐Ÿ†•
242
256
 
243
257
  ```tsx
244
- import { useRef, useState } from 'react';
245
- import { MarkdownCMD, MarkdownCMDRef } from 'ds-markdown';
246
-
247
- function AdvancedCallbackDemo() {
248
- const markdownRef = useRef<MarkdownCMDRef>(null);
249
- const [typingStats, setTypingStats] = useState({ progress: 0, currentChar: '', totalChars: 0 });
250
-
251
- const handleBeforeTypedChar = async (data) => {
252
- // Perform async operations before character typing
253
- console.log('About to type:', data.currentChar);
254
-
255
- // Can perform network requests, data validation, etc.
256
- if (data.currentChar === '!') {
257
- await new Promise((resolve) => setTimeout(resolve, 500)); // Simulate delay
258
- }
259
- };
260
-
261
- const handleTypedChar = (data) => {
262
- // Update typing statistics
263
- setTypingStats({
264
- progress: Math.round(data.percent),
265
- currentChar: data.currentChar,
266
- totalChars: data.currentIndex + 1,
267
- });
268
-
269
- // Can add sound effects, animations, etc.
270
- if (data.currentChar === '.') {
271
- // Play period sound effect
272
- console.log('Play period sound effect');
273
- }
274
- };
275
-
276
- const handleStart = (data) => {
277
- console.log('Start typing:', data.currentChar);
278
- };
279
-
280
- const handleEnd = (data) => {
281
- console.log('Typing complete:', data.str);
282
- };
283
-
284
- const startDemo = () => {
285
- markdownRef.current?.clear();
286
- markdownRef.current?.push(
287
- '# Advanced Callback Demo\n\n' +
288
- 'This example shows how to use `onBeforeTypedChar` and `onTypedChar` callbacks:\n\n' +
289
- '- ๐ŸŽฏ **Pre-typing callback**: Can perform async operations before character display\n' +
290
- '- ๐Ÿ“Š **Post-typing callback**: Can update progress in real-time and add effects\n' +
291
- '- โšก **Performance optimization**: Supports async operations without affecting typing smoothness\n\n' +
292
- 'Current progress: ' +
293
- typingStats.progress +
294
- '%\n' +
295
- 'Characters typed: ' +
296
- typingStats.totalChars +
297
- '\n\n' +
298
- 'This is a very powerful feature!',
299
- 'answer',
300
- );
301
- };
302
-
303
- return (
304
- <div>
305
- <button onClick={startDemo}>๐Ÿš€ Start Advanced Demo</button>
258
+ import DsMarkdown from 'ds-markdown';
259
+ import 'ds-markdown/style.css';
306
260
 
307
- <div style={{ margin: '10px 0', padding: '10px', background: '#f5f5f5', borderRadius: '4px' }}>
308
- <strong>Typing Stats:</strong> Progress {typingStats.progress}% | Current char: "{typingStats.currentChar}" | Total chars: {typingStats.totalChars}
309
- </div>
261
+ function CodeBlockDemo() {
262
+ const codeContent = `# Hello World
310
263
 
311
- <MarkdownCMD ref={markdownRef} interval={30} onBeforeTypedChar={handleBeforeTypedChar} onTypedChar={handleTypedChar} onStart={handleStart} onEnd={handleEnd} />
312
- </div>
313
- );
264
+ \`\`\`javascript
265
+ function greet(name) {
266
+ console.log(\`Hello, \${name}!\`);
314
267
  }
315
- ```
316
-
317
- ### ๐Ÿ”„ Restart Animation Demo
318
-
319
- ```tsx
320
- import { useRef, useState } from 'react';
321
- import { MarkdownCMD, MarkdownCMDRef } from 'ds-markdown';
322
-
323
- function RestartDemo() {
324
- const markdownRef = useRef<MarkdownCMDRef>(null);
325
- const [isPlaying, setIsPlaying] = useState(false);
326
- const [hasStarted, setHasStarted] = useState(false);
327
-
328
- const startContent = () => {
329
- markdownRef.current?.clear();
330
- markdownRef.current?.push(
331
- '# Restart Animation Demo\n\n' +
332
- 'This example shows how to use the `restart()` method:\n\n' +
333
- '- ๐Ÿ”„ **Restart**: Play current content from the beginning\n' +
334
- '- โธ๏ธ **Pause/Resume**: Can pause and resume at any time\n' +
335
- '- ๐ŸŽฏ **Precise Control**: Complete control over animation playback state\n\n' +
336
- 'Current state: ' +
337
- (isPlaying ? 'Playing' : 'Paused') +
338
- '\n\n' +
339
- 'This is a very practical feature!',
340
- 'answer',
341
- );
342
- setIsPlaying(true);
343
- };
344
268
 
345
- const handleStart = () => {
346
- if (hasStarted) {
347
- // If already started, restart
348
- markdownRef.current?.restart();
349
- } else {
350
- // First time start
351
- markdownRef.current?.start();
352
- setHasStarted(true);
353
- }
354
- setIsPlaying(true);
355
- };
356
-
357
- const handleStop = () => {
358
- markdownRef.current?.stop();
359
- setIsPlaying(false);
360
- };
361
-
362
- const handleResume = () => {
363
- markdownRef.current?.resume();
364
- setIsPlaying(true);
365
- };
269
+ greet('ds-markdown');
270
+ \`\`\`
366
271
 
367
- const handleRestart = () => {
368
- markdownRef.current?.restart();
369
- setIsPlaying(true);
370
- };
371
-
372
- const handleEnd = () => {
373
- setIsPlaying(false);
374
- };
272
+ Supports code highlighting, copy, and download features!`;
375
273
 
376
274
  return (
377
- <div>
378
- <div style={{ marginBottom: '10px', display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
379
- <button onClick={startContent}>๐Ÿš€ Start Content</button>
380
- <button onClick={handleStart} disabled={isPlaying}>
381
- {hasStarted ? '๐Ÿ”„ Restart' : 'โ–ถ๏ธ Start'}
382
- </button>
383
- <button onClick={handleStop} disabled={!isPlaying}>
384
- โธ๏ธ Pause
385
- </button>
386
- <button onClick={handleResume} disabled={isPlaying}>
387
- โ–ถ๏ธ Resume
388
- </button>
389
- <button onClick={handleRestart}>๐Ÿ”„ Restart</button>
390
- </div>
391
-
392
- <div style={{ margin: '10px 0', padding: '10px', background: '#f5f5f5', borderRadius: '4px' }}>
393
- <strong>Animation State:</strong> {isPlaying ? '๐ŸŸข Playing' : '๐Ÿ”ด Paused'}
394
- </div>
395
-
396
- <MarkdownCMD ref={markdownRef} interval={25} onEnd={handleEnd} />
397
- </div>
275
+ <DsMarkdown
276
+ interval={20}
277
+ answerType="answer"
278
+ codeBlock={{
279
+ headerActions: true, // Enable code block header action buttons
280
+ }}
281
+ >
282
+ {codeContent}
283
+ </DsMarkdown>
398
284
  );
399
285
  }
400
286
  ```
401
287
 
402
- ### โ–ถ๏ธ Manual Start Animation Demo
288
+ ### Mermaid Chart Support ๐Ÿ†•
403
289
 
404
290
  ```tsx
405
- import { useRef, useState } from 'react';
406
- import { MarkdownCMD, MarkdownCMDRef } from 'ds-markdown';
407
-
408
- function StartDemo() {
409
- const markdownRef = useRef<MarkdownCMDRef>(null);
410
- const [isPlaying, setIsPlaying] = useState(false);
411
- const [hasStarted, setHasStarted] = useState(false);
412
-
413
- const loadContent = () => {
414
- markdownRef.current?.clear();
415
- markdownRef.current?.push(
416
- '# Manual Start Animation Demo\n\n' +
417
- 'This example shows how to use the `start()` method:\n\n' +
418
- '- ๐ŸŽฏ **Manual Control**: When `autoStartTyping=false`, need to manually call `start()`\n' +
419
- '- โฑ๏ธ **Delayed Start**: Can start animation after user interaction\n' +
420
- '- ๐ŸŽฎ **Gamification**: Suitable for scenarios requiring user initiative\n\n' +
421
- 'Click the "Start Animation" button to manually trigger the typing effect!',
422
- 'answer',
423
- );
424
- setIsPlaying(false);
425
- };
426
-
427
- const handleStart = () => {
428
- if (hasStarted) {
429
- // If already started, restart
430
- markdownRef.current?.restart();
431
- } else {
432
- // First time start
433
- markdownRef.current?.start();
434
- setHasStarted(true);
435
- }
436
- setIsPlaying(true);
437
- };
291
+ import DsMarkdown from 'ds-markdown';
292
+ import { ConfigProvider } from 'ds-markdown';
293
+ import mermaidPlugin from 'ds-markdown-mermaid-plugin';
294
+ import 'ds-markdown/style.css';
438
295
 
439
- const handleEnd = () => {
440
- setIsPlaying(false);
441
- };
296
+ function MermaidDemo() {
297
+ const chartContent = `# Flowchart Example
298
+
299
+ \`\`\`mermaid
300
+ flowchart TD
301
+ A[Start] --> B{Decision}
302
+ B -->|Yes| C[Process A]
303
+ B -->|No| D[Process B]
304
+ C --> E[End]
305
+ D --> E
306
+ \`\`\`
307
+
308
+ ## Sequence Diagram Example
309
+
310
+ \`\`\`mermaid
311
+ sequenceDiagram
312
+ participant User
313
+ participant System
314
+ participant Database
315
+
316
+ User->>System: Login Request
317
+ System->>Database: Verify User
318
+ Database-->>System: Return Result
319
+ System-->>User: Login Response
320
+ \`\`\`
321
+
322
+ Supports flowcharts, sequence diagrams, Gantt charts, class diagrams, and many other chart types!`;
442
323
 
443
324
  return (
444
- <div>
445
- <div style={{ marginBottom: '10px', display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
446
- <button onClick={loadContent}>๐Ÿ“ Load Content</button>
447
- <button onClick={handleStart} disabled={isPlaying}>
448
- {hasStarted ? '๐Ÿ”„ Restart' : 'โ–ถ๏ธ Start Animation'}
449
- </button>
450
- </div>
451
-
452
- <div style={{ margin: '10px 0', padding: '10px', background: '#f5f5f5', borderRadius: '4px' }}>
453
- <strong>State:</strong> {isPlaying ? '๐ŸŸข Animation Playing' : '๐Ÿ”ด Waiting to Start'}
454
- </div>
455
-
456
- <MarkdownCMD ref={markdownRef} interval={30} autoStartTyping={false} onEnd={handleEnd} />
457
- </div>
325
+ <ConfigProvider>
326
+ <DsMarkdown interval={20} answerType="answer" plugins={[mermaidPlugin]}>
327
+ {chartContent}
328
+ </DsMarkdown>
329
+ </ConfigProvider>
458
330
  );
459
331
  }
460
332
  ```
@@ -472,8 +344,8 @@ import DsMarkdown, { MarkdownCMD } from 'ds-markdown';
472
344
  | Property | Type | Description | Default |
473
345
  | ------------------- | ------------------------------------------- | ---------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
474
346
  | `interval` | `number` | Typing interval (milliseconds) | `30` |
475
- | `timerType` | `'setTimeout'` \| `'requestAnimationFrame'` | Timer type | Current default is `setTimeout`, will change to `requestAnimationFrame` later |
476
- | `answerType` | `'thinking'` \| `'answer'` | Content type (affects styling) | `'answer'` |
347
+ | `timerType` | `'setTimeout'` \| `'requestAnimationFrame'` | Timer type, cannot be modified dynamically | Current default is `setTimeout`, will change to `requestAnimationFrame` later |
348
+ | `answerType` | `'thinking'` \| `'answer'` | Content type (affects styling), cannot be modified dynamically | `'answer'` |
477
349
  | `theme` | `'light'` \| `'dark'` | Theme type | `'light'` |
478
350
  | `plugins` | `IMarkdownPlugin[]` | Plugin configuration | `[]` |
479
351
  | `math` | [IMarkdownMath](#IMarkdownMath) | Mathematical formula config | `{ splitSymbol: 'dollar' }` |
@@ -483,6 +355,7 @@ import DsMarkdown, { MarkdownCMD } from 'ds-markdown';
483
355
  | `onTypedChar` | `(data: ITypedChar) => void` | Character typing post-callback | - |
484
356
  | `disableTyping` | `boolean` | Disable typing animation | `false` |
485
357
  | `autoStartTyping` | `boolean` | Whether to auto-start typing animation, set to false for manual trigger | `true` |
358
+ | `codeBlock` | `IMarkdownCode` | Code block configuration | `{headerActions: true}` |
486
359
 
487
360
  > Note: If `disableTyping` changes from `true` to `false` during typing, all remaining characters will be displayed at once on the next typing trigger.
488
361
 
@@ -518,14 +391,21 @@ import DsMarkdown, { MarkdownCMD } from 'ds-markdown';
518
391
  - `'dollar'`: Uses `$...$` and `$$...$$` syntax
519
392
  - `'bracket'`: Uses `\(...\)` and `\[...\]` syntax
520
393
 
394
+ #### IMarkdownCode ๐Ÿ†•
395
+
396
+ | Property | Type | Description | Default |
397
+ | --------------- | --------- | -------------------------- | ------- |
398
+ | `headerActions` | `boolean` | Show header action buttons | `true` |
399
+
521
400
  #### IMarkdownPlugin
522
401
 
523
- | Property | Type | Description | Default |
524
- | -------------- | ------------------------- | ---------------- | ------- |
525
- | `remarkPlugin` | `unknown` | remark plugin | - |
526
- | `rehypePlugin` | `unknown` | rehype plugin | - |
527
- | `type` | `'buildIn'` \| `'custom'` | Plugin type | - |
528
- | `id` | `any` | Plugin unique ID | - |
402
+ | Property | Type | Description | Default |
403
+ | -------------- | ---------------------------------------------- | --------------------------- | ------- |
404
+ | `remarkPlugin` | `Pluggable` | remark plugin | - |
405
+ | `rehypePlugin` | `Pluggable` | rehype plugin | - |
406
+ | `type` | `'buildIn'` \| `'custom'` | Plugin type | - |
407
+ | `id` | `any` | Plugin unique identifier | - |
408
+ | `components` | `Record<string, React.ComponentType<unknown>>` | Custom component mapping ๐Ÿ†• | - |
529
409
 
530
410
  ### Component Exposed Methods
531
411
 
@@ -561,106 +441,97 @@ markdownRef.current?.restart(); // Restart animation
561
441
 
562
442
  ---
563
443
 
564
- ## ๐Ÿงฎ Mathematical Formula Usage Guide
444
+ ## ๐Ÿ”Œ Plugin System
565
445
 
566
- [DEMO1: Pythagorean Theorem](https://stackblitz.com/edit/vitejs-vite-z94syu8j?file=src%2FApp.tsx)
446
+ ### Built-in Plugins
567
447
 
568
- [DEMO2: Problem Solving](https://stackblitz.com/edit/vitejs-vite-xk9lxagc?file=README.md)
448
+ #### KaTeX Mathematical Formula Plugin
569
449
 
570
- ### Basic Syntax
450
+ [DEMO](https://stackblitz.com/edit/vitejs-vite-iqbyta3j?file=index.html)
571
451
 
572
452
  ```tsx
573
453
  import { katexPlugin } from 'ds-markdown/plugins';
574
454
 
575
- // 1. Enable mathematical formula support
576
- <DsMarkdown plugins={[katexPlugin]}>
577
- # Mathematical Formula Example
578
-
579
- // Inline formula
580
- This is an inline formula: $E = mc^2$
581
-
582
- // Block formula
583
- $$\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}$$
584
- </DsMarkdown>
455
+ // Enable mathematical formula support
456
+ <DsMarkdown plugins={[katexPlugin]}>Mathematical formula: $E = mc^2$</DsMarkdown>;
585
457
  ```
586
458
 
587
- ### Delimiter Selection
588
-
589
- ```tsx
590
- // Using dollar sign delimiters (default)
591
- <DsMarkdown
592
- plugins={[katexPlugin]}
593
- math={{ splitSymbol: 'dollar' }}
594
- >
595
- Inline: $a + b = c$
596
- Block: $$\sum_{i=1}^{n} x_i = x_1 + x_2 + \cdots + x_n$$
597
- </DsMarkdown>
598
-
599
- // Using bracket delimiters
600
- <DsMarkdown
601
- plugins={[katexPlugin]}
602
- math={{ splitSymbol: 'bracket' }}
603
- >
604
- Inline: \(a + b = c\)
605
- Block: \[\sum_{i=1}^{n} x_i = x_1 + x_2 + \cdots + x_n\]
606
- </DsMarkdown>
607
- ```
459
+ #### Mermaid Chart Plugin ๐Ÿ†•
608
460
 
609
- ### Streaming Mathematical Formulas
461
+ **Install Mermaid plugin:**
610
462
 
611
- ```tsx
612
- // Perfect support for mathematical formulas in streaming output
613
- const mathContent = [
614
- 'Pythagorean Theorem:',
615
- '$a^2 + b^2 = c^2$',
616
- '\n\n',
617
- 'Where:',
618
- '- $a$ and $b$ are the legs\n',
619
- '- $c$ is the hypotenuse\n\n',
620
- 'For the classic "3-4-5" triangle:\n',
621
- '$c = \\sqrt{3^2 + 4^2} = \\sqrt{25} = 5$\n\n',
622
- 'This theorem has wide applications in geometry!',
623
- ];
624
-
625
- mathContent.forEach((chunk) => {
626
- markdownRef.current?.push(chunk, 'answer');
627
- });
463
+ ```bash
464
+ npm install ds-markdown-mermaid-plugin
628
465
  ```
629
466
 
630
- ### Style Customization
467
+ **Basic usage:**
631
468
 
632
- ```css
633
- /* Mathematical formula style customization */
634
- .katex {
635
- font-size: 1.1em;
636
- }
469
+ ```tsx
470
+ import { ConfigProvider, Markdown } from 'ds-markdown';
471
+ import mermaidPlugin from 'ds-markdown-mermaid-plugin';
637
472
 
638
- .katex-display {
639
- margin: 1em 0;
640
- text-align: center;
641
- }
473
+ function App() {
474
+ const content = `
475
+ # Flowchart Example
476
+
477
+ \`\`\`mermaid
478
+ flowchart TD
479
+ A[Start] --> B{Decision}
480
+ B -->|Yes| C[Process A]
481
+ B -->|No| D[Process B]
482
+ C --> E[End]
483
+ D --> E
484
+ \`\`\`
485
+ `;
642
486
 
643
- /* Dark theme adaptation */
644
- [data-theme='dark'] .katex {
645
- color: #e1e1e1;
487
+ return (
488
+ <ConfigProvider>
489
+ <Markdown plugins={[mermaidPlugin]}>{content}</Markdown>
490
+ </ConfigProvider>
491
+ );
646
492
  }
647
493
  ```
648
494
 
649
- ---
650
-
651
- ## ๐Ÿ”Œ Plugin System
495
+ **Supported chart types:**
652
496
 
653
- ### Built-in Plugins
497
+ - ๐Ÿ”„ **Flowchart** - Display processes and decision paths
498
+ - ๐Ÿ“‹ **Sequence Diagram** - Display interaction timing between objects
499
+ - ๐Ÿ“… **Gantt Chart** - Project planning and timelines
500
+ - ๐Ÿ—๏ธ **Class Diagram** - Object-oriented design
501
+ - ๐Ÿฅง **Pie Chart** - Data proportion display
502
+ - ๐Ÿ”€ **State Diagram** - State transition processes
503
+ - ๐Ÿ“Š **Git Graph** - Code branch history
504
+ - ๐Ÿ—บ๏ธ **User Journey** - User experience processes
654
505
 
655
- #### KaTeX Mathematical Formula Plugin
506
+ **Configure Mermaid:**
656
507
 
657
508
  ```tsx
658
- import { katexPlugin } from 'ds-markdown/plugins';
509
+ import { ConfigProvider } from 'ds-markdown';
659
510
 
660
- // Enable mathematical formula support
661
- <DsMarkdown plugins={[katexPlugin]}>Mathematical formula: $E = mc^2$</DsMarkdown>;
511
+ const mermaidConfig = {
512
+ theme: 'default', // Themes: default, neutral, dark, forest
513
+ flowchart: {
514
+ useMaxWidth: true,
515
+ htmlLabels: true,
516
+ },
517
+ sequence: {
518
+ diagramMarginX: 50,
519
+ diagramMarginY: 10,
520
+ },
521
+ };
522
+
523
+ return (
524
+ <ConfigProvider mermaidConfig={mermaidConfig}>
525
+ <Markdown plugins={[mermaidPlugin]}>{chartContent}</Markdown>
526
+ </ConfigProvider>
527
+ );
662
528
  ```
663
529
 
530
+ **Related links:**
531
+
532
+ - [ds-markdown-mermaid-plugin GitHub](https://github.com/onshinpei/ds-markdown-mermaid-plugin)
533
+ - [Mermaid Official Documentation](https://mermaid.js.org/)
534
+
664
535
  ### Custom Plugins
665
536
 
666
537
  ```tsx
@@ -671,6 +542,10 @@ const customPlugin = createBuildInPlugin({
671
542
  remarkPlugin: yourRemarkPlugin,
672
543
  rehypePlugin: yourRehypePlugin,
673
544
  id: Symbol('custom-plugin'),
545
+ components: {
546
+ // Custom component mapping ๐Ÿ†•
547
+ CustomComponent: MyCustomComponent,
548
+ },
674
549
  });
675
550
 
676
551
  // Use custom plugin
@@ -679,50 +554,76 @@ const customPlugin = createBuildInPlugin({
679
554
 
680
555
  ---
681
556
 
682
- ## ๐ŸŽ›๏ธ Timer Mode Details
557
+ ## ๐ŸŽจ UI Component System ๐Ÿ†•
683
558
 
684
- ### `requestAnimationFrame` Mode ๐ŸŒŸ (Recommended)
559
+ ds-markdown provides rich UI components that can be used independently or in combination with markdown components.
685
560
 
686
- ```typescript
687
- // ๐ŸŽฏ Features
688
- - Time-driven: Calculates character count based on actual elapsed time
689
- - Batch processing: Can process multiple characters in a single frame
690
- - Frame-synchronized: Syncs with browser 60fps refresh rate
691
- - High-frequency optimized: Perfect support for interval < 16ms high-speed typing
561
+ ### Core Components
692
562
 
693
- // ๐ŸŽฏ Use Cases
694
- - Default choice for modern web applications
695
- - Pursuit of smooth animation effects
696
- - High-frequency typing (interval > 0 works)
697
- - AI real-time conversation scenarios
698
- ```
563
+ ```tsx
564
+ import {
565
+ Button,
566
+ IconButton,
567
+ ToolTip,
568
+ Segmented,
569
+ CopyButton,
570
+ DownloadButton
571
+ } from 'ds-markdown';
572
+
573
+ // Button component
574
+ <Button icon={<span>๐Ÿ“„</span>} onClick={() => {}}>
575
+ Click Button
576
+ </Button>
577
+
578
+ // Tooltip
579
+ <ToolTip title="Tooltip information">
580
+ <IconButton icon={<span>๐Ÿ“‹</span>} onClick={() => {}} />
581
+ </ToolTip>
582
+
583
+ // Segmented controller
584
+ <Segmented
585
+ Segmented={[
586
+ { label: 'Chart', value: 'diagram' },
587
+ { label: 'Code', value: 'code' }
588
+ ]}
589
+ value={value}
590
+ onChange={setValue}
591
+ />
699
592
 
700
- ### `setTimeout` Mode ๐Ÿ“Ÿ (Compatible)
593
+ // Code block operations
594
+ <CopyButton codeContent="console.log('Hello')" />
595
+ <DownloadButton codeContent="console.log('Hello')" language="javascript" />
596
+ ```
701
597
 
702
- ```typescript
703
- // ๐ŸŽฏ Features
704
- - Single character: Precisely processes one character at a time
705
- - Fixed interval: Strictly executes at set time intervals
706
- - Rhythmic: Classic typewriter rhythm feel
707
- - Precise control: Suitable for specific timing requirements
598
+ ### Style Customization
708
599
 
709
- // ๐ŸŽฏ Use Cases
710
- - Need precise timing control
711
- - Creating retro typewriter effects
712
- - Scenarios with high compatibility requirements
600
+ ```css
601
+ :root {
602
+ --ds-button-bg-color: #f5f5f5;
603
+ --ds-button-hover-color: #e0e0e0;
604
+ --ds-tooltip-bg-color: rgba(0, 0, 0, 0.8);
605
+ }
713
606
  ```
714
607
 
715
- ### ๐Ÿ“Š Performance Comparison
608
+ ---
609
+
610
+ ## Internationalization Configuration
611
+
612
+ ```tsx
613
+ import { ConfigProvider } from 'ds-markdown';
614
+ import zhCN from 'ds-markdown/i18n/zh';
615
+ import enUS from 'ds-markdown/i18n/en';
716
616
 
717
- | Feature | requestAnimationFrame | setTimeout |
718
- | ------------------------ | ----------------------------------- | ----------------------- |
719
- | **Character Processing** | Multiple characters per frame | One character at a time |
720
- | **High Frequency** | โœ… Excellent (5ms โ†’ 3 chars/frame) | โŒ May lag |
721
- | **Low Frequency** | โœ… Normal (100ms โ†’ 1 char/6 frames) | โœ… Precise |
722
- | **Visual Effect** | ๐ŸŽฌ Smooth animation feel | โšก Precise rhythm feel |
723
- | **Performance Overhead** | ๐ŸŸข Low (frame-synced) | ๐ŸŸก Medium (timer) |
617
+ // Chinese
618
+ <ConfigProvider locale={zhCN}>
619
+ <DsMarkdown {...props} />
620
+ </ConfigProvider>
724
621
 
725
- High frequency recommended `requestAnimationFrame`, low frequency recommended `setTimeout`
622
+ // English
623
+ <ConfigProvider locale={enUS}>
624
+ <DsMarkdown {...props} />
625
+ </ConfigProvider>
626
+ ```
726
627
 
727
628
  ---
728
629
 
@@ -732,7 +633,7 @@ High frequency recommended `requestAnimationFrame`, low frequency recommended `s
732
633
 
733
634
  [DEMO: ๐Ÿ”ง StackBlitz Experience](https://stackblitz.com/edit/vitejs-vite-2ri8kex3?file=src%2FApp.tsx)
734
635
 
735
- ````tsx
636
+ ```tsx
736
637
  import { useRef } from 'react';
737
638
  import { MarkdownCMD, MarkdownCMDRef } from 'ds-markdown';
738
639
 
@@ -756,19 +657,6 @@ function StreamingChat() {
756
657
  '- ๐ŸŽฏ **Automatic optimization**: No need for manual memo and useMemo\n',
757
658
  '- โšก **Performance boost**: Compile-time optimization, zero runtime overhead\n',
758
659
  '- ๐Ÿ”ง **Backward compatible**: Existing code needs no modification\n\n',
759
- '## ๐Ÿ“ Actions Simplify Forms\n',
760
- 'The new Actions API makes form handling simpler:\n\n',
761
- '```tsx\n',
762
- 'function ContactForm({ action }) {\n',
763
- ' const [state, formAction] = useActionState(action, null);\n',
764
- ' return (\n',
765
- ' <form action={formAction}>\n',
766
- ' <input name="email" type="email" />\n',
767
- ' <button>Submit</button>\n',
768
- ' </form>\n',
769
- ' );\n',
770
- '}\n',
771
- '```\n\n',
772
660
  'Hope this answer helps you! ๐ŸŽ‰',
773
661
  ];
774
662
 
@@ -778,273 +666,12 @@ function StreamingChat() {
778
666
  }
779
667
  };
780
668
 
669
+ const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
670
+
781
671
  return (
782
672
  <div className="chat-container">
783
673
  <button onClick={simulateAIResponse}>๐Ÿค– Ask about React 19 features</button>
784
-
785
- <MarkdownCMD ref={markdownRef} interval={10} timerType="requestAnimationFrame" onEnd={(data) => console.log('Section complete:', data)} />
786
- </div>
787
- );
788
- }
789
-
790
- const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
791
- ````
792
-
793
- ### ๐Ÿงฎ Mathematical Formula Streaming Rendering
794
-
795
- ```tsx
796
- import { katexPlugin } from 'ds-markdown/plugins';
797
-
798
- function MathStreamingDemo() {
799
- const markdownRef = useRef<MarkdownCMDRef>(null);
800
-
801
- const simulateMathResponse = async () => {
802
- markdownRef.current?.clear();
803
-
804
- const mathChunks = [
805
- '# Pythagorean Theorem Explained\n\n',
806
- 'In a right triangle, the square of the hypotenuse equals the sum of squares of the two legs:\n\n',
807
- '$a^2 + b^2 = c^2$\n\n',
808
- 'Where:\n',
809
- '- $a$ and $b$ are the legs\n',
810
- '- $c$ is the hypotenuse\n\n',
811
- 'For the classic "3-4-5" triangle:\n',
812
- '$c = \\sqrt{3^2 + 4^2} = \\sqrt{25} = 5$\n\n',
813
- 'This theorem has wide applications in geometry!',
814
- ];
815
-
816
- for (const chunk of mathChunks) {
817
- await delay(150);
818
- markdownRef.current?.push(chunk, 'answer');
819
- }
820
- };
821
-
822
- return (
823
- <div>
824
- <button onClick={simulateMathResponse}>๐Ÿ“ Explain Pythagorean Theorem</button>
825
-
826
- <MarkdownCMD ref={markdownRef} interval={20} timerType="requestAnimationFrame" plugins={[katexPlugin]} math={{ splitSymbol: 'dollar' }} />
827
- </div>
828
- );
829
- }
830
- ```
831
-
832
- ### ๐ŸŽฏ Advanced Callback Control
833
-
834
- ```tsx
835
- import { useRef, useState } from 'react';
836
- import { MarkdownCMD, MarkdownCMDRef } from 'ds-markdown';
837
-
838
- function AdvancedCallbackDemo() {
839
- const markdownRef = useRef<MarkdownCMDRef>(null);
840
- const [typingStats, setTypingStats] = useState({ progress: 0, currentChar: '', totalChars: 0 });
841
-
842
- const handleBeforeTypedChar = async (data) => {
843
- // Perform async operations before character typing
844
- console.log('About to type:', data.currentChar);
845
-
846
- // Can perform network requests, data validation, etc.
847
- if (data.currentChar === '!') {
848
- await new Promise((resolve) => setTimeout(resolve, 500)); // Simulate delay
849
- }
850
- };
851
-
852
- const handleTypedChar = (data) => {
853
- // Update typing statistics
854
- setTypingStats({
855
- progress: Math.round(data.percent),
856
- currentChar: data.currentChar,
857
- totalChars: data.currentIndex + 1,
858
- });
859
-
860
- // Can add sound effects, animations, etc.
861
- if (data.currentChar === '.') {
862
- // Play period sound effect
863
- console.log('Play period sound effect');
864
- }
865
- };
866
-
867
- const handleStart = (data) => {
868
- console.log('Start typing:', data.currentChar);
869
- };
870
-
871
- const handleEnd = (data) => {
872
- console.log('Typing complete:', data.str);
873
- };
874
-
875
- const startDemo = () => {
876
- markdownRef.current?.clear();
877
- markdownRef.current?.push(
878
- '# Advanced Callback Demo\n\n' +
879
- 'This example shows how to use `onBeforeTypedChar` and `onTypedChar` callbacks:\n\n' +
880
- '- ๐ŸŽฏ **Pre-typing callback**: Can perform async operations before character display\n' +
881
- '- ๐Ÿ“Š **Post-typing callback**: Can update progress in real-time and add effects\n' +
882
- '- โšก **Performance optimization**: Supports async operations without affecting typing smoothness\n\n' +
883
- 'Current progress: ' +
884
- typingStats.progress +
885
- '%\n' +
886
- 'Characters typed: ' +
887
- typingStats.totalChars +
888
- '\n\n' +
889
- 'This is a very powerful feature!',
890
- 'answer',
891
- );
892
- };
893
-
894
- return (
895
- <div>
896
- <button onClick={startDemo}>๐Ÿš€ Start Advanced Demo</button>
897
-
898
- <div style={{ margin: '10px 0', padding: '10px', background: '#f5f5f5', borderRadius: '4px' }}>
899
- <strong>Typing Stats:</strong> Progress {typingStats.progress}% | Current char: "{typingStats.currentChar}" | Total chars: {typingStats.totalChars}
900
- </div>
901
-
902
- <MarkdownCMD ref={markdownRef} interval={30} onBeforeTypedChar={handleBeforeTypedChar} onTypedChar={handleTypedChar} onStart={handleStart} onEnd={handleEnd} />
903
- </div>
904
- );
905
- }
906
- ```
907
-
908
- ### ๐Ÿ”„ Restart Animation Demo
909
-
910
- ```tsx
911
- import { useRef, useState } from 'react';
912
- import { MarkdownCMD, MarkdownCMDRef } from 'ds-markdown';
913
-
914
- function RestartDemo() {
915
- const markdownRef = useRef<MarkdownCMDRef>(null);
916
- const [isPlaying, setIsPlaying] = useState(false);
917
- const [hasStarted, setHasStarted] = useState(false);
918
-
919
- const startContent = () => {
920
- markdownRef.current?.clear();
921
- markdownRef.current?.push(
922
- '# Restart Animation Demo\n\n' +
923
- 'This example shows how to use the `restart()` method:\n\n' +
924
- '- ๐Ÿ”„ **Restart**: Play current content from the beginning\n' +
925
- '- โธ๏ธ **Pause/Resume**: Can pause and resume at any time\n' +
926
- '- ๐ŸŽฏ **Precise Control**: Complete control over animation playback state\n\n' +
927
- 'Current state: ' +
928
- (isPlaying ? 'Playing' : 'Paused') +
929
- '\n\n' +
930
- 'This is a very practical feature!',
931
- 'answer',
932
- );
933
- setIsPlaying(true);
934
- };
935
-
936
- const handleStart = () => {
937
- if (hasStarted) {
938
- // If already started, restart
939
- markdownRef.current?.restart();
940
- } else {
941
- // First time start
942
- markdownRef.current?.start();
943
- setHasStarted(true);
944
- }
945
- setIsPlaying(true);
946
- };
947
-
948
- const handleStop = () => {
949
- markdownRef.current?.stop();
950
- setIsPlaying(false);
951
- };
952
-
953
- const handleResume = () => {
954
- markdownRef.current?.resume();
955
- setIsPlaying(true);
956
- };
957
-
958
- const handleRestart = () => {
959
- markdownRef.current?.restart();
960
- setIsPlaying(true);
961
- };
962
-
963
- const handleEnd = () => {
964
- setIsPlaying(false);
965
- };
966
-
967
- return (
968
- <div>
969
- <div style={{ marginBottom: '10px', display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
970
- <button onClick={startContent}>๐Ÿš€ Start Content</button>
971
- <button onClick={handleStart} disabled={isPlaying}>
972
- {hasStarted ? '๐Ÿ”„ Restart' : 'โ–ถ๏ธ Start'}
973
- </button>
974
- <button onClick={handleStop} disabled={!isPlaying}>
975
- โธ๏ธ Pause
976
- </button>
977
- <button onClick={handleResume} disabled={isPlaying}>
978
- โ–ถ๏ธ Resume
979
- </button>
980
- <button onClick={handleRestart}>๐Ÿ”„ Restart</button>
981
- </div>
982
-
983
- <div style={{ margin: '10px 0', padding: '10px', background: '#f5f5f5', borderRadius: '4px' }}>
984
- <strong>Animation State:</strong> {isPlaying ? '๐ŸŸข Playing' : '๐Ÿ”ด Paused'}
985
- </div>
986
-
987
- <MarkdownCMD ref={markdownRef} interval={25} onEnd={handleEnd} />
988
- </div>
989
- );
990
- }
991
- ```
992
-
993
- ### โ–ถ๏ธ Manual Start Animation Demo
994
-
995
- ```tsx
996
- import { useRef, useState } from 'react';
997
- import { MarkdownCMD, MarkdownCMDRef } from 'ds-markdown';
998
-
999
- function StartDemo() {
1000
- const markdownRef = useRef<MarkdownCMDRef>(null);
1001
- const [isPlaying, setIsPlaying] = useState(false);
1002
- const [hasStarted, setHasStarted] = useState(false);
1003
-
1004
- const loadContent = () => {
1005
- markdownRef.current?.clear();
1006
- markdownRef.current?.push(
1007
- '# Manual Start Animation Demo\n\n' +
1008
- 'This example shows how to use the `start()` method:\n\n' +
1009
- '- ๐ŸŽฏ **Manual Control**: When `autoStartTyping=false`, need to manually call `start()`\n' +
1010
- '- โฑ๏ธ **Delayed Start**: Can start animation after user interaction\n' +
1011
- '- ๐ŸŽฎ **Gamification**: Suitable for scenarios requiring user initiative\n\n' +
1012
- 'Click the "Start Animation" button to manually trigger the typing effect!',
1013
- 'answer',
1014
- );
1015
- setIsPlaying(false);
1016
- };
1017
-
1018
- const handleStart = () => {
1019
- if (hasStarted) {
1020
- // If already started, restart
1021
- markdownRef.current?.restart();
1022
- } else {
1023
- // First time start
1024
- markdownRef.current?.start();
1025
- setHasStarted(true);
1026
- }
1027
- setIsPlaying(true);
1028
- };
1029
-
1030
- const handleEnd = () => {
1031
- setIsPlaying(false);
1032
- };
1033
-
1034
- return (
1035
- <div>
1036
- <div style={{ marginBottom: '10px', display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
1037
- <button onClick={loadContent}>๐Ÿ“ Load Content</button>
1038
- <button onClick={handleStart} disabled={isPlaying}>
1039
- {hasStarted ? '๐Ÿ”„ Restart' : 'โ–ถ๏ธ Start Animation'}
1040
- </button>
1041
- </div>
1042
-
1043
- <div style={{ margin: '10px 0', padding: '10px', background: '#f5f5f5', borderRadius: '4px' }}>
1044
- <strong>State:</strong> {isPlaying ? '๐ŸŸข Animation Playing' : '๐Ÿ”ด Waiting to Start'}
1045
- </div>
1046
-
1047
- <MarkdownCMD ref={markdownRef} interval={30} autoStartTyping={false} onEnd={handleEnd} />
674
+ <MarkdownCMD ref={markdownRef} interval={10} timerType="requestAnimationFrame" />
1048
675
  </div>
1049
676
  );
1050
677
  }
@@ -1060,9 +687,6 @@ function StartDemo() {
1060
687
  timerType="requestAnimationFrame"
1061
688
  interval={15} // 15-30ms for best experience
1062
689
  />
1063
-
1064
- // โŒ Avoid too small intervals
1065
- <DsMarkdown interval={1} /> // May cause performance issues
1066
690
  ```
1067
691
 
1068
692
  ### 2. Streaming Data Processing
@@ -1073,141 +697,31 @@ const ref = useRef<MarkdownCMDRef>(null);
1073
697
  useEffect(() => {
1074
698
  ref.current?.push(newChunk, 'answer');
1075
699
  }, [newChunk]);
1076
-
1077
- // โŒ Avoid: Frequent children updates
1078
- const [content, setContent] = useState('');
1079
- // Each update re-parses the entire content
1080
700
  ```
1081
701
 
1082
702
  ### 3. Mathematical Formula Optimization
1083
703
 
1084
704
  ```tsx
1085
- // โœ… Recommended: Load math formula styles on demand
1086
- import 'ds-markdown/style.css';
705
+ // โœ… Recommended: Load on demand
706
+ import { katexPlugin } from 'ds-markdown/plugins';
1087
707
  import 'ds-markdown/katex.css'; // Only import when needed
1088
708
 
1089
- // โœ… Recommended: Use delimiters appropriately
1090
- // For simple formulas, use $...$ for simplicity
1091
- // For complex formulas, use $$...$$ for clarity
1092
-
1093
- // โœ… Recommended: Plugin configuration
1094
- import { katexPlugin } from 'ds-markdown/plugins';
1095
709
  <DsMarkdown plugins={[katexPlugin]}>Mathematical formula content</DsMarkdown>;
1096
710
  ```
1097
711
 
1098
- ### 4. Type Safety
712
+ ### 4. Mermaid Chart Best Practices ๐Ÿ†•
1099
713
 
1100
714
  ```tsx
1101
- import { MarkdownCMDRef } from 'ds-markdown';
715
+ // โœ… Recommended: Install plugin separately
716
+ npm install ds-markdown-mermaid-plugin
1102
717
 
1103
- const ref = useRef<MarkdownCMDRef>(null);
1104
- // Complete TypeScript type hints
1105
- ```
1106
-
1107
- ## ConfigProvider Internationalization (i18n)
1108
-
1109
- ConfigProvider is a component provided by ds-markdown for managing internationalized text in your application.
1110
-
1111
- ### Basic Usage
1112
-
1113
- ```tsx
1114
- import React from 'react';
1115
- import { ConfigProvider } from 'ds-markdown';
1116
- import zhCN from 'ds-markdown/i18n/zh';
1117
-
1118
- const App: React.FC = () => {
1119
- return (
1120
- <ConfigProvider locale={zhCN}>
1121
- <YourApp />
1122
- </ConfigProvider>
1123
- );
718
+ // โœ… Recommended: Configure suitable theme
719
+ const mermaidConfig = {
720
+ theme: 'default', // Choose based on application theme
721
+ flowchart: { useMaxWidth: true },
1124
722
  };
1125
- ```
1126
-
1127
- ### Available Locales
1128
-
1129
- #### Chinese (zhCN)
1130
723
 
1131
- ```tsx
1132
- import zhCN from 'ds-markdown/i18n/zh';
724
+ <ConfigProvider mermaidConfig={mermaidConfig}>
725
+ <DsMarkdown plugins={[mermaidPlugin]} />
726
+ </ConfigProvider>
1133
727
  ```
1134
-
1135
- #### English (enUS)
1136
-
1137
- ```tsx
1138
- import enUS from 'ds-markdown/i18n/en';
1139
- ```
1140
-
1141
- ### Using Locale in Components
1142
-
1143
- Use the `useLocale` hook to get the current locale:
1144
-
1145
- ```tsx
1146
- import React from 'react';
1147
- import { useLocale } from 'ds-markdown';
1148
-
1149
- const MyComponent: React.FC = () => {
1150
- const locale = useLocale();
1151
-
1152
- return (
1153
- <div>
1154
- <button>{locale.codeBlock.copy}</button>
1155
- <span>{locale.codeBlock.copied}</span>
1156
- <button>{locale.codeBlock.download}</button>
1157
- </div>
1158
- );
1159
- };
1160
- ```
1161
-
1162
- ### Locale Structure
1163
-
1164
- Currently supported locale fields:
1165
-
1166
- ```typescript
1167
- interface Locale {
1168
- codeBlock: {
1169
- copy: string;
1170
- copied: string;
1171
- download: string;
1172
- };
1173
- [key: string]: string;
1174
- }
1175
- ```
1176
-
1177
- ### Full Example
1178
-
1179
- ```tsx
1180
- import React from 'react';
1181
- import { ConfigProvider, useLocale } from 'ds-markdown';
1182
- import zhCN from 'ds-markdown/i18n/zh';
1183
-
1184
- const ExampleComponent: React.FC = () => {
1185
- const locale = useLocale();
1186
-
1187
- return (
1188
- <div>
1189
- <h2>i18n Example</h2>
1190
- <p>Copy button: {locale.codeBlock.copy}</p>
1191
- <p>Copied tip: {locale.codeBlock.copied}</p>
1192
- <p>Download button: {locale.codeBlock.download}</p>
1193
- </div>
1194
- );
1195
- };
1196
-
1197
- const App: React.FC = () => {
1198
- return (
1199
- <ConfigProvider locale={zhCN}>
1200
- <ExampleComponent />
1201
- </ConfigProvider>
1202
- );
1203
- };
1204
-
1205
- export default App;
1206
- ```
1207
-
1208
- ### Notes
1209
-
1210
- 1. `ConfigProvider` must wrap components that use `useLocale`.
1211
- 2. The locale object is memoized to avoid unnecessary re-renders.
1212
- 3. You can extend the locale object with custom fields.
1213
- 4. If `ConfigProvider` is not provided, the default locale is Chinese.