@incremark/react 0.2.7 → 0.3.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.en.md CHANGED
@@ -1,15 +1,18 @@
1
1
  # @incremark/react
2
2
 
3
- React 18+ integration for Incremark.
3
+ React 18+ integration library for Incremark, providing high-performance streaming Markdown rendering components.
4
4
 
5
5
  **[🇨🇳 中文](./README.md)** | 🇺🇸 English
6
6
 
7
- ## Features
7
+ ## Core Advantages
8
8
 
9
- - 📦 **Out of the Box** - Provides `useIncremark` hook and `<Incremark>` component
10
- - 🎨 **Customizable** - Support for custom render components
11
- - **High Performance** - Leverages React's reconciliation mechanism
12
- - 🔧 **DevTools** - Built-in developer tools
9
+ - 📦 **Out of the Box** - Provides `IncremarkContent` component and `useIncremark` hook
10
+ - **Extreme Performance** - Incremental parsing with O(n) complexity, dual-engine support
11
+ - ⌨️ **Typewriter Effect** - Built-in animation effects (fade-in, typing)
12
+ - 🎨 **Highly Customizable** - Custom components, code blocks, containers
13
+ - 🎯 **Theme System** - Built-in ThemeProvider with light/dark themes
14
+ - 📜 **Auto Scroll** - Built-in AutoScrollContainer component
15
+ - 🔧 **DevTools** - Built-in developer debugging tools
13
16
 
14
17
  ## Installation
15
18
 
@@ -19,20 +22,63 @@ pnpm add @incremark/core @incremark/react
19
22
 
20
23
  ## Quick Start
21
24
 
22
- **1. Import Styles**
25
+ ### Recommended: IncremarkContent Component
23
26
 
24
27
  ```tsx
28
+ import { useState } from 'react'
29
+ import { IncremarkContent } from '@incremark/react'
25
30
  import '@incremark/react/styles.css'
31
+
32
+ function App() {
33
+ const [content, setContent] = useState('')
34
+ const [isFinished, setIsFinished] = useState(false)
35
+
36
+ // Handle AI streaming output
37
+ async function handleStream(stream: ReadableStream) {
38
+ setContent('')
39
+ setIsFinished(false)
40
+
41
+ const reader = stream.getReader()
42
+ const decoder = new TextDecoder()
43
+
44
+ while (true) {
45
+ const { done, value } = await reader.read()
46
+ if (done) break
47
+ setContent(prev => prev + decoder.decode(value))
48
+ }
49
+
50
+ setIsFinished(true)
51
+ }
52
+
53
+ return (
54
+ <>
55
+ <button onClick={() => handleStream(stream)}>Start</button>
56
+ <IncremarkContent
57
+ content={content}
58
+ isFinished={isFinished}
59
+ incremarkOptions={{
60
+ gfm: true,
61
+ math: true,
62
+ containers: true,
63
+ htmlTree: true
64
+ }}
65
+ />
66
+ </>
67
+ )
68
+ }
26
69
  ```
27
70
 
28
- **2. Use in Your Component**
71
+ ### Advanced: useIncremark Hook
29
72
 
30
73
  ```tsx
31
74
  import { useIncremark, Incremark } from '@incremark/react'
32
75
  import '@incremark/react/styles.css'
33
76
 
34
77
  function App() {
35
- const { blocks, append, finalize, reset } = useIncremark({ gfm: true })
78
+ const { blocks, append, finalize, reset } = useIncremark({
79
+ gfm: true,
80
+ math: true
81
+ })
36
82
 
37
83
  async function handleStream(stream: ReadableStream) {
38
84
  reset()
@@ -57,64 +103,170 @@ function App() {
57
103
  }
58
104
  ```
59
105
 
60
- ## API
61
-
62
- ### useIncremark(options)
106
+ ## IncremarkContent Component
107
+
108
+ Declarative all-in-one component, recommended for most scenarios.
109
+
110
+ ### Props
111
+
112
+ ```ts
113
+ interface IncremarkContentProps {
114
+ // Input (choose one)
115
+ content?: string // Accumulated Markdown string
116
+ stream?: () => AsyncGenerator<string> // Async generator function
117
+
118
+ // Status
119
+ isFinished?: boolean // Stream finished flag (required for content mode)
120
+
121
+ // Configuration
122
+ incremarkOptions?: {
123
+ gfm?: boolean // GFM support
124
+ math?: boolean // Math formulas
125
+ htmlTree?: boolean // HTML structured parsing
126
+ containers?: boolean // ::: container syntax
127
+ typewriter?: { // Typewriter effect
128
+ enabled?: boolean
129
+ charsPerTick?: number | [number, number]
130
+ tickInterval?: number
131
+ effect?: 'none' | 'fade-in' | 'typing'
132
+ cursor?: string
133
+ }
134
+ }
63
135
 
64
- Core hook.
136
+ // Custom rendering
137
+ components?: ComponentMap // Custom components
138
+ customContainers?: Record<string, ComponentType> // Custom containers
139
+ customCodeBlocks?: Record<string, ComponentType> // Custom code blocks
140
+ codeBlockConfigs?: Record<string, CodeBlockConfig>
65
141
 
66
- **Returns:**
142
+ // Styling
143
+ showBlockStatus?: boolean // Show block status border
144
+ pendingClass?: string // CSS class for pending blocks
145
+ }
146
+ ```
67
147
 
68
- | Property | Type | Description |
69
- |----------|------|-------------|
70
- | `markdown` | `string` | Complete Markdown |
71
- | `blocks` | `Block[]` | All blocks |
72
- | `completedBlocks` | `Block[]` | Completed blocks |
73
- | `pendingBlocks` | `Block[]` | Pending blocks |
74
- | `append` | `Function` | Append content |
75
- | `finalize` | `Function` | Complete parsing |
76
- | `reset` | `Function` | Reset state |
77
- | `render` | `Function` | Render once (reset + append + finalize) |
148
+ ### Example: Enable Typewriter Effect
78
149
 
79
- ### useDevTools(incremark)
150
+ ```tsx
151
+ <IncremarkContent
152
+ content={content}
153
+ isFinished={isFinished}
154
+ incremarkOptions={{
155
+ gfm: true,
156
+ typewriter: {
157
+ enabled: true,
158
+ charsPerTick: [1, 3],
159
+ tickInterval: 30,
160
+ effect: 'fade-in'
161
+ }
162
+ }}
163
+ />
164
+ ```
80
165
 
81
- Enable DevTools.
166
+ ### Example: Custom Components
82
167
 
83
168
  ```tsx
84
- const incremark = useIncremark()
85
- useDevTools(incremark)
169
+ import CustomHeading from './CustomHeading'
170
+ import WarningContainer from './WarningContainer'
171
+ import EchartsCodeBlock from './EchartsCodeBlock'
172
+
173
+ <IncremarkContent
174
+ content={content}
175
+ isFinished={isFinished}
176
+ components={{ heading: CustomHeading }}
177
+ customContainers={{ warning: WarningContainer }}
178
+ customCodeBlocks={{ echarts: EchartsCodeBlock }}
179
+ codeBlockConfigs={{ echarts: { takeOver: true } }}
180
+ />
86
181
  ```
87
182
 
88
- ### \<Incremark\>
89
-
90
- Render component.
183
+ ## Theme System
91
184
 
92
185
  ```tsx
93
- <Incremark
94
- blocks={blocks}
95
- components={{ heading: MyHeading }}
96
- />
186
+ import { ThemeProvider, IncremarkContent } from '@incremark/react'
187
+
188
+ // Built-in theme
189
+ <ThemeProvider theme="dark">
190
+ <IncremarkContent content={content} isFinished={isFinished} />
191
+ </ThemeProvider>
192
+
193
+ // Custom theme
194
+ <ThemeProvider theme={{ color: { brand: { primary: '#8b5cf6' } } }}>
195
+ <IncremarkContent content={content} isFinished={isFinished} />
196
+ </ThemeProvider>
97
197
  ```
98
198
 
99
- ## Custom Components
199
+ ## Auto Scroll
100
200
 
101
201
  ```tsx
102
- import { useIncremark, Incremark } from '@incremark/react'
103
- import MyCode from './MyCode'
202
+ import { useRef, useState } from 'react'
203
+ import { AutoScrollContainer, IncremarkContent, type AutoScrollContainerRef } from '@incremark/react'
104
204
 
105
205
  function App() {
106
- const { blocks } = useIncremark()
107
-
206
+ const scrollRef = useRef<AutoScrollContainerRef>(null)
207
+ const [autoScrollEnabled, setAutoScrollEnabled] = useState(true)
208
+
108
209
  return (
109
- <Incremark
110
- blocks={blocks}
111
- components={{ code: MyCode }}
112
- />
210
+ <div>
211
+ <AutoScrollContainer
212
+ ref={scrollRef}
213
+ enabled={autoScrollEnabled}
214
+ threshold={50}
215
+ behavior="smooth"
216
+ >
217
+ <IncremarkContent content={content} isFinished={isFinished} />
218
+ </AutoScrollContainer>
219
+
220
+ <button onClick={() => scrollRef.current?.scrollToBottom()}>
221
+ Scroll to Bottom
222
+ </button>
223
+ </div>
113
224
  )
114
225
  }
115
226
  ```
116
227
 
117
- ## Integration with React Query
228
+ ## useIncremark API
229
+
230
+ ```ts
231
+ const {
232
+ // State
233
+ markdown, // string - Complete Markdown
234
+ blocks, // Block[] - All blocks
235
+ completedBlocks, // Block[] - Completed blocks
236
+ pendingBlocks, // Block[] - Pending blocks
237
+ isLoading, // boolean - Is loading
238
+ isDisplayComplete, // boolean - Is display complete
239
+
240
+ // Methods
241
+ append, // (chunk: string) => IncrementalUpdate
242
+ finalize, // () => IncrementalUpdate
243
+ reset, // () => void
244
+ render, // (content: string) => IncrementalUpdate
245
+
246
+ // Typewriter controls
247
+ typewriter: {
248
+ enabled, // boolean - Is enabled
249
+ isProcessing, // boolean - Is processing
250
+ skip, // () => void - Skip animation
251
+ setOptions // (options) => void - Update config
252
+ }
253
+ } = useIncremark(options)
254
+ ```
255
+
256
+ ## DevTools
257
+
258
+ ```tsx
259
+ import { useIncremark, useDevTools, Incremark } from '@incremark/react'
260
+
261
+ function App() {
262
+ const incremark = useIncremark()
263
+ useDevTools(incremark)
264
+
265
+ return <Incremark blocks={incremark.blocks} />
266
+ }
267
+ ```
268
+
269
+ ## React Query Integration
118
270
 
119
271
  ```tsx
120
272
  import { useQuery } from '@tanstack/react-query'
@@ -127,7 +279,7 @@ function StreamingContent() {
127
279
  queryKey: ['chat'],
128
280
  queryFn: async () => {
129
281
  reset()
130
- // ... streaming handling
282
+ // ... streaming logic
131
283
  finalize()
132
284
  return null
133
285
  },
@@ -143,7 +295,24 @@ function StreamingContent() {
143
295
  }
144
296
  ```
145
297
 
298
+ ## Math Formula Support
299
+
300
+ Built-in support, just enable `math: true`:
301
+
302
+ ```tsx
303
+ <IncremarkContent
304
+ content={content}
305
+ isFinished={isFinished}
306
+ incremarkOptions={{ math: true }}
307
+ />
308
+ ```
309
+
310
+ Import KaTeX styles:
311
+
312
+ ```ts
313
+ import 'katex/dist/katex.min.css'
314
+ ```
315
+
146
316
  ## License
147
317
 
148
318
  MIT
149
-
package/dist/index.d.ts CHANGED
@@ -4,6 +4,9 @@ import React$1, { ReactNode, ComponentType } from 'react';
4
4
  import { Definition, FootnoteDefinition, RootContent, PhrasingContent } from 'mdast';
5
5
  import * as _incremark_devtools from '@incremark/devtools';
6
6
  import { DevToolsOptions } from '@incremark/devtools';
7
+ import * as react_jsx_runtime from 'react/jsx-runtime';
8
+ import { IncremarkLocale } from '@incremark/shared';
9
+ export { IncremarkLocale, en, zhCN } from '@incremark/shared';
7
10
  import { DesignTokens } from '@incremark/theme';
8
11
  export { DesignTokens, applyTheme, darkTheme, defaultTheme, generateCSSVars, mergeTheme } from '@incremark/theme';
9
12
 
@@ -293,6 +296,15 @@ interface UseBlockTransformerReturn<T = unknown> {
293
296
  */
294
297
  declare function useBlockTransformer<T = unknown>(sourceBlocks: SourceBlock<T>[], options?: UseBlockTransformerOptions): UseBlockTransformerReturn<T>;
295
298
 
299
+ /**
300
+ * React 国际化 Hook
301
+ */
302
+ interface UseLocaleReturn {
303
+ /** 翻译函数 */
304
+ t: (key: string) => string;
305
+ }
306
+ declare function useLocale(): UseLocaleReturn;
307
+
296
308
  type ComponentMap = Partial<Record<string, ComponentType<{
297
309
  node: any;
298
310
  }>>>;
@@ -588,6 +600,12 @@ interface IncremarkContainerProviderProps {
588
600
  */
589
601
  declare const IncremarkContainerProvider: React$1.FC<IncremarkContainerProviderProps>;
590
602
 
603
+ interface ConfigProviderProps {
604
+ children: ReactNode;
605
+ locale?: IncremarkLocale;
606
+ }
607
+ declare function ConfigProvider({ children, locale }: ConfigProviderProps): react_jsx_runtime.JSX.Element;
608
+
591
609
  interface ThemeProviderProps {
592
610
  /** 主题配置,可以是:
593
611
  * - 字符串:'default' | 'dark'
@@ -620,4 +638,4 @@ interface ThemeProviderProps {
620
638
  */
621
639
  declare const ThemeProvider: React$1.FC<ThemeProviderProps>;
622
640
 
623
- export { AutoScrollContainer, type AutoScrollContainerProps, type AutoScrollContainerRef, type DefinitionsContextValue, DefinitionsProvider, type DefinitionsProviderProps, type HtmlElementNode, Incremark, IncremarkContainerProvider, type IncremarkContainerProviderProps, IncremarkContent, type IncremarkContentProps, IncremarkFootnotes, IncremarkHtmlElement, type IncremarkHtmlElementProps, IncremarkInline, type IncremarkInlineProps, type IncremarkProps, IncremarkRenderer, type IncremarkRendererProps, ThemeProvider, type ThemeProviderProps, type TypewriterControls, type TypewriterOptions, type UseBlockTransformerOptions, type UseBlockTransformerReturn, type UseDevToolsOptions, type UseIncremarkOptions, type UseIncremarkReturn, useBlockTransformer, useDefinitions, useDevTools, useIncremark };
641
+ export { AutoScrollContainer, type AutoScrollContainerProps, type AutoScrollContainerRef, ConfigProvider, type DefinitionsContextValue, DefinitionsProvider, type DefinitionsProviderProps, type HtmlElementNode, Incremark, IncremarkContainerProvider, type IncremarkContainerProviderProps, IncremarkContent, type IncremarkContentProps, IncremarkFootnotes, IncremarkHtmlElement, type IncremarkHtmlElementProps, IncremarkInline, type IncremarkInlineProps, type IncremarkProps, IncremarkRenderer, type IncremarkRendererProps, ThemeProvider, type ThemeProviderProps, type TypewriterControls, type TypewriterOptions, type UseBlockTransformerOptions, type UseBlockTransformerReturn, type UseDevToolsOptions, type UseIncremarkOptions, type UseIncremarkReturn, type UseLocaleReturn, useBlockTransformer, useDefinitions, useDevTools, useIncremark, useLocale };