@incremark/vue 0.2.7 → 0.3.1

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/vue
2
2
 
3
- Vue 3 integration for Incremark.
3
+ Vue 3 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` composable and `<Incremark>` component
10
- - 🎨 **Customizable** - Support for custom render components
11
- - **High Performance** - Optimized with `shallowRef` and `markRaw`
12
- - 🔧 **DevTools** - Built-in developer tools
9
+ - 📦 **Out of the Box** - Provides `IncremarkContent` component and `useIncremark` composable
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,56 @@ pnpm add @incremark/core @incremark/vue
19
22
 
20
23
  ## Quick Start
21
24
 
22
- **1. Import Styles**
25
+ ### Recommended: IncremarkContent Component
23
26
 
24
- ```ts
27
+ ```vue
28
+ <script setup>
29
+ import { ref } from 'vue'
30
+ import { IncremarkContent } from '@incremark/vue'
25
31
  import '@incremark/vue/style.css'
32
+
33
+ const content = ref('')
34
+ const isFinished = ref(false)
35
+
36
+ // Handle AI streaming output
37
+ async function handleStream(stream) {
38
+ content.value = ''
39
+ isFinished.value = false
40
+
41
+ for await (const chunk of stream) {
42
+ content.value += chunk
43
+ }
44
+
45
+ isFinished.value = true
46
+ }
47
+ </script>
48
+
49
+ <template>
50
+ <button @click="handleStream(stream)">Start</button>
51
+ <IncremarkContent
52
+ :content="content"
53
+ :is-finished="isFinished"
54
+ :incremark-options="{
55
+ gfm: true,
56
+ math: true,
57
+ containers: true,
58
+ htmlTree: true
59
+ }"
60
+ />
61
+ </template>
26
62
  ```
27
63
 
28
- **2. Use in Your Component**
64
+ ### Advanced: useIncremark Composable
29
65
 
30
66
  ```vue
31
67
  <script setup>
32
68
  import { useIncremark, Incremark } from '@incremark/vue'
33
69
  import '@incremark/vue/style.css'
34
70
 
35
- const { blocks, append, finalize, reset } = useIncremark({ gfm: true })
71
+ const { blocks, append, finalize, reset } = useIncremark({
72
+ gfm: true,
73
+ math: true
74
+ })
36
75
 
37
76
  async function handleStream(stream) {
38
77
  reset()
@@ -44,89 +83,200 @@ async function handleStream(stream) {
44
83
  </script>
45
84
 
46
85
  <template>
47
- <button @click="handleStream">Start</button>
86
+ <button @click="handleStream(stream)">Start</button>
48
87
  <Incremark :blocks="blocks" />
49
88
  </template>
50
89
  ```
51
90
 
52
- ## API
91
+ ## IncremarkContent Component
53
92
 
54
- ### useIncremark(options)
93
+ Declarative all-in-one component, recommended for most scenarios.
55
94
 
56
- Core composable.
95
+ ### Props
57
96
 
58
- **Returns:**
97
+ ```ts
98
+ interface IncremarkContentProps {
99
+ // Input (choose one)
100
+ content?: string // Accumulated Markdown string
101
+ stream?: () => AsyncGenerator<string> // Async generator function
102
+
103
+ // Status
104
+ isFinished?: boolean // Stream finished flag (required for content mode)
105
+
106
+ // Configuration
107
+ incremarkOptions?: {
108
+ gfm?: boolean // GFM support
109
+ math?: boolean // Math formulas
110
+ htmlTree?: boolean // HTML structured parsing
111
+ containers?: boolean // ::: container syntax
112
+ typewriter?: { // Typewriter effect
113
+ enabled?: boolean
114
+ charsPerTick?: number | [number, number]
115
+ tickInterval?: number
116
+ effect?: 'none' | 'fade-in' | 'typing'
117
+ cursor?: string
118
+ }
119
+ }
59
120
 
60
- | Property | Type | Description |
61
- |----------|------|-------------|
62
- | `markdown` | `Ref<string>` | Complete Markdown |
63
- | `blocks` | `ComputedRef<Block[]>` | All blocks |
64
- | `completedBlocks` | `ShallowRef<Block[]>` | Completed blocks |
65
- | `pendingBlocks` | `ShallowRef<Block[]>` | Pending blocks |
66
- | `append` | `Function` | Append content |
67
- | `finalize` | `Function` | Complete parsing |
68
- | `reset` | `Function` | Reset state |
69
- | `render` | `Function` | Render once (reset + append + finalize) |
121
+ // Custom rendering
122
+ components?: ComponentMap // Custom components
123
+ customContainers?: Record<string, Component> // Custom containers
124
+ customCodeBlocks?: Record<string, Component> // Custom code blocks
125
+ codeBlockConfigs?: Record<string, CodeBlockConfig>
70
126
 
71
- ### useDevTools(incremark)
127
+ // Styling
128
+ showBlockStatus?: boolean // Show block status border
129
+ pendingClass?: string // CSS class for pending blocks
130
+ }
131
+ ```
72
132
 
73
- Enable DevTools.
133
+ ### Example: Enable Typewriter Effect
74
134
 
75
- ```ts
76
- const incremark = useIncremark()
77
- useDevTools(incremark)
135
+ ```vue
136
+ <IncremarkContent
137
+ :content="content"
138
+ :is-finished="isFinished"
139
+ :incremark-options="{
140
+ gfm: true,
141
+ typewriter: {
142
+ enabled: true,
143
+ charsPerTick: [1, 3],
144
+ tickInterval: 30,
145
+ effect: 'fade-in'
146
+ }
147
+ }"
148
+ />
78
149
  ```
79
150
 
80
- ### \<Incremark\>
151
+ ### Example: Custom Components
152
+
153
+ ```vue
154
+ <script setup>
155
+ import CustomHeading from './CustomHeading.vue'
156
+ import WarningContainer from './WarningContainer.vue'
157
+ import EchartsCodeBlock from './EchartsCodeBlock.vue'
158
+ </script>
159
+
160
+ <template>
161
+ <IncremarkContent
162
+ :content="content"
163
+ :is-finished="isFinished"
164
+ :components="{ heading: CustomHeading }"
165
+ :custom-containers="{ warning: WarningContainer }"
166
+ :custom-code-blocks="{ echarts: EchartsCodeBlock }"
167
+ :code-block-configs="{ echarts: { takeOver: true } }"
168
+ />
169
+ </template>
170
+ ```
81
171
 
82
- Render component.
172
+ ## Theme System
83
173
 
84
174
  ```vue
85
- <Incremark
86
- :blocks="blocks"
87
- :components="{ heading: MyHeading }"
88
- />
175
+ <script setup>
176
+ import { ThemeProvider, IncremarkContent } from '@incremark/vue'
177
+ </script>
178
+
179
+ <template>
180
+ <!-- Built-in theme -->
181
+ <ThemeProvider theme="dark">
182
+ <IncremarkContent :content="content" :is-finished="isFinished" />
183
+ </ThemeProvider>
184
+
185
+ <!-- Custom theme -->
186
+ <ThemeProvider :theme="{ color: { brand: { primary: '#8b5cf6' } } }">
187
+ <IncremarkContent :content="content" :is-finished="isFinished" />
188
+ </ThemeProvider>
189
+ </template>
89
190
  ```
90
191
 
91
- ## Custom Components
192
+ ## Auto Scroll
92
193
 
93
194
  ```vue
94
195
  <script setup>
95
- import { useIncremark, Incremark } from '@incremark/vue'
96
- import MyCode from './MyCode.vue'
196
+ import { ref } from 'vue'
197
+ import { AutoScrollContainer, IncremarkContent } from '@incremark/vue'
97
198
 
98
- const { blocks } = useIncremark()
199
+ const scrollRef = ref()
200
+ const autoScrollEnabled = ref(true)
99
201
  </script>
100
202
 
101
203
  <template>
102
- <Incremark
103
- :blocks="blocks"
104
- :components="{ code: MyCode }"
105
- />
204
+ <AutoScrollContainer
205
+ ref="scrollRef"
206
+ :enabled="autoScrollEnabled"
207
+ :threshold="50"
208
+ behavior="smooth"
209
+ >
210
+ <IncremarkContent :content="content" :is-finished="isFinished" />
211
+ </AutoScrollContainer>
212
+
213
+ <button @click="scrollRef?.scrollToBottom()">
214
+ Scroll to Bottom
215
+ </button>
106
216
  </template>
107
217
  ```
108
218
 
109
- ## Math Formula Support
219
+ ## useIncremark API
110
220
 
111
- ```bash
112
- pnpm add micromark-extension-math mdast-util-math katex
221
+ ```ts
222
+ const {
223
+ // State
224
+ markdown, // Ref<string> - Complete Markdown
225
+ blocks, // ComputedRef<Block[]> - All blocks
226
+ completedBlocks, // ShallowRef<Block[]> - Completed blocks
227
+ pendingBlocks, // ShallowRef<Block[]> - Pending blocks
228
+ isLoading, // Ref<boolean> - Is loading
229
+ isDisplayComplete, // ComputedRef<boolean> - Is display complete
230
+
231
+ // Methods
232
+ append, // (chunk: string) => IncrementalUpdate
233
+ finalize, // () => IncrementalUpdate
234
+ reset, // () => void
235
+ render, // (content: string) => IncrementalUpdate
236
+
237
+ // Typewriter controls
238
+ typewriter: {
239
+ enabled, // Ref<boolean> - Is enabled
240
+ isProcessing, // Ref<boolean> - Is processing
241
+ skip, // () => void - Skip animation
242
+ setOptions // (options) => void - Update config
243
+ }
244
+ } = useIncremark(options)
113
245
  ```
114
246
 
247
+ ## DevTools
248
+
115
249
  ```vue
116
250
  <script setup>
117
- import { useIncremark } from '@incremark/vue'
118
- import { math } from 'micromark-extension-math'
119
- import { mathFromMarkdown } from 'mdast-util-math'
120
- import 'katex/dist/katex.min.css'
251
+ import { useIncremark, useDevTools, Incremark } from '@incremark/vue'
121
252
 
122
- const { blocks } = useIncremark({
123
- extensions: [math()],
124
- mdastExtensions: [mathFromMarkdown()]
125
- })
253
+ const incremark = useIncremark()
254
+ useDevTools(incremark)
126
255
  </script>
256
+
257
+ <template>
258
+ <Incremark :blocks="incremark.blocks" />
259
+ </template>
260
+ ```
261
+
262
+ ## Math Formula Support
263
+
264
+ Built-in support, just enable `math: true`:
265
+
266
+ ```vue
267
+ <IncremarkContent
268
+ :content="content"
269
+ :is-finished="isFinished"
270
+ :incremark-options="{ math: true }"
271
+ />
272
+ ```
273
+
274
+ Import KaTeX styles:
275
+
276
+ ```ts
277
+ import 'katex/dist/katex.min.css'
127
278
  ```
128
279
 
129
280
  ## License
130
281
 
131
282
  MIT
132
-
@@ -0,0 +1,19 @@
1
+ import type { IncremarkLocale } from '@incremark/shared';
2
+ interface Props {
3
+ /** locale 对象 */
4
+ locale?: IncremarkLocale;
5
+ }
6
+ declare var __VLS_1: {};
7
+ type __VLS_Slots = {} & {
8
+ default?: (props: typeof __VLS_1) => any;
9
+ };
10
+ declare const __VLS_component: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {
11
+ locale: IncremarkLocale;
12
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
13
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
14
+ export default _default;
15
+ type __VLS_WithSlots<T, S> = T & {
16
+ new (): {
17
+ $slots: S;
18
+ };
19
+ };
@@ -12,13 +12,6 @@ export interface CodeBlockConfig {
12
12
  /** 是否从一开始就接管渲染,而不是等到 completed 状态 */
13
13
  takeOver?: boolean;
14
14
  }
15
- /**
16
- * 代码块配置
17
- */
18
- export interface CodeBlockConfig {
19
- /** 是否从一开始就接管渲染,而不是等到 completed 状态 */
20
- takeOver?: boolean;
21
- }
22
15
  type __VLS_Props = {
23
16
  /** 要渲染的块列表(来自 useIncremark 的 blocks) */
24
17
  blocks?: RenderableBlock[];
@@ -1,7 +1,7 @@
1
1
  import type { Code } from 'mdast';
2
2
  import type { Component } from 'vue';
3
3
  import type { CodeBlockConfig } from './Incremark.vue';
4
- type __VLS_Props = {
4
+ interface Props {
5
5
  node: Code;
6
6
  /** Shiki 主题,默认 github-dark */
7
7
  theme?: string;
@@ -17,14 +17,17 @@ type __VLS_Props = {
17
17
  codeBlockConfigs?: Record<string, CodeBlockConfig>;
18
18
  /** 块状态,用于判断是否使用自定义组件 */
19
19
  blockStatus?: 'pending' | 'stable' | 'completed';
20
- };
21
- declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
20
+ /** 默认代码块渲染组件(当不是 mermaid 且没有自定义组件时使用) */
21
+ defaultCodeComponent?: Component;
22
+ }
23
+ declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {
22
24
  theme: string;
25
+ mermaidDelay: number;
23
26
  fallbackTheme: string;
24
27
  disableHighlight: boolean;
25
- mermaidDelay: number;
26
28
  customCodeBlocks: Record<string, Component>;
27
29
  codeBlockConfigs: Record<string, CodeBlockConfig>;
28
30
  blockStatus: "pending" | "stable" | "completed";
31
+ defaultCodeComponent: Component;
29
32
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
30
33
  export default _default;
@@ -0,0 +1,16 @@
1
+ import type { Code } from 'mdast';
2
+ interface Props {
3
+ node: Code;
4
+ /** Shiki 主题,默认 github-dark */
5
+ theme?: string;
6
+ /** 默认回退主题(当指定主题加载失败时使用),默认 github-dark */
7
+ fallbackTheme?: string;
8
+ /** 是否禁用代码高亮 */
9
+ disableHighlight?: boolean;
10
+ }
11
+ declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {
12
+ theme: string;
13
+ fallbackTheme: string;
14
+ disableHighlight: boolean;
15
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
16
+ export default _default;
@@ -0,0 +1,10 @@
1
+ import type { Code } from 'mdast';
2
+ interface Props {
3
+ node: Code;
4
+ /** Mermaid 渲染延迟(毫秒),用于流式输入时防抖 */
5
+ mermaidDelay?: number;
6
+ }
7
+ declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {
8
+ mermaidDelay: number;
9
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
10
+ export default _default;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * SvgIcon 组件
3
+ *
4
+ * 直接渲染 SVG 字符串
5
+ */
6
+ interface Props {
7
+ /** SVG 字符串内容 */
8
+ svg: string;
9
+ /** 图标大小 class,如 incremark-icon--sm, incremark-icon--md 等 */
10
+ sizeClass?: string;
11
+ }
12
+ declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
13
+ export default _default;
@@ -6,3 +6,4 @@ export { useDevTools } from './useDevTools';
6
6
  export type { UseDevToolsOptions } from './useDevTools';
7
7
  export { useBlockTransformer } from './useBlockTransformer';
8
8
  export type { UseBlockTransformerOptions, UseBlockTransformerReturn } from './useBlockTransformer';
9
+ export { useLocale, type UseLocaleReturn } from './useLocale';
@@ -1,5 +1,5 @@
1
1
  import { type ComputedRef, type MaybeRefOrGetter } from 'vue';
2
- import { type ParserOptions, type ParsedBlock, type IncrementalUpdate, type Root, type TransformerPlugin, type AnimationEffect } from '@incremark/core';
2
+ import { type IncremarkParserOptions, type ParsedBlock, type IncrementalUpdate, type Root, type TransformerPlugin, type AnimationEffect } from '@incremark/core';
3
3
  /** 打字机效果配置 */
4
4
  export interface TypewriterOptions {
5
5
  /** 是否启用打字机效果(可响应式切换) */
@@ -17,7 +17,7 @@ export interface TypewriterOptions {
17
17
  /** 自定义插件 */
18
18
  plugins?: TransformerPlugin[];
19
19
  }
20
- export interface UseIncremarkOptions extends ParserOptions {
20
+ export interface UseIncremarkOptions extends IncremarkParserOptions {
21
21
  /** 打字机配置,传入即创建 transformer(可通过 enabled 控制是否启用) */
22
22
  typewriter?: TypewriterOptions;
23
23
  }
@@ -0,0 +1,21 @@
1
+ import { type Ref, type ComputedRef, type InjectionKey } from 'vue';
2
+ import type { IncremarkLocale } from '@incremark/shared';
3
+ /**
4
+ * Locale 注入 key,用于 provide/inject
5
+ */
6
+ declare const LOCALE_KEY: InjectionKey<Ref<IncremarkLocale>>;
7
+ /**
8
+ * Vue 国际化 Hook
9
+ */
10
+ export interface UseLocaleReturn {
11
+ /** 翻译函数 */
12
+ t: ComputedRef<(key: string) => string>;
13
+ }
14
+ /**
15
+ * 使用 locale
16
+ */
17
+ export declare function useLocale(): UseLocaleReturn;
18
+ /**
19
+ * 提供 locale 的 key(用于 ConfigProvider)
20
+ */
21
+ export { LOCALE_KEY };
@@ -47,8 +47,12 @@ declare class ShikiManager {
47
47
  */
48
48
  disposeAll(): void;
49
49
  }
50
- declare const shikiManager: ShikiManager;
51
- export { shikiManager, ShikiManager };
50
+ /**
51
+ * 获取 ShikiManager 单例(延迟初始化)
52
+ * 避免模块加载时立即创建实例,支持 SSR
53
+ */
54
+ declare function getShikiManager(): ShikiManager;
55
+ export { getShikiManager, ShikiManager };
52
56
  /**
53
57
  * 使用 Shiki Highlighter(组合式函数)
54
58
  *
package/dist/index.d.ts CHANGED
@@ -1,9 +1,14 @@
1
- export { useIncremark, useStreamRenderer, useDevTools, useBlockTransformer } from './composables';
1
+ export { useIncremark, useStreamRenderer, useDevTools, useBlockTransformer, useLocale } from './composables';
2
2
  export { useProvideDefinations } from './composables/useProvideDefinations';
3
3
  export { useDefinationsContext } from './composables/useDefinationsContext';
4
4
  export type { UseIncremarkOptions, TypewriterOptions, TypewriterControls, UseStreamRendererOptions, UseDevToolsOptions, UseBlockTransformerOptions, UseBlockTransformerReturn } from './composables';
5
5
  export * from './components';
6
6
  export { default as ThemeProvider } from './ThemeProvider.vue';
7
+ export { default as ConfigProvider } from './components/ConfigProvider.vue';
7
8
  export type { ParsedBlock, IncrementalUpdate, ParserOptions, BlockStatus, Root, RootContent, SourceBlock, DisplayBlock, TransformerPlugin, TransformerOptions, TransformerState, AnimationEffect } from '@incremark/core';
8
9
  export { BlockTransformer, createBlockTransformer, countChars, sliceAst, cloneNode, codeBlockPlugin, mermaidPlugin, imagePlugin, mathPlugin, thematicBreakPlugin, defaultPlugins, allPlugins, createPlugin } from '@incremark/core';
9
10
  export { type DesignTokens, defaultTheme, darkTheme, generateCSSVars, mergeTheme, applyTheme } from '@incremark/theme';
11
+ import { en as enShared, zhCN as zhCNShared } from '@incremark/shared';
12
+ import type { IncremarkLocale } from '@incremark/shared';
13
+ export { enShared as en, zhCNShared as zhCN };
14
+ export type { IncremarkLocale };