Package Exports
- ds-markdown
- ds-markdown/i18n/en
- ds-markdown/i18n/zh
- ds-markdown/katex.css
- ds-markdown/plugins
- ds-markdown/style.css
Readme
ds-markdown
π React Markdown typing animation component for modern chat interface effects
πΊπΈ English | π¨π³ δΈζ
A React component designed specifically for modern AI applications, providing smooth real-time typing animations and complete Markdown rendering capabilities.
- Documentation
- Usage Examples
If you want a clean react markdown typing component, you can use react-markdown-typer
β Why use ds-markdown?
π― Core Problems Solved
Streaming Data Typing Stuttering Issues
Traditional typewriter components experience stuttering and character jumping when processing AI backend streaming data, as each chunk contains multiple characters. ds-markdown intelligently splits each chunk to ensure smooth typing for every character.Markdown Rendering and Typing Animation Disconnection
Most typewriter components only support plain text and cannot render Markdown syntax, mathematical formulas, charts, and other rich media content in real-time during typing.
π Value Delivered
Enhanced User Immersion
Provides professional-level AI chat experience, allowing users to feel authentic AI interaction processes, greatly improving product professionalism and user satisfaction.Out-of-the-box, Reduces Development Complexity
Complete solution that requires no additional configuration to support streaming data, Markdown rendering, mathematical formulas, charts, and other complex features.Adapts to Multiple Application Scenarios
From AI chatbots to educational content display, from technical documentation to product demos, one component meets multiple needs.
Table of Contents
- ds-markdown
β¨ Core Features
π€ AI Chat Scenarios
- Professional-level AI chat response effects, comparable to mainstream AI platform experiences
- Supports thinking process (
thinking) and answer contentanswer) dual modes - Perfect streaming data adaptation with zero-delay response to user input
π Content Display Scenarios
- Complete Markdown syntax support, including code highlighting, tables, lists, etc.
- Mathematical formula rendering (KaTeX), supporting
$...$and\[...\]syntax - Mermaid chart support, including flowcharts, sequence diagrams, Gantt charts, class diagrams, etc. π
- Supports light/dark themes, adapting to different product styles
- Plugin architecture supporting remark/rehype plugin extensions
π¨ UI Component System π
- Code block and chart enhancement features: copy, download, language, etc.
- Built-in rich UI components: Button, IconButton, ToolTip, Segmented, etc.
- Complete interactive experience and accessibility support
π§ Development Experience
- Rich imperative API:
start,stop,resume,restart, etc. - Supports typing interruption and continuation, flexible control of animation states
- Supports typing on/off, meeting different scenario requirements
- Complete TypeScript type support
π¬ Smooth Animation
- Dual-mode timer optimization, supporting
requestAnimationFrameandsetTimeoutmodes - High-frequency typing support (typing interval can be as low as close to
0msinrequestAnimationFramemode) - Frame-synchronized rendering, perfectly coordinated with browser refresh
- Intelligent character batch processing for more natural visual effects
β‘ Performance Optimization
- Lightweight design, small size and excellent performance
- Core dependency react-markdown, no heavyweight dependencies
π¦ Quick Installation
# npm
npm install ds-markdown
# yarn
yarn add ds-markdown
# pnpm
pnpm add ds-markdownUsing via ESM CDN
No installation required, use directly in the browser:
<!-- Import styles, required -->
<link rel="stylesheet" href="https://esm.sh/ds-markdown/dist/style.css" />
<!-- Import KaTeX math formula styles, only import if needed -->
<link rel="stylesheet" href="https://esm.sh/ds-markdown/dist/katex.css" />
<!-- Import component -->
<script type="module">
import Markdown from 'https://esm.sh/ds-markdown';
</script>π 5-Minute Quick Start
β Starting from v1.0+, you no longer need to manually import
ds-markdown/style.css; the component automatically injects the required base styles.
Basic Usage
import DsMarkdown from 'ds-markdown';
function App() {
return (
<DsMarkdown interval={20} answerType="answer">
# Hello ds-markdown This is a **high-performance** typing animation component! ## Features - β‘ Zero-delay streaming processing - π¬ Smooth typing animation - π― Perfect syntax support
</DsMarkdown>
);
}Disable Typing Animation
import DsMarkdown from 'ds-markdown';
function StaticDemo() {
const [disableTyping, setDisableTyping] = useState(false);
return (
<div>
<button onClick={() => setDisableTyping(!disableTyping)}>{disableTyping ? 'Enable' : 'Disable'} Typewriter Effect</button>
<DsMarkdown interval={20} answerType="answer" disableTyping={disableTyping}>
# Static Display Mode When `disableTyping` is `true`, content will be displayed immediately without typing animation effects. This is very useful in certain scenarios: - π Static document
display - π Switching display modes - β‘ Quick content preview
</DsMarkdown>
</div>
);
}Mathematical Formula Support
import DsMarkdown from 'ds-markdown';
// If you need to display formulas, you need to import the formula conversion plugin
import { katexPlugin } from 'ds-markdown/plugins';
import 'ds-markdown/style.css';
// If you need to display formulas, you need to import math formula styles
import 'ds-markdown/katex.css';
function MathDemo() {
return (
<DsMarkdown interval={20} answerType="answer" plugins={[katexPlugin]} math={{ splitSymbol: 'dollar' }}>
# Pythagorean Theorem In a right triangle, the square of the hypotenuse equals the sum of the squares of the two legs: $a^2 + b^2 = c^2$ Where: - $a$ and $b$ are the legs - $c$ is the hypotenuse
For the classic "3-4-5 triangle": $c = \sqrt{3 ^ (2 + 4) ^ 2} = \sqrt{25} = 5$
</DsMarkdown>
);
}AI Chat Scenarios
function ChatDemo() {
const [thinking, setThinking] = useState('');
const [answer, setAnswer] = useState('');
const handleAsk = () => {
setThinking('π€ Thinking about your question...');
setTimeout(() => {
setAnswer(`# About React 19
React 19 brings many exciting new features:
## π Major Updates
1. **React Compiler** - Automatic performance optimization
2. **Actions** - Simplified form handling
3. **Document Metadata** - Built-in SEO support
Let's explore these new features together!`);
}, 2000);
};
return (
<div>
<button onClick={handleAsk}>Ask AI</button>
{thinking && (
<DsMarkdown answerType="thinking" interval={30}>
{thinking}
</DsMarkdown>
)}
{answer && (
<DsMarkdown answerType="answer" interval={15}>
{answer}
</DsMarkdown>
)}
</div>
);
}Code Block Features π
import DsMarkdown from 'ds-markdown';
function CodeBlockDemo() {
const codeContent = `# Hello World
\`\`\`javascript
function greet(name) {
console.log(\`Hello, \${name}!\`);
}
greet('ds-markdown');
\`\`\`
Supports code highlighting, copying, and downloading!`;
return (
<DsMarkdown
interval={20}
answerType="answer"
codeBlock={{
headerActions: true, // Enable code block header action buttons
}}
>
{codeContent}
</DsMarkdown>
);
}Mermaid Chart Support
import DsMarkdown from 'ds-markdown';
import { ConfigProvider } from 'ds-markdown';
import mermaidPlugin from 'ds-markdown-mermaid-plugin';
import 'ds-markdown/style.css';
function MermaidDemo() {
const chartContent = `Here's a simplified learning to drive flowchart, keeping only the **most core steps**, suitable for quickly mastering key nodes:
\`\`\`mermaid
graph TD
A[Start] --> B[Subject 1: Theory Exam]
B --> C[Subject 2: Field Five Items]
C --> D[Subject 3: Road Test]
D --> E[Subject 4: Safety Written Test]
E --> F[Get Driver's License]
F --> G[Actual Driving Practice]
\`\`\`
### Minimalist Explanation:
1. **Theory First**: Pass traffic rules written test (Subject 1).
2. **Field Basics**: Practice reversing, hill starts, etc. (Subject 2).
3. **Road Combat**: Actual road driving test (Subject 3).
4. **Safety Finish**: Pass Subject 4 to get license.
5. **Continuous Proficiency**: Continue practicing after getting license to adapt to real road conditions.
### Visualization Suggestions:
- When sketching with phone memo or white paper, write steps in **arrow order**.
- Want more intuitive? Use circular sticky notes for each subject, connect them into a flow.`;
return (
<ConfigProvider>
<DsMarkdown interval={20} answerType="answer" plugins={[mermaidPlugin]}>
{chartContent}
</DsMarkdown>
</ConfigProvider>
);
}
π Complete API Documentation
Default export DsMarkdown and MarkdownCMD props
import DsMarkdown, { MarkdownCMD } from 'ds-markdown';| Property | Type | Description | Default Value |
|---|---|---|---|
interval |
number |
Typing interval (milliseconds) | 30 |
timerType |
'setTimeout' | 'requestAnimationFrame' |
Timer type, does not support dynamic modification | Current default is setTimeout, will change to requestAnimationFrame later |
answerType |
'thinking' | 'answer' |
Content type (affects style theme), does not support dynamic modification | 'answer' |
theme |
'light' | 'dark' |
Theme type | 'light' |
plugins |
IMarkdownPlugin[] |
Plugin configuration | [] |
math |
IMarkdownMath | Mathematical formula configuration | { splitSymbol: 'dollar' } |
onEnd |
(data: EndData) => void |
Typing completion callback | - |
onStart |
(data: StartData) => void |
Typing start callback | - |
onBeforeTypedChar |
(data: IBeforeTypedChar) => Promise<void> |
Callback before character typing, supports async operations, blocks subsequent typing | - |
onTypedChar |
(data: ITypedChar) => void |
Callback after each character typing | - |
disableTyping |
boolean |
Disable typing animation effects | false |
autoStartTyping |
boolean |
Whether to automatically start typing animation, set to false for manual trigger, does not support dynamic modification | true |
codeBlock |
IMarkdownCode |
Code block configuration | {headerActions: true} |
Note: If
disableTypingchanges fromtruetofalseduring typing
IBeforeTypedChar
| Property | Type | Description | Default Value |
|---|---|---|---|
currentIndex |
number |
Current character index in the entire string | 0 |
currentChar |
string |
Current character about to be typed | - |
answerType |
AnswerType |
Content type (thinking/answer) | - |
prevStr |
string |
Prefix string of current type content | - |
percent |
number |
Typing progress percentage (0-100) | 0 |
ITypedChar
| Property | Type | Description | Default Value |
|---|---|---|---|
currentIndex |
number |
Current character index in the entire string | 0 |
currentChar |
string |
Current typed character | - |
answerType |
AnswerType |
Content type (thinking/answer) | - |
prevStr |
string |
Prefix string of current type content | - |
currentStr |
string |
Complete string of current type content | - |
percent |
number |
Typing progress percentage (0-100) | 0 |
IMarkdownMath
| Property | Type | Description | Default Value |
|---|---|---|---|
splitSymbol |
'dollar' | 'bracket' |
Math formula delimiter type | 'dollar' |
Delimiter Description:
'dollar': Uses$...$and$$...$$syntax'bracket': Uses\(...\)and\[...\]syntax
IMarkdownCode π
| Property | Type | Description | Default Value |
|---|---|---|---|
headerActions |
boolean |
Whether to show header action buttons | true |
IMarkdownPlugin
| Property | Type | Description | Default Value |
|---|---|---|---|
remarkPlugin |
Pluggable |
remark plugin | - |
rehypePlugin |
Pluggable |
rehype plugin | - |
type |
'buildIn' | 'custom' |
Plugin type | - |
id |
any |
Plugin unique identifier | - |
components |
Record<string, React.ComponentType<unknown>> |
Custom component mapping π | - |
Component Exposed Methods
Default export DsMarkdown
| Method | Parameters | Description |
|---|---|---|
start |
- | Start typing animation |
stop |
- | Pause typing animation |
resume |
- | Resume typing animation |
restart |
- | Restart typing animation, play current content from beginning |
MarkdownCMD Exposed Methods
| Method | Parameters | Description |
|---|---|---|
push |
(content: string, answerType: AnswerType) |
Add content and start typing |
clear |
- | Clear all content and state |
triggerWholeEnd |
- | Manually trigger completion callback |
start |
- | Start typing animation |
stop |
- | Pause typing animation |
resume |
- | Resume typing animation |
restart |
- | Restart typing animation, play current content from beginning |
Usage Examples:
markdownRef.current?.start(); // Start animation
markdownRef.current?.stop(); // Pause animation
markdownRef.current?.resume(); // Resume animation
markdownRef.current?.restart(); // Restart animationπ Plugin System
Built-in Plugins
KaTeX Mathematical Formula Plugin
import { katexPlugin } from 'ds-markdown/plugins';
// Enable mathematical formula support
<DsMarkdown plugins={[katexPlugin]}>Math formula: $E = mc^2$</DsMarkdown>;Mermaid Chart Plugin π
Install Mermaid Plugin:
npm install ds-markdown-mermaid-pluginBasic Usage:
import { ConfigProvider, Markdown } from 'ds-markdown';
import mermaidPlugin from 'ds-markdown-mermaid-plugin';
function App() {
const content = `
# Flowchart Example
\`\`\`mermaid
flowchart TD
A[Start] --> B{Decision}
B -->|Yes| C[Process A]
B -->|No| D[Process B]
C --> E[End]
D --> E
\`\`\`
`;
return (
<ConfigProvider>
<Markdown plugins={[mermaidPlugin]}>{content}</Markdown>
</ConfigProvider>
);
}Supported Chart Types:
- π Flowchart - Display processes and decision paths
- π Sequence Diagram - Display interaction timing between objects
- π Gantt Chart - Project planning and timelines
- ποΈ Class Diagram - Object-oriented design
- π₯§ Pie Chart - Data proportion display
- π State Diagram - State transition processes
- π Git Graph - Code branch history
- πΊοΈ User Journey - User experience flow
Configure Mermaid:
import { ConfigProvider } from 'ds-markdown';
const mermaidConfig = {
theme: 'default', // Theme: default, neutral, dark, forest
flowchart: {
useMaxWidth: true,
htmlLabels: true,
},
sequence: {
diagramMarginX: 50,
diagramMarginY: 10,
},
};
return (
<ConfigProvider mermaidConfig={mermaidConfig}>
<Markdown plugins={[mermaidPlugin]}>{chartContent}</Markdown>
</ConfigProvider>
);Related Links:
Custom Plugins
import { createBuildInPlugin } from 'ds-markdown/plugins';
// Create custom plugin
const customPlugin = createBuildInPlugin({
remarkPlugin: yourRemarkPlugin,
rehypePlugin: yourRehypePlugin,
id: Symbol('custom-plugin'),
components: {
// Custom component mapping π
CustomComponent: MyCustomComponent,
},
});
// Use custom plugin
<DsMarkdown plugins={[katexPlugin, customPlugin]}>Content</DsMarkdown>;π¨ UI Component System π
ds-markdown provides rich UI components that can be used individually or in combination with markdown components.
Core Components
import {
Button,
IconButton,
ToolTip,
Segmented,
CopyButton,
DownloadButton
} from 'ds-markdown';
// Button component
<Button icon={<span>π</span>} onClick={() => {}}>
Click Button
</Button>
// Tooltip
<ToolTip title="Tooltip information">
<IconButton icon={<span>π</span>} onClick={() => {}} />
</ToolTip>
// Segmented controller
<Segmented
options={[
{ label: 'Chart', value: 'diagram' },
{ label: 'Code', value: 'code' }
]}
value={value}
onChange={setValue}
/>
// Code block operations
<CopyButton codeContent="console.log('Hello')" />
<DownloadButton codeContent="console.log('Hello')" language="javascript" />Style Customization
:root {
--ds-button-bg-color: #f5f5f5;
--ds-button-hover-color: #e0e0e0;
--ds-tooltip-bg-color: rgba(0, 0, 0, 0.8);
}Multi-language Configuration
import { ConfigProvider } from 'ds-markdown';
import zhCN from 'ds-markdown/i18n/zh';
import enUS from 'ds-markdown/i18n/en';
// Chinese
<ConfigProvider locale={zhCN}>
<DsMarkdown {...props} />
</ConfigProvider>
// English
<ConfigProvider locale={enUS}>
<DsMarkdown {...props} />
</ConfigProvider>π‘ Practical Examples
π AI Streaming Chat
DEMO: π§ StackBlitz Experience
import { useRef } from 'react';
import { MarkdownCMD, MarkdownCMDRef } from 'ds-markdown';
function StreamingChat() {
const markdownRef = useRef<MarkdownCMDRef>(null);
// Simulate AI streaming response
const simulateAIResponse = async () => {
markdownRef.current?.clear();
// Thinking phase
markdownRef.current?.push('π€ Analyzing your question...', 'thinking');
await delay(1000);
markdownRef.current?.push('\n\nβ
Analysis complete, starting to answer', 'thinking');
// Streaming answer
const chunks = [
'# React 19 New Features Analysis\n\n',
'## π React Compiler\n',
'The biggest highlight of React 19 is the introduction of **React Compiler**:\n\n',
'- π― **Automatic Optimization**: No need for manual memo and useMemo\n',
'- β‘ **Performance Boost**: Compile-time optimization, zero runtime overhead\n',
'- π§ **Backward Compatible**: Existing code requires no modification\n\n',
'Hope this answer helps you! π',
];
for (const chunk of chunks) {
await delay(100);
markdownRef.current?.push(chunk, 'answer');
}
};
const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
return (
<div className="chat-container">
<button onClick={simulateAIResponse}>π€ Ask about React 19 New Features</button>
<MarkdownCMD ref={markdownRef} interval={10} timerType="requestAnimationFrame" />
</div>
);
}π§ Best Practices
1. Performance Optimization
// β
Recommended configuration
<DsMarkdown
timerType="requestAnimationFrame"
interval={15} // 15-30ms for best experience
/>2. Streaming Data Processing
// β
Recommended: Imperative API
const ref = useRef<MarkdownCMDRef>(null);
useEffect(() => {
ref.current?.push(newChunk, 'answer');
}, [newChunk]);3. Mathematical Formula Optimization
// β
Recommended: Load on demand
import { katexPlugin } from 'ds-markdown/plugins';
import 'ds-markdown/katex.css'; // Only import when needed
<DsMarkdown plugins={[katexPlugin]}>Mathematical formula content</DsMarkdown>;4. Mermaid Chart Best Practices π
// β
Recommended: Install plugin separately
npm install ds-markdown-mermaid-plugin
// β
Recommended: Configure suitable themes
const mermaidConfig = {
theme: 'default', // Choose based on application theme
flowchart: { useMaxWidth: true },
};
<ConfigProvider mermaidConfig={mermaidConfig}>
<DsMarkdown plugins={[mermaidPlugin]} />
</ConfigProvider>