@incremark/react 0.2.6 → 0.2.7
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/dist/index.d.ts +81 -28
- package/dist/index.js +268 -84
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ParserOptions, AnimationEffect, TransformerPlugin, ParsedBlock, Root, IncrementalUpdate, IncremarkParser, SourceBlock, TransformerOptions, DisplayBlock, BlockTransformer } from '@incremark/core';
|
|
2
2
|
export { AnimationEffect, BlockTransformer, DisplayBlock, IncrementalUpdate, ParsedBlock, ParserOptions, Root, RootContent, SourceBlock, TransformerOptions, TransformerPlugin, TransformerState, allPlugins, cloneNode, codeBlockPlugin, countChars, createBlockTransformer, createPlugin, defaultPlugins, imagePlugin, mathPlugin, mermaidPlugin, sliceAst, thematicBreakPlugin } from '@incremark/core';
|
|
3
|
-
import React, { ReactNode } from 'react';
|
|
3
|
+
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';
|
|
@@ -69,7 +69,7 @@ interface DefinitionsProviderProps {
|
|
|
69
69
|
* }
|
|
70
70
|
* ```
|
|
71
71
|
*/
|
|
72
|
-
declare const DefinitionsProvider: React.FC<DefinitionsProviderProps>;
|
|
72
|
+
declare const DefinitionsProvider: React$1.FC<DefinitionsProviderProps>;
|
|
73
73
|
/**
|
|
74
74
|
* useDefinitions Hook
|
|
75
75
|
*
|
|
@@ -111,10 +111,9 @@ interface UseIncremarkOptions extends ParserOptions {
|
|
|
111
111
|
/** 打字机配置,传入即创建 transformer(可通过 enabled 控制是否启用) */
|
|
112
112
|
typewriter?: TypewriterOptions;
|
|
113
113
|
}
|
|
114
|
-
|
|
115
|
-
stableId: string;
|
|
114
|
+
type RenderableBlock = ParsedBlock & {
|
|
116
115
|
isLastPending?: boolean;
|
|
117
|
-
}
|
|
116
|
+
};
|
|
118
117
|
/** 打字机控制对象 */
|
|
119
118
|
interface TypewriterControls {
|
|
120
119
|
/** 是否启用 */
|
|
@@ -175,7 +174,7 @@ declare function useIncremark(options?: UseIncremarkOptions): {
|
|
|
175
174
|
/** 当前完整的 AST */
|
|
176
175
|
ast: Root;
|
|
177
176
|
/** 用于渲染的 blocks(根据打字机设置自动处理) */
|
|
178
|
-
blocks:
|
|
177
|
+
blocks: RenderableBlock[];
|
|
179
178
|
/** 是否正在加载 */
|
|
180
179
|
isLoading: boolean;
|
|
181
180
|
/** 是否已完成(finalize) */
|
|
@@ -294,10 +293,41 @@ interface UseBlockTransformerReturn<T = unknown> {
|
|
|
294
293
|
*/
|
|
295
294
|
declare function useBlockTransformer<T = unknown>(sourceBlocks: SourceBlock<T>[], options?: UseBlockTransformerOptions): UseBlockTransformerReturn<T>;
|
|
296
295
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
296
|
+
type ComponentMap = Partial<Record<string, ComponentType<{
|
|
297
|
+
node: any;
|
|
298
|
+
}>>>;
|
|
299
|
+
/**
|
|
300
|
+
* 代码块配置
|
|
301
|
+
*/
|
|
302
|
+
interface CodeBlockConfig$1 {
|
|
303
|
+
/** 是否从一开始就接管渲染,而不是等到 completed 状态 */
|
|
304
|
+
takeOver?: boolean;
|
|
305
|
+
}
|
|
306
|
+
interface IncremarkContentProps {
|
|
307
|
+
stream?: () => AsyncGenerator<string>;
|
|
308
|
+
content?: string;
|
|
309
|
+
components?: ComponentMap;
|
|
310
|
+
/** 自定义容器组件映射,key 为容器名称(如 'warning', 'info') */
|
|
311
|
+
customContainers?: Record<string, ComponentType<{
|
|
312
|
+
name: string;
|
|
313
|
+
options?: Record<string, any>;
|
|
314
|
+
children?: React.ReactNode;
|
|
315
|
+
}>>;
|
|
316
|
+
/** 自定义代码块组件映射,key 为代码语言名称(如 'echart', 'mermaid') */
|
|
317
|
+
customCodeBlocks?: Record<string, ComponentType<{
|
|
318
|
+
codeStr: string;
|
|
319
|
+
lang?: string;
|
|
320
|
+
completed?: boolean;
|
|
321
|
+
takeOver?: boolean;
|
|
322
|
+
}>>;
|
|
323
|
+
/** 代码块配置映射,key 为代码语言名称 */
|
|
324
|
+
codeBlockConfigs?: Record<string, CodeBlockConfig$1>;
|
|
325
|
+
isFinished?: boolean;
|
|
326
|
+
incremarkOptions?: UseIncremarkOptions;
|
|
327
|
+
pendingClass?: string;
|
|
328
|
+
showBlockStatus?: boolean;
|
|
300
329
|
}
|
|
330
|
+
|
|
301
331
|
/**
|
|
302
332
|
* 代码块配置
|
|
303
333
|
*/
|
|
@@ -307,22 +337,22 @@ interface CodeBlockConfig {
|
|
|
307
337
|
}
|
|
308
338
|
interface IncremarkProps {
|
|
309
339
|
/** 要渲染的块列表 */
|
|
310
|
-
blocks?:
|
|
340
|
+
blocks?: RenderableBlock[];
|
|
311
341
|
/** 内容是否完全显示完成(用于控制脚注等需要在内容完全显示后才出现的元素)
|
|
312
342
|
* 如果传入了 incremark,则会自动使用 incremark.isDisplayComplete,此 prop 被忽略 */
|
|
313
343
|
isDisplayComplete?: boolean;
|
|
314
344
|
/** 自定义组件映射 */
|
|
315
|
-
components?: Partial<Record<string, React.ComponentType<{
|
|
345
|
+
components?: Partial<Record<string, React$1.ComponentType<{
|
|
316
346
|
node: any;
|
|
317
347
|
}>>>;
|
|
318
348
|
/** 自定义容器组件映射,key 为容器名称(如 'warning', 'info') */
|
|
319
|
-
customContainers?: Record<string, React.ComponentType<{
|
|
349
|
+
customContainers?: Record<string, React$1.ComponentType<{
|
|
320
350
|
name: string;
|
|
321
351
|
options?: Record<string, any>;
|
|
322
|
-
children?: React.ReactNode;
|
|
352
|
+
children?: React$1.ReactNode;
|
|
323
353
|
}>>;
|
|
324
354
|
/** 自定义代码块组件映射,key 为代码语言名称(如 'echart', 'mermaid') */
|
|
325
|
-
customCodeBlocks?: Record<string, React.ComponentType<{
|
|
355
|
+
customCodeBlocks?: Record<string, React$1.ComponentType<{
|
|
326
356
|
codeStr: string;
|
|
327
357
|
lang?: string | undefined;
|
|
328
358
|
completed?: boolean | undefined;
|
|
@@ -334,6 +364,10 @@ interface IncremarkProps {
|
|
|
334
364
|
showBlockStatus?: boolean;
|
|
335
365
|
/** 自定义类名 */
|
|
336
366
|
className?: string;
|
|
367
|
+
/** 待处理块的样式类名 */
|
|
368
|
+
pendingClass?: string;
|
|
369
|
+
/** 已完成块的样式类名 */
|
|
370
|
+
completedClass?: string;
|
|
337
371
|
/** 可选:useIncremark 返回的对象(用于自动提供 context) */
|
|
338
372
|
incremark?: UseIncremarkReturn;
|
|
339
373
|
}
|
|
@@ -351,7 +385,26 @@ interface IncremarkProps {
|
|
|
351
385
|
* }
|
|
352
386
|
* ```
|
|
353
387
|
*/
|
|
354
|
-
declare const Incremark: React.FC<IncremarkProps>;
|
|
388
|
+
declare const Incremark: React$1.FC<IncremarkProps>;
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* IncremarkContent 组件
|
|
392
|
+
*
|
|
393
|
+
* 提供开箱即用的 Markdown 渲染体验,自动处理流式内容和普通内容
|
|
394
|
+
*
|
|
395
|
+
* @example
|
|
396
|
+
* ```tsx
|
|
397
|
+
* // 普通内容
|
|
398
|
+
* <IncremarkContent content={markdownString} />
|
|
399
|
+
*
|
|
400
|
+
* // 流式内容
|
|
401
|
+
* <IncremarkContent stream={() => streamGenerator()} />
|
|
402
|
+
*
|
|
403
|
+
* // 增量更新内容
|
|
404
|
+
* <IncremarkContent content={partialContent} isFinished={false} />
|
|
405
|
+
* ```
|
|
406
|
+
*/
|
|
407
|
+
declare const IncremarkContent: React$1.FC<IncremarkContentProps>;
|
|
355
408
|
|
|
356
409
|
/**
|
|
357
410
|
* 容器节点类型定义
|
|
@@ -366,15 +419,15 @@ interface ContainerNode {
|
|
|
366
419
|
|
|
367
420
|
interface IncremarkRendererProps {
|
|
368
421
|
node: RootContent | ContainerNode;
|
|
369
|
-
components?: Partial<Record<string, React.ComponentType<{
|
|
422
|
+
components?: Partial<Record<string, React$1.ComponentType<{
|
|
370
423
|
node: any;
|
|
371
424
|
}>>>;
|
|
372
|
-
customContainers?: Record<string, React.ComponentType<{
|
|
425
|
+
customContainers?: Record<string, React$1.ComponentType<{
|
|
373
426
|
name: string;
|
|
374
427
|
options?: Record<string, any>;
|
|
375
428
|
children?: ReactNode;
|
|
376
429
|
}>>;
|
|
377
|
-
customCodeBlocks?: Record<string, React.ComponentType<{
|
|
430
|
+
customCodeBlocks?: Record<string, React$1.ComponentType<{
|
|
378
431
|
codeStr: string;
|
|
379
432
|
lang?: string;
|
|
380
433
|
completed?: boolean;
|
|
@@ -388,11 +441,11 @@ interface IncremarkRendererProps {
|
|
|
388
441
|
/**
|
|
389
442
|
* 渲染单个 AST 节点
|
|
390
443
|
*/
|
|
391
|
-
declare const IncremarkRenderer: React.FC<IncremarkRendererProps>;
|
|
444
|
+
declare const IncremarkRenderer: React$1.FC<IncremarkRendererProps>;
|
|
392
445
|
|
|
393
446
|
interface AutoScrollContainerProps {
|
|
394
447
|
/** 子元素 */
|
|
395
|
-
children: React.ReactNode;
|
|
448
|
+
children: React$1.ReactNode;
|
|
396
449
|
/** 是否启用自动滚动 */
|
|
397
450
|
enabled?: boolean;
|
|
398
451
|
/** 触发自动滚动的底部阈值(像素) */
|
|
@@ -400,7 +453,7 @@ interface AutoScrollContainerProps {
|
|
|
400
453
|
/** 滚动行为 */
|
|
401
454
|
behavior?: ScrollBehavior;
|
|
402
455
|
/** 容器样式 */
|
|
403
|
-
style?: React.CSSProperties;
|
|
456
|
+
style?: React$1.CSSProperties;
|
|
404
457
|
/** 容器类名 */
|
|
405
458
|
className?: string;
|
|
406
459
|
}
|
|
@@ -430,7 +483,7 @@ interface AutoScrollContainerRef {
|
|
|
430
483
|
* scrollRef.current?.scrollToBottom()
|
|
431
484
|
* ```
|
|
432
485
|
*/
|
|
433
|
-
declare const AutoScrollContainer: React.ForwardRefExoticComponent<AutoScrollContainerProps & React.RefAttributes<AutoScrollContainerRef>>;
|
|
486
|
+
declare const AutoScrollContainer: React$1.ForwardRefExoticComponent<AutoScrollContainerProps & React$1.RefAttributes<AutoScrollContainerRef>>;
|
|
434
487
|
|
|
435
488
|
interface IncremarkInlineProps {
|
|
436
489
|
nodes: PhrasingContent[];
|
|
@@ -450,7 +503,7 @@ interface IncremarkInlineProps {
|
|
|
450
503
|
*
|
|
451
504
|
* 注意:此组件与 Vue 版本保持完全一致的逻辑和结构
|
|
452
505
|
*/
|
|
453
|
-
declare const IncremarkInline: React.FC<IncremarkInlineProps>;
|
|
506
|
+
declare const IncremarkInline: React$1.FC<IncremarkInlineProps>;
|
|
454
507
|
|
|
455
508
|
/**
|
|
456
509
|
* HtmlElementNode 类型定义(与 @incremark/core 中的定义一致)
|
|
@@ -474,7 +527,7 @@ interface IncremarkHtmlElementProps {
|
|
|
474
527
|
*
|
|
475
528
|
* 渲染结构化的 HTML 元素节点
|
|
476
529
|
*/
|
|
477
|
-
declare const IncremarkHtmlElement: React.FC<IncremarkHtmlElementProps>;
|
|
530
|
+
declare const IncremarkHtmlElement: React$1.FC<IncremarkHtmlElementProps>;
|
|
478
531
|
|
|
479
532
|
/**
|
|
480
533
|
* 脚注列表组件
|
|
@@ -501,7 +554,7 @@ declare const IncremarkHtmlElement: React.FC<IncremarkHtmlElementProps>;
|
|
|
501
554
|
* <IncremarkFootnotes />
|
|
502
555
|
* ```
|
|
503
556
|
*/
|
|
504
|
-
declare const IncremarkFootnotes: React.FC;
|
|
557
|
+
declare const IncremarkFootnotes: React$1.FC;
|
|
505
558
|
|
|
506
559
|
/**
|
|
507
560
|
* @file IncremarkContainerProvider - Incremark 容器级 Provider
|
|
@@ -533,7 +586,7 @@ interface IncremarkContainerProviderProps {
|
|
|
533
586
|
* @param props - 组件参数
|
|
534
587
|
* @returns ReactElement
|
|
535
588
|
*/
|
|
536
|
-
declare const IncremarkContainerProvider: React.FC<IncremarkContainerProviderProps>;
|
|
589
|
+
declare const IncremarkContainerProvider: React$1.FC<IncremarkContainerProviderProps>;
|
|
537
590
|
|
|
538
591
|
interface ThemeProviderProps {
|
|
539
592
|
/** 主题配置,可以是:
|
|
@@ -565,6 +618,6 @@ interface ThemeProviderProps {
|
|
|
565
618
|
* </ThemeProvider>
|
|
566
619
|
* ```
|
|
567
620
|
*/
|
|
568
|
-
declare const ThemeProvider: React.FC<ThemeProviderProps>;
|
|
621
|
+
declare const ThemeProvider: React$1.FC<ThemeProviderProps>;
|
|
569
622
|
|
|
570
|
-
export { AutoScrollContainer, type AutoScrollContainerProps, type AutoScrollContainerRef, type DefinitionsContextValue, DefinitionsProvider, type DefinitionsProviderProps, type HtmlElementNode, Incremark, IncremarkContainerProvider, type IncremarkContainerProviderProps, 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 };
|
|
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 };
|
package/dist/index.js
CHANGED
|
@@ -193,17 +193,7 @@ function useTypewriter(options) {
|
|
|
193
193
|
}, [sourceBlocks, transformer]);
|
|
194
194
|
const blocks = useMemo(() => {
|
|
195
195
|
if (!typewriterEnabled || !transformer) {
|
|
196
|
-
|
|
197
|
-
for (const block of completedBlocks) {
|
|
198
|
-
result.push({ ...block, stableId: block.id });
|
|
199
|
-
}
|
|
200
|
-
for (let i = 0; i < pendingBlocks.length; i++) {
|
|
201
|
-
result.push({
|
|
202
|
-
...pendingBlocks[i],
|
|
203
|
-
stableId: `pending-${i}`
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
return result;
|
|
196
|
+
return [...completedBlocks, ...pendingBlocks];
|
|
207
197
|
}
|
|
208
198
|
return displayBlocks.map((db, index) => {
|
|
209
199
|
const isPending = !db.isDisplayComplete;
|
|
@@ -220,7 +210,6 @@ function useTypewriter(options) {
|
|
|
220
210
|
}
|
|
221
211
|
const block = {
|
|
222
212
|
id: db.id,
|
|
223
|
-
stableId: db.id,
|
|
224
213
|
status: db.isDisplayComplete ? "completed" : "pending",
|
|
225
214
|
isLastPending,
|
|
226
215
|
node,
|
|
@@ -452,8 +441,8 @@ function useDevTools(incremark, options = {}) {
|
|
|
452
441
|
devtoolsRef.current = devtools;
|
|
453
442
|
incremark.parser.setOnChange((state) => {
|
|
454
443
|
const blocks = [
|
|
455
|
-
...state.completedBlocks
|
|
456
|
-
...state.pendingBlocks
|
|
444
|
+
...state.completedBlocks,
|
|
445
|
+
...state.pendingBlocks
|
|
457
446
|
];
|
|
458
447
|
devtools.update({
|
|
459
448
|
blocks,
|
|
@@ -844,7 +833,135 @@ var IncremarkParagraph = ({ node }) => {
|
|
|
844
833
|
};
|
|
845
834
|
|
|
846
835
|
// src/components/IncremarkCode.tsx
|
|
847
|
-
import
|
|
836
|
+
import React5, { useState as useState5, useEffect as useEffect4, useRef as useRef5, useCallback as useCallback5 } from "react";
|
|
837
|
+
|
|
838
|
+
// src/hooks/useShiki.ts
|
|
839
|
+
import React4 from "react";
|
|
840
|
+
var ShikiManager = class _ShikiManager {
|
|
841
|
+
static instance = null;
|
|
842
|
+
/** 存储 highlighter 实例,key 为主题名称 */
|
|
843
|
+
highlighters = /* @__PURE__ */ new Map();
|
|
844
|
+
constructor() {
|
|
845
|
+
}
|
|
846
|
+
static getInstance() {
|
|
847
|
+
if (!_ShikiManager.instance) {
|
|
848
|
+
_ShikiManager.instance = new _ShikiManager();
|
|
849
|
+
}
|
|
850
|
+
return _ShikiManager.instance;
|
|
851
|
+
}
|
|
852
|
+
/**
|
|
853
|
+
* 获取或创建 highlighter
|
|
854
|
+
* @param theme 主题名称
|
|
855
|
+
* @returns highlighter 实例
|
|
856
|
+
*/
|
|
857
|
+
async getHighlighter(theme) {
|
|
858
|
+
if (this.highlighters.has(theme)) {
|
|
859
|
+
return this.highlighters.get(theme);
|
|
860
|
+
}
|
|
861
|
+
const { createHighlighter } = await import("shiki");
|
|
862
|
+
const highlighter = await createHighlighter({
|
|
863
|
+
themes: [theme],
|
|
864
|
+
langs: []
|
|
865
|
+
});
|
|
866
|
+
const info = {
|
|
867
|
+
highlighter,
|
|
868
|
+
loadedLanguages: /* @__PURE__ */ new Set(),
|
|
869
|
+
loadedThemes: /* @__PURE__ */ new Set([theme])
|
|
870
|
+
};
|
|
871
|
+
this.highlighters.set(theme, info);
|
|
872
|
+
return info;
|
|
873
|
+
}
|
|
874
|
+
/**
|
|
875
|
+
* 加载语言(按需)
|
|
876
|
+
* @param theme 主题名称
|
|
877
|
+
* @param lang 语言名称
|
|
878
|
+
*/
|
|
879
|
+
async loadLanguage(theme, lang) {
|
|
880
|
+
const info = this.highlighters.get(theme);
|
|
881
|
+
if (!info || info.loadedLanguages.has(lang)) return;
|
|
882
|
+
try {
|
|
883
|
+
await info.highlighter.loadLanguage(lang);
|
|
884
|
+
info.loadedLanguages.add(lang);
|
|
885
|
+
} catch {
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
/**
|
|
889
|
+
* 加载主题(按需)
|
|
890
|
+
* @param theme 主题名称
|
|
891
|
+
*/
|
|
892
|
+
async loadTheme(theme) {
|
|
893
|
+
const info = this.highlighters.get(theme);
|
|
894
|
+
if (!info || info.loadedThemes.has(theme)) return;
|
|
895
|
+
try {
|
|
896
|
+
await info.highlighter.loadTheme(theme);
|
|
897
|
+
info.loadedThemes.add(theme);
|
|
898
|
+
} catch {
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
/**
|
|
902
|
+
* 高亮代码
|
|
903
|
+
* @param theme 主题名称
|
|
904
|
+
* @param code 代码内容
|
|
905
|
+
* @param lang 语言名称
|
|
906
|
+
* @param fallbackTheme 回退主题
|
|
907
|
+
* @returns 高亮后的 HTML
|
|
908
|
+
*/
|
|
909
|
+
async codeToHtml(theme, code, lang, fallbackTheme) {
|
|
910
|
+
const info = this.highlighters.get(theme);
|
|
911
|
+
if (!info) throw new Error("Highlighter not found");
|
|
912
|
+
const actualLang = info.loadedLanguages.has(lang) ? lang : "text";
|
|
913
|
+
const actualTheme = info.loadedThemes.has(theme) ? theme : fallbackTheme;
|
|
914
|
+
return info.highlighter.codeToHtml(code, {
|
|
915
|
+
lang: actualLang,
|
|
916
|
+
theme: actualTheme
|
|
917
|
+
});
|
|
918
|
+
}
|
|
919
|
+
/**
|
|
920
|
+
* 清理所有 highlighter(应用退出或需要重置时调用)
|
|
921
|
+
*/
|
|
922
|
+
disposeAll() {
|
|
923
|
+
for (const [, info] of this.highlighters) {
|
|
924
|
+
if (info.highlighter?.dispose) {
|
|
925
|
+
info.highlighter.dispose();
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
this.highlighters.clear();
|
|
929
|
+
}
|
|
930
|
+
};
|
|
931
|
+
var shikiManager = ShikiManager.getInstance();
|
|
932
|
+
function useShiki(theme) {
|
|
933
|
+
const [isHighlighting, setIsHighlighting] = React4.useState(false);
|
|
934
|
+
const highlighterInfoRef = React4.useRef(null);
|
|
935
|
+
const getHighlighter = React4.useCallback(async () => {
|
|
936
|
+
if (!highlighterInfoRef.current) {
|
|
937
|
+
highlighterInfoRef.current = await shikiManager.getHighlighter(theme);
|
|
938
|
+
}
|
|
939
|
+
return highlighterInfoRef.current;
|
|
940
|
+
}, [theme]);
|
|
941
|
+
const highlight = React4.useCallback(async (code, lang, fallbackTheme) => {
|
|
942
|
+
setIsHighlighting(true);
|
|
943
|
+
try {
|
|
944
|
+
const info = await getHighlighter();
|
|
945
|
+
if (!info.loadedLanguages.has(lang) && lang !== "text") {
|
|
946
|
+
await shikiManager.loadLanguage(theme, lang);
|
|
947
|
+
}
|
|
948
|
+
if (!info.loadedThemes.has(theme)) {
|
|
949
|
+
await shikiManager.loadTheme(theme);
|
|
950
|
+
}
|
|
951
|
+
return await shikiManager.codeToHtml(theme, code, lang, fallbackTheme);
|
|
952
|
+
} catch (e) {
|
|
953
|
+
throw e;
|
|
954
|
+
} finally {
|
|
955
|
+
setIsHighlighting(false);
|
|
956
|
+
}
|
|
957
|
+
}, [getHighlighter, theme]);
|
|
958
|
+
return {
|
|
959
|
+
isHighlighting,
|
|
960
|
+
highlight
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
// src/components/IncremarkCode.tsx
|
|
848
965
|
import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
849
966
|
var IncremarkCode = ({
|
|
850
967
|
node,
|
|
@@ -858,19 +975,16 @@ var IncremarkCode = ({
|
|
|
858
975
|
}) => {
|
|
859
976
|
const [copied, setCopied] = useState5(false);
|
|
860
977
|
const [highlightedHtml, setHighlightedHtml] = useState5("");
|
|
861
|
-
const [isHighlighting, setIsHighlighting] = useState5(false);
|
|
862
978
|
const [mermaidSvg, setMermaidSvg] = useState5("");
|
|
863
979
|
const [mermaidLoading, setMermaidLoading] = useState5(false);
|
|
864
980
|
const [mermaidViewMode, setMermaidViewMode] = useState5("preview");
|
|
865
981
|
const mermaidRef = useRef5(null);
|
|
866
|
-
const highlighterRef = useRef5(null);
|
|
867
982
|
const mermaidTimerRef = useRef5(null);
|
|
868
|
-
const loadedLanguagesRef = useRef5(/* @__PURE__ */ new Set());
|
|
869
|
-
const loadedThemesRef = useRef5(/* @__PURE__ */ new Set());
|
|
870
983
|
const language = node.lang || "text";
|
|
871
984
|
const code = node.value;
|
|
872
985
|
const isMermaid = language === "mermaid";
|
|
873
|
-
const
|
|
986
|
+
const { isHighlighting, highlight } = useShiki(theme);
|
|
987
|
+
const CustomCodeBlock = React5.useMemo(() => {
|
|
874
988
|
const component = customCodeBlocks?.[language];
|
|
875
989
|
if (!component) return null;
|
|
876
990
|
const config = codeBlockConfigs?.[language];
|
|
@@ -902,7 +1016,8 @@ var IncremarkCode = ({
|
|
|
902
1016
|
mermaidRef.current.initialize({
|
|
903
1017
|
startOnLoad: false,
|
|
904
1018
|
theme: "dark",
|
|
905
|
-
securityLevel: "loose"
|
|
1019
|
+
securityLevel: "loose",
|
|
1020
|
+
suppressErrorRendering: true
|
|
906
1021
|
});
|
|
907
1022
|
}
|
|
908
1023
|
const mermaid = mermaidRef.current;
|
|
@@ -925,7 +1040,7 @@ var IncremarkCode = ({
|
|
|
925
1040
|
doRenderMermaid();
|
|
926
1041
|
}, mermaidDelay);
|
|
927
1042
|
}, [isMermaid, code, mermaidDelay, doRenderMermaid]);
|
|
928
|
-
const
|
|
1043
|
+
const doHighlight = useCallback5(async () => {
|
|
929
1044
|
if (isMermaid) {
|
|
930
1045
|
scheduleRenderMermaid();
|
|
931
1046
|
return;
|
|
@@ -934,46 +1049,16 @@ var IncremarkCode = ({
|
|
|
934
1049
|
setHighlightedHtml("");
|
|
935
1050
|
return;
|
|
936
1051
|
}
|
|
937
|
-
setIsHighlighting(true);
|
|
938
1052
|
try {
|
|
939
|
-
|
|
940
|
-
const { createHighlighter } = await import("shiki");
|
|
941
|
-
highlighterRef.current = await createHighlighter({
|
|
942
|
-
themes: [theme],
|
|
943
|
-
langs: []
|
|
944
|
-
});
|
|
945
|
-
loadedThemesRef.current.add(theme);
|
|
946
|
-
}
|
|
947
|
-
const highlighter = highlighterRef.current;
|
|
948
|
-
const lang = language;
|
|
949
|
-
if (!loadedLanguagesRef.current.has(lang) && lang !== "text") {
|
|
950
|
-
try {
|
|
951
|
-
await highlighter.loadLanguage(lang);
|
|
952
|
-
loadedLanguagesRef.current.add(lang);
|
|
953
|
-
} catch {
|
|
954
|
-
}
|
|
955
|
-
}
|
|
956
|
-
if (!loadedThemesRef.current.has(theme)) {
|
|
957
|
-
try {
|
|
958
|
-
await highlighter.loadTheme(theme);
|
|
959
|
-
loadedThemesRef.current.add(theme);
|
|
960
|
-
} catch {
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
|
-
const html = highlighter.codeToHtml(code, {
|
|
964
|
-
lang: loadedLanguagesRef.current.has(lang) ? lang : "text",
|
|
965
|
-
theme: loadedThemesRef.current.has(theme) ? theme : fallbackTheme
|
|
966
|
-
});
|
|
1053
|
+
const html = await highlight(code, language, fallbackTheme);
|
|
967
1054
|
setHighlightedHtml(html);
|
|
968
1055
|
} catch {
|
|
969
1056
|
setHighlightedHtml("");
|
|
970
|
-
} finally {
|
|
971
|
-
setIsHighlighting(false);
|
|
972
1057
|
}
|
|
973
|
-
}, [code, language,
|
|
1058
|
+
}, [code, language, fallbackTheme, disableHighlight, isMermaid, highlight, scheduleRenderMermaid]);
|
|
974
1059
|
useEffect4(() => {
|
|
975
|
-
|
|
976
|
-
}, [
|
|
1060
|
+
doHighlight();
|
|
1061
|
+
}, [doHighlight]);
|
|
977
1062
|
useEffect4(() => {
|
|
978
1063
|
return () => {
|
|
979
1064
|
if (mermaidTimerRef.current) {
|
|
@@ -1024,7 +1109,7 @@ var IncremarkCode = ({
|
|
|
1024
1109
|
};
|
|
1025
1110
|
|
|
1026
1111
|
// src/components/IncremarkList.tsx
|
|
1027
|
-
import
|
|
1112
|
+
import React6 from "react";
|
|
1028
1113
|
import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1029
1114
|
function getItemInlineContent(item) {
|
|
1030
1115
|
const firstChild = item.children[0];
|
|
@@ -1044,7 +1129,7 @@ function getItemBlockChildren(item) {
|
|
|
1044
1129
|
var IncremarkList = ({ node }) => {
|
|
1045
1130
|
const Tag = node.ordered ? "ol" : "ul";
|
|
1046
1131
|
const isTaskList = node.children?.some((item) => item.checked !== null && item.checked !== void 0);
|
|
1047
|
-
return /* @__PURE__ */ jsx7(Tag, { className: `incremark-list ${isTaskList ? "task-list" : ""}`, children: node.children?.map((item, index) => {
|
|
1132
|
+
return /* @__PURE__ */ jsx7(Tag, { className: `incremark-list ${isTaskList ? "task-list" : ""}`, start: node.start || void 0, children: node.children?.map((item, index) => {
|
|
1048
1133
|
const isTaskItem = item.checked !== null && item.checked !== void 0;
|
|
1049
1134
|
const inlineContent = getItemInlineContent(item);
|
|
1050
1135
|
const blockChildren = getItemBlockChildren(item);
|
|
@@ -1064,16 +1149,16 @@ var IncremarkList = ({ node }) => {
|
|
|
1064
1149
|
}
|
|
1065
1150
|
return /* @__PURE__ */ jsxs3("li", { className: "incremark-list-item", children: [
|
|
1066
1151
|
/* @__PURE__ */ jsx7(IncremarkInline, { nodes: inlineContent }),
|
|
1067
|
-
blockChildren.map((child, childIndex) => /* @__PURE__ */ jsx7(
|
|
1152
|
+
blockChildren.map((child, childIndex) => /* @__PURE__ */ jsx7(React6.Fragment, { children: /* @__PURE__ */ jsx7(IncremarkRenderer, { node: child }) }, childIndex))
|
|
1068
1153
|
] }, index);
|
|
1069
1154
|
}) });
|
|
1070
1155
|
};
|
|
1071
1156
|
|
|
1072
1157
|
// src/components/IncremarkBlockquote.tsx
|
|
1073
|
-
import
|
|
1158
|
+
import React7 from "react";
|
|
1074
1159
|
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
1075
1160
|
var IncremarkBlockquote = ({ node }) => {
|
|
1076
|
-
return /* @__PURE__ */ jsx8("blockquote", { className: "incremark-blockquote", children: node.children.map((child, index) => /* @__PURE__ */ jsx8(
|
|
1161
|
+
return /* @__PURE__ */ jsx8("blockquote", { className: "incremark-blockquote", children: node.children.map((child, index) => /* @__PURE__ */ jsx8(React7.Fragment, { children: /* @__PURE__ */ jsx8(IncremarkRenderer, { node: child }) }, index)) });
|
|
1077
1162
|
};
|
|
1078
1163
|
|
|
1079
1164
|
// src/components/IncremarkTable.tsx
|
|
@@ -1267,11 +1352,11 @@ var IncremarkRenderer = ({
|
|
|
1267
1352
|
};
|
|
1268
1353
|
|
|
1269
1354
|
// src/components/IncremarkFootnotes.tsx
|
|
1270
|
-
import
|
|
1355
|
+
import React9 from "react";
|
|
1271
1356
|
import { jsx as jsx15, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1272
1357
|
var IncremarkFootnotes = () => {
|
|
1273
1358
|
const { footnoteDefinitions, footnoteReferenceOrder } = useDefinitions();
|
|
1274
|
-
const orderedFootnotes =
|
|
1359
|
+
const orderedFootnotes = React9.useMemo(() => {
|
|
1275
1360
|
return footnoteReferenceOrder.map((identifier) => ({
|
|
1276
1361
|
identifier,
|
|
1277
1362
|
definition: footnoteDefinitions[identifier]
|
|
@@ -1328,6 +1413,8 @@ var Incremark = (props) => {
|
|
|
1328
1413
|
customCodeBlocks,
|
|
1329
1414
|
showBlockStatus = true,
|
|
1330
1415
|
className = "",
|
|
1416
|
+
pendingClass = "incremark-pending",
|
|
1417
|
+
completedClass = "incremark-completed",
|
|
1331
1418
|
incremark
|
|
1332
1419
|
} = props;
|
|
1333
1420
|
if (incremark) {
|
|
@@ -1341,6 +1428,8 @@ var Incremark = (props) => {
|
|
|
1341
1428
|
customCodeBlocks,
|
|
1342
1429
|
showBlockStatus,
|
|
1343
1430
|
className,
|
|
1431
|
+
pendingClass,
|
|
1432
|
+
completedClass,
|
|
1344
1433
|
isDisplayComplete: isDisplayComplete2
|
|
1345
1434
|
}
|
|
1346
1435
|
) });
|
|
@@ -1356,6 +1445,8 @@ var Incremark = (props) => {
|
|
|
1356
1445
|
customCodeBlocks,
|
|
1357
1446
|
showBlockStatus,
|
|
1358
1447
|
className,
|
|
1448
|
+
pendingClass,
|
|
1449
|
+
completedClass,
|
|
1359
1450
|
isDisplayComplete
|
|
1360
1451
|
}
|
|
1361
1452
|
);
|
|
@@ -1368,6 +1459,8 @@ var IncremarkInternal = ({
|
|
|
1368
1459
|
codeBlockConfigs,
|
|
1369
1460
|
showBlockStatus,
|
|
1370
1461
|
className,
|
|
1462
|
+
pendingClass,
|
|
1463
|
+
completedClass,
|
|
1371
1464
|
isDisplayComplete
|
|
1372
1465
|
}) => {
|
|
1373
1466
|
return /* @__PURE__ */ jsxs7("div", { className: `incremark ${className}`, children: [
|
|
@@ -1378,7 +1471,7 @@ var IncremarkInternal = ({
|
|
|
1378
1471
|
const isPending = block.status === "pending";
|
|
1379
1472
|
const classes = [
|
|
1380
1473
|
"incremark-block",
|
|
1381
|
-
isPending ?
|
|
1474
|
+
isPending ? pendingClass : completedClass,
|
|
1382
1475
|
showBlockStatus && "incremark-show-status",
|
|
1383
1476
|
block.isLastPending && "incremark-last-pending"
|
|
1384
1477
|
].filter(Boolean).join(" ");
|
|
@@ -1392,22 +1485,112 @@ var IncremarkInternal = ({
|
|
|
1392
1485
|
codeBlockConfigs,
|
|
1393
1486
|
blockStatus: block.status
|
|
1394
1487
|
}
|
|
1395
|
-
) }, block.
|
|
1488
|
+
) }, block.id);
|
|
1396
1489
|
}),
|
|
1397
1490
|
isDisplayComplete && /* @__PURE__ */ jsx17(IncremarkFootnotes, {})
|
|
1398
1491
|
] });
|
|
1399
1492
|
};
|
|
1400
1493
|
|
|
1494
|
+
// src/components/IncremarkContent.tsx
|
|
1495
|
+
import { useEffect as useEffect6, useRef as useRef7, useMemo as useMemo3, useCallback as useCallback7 } from "react";
|
|
1496
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
1497
|
+
var IncremarkContent = (props) => {
|
|
1498
|
+
const {
|
|
1499
|
+
stream,
|
|
1500
|
+
content,
|
|
1501
|
+
components,
|
|
1502
|
+
customContainers,
|
|
1503
|
+
customCodeBlocks,
|
|
1504
|
+
codeBlockConfigs,
|
|
1505
|
+
isFinished = false,
|
|
1506
|
+
incremarkOptions,
|
|
1507
|
+
showBlockStatus,
|
|
1508
|
+
pendingClass
|
|
1509
|
+
} = props;
|
|
1510
|
+
const initialOptionsRef = useRef7({
|
|
1511
|
+
gfm: true,
|
|
1512
|
+
htmlTree: true,
|
|
1513
|
+
containers: true,
|
|
1514
|
+
math: true,
|
|
1515
|
+
...incremarkOptions
|
|
1516
|
+
});
|
|
1517
|
+
const { blocks, append, finalize, render, reset, isDisplayComplete, markdown, typewriter, _definitionsContextValue } = useIncremark(initialOptionsRef.current);
|
|
1518
|
+
useEffect6(() => {
|
|
1519
|
+
if (incremarkOptions?.typewriter) {
|
|
1520
|
+
typewriter.setOptions(incremarkOptions.typewriter);
|
|
1521
|
+
}
|
|
1522
|
+
}, [incremarkOptions?.typewriter, typewriter]);
|
|
1523
|
+
const isStreamMode = useMemo3(() => typeof stream === "function", [stream]);
|
|
1524
|
+
const prevContentRef = useRef7(void 0);
|
|
1525
|
+
const isStreamingRef = useRef7(false);
|
|
1526
|
+
const handleStreamInput = useCallback7(async () => {
|
|
1527
|
+
if (!stream || isStreamingRef.current) return;
|
|
1528
|
+
isStreamingRef.current = true;
|
|
1529
|
+
try {
|
|
1530
|
+
const streamGen = stream();
|
|
1531
|
+
for await (const chunk of streamGen) {
|
|
1532
|
+
append(chunk);
|
|
1533
|
+
}
|
|
1534
|
+
finalize();
|
|
1535
|
+
} catch (error) {
|
|
1536
|
+
console.error("Stream error: ", error);
|
|
1537
|
+
finalize();
|
|
1538
|
+
} finally {
|
|
1539
|
+
isStreamingRef.current = false;
|
|
1540
|
+
}
|
|
1541
|
+
}, [stream, append, finalize]);
|
|
1542
|
+
const handleContentInput = useCallback7((newContent, oldContent) => {
|
|
1543
|
+
if (!newContent) {
|
|
1544
|
+
if (oldContent) {
|
|
1545
|
+
reset();
|
|
1546
|
+
}
|
|
1547
|
+
return;
|
|
1548
|
+
}
|
|
1549
|
+
if (newContent?.startsWith(oldContent ?? "")) {
|
|
1550
|
+
const delta = newContent.slice((oldContent || "").length);
|
|
1551
|
+
append(delta);
|
|
1552
|
+
} else {
|
|
1553
|
+
render(newContent);
|
|
1554
|
+
}
|
|
1555
|
+
}, [append, render, reset]);
|
|
1556
|
+
useEffect6(() => {
|
|
1557
|
+
if (isStreamMode) {
|
|
1558
|
+
handleStreamInput();
|
|
1559
|
+
} else {
|
|
1560
|
+
handleContentInput(content, prevContentRef.current);
|
|
1561
|
+
}
|
|
1562
|
+
prevContentRef.current = content;
|
|
1563
|
+
}, [content, isStreamMode, handleStreamInput, handleContentInput]);
|
|
1564
|
+
useEffect6(() => {
|
|
1565
|
+
if (isFinished && content === markdown) {
|
|
1566
|
+
finalize();
|
|
1567
|
+
}
|
|
1568
|
+
}, [isFinished, content, markdown, finalize]);
|
|
1569
|
+
return /* @__PURE__ */ jsx18(IncremarkContainerProvider, { definitions: _definitionsContextValue, children: /* @__PURE__ */ jsx18(
|
|
1570
|
+
Incremark,
|
|
1571
|
+
{
|
|
1572
|
+
blocks,
|
|
1573
|
+
isDisplayComplete,
|
|
1574
|
+
showBlockStatus,
|
|
1575
|
+
pendingClass,
|
|
1576
|
+
components,
|
|
1577
|
+
customContainers,
|
|
1578
|
+
customCodeBlocks,
|
|
1579
|
+
codeBlockConfigs
|
|
1580
|
+
}
|
|
1581
|
+
) });
|
|
1582
|
+
};
|
|
1583
|
+
|
|
1401
1584
|
// src/components/AutoScrollContainer.tsx
|
|
1402
1585
|
import {
|
|
1403
|
-
useRef as
|
|
1404
|
-
useEffect as
|
|
1405
|
-
useCallback as
|
|
1586
|
+
useRef as useRef8,
|
|
1587
|
+
useEffect as useEffect7,
|
|
1588
|
+
useCallback as useCallback8,
|
|
1406
1589
|
useState as useState7,
|
|
1407
1590
|
forwardRef,
|
|
1408
1591
|
useImperativeHandle
|
|
1409
1592
|
} from "react";
|
|
1410
|
-
import { jsx as
|
|
1593
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
1411
1594
|
var AutoScrollContainer = forwardRef(
|
|
1412
1595
|
({
|
|
1413
1596
|
children,
|
|
@@ -1417,17 +1600,17 @@ var AutoScrollContainer = forwardRef(
|
|
|
1417
1600
|
style,
|
|
1418
1601
|
className
|
|
1419
1602
|
}, ref) => {
|
|
1420
|
-
const containerRef =
|
|
1603
|
+
const containerRef = useRef8(null);
|
|
1421
1604
|
const [isUserScrolledUp, setIsUserScrolledUp] = useState7(false);
|
|
1422
|
-
const lastScrollTopRef =
|
|
1423
|
-
const lastScrollHeightRef =
|
|
1424
|
-
const isNearBottom =
|
|
1605
|
+
const lastScrollTopRef = useRef8(0);
|
|
1606
|
+
const lastScrollHeightRef = useRef8(0);
|
|
1607
|
+
const isNearBottom = useCallback8(() => {
|
|
1425
1608
|
const container = containerRef.current;
|
|
1426
1609
|
if (!container) return true;
|
|
1427
1610
|
const { scrollTop, scrollHeight, clientHeight } = container;
|
|
1428
1611
|
return scrollHeight - scrollTop - clientHeight <= threshold;
|
|
1429
1612
|
}, [threshold]);
|
|
1430
|
-
const scrollToBottom =
|
|
1613
|
+
const scrollToBottom = useCallback8(
|
|
1431
1614
|
(force = false) => {
|
|
1432
1615
|
const container = containerRef.current;
|
|
1433
1616
|
if (!container) return;
|
|
@@ -1439,12 +1622,12 @@ var AutoScrollContainer = forwardRef(
|
|
|
1439
1622
|
},
|
|
1440
1623
|
[isUserScrolledUp, behavior]
|
|
1441
1624
|
);
|
|
1442
|
-
const hasScrollbar =
|
|
1625
|
+
const hasScrollbar = useCallback8(() => {
|
|
1443
1626
|
const container = containerRef.current;
|
|
1444
1627
|
if (!container) return false;
|
|
1445
1628
|
return container.scrollHeight > container.clientHeight;
|
|
1446
1629
|
}, []);
|
|
1447
|
-
const handleScroll =
|
|
1630
|
+
const handleScroll = useCallback8(() => {
|
|
1448
1631
|
const container = containerRef.current;
|
|
1449
1632
|
if (!container) return;
|
|
1450
1633
|
const { scrollTop, scrollHeight, clientHeight } = container;
|
|
@@ -1466,14 +1649,14 @@ var AutoScrollContainer = forwardRef(
|
|
|
1466
1649
|
lastScrollTopRef.current = scrollTop;
|
|
1467
1650
|
lastScrollHeightRef.current = scrollHeight;
|
|
1468
1651
|
}, [isNearBottom]);
|
|
1469
|
-
|
|
1652
|
+
useEffect7(() => {
|
|
1470
1653
|
const container = containerRef.current;
|
|
1471
1654
|
if (container) {
|
|
1472
1655
|
lastScrollTopRef.current = container.scrollTop;
|
|
1473
1656
|
lastScrollHeightRef.current = container.scrollHeight;
|
|
1474
1657
|
}
|
|
1475
1658
|
}, []);
|
|
1476
|
-
|
|
1659
|
+
useEffect7(() => {
|
|
1477
1660
|
const container = containerRef.current;
|
|
1478
1661
|
if (!container || !enabled) return;
|
|
1479
1662
|
const observer = new MutationObserver(() => {
|
|
@@ -1505,7 +1688,7 @@ var AutoScrollContainer = forwardRef(
|
|
|
1505
1688
|
}),
|
|
1506
1689
|
[scrollToBottom, isUserScrolledUp]
|
|
1507
1690
|
);
|
|
1508
|
-
return /* @__PURE__ */
|
|
1691
|
+
return /* @__PURE__ */ jsx19(
|
|
1509
1692
|
"div",
|
|
1510
1693
|
{
|
|
1511
1694
|
ref: containerRef,
|
|
@@ -1524,21 +1707,21 @@ var AutoScrollContainer = forwardRef(
|
|
|
1524
1707
|
AutoScrollContainer.displayName = "AutoScrollContainer";
|
|
1525
1708
|
|
|
1526
1709
|
// src/ThemeProvider.tsx
|
|
1527
|
-
import { useEffect as
|
|
1710
|
+
import { useEffect as useEffect8, useRef as useRef9 } from "react";
|
|
1528
1711
|
import { applyTheme } from "@incremark/theme";
|
|
1529
|
-
import { jsx as
|
|
1712
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
1530
1713
|
var ThemeProvider = ({
|
|
1531
1714
|
theme,
|
|
1532
1715
|
children,
|
|
1533
1716
|
className = ""
|
|
1534
1717
|
}) => {
|
|
1535
|
-
const containerRef =
|
|
1536
|
-
|
|
1718
|
+
const containerRef = useRef9(null);
|
|
1719
|
+
useEffect8(() => {
|
|
1537
1720
|
if (containerRef.current) {
|
|
1538
1721
|
applyTheme(containerRef.current, theme);
|
|
1539
1722
|
}
|
|
1540
1723
|
}, [theme]);
|
|
1541
|
-
return /* @__PURE__ */
|
|
1724
|
+
return /* @__PURE__ */ jsx20("div", { ref: containerRef, className: `incremark-theme-provider ${className}`.trim(), children });
|
|
1542
1725
|
};
|
|
1543
1726
|
|
|
1544
1727
|
// src/index.ts
|
|
@@ -1570,6 +1753,7 @@ export {
|
|
|
1570
1753
|
DefinitionsProvider,
|
|
1571
1754
|
Incremark,
|
|
1572
1755
|
IncremarkContainerProvider,
|
|
1756
|
+
IncremarkContent,
|
|
1573
1757
|
IncremarkFootnotes,
|
|
1574
1758
|
IncremarkHtmlElement,
|
|
1575
1759
|
IncremarkInline,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@incremark/react",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.7",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Incremark React integration - Incremental Markdown parser for AI streaming",
|
|
6
6
|
"type": "module",
|
|
@@ -21,13 +21,13 @@
|
|
|
21
21
|
"mermaid": "^10.0.0 || ^11.0.0",
|
|
22
22
|
"katex": "^0.16.0",
|
|
23
23
|
"react": ">=18.0.0",
|
|
24
|
-
"@incremark/core": "0.2.
|
|
24
|
+
"@incremark/core": "0.2.7"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"shiki": "^3.20.0",
|
|
28
|
-
"@incremark/
|
|
29
|
-
"@incremark/theme": "0.2.
|
|
30
|
-
"@incremark/
|
|
28
|
+
"@incremark/devtools": "0.2.7",
|
|
29
|
+
"@incremark/theme": "0.2.7",
|
|
30
|
+
"@incremark/shared": "0.2.7"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/mdast": "^4.0.0",
|