@ai-react-markdown/core 1.0.1 → 1.0.5

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.md ADDED
@@ -0,0 +1,407 @@
1
+ # @ai-react-markdown/core
2
+
3
+ A batteries-included React component for rendering AI-generated markdown with first-class support for LaTeX math, GFM, CJK text, and streaming content.
4
+
5
+ ## Features
6
+
7
+ - **GFM** -- tables, strikethrough, task lists, autolinks via `remark-gfm`
8
+ - **LaTeX math** -- inline and display math rendered with KaTeX; smart preprocessing handles currency `$` signs, bracket delimiters (`\[...\]`, `\(...\)`), pipe escaping, and mhchem commands
9
+ - **Emoji** -- shortcode support (`:smile:`) via `remark-emoji`
10
+ - **CJK-friendly** -- proper line breaking and spacing for Chinese, Japanese, and Korean text
11
+ - **Extra syntax** -- highlight (`==text==`), definition lists, superscript/subscript
12
+ - **Display optimizations** -- SmartyPants typography, pangu CJK spacing, HTML comment removal
13
+ - **Streaming-aware** -- built-in `streaming` flag propagated via context for custom components
14
+ - **Customizable** -- swap typography, color scheme, individual markdown element renderers, and inject extra style wrappers
15
+ - **Metadata context** -- pass arbitrary data to deeply nested custom components without prop drilling, isolated from render state to avoid unnecessary re-renders
16
+ - **TypeScript** -- full generic support for extended configs and metadata types
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ # npm
22
+ npm install @ai-react-markdown/core
23
+
24
+ # pnpm
25
+ pnpm add @ai-react-markdown/core
26
+
27
+ # yarn
28
+ yarn add @ai-react-markdown/core
29
+ ```
30
+
31
+ ### Peer Dependencies
32
+
33
+ ```json
34
+ {
35
+ "react": ">=19.0.0",
36
+ "react-dom": ">=19.0.0"
37
+ }
38
+ ```
39
+
40
+ ### CSS Dependencies
41
+
42
+ For LaTeX math rendering, include the KaTeX stylesheet:
43
+
44
+ ```tsx
45
+ import 'katex/dist/katex.min.css';
46
+ ```
47
+
48
+ For the built-in default typography, include the typography CSS:
49
+
50
+ ```tsx
51
+ import '@ai-react-markdown/core/typography/default.css';
52
+ // or import all typography variants at once:
53
+ import '@ai-react-markdown/core/typography/all.css';
54
+ ```
55
+
56
+ ## Quick Start
57
+
58
+ ```tsx
59
+ import AIMarkdown from '@ai-react-markdown/core';
60
+ import 'katex/dist/katex.min.css';
61
+ import '@ai-react-markdown/core/typography/default.css';
62
+
63
+ function App() {
64
+ return <AIMarkdown content="Hello **world**! Math: $E = mc^2$" />;
65
+ }
66
+ ```
67
+
68
+ ### Streaming Example
69
+
70
+ ```tsx
71
+ function StreamingChat({ content, isStreaming }: { content: string; isStreaming: boolean }) {
72
+ return <AIMarkdown content={content} streaming={isStreaming} colorScheme="dark" />;
73
+ }
74
+ ```
75
+
76
+ ## Props API Reference
77
+
78
+ ### `AIMarkdownProps<TConfig, TRenderData>`
79
+
80
+ | Prop | Type | Default | Description |
81
+ | ---------------------- | -------------------------------- | ------------------------------- | ---------------------------------------------------------------------- |
82
+ | `content` | `string` | **(required)** | Raw markdown content to render. |
83
+ | `streaming` | `boolean` | `false` | Whether content is actively being streamed (e.g. from an LLM). |
84
+ | `fontSize` | `number \| string` | `'0.875rem'` | Base font size. Numbers are treated as pixels. |
85
+ | `variant` | `AIMarkdownVariant` | `'default'` | Typography variant name. |
86
+ | `colorScheme` | `AIMarkdownColorScheme` | `'light'` | Color scheme name (`'light'`, `'dark'`, or custom). |
87
+ | `config` | `PartialDeep<TConfig>` | `undefined` | Partial render config, deep-merged with defaults. |
88
+ | `defaultConfig` | `TConfig` | `defaultAIMarkdownRenderConfig` | Base config to merge against. Sub-packages can pass extended defaults. |
89
+ | `metadata` | `TRenderData` | `undefined` | Arbitrary data passed to custom components via a dedicated context. |
90
+ | `contentPreprocessors` | `AIMDContentPreprocessor[]` | `[]` | Additional preprocessors run after the built-in LaTeX preprocessor. |
91
+ | `customComponents` | `AIMarkdownCustomComponents` | `undefined` | `react-markdown` component overrides for specific HTML elements. |
92
+ | `Typography` | `AIMarkdownTypographyComponent` | `DefaultTypography` | Typography wrapper component. |
93
+ | `ExtraStyles` | `AIMarkdownExtraStylesComponent` | `undefined` | Optional extra style wrapper rendered between typography and content. |
94
+
95
+ ## Configuration
96
+
97
+ Rendering behavior is controlled by `AIMarkdownRenderConfig`, which has two configuration arrays:
98
+
99
+ ### Extra Syntax Extensions
100
+
101
+ Enable via `config.extraSyntaxSupported`. All are enabled by default.
102
+
103
+ | Value | Description |
104
+ | --------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
105
+ | `AIMarkdownRenderExtraSyntax.HIGHLIGHT` | `==Highlight==` syntax support |
106
+ | `AIMarkdownRenderExtraSyntax.DEFINITION_LIST` | Definition list syntax ([PHP Markdown Extra](https://michelf.ca/projects/php-markdown/extra/#def-list)) |
107
+ | `AIMarkdownRenderExtraSyntax.SUBSCRIPT` | Superscript (`^text^`) and subscript (`~text~`) |
108
+
109
+ ### Display Optimization Abilities
110
+
111
+ Enable via `config.displayOptimizeAbilities`. All are enabled by default.
112
+
113
+ | Value | Description |
114
+ | -------------------------------------------------------- | -------------------------------------------------------- |
115
+ | `AIMarkdownRenderDisplayOptimizeAbility.REMOVE_COMMENTS` | Strip HTML comments |
116
+ | `AIMarkdownRenderDisplayOptimizeAbility.SMARTYPANTS` | Typographic enhancements (curly quotes, em-dashes, etc.) |
117
+ | `AIMarkdownRenderDisplayOptimizeAbility.PANGU` | Auto-insert spaces between CJK and half-width characters |
118
+
119
+ ### Example: Selective Configuration
120
+
121
+ ```tsx
122
+ import AIMarkdown, {
123
+ AIMarkdownRenderExtraSyntax,
124
+ AIMarkdownRenderDisplayOptimizeAbility,
125
+ } from '@ai-react-markdown/core';
126
+
127
+ <AIMarkdown
128
+ content={markdown}
129
+ config={{
130
+ extraSyntaxSupported: [AIMarkdownRenderExtraSyntax.HIGHLIGHT],
131
+ displayOptimizeAbilities: [AIMarkdownRenderDisplayOptimizeAbility.SMARTYPANTS],
132
+ }}
133
+ />;
134
+ ```
135
+
136
+ When you provide a partial `config`, it is deep-merged with the defaults. Array values (like `extraSyntaxSupported`) are **replaced entirely**, not merged by index -- so the example above enables only the highlight extension, disabling definition lists and subscript.
137
+
138
+ ## Hooks
139
+
140
+ ### `useAIMarkdownRenderState<TConfig>()`
141
+
142
+ Access the current render state from within any component rendered inside `<AIMarkdown>`. Throws if called outside the provider boundary.
143
+
144
+ ```tsx
145
+ import { useAIMarkdownRenderState } from '@ai-react-markdown/core';
146
+
147
+ function CustomCodeBlock({ children }: PropsWithChildren) {
148
+ const { streaming, config, fontSize, variant, colorScheme } = useAIMarkdownRenderState();
149
+
150
+ if (streaming) {
151
+ return <pre className="streaming">{children}</pre>;
152
+ }
153
+ return <pre>{children}</pre>;
154
+ }
155
+ ```
156
+
157
+ **Returns** `AIMarkdownRenderState<TConfig>`:
158
+
159
+ | Field | Type | Description |
160
+ | ------------- | ----------------------- | --------------------------------------------------- |
161
+ | `streaming` | `boolean` | Whether content is being streamed. |
162
+ | `fontSize` | `string` | Resolved CSS font-size value. |
163
+ | `variant` | `AIMarkdownVariant` | Active typography variant. |
164
+ | `colorScheme` | `AIMarkdownColorScheme` | Active color scheme. |
165
+ | `config` | `TConfig` | Active render configuration (merged with defaults). |
166
+
167
+ ### `useAIMarkdownMetadata<TMetadata>()`
168
+
169
+ Access arbitrary metadata from within the `<AIMarkdown>` tree. Metadata lives in a **separate** React context from render state, so metadata changes do not trigger re-renders in components that only consume render state.
170
+
171
+ ```tsx
172
+ import { useAIMarkdownMetadata } from '@ai-react-markdown/core';
173
+
174
+ interface MyMetadata {
175
+ onCopyCode: (code: string) => void;
176
+ messageId: string;
177
+ }
178
+
179
+ function CustomCodeBlock({ children }: PropsWithChildren) {
180
+ const metadata = useAIMarkdownMetadata<MyMetadata>();
181
+ return (
182
+ <pre>
183
+ <button onClick={() => metadata?.onCopyCode(String(children))}>Copy</button>
184
+ {children}
185
+ </pre>
186
+ );
187
+ }
188
+ ```
189
+
190
+ **Returns** `TMetadata | undefined` -- `undefined` when no metadata was provided.
191
+
192
+ ### `useStableValue<T>(value: T)`
193
+
194
+ Returns a referentially stable version of `value`. On each render the new value is deep-compared (via `lodash/isEqual`) against the previous one. If they are structurally equal, the previous reference is returned, preventing unnecessary re-renders in downstream `useMemo`/`useEffect` consumers.
195
+
196
+ ```tsx
197
+ import { useStableValue } from '@ai-react-markdown/core';
198
+
199
+ const stableConfig = useStableValue(config);
200
+ // stableConfig keeps the same reference as long as config is deep-equal.
201
+ ```
202
+
203
+ ## Typography and Styling
204
+
205
+ The `<AIMarkdown>` component wraps its content in a typography component that controls font size, variant, and color scheme.
206
+
207
+ ### Built-in Default Typography
208
+
209
+ The built-in `DefaultTypography` renders a `<div>` with CSS class names for the active variant and color scheme:
210
+
211
+ ```html
212
+ <div class="aim-typography-root default light" style="width: 100%; font-size: 0.875rem">
213
+ <!-- markdown content -->
214
+ </div>
215
+ ```
216
+
217
+ Import the corresponding CSS to activate styles:
218
+
219
+ ```tsx
220
+ import '@ai-react-markdown/core/typography/default.css';
221
+ ```
222
+
223
+ ### Custom Typography Component
224
+
225
+ Replace the typography wrapper by passing a custom component:
226
+
227
+ ```tsx
228
+ import type { AIMarkdownTypographyProps } from '@ai-react-markdown/core';
229
+
230
+ function MyTypography({ children, fontSize, variant, colorScheme }: AIMarkdownTypographyProps) {
231
+ return (
232
+ <div className={`my-markdown ${colorScheme}`} style={{ fontSize }}>
233
+ {children}
234
+ </div>
235
+ );
236
+ }
237
+
238
+ <AIMarkdown content={markdown} Typography={MyTypography} />;
239
+ ```
240
+
241
+ ### Extra Styles Wrapper
242
+
243
+ The `ExtraStyles` prop accepts a component rendered between the typography wrapper and the markdown content. Useful for injecting additional CSS scope or theme providers:
244
+
245
+ ```tsx
246
+ import type { AIMarkdownExtraStylesProps } from '@ai-react-markdown/core';
247
+
248
+ function MyExtraStyles({ children }: AIMarkdownExtraStylesProps) {
249
+ return <div className="my-extra-scope">{children}</div>;
250
+ }
251
+
252
+ <AIMarkdown content={markdown} ExtraStyles={MyExtraStyles} />;
253
+ ```
254
+
255
+ ## Custom Components
256
+
257
+ Override the default renderers for specific HTML elements using the `customComponents` prop. This maps directly to `react-markdown`'s `Components` type:
258
+
259
+ ```tsx
260
+ import type { AIMarkdownCustomComponents } from '@ai-react-markdown/core';
261
+
262
+ const components: AIMarkdownCustomComponents = {
263
+ a: ({ href, children }) => (
264
+ <a href={href} target="_blank" rel="noopener noreferrer">
265
+ {children}
266
+ </a>
267
+ ),
268
+ img: ({ src, alt }) => <img src={src} alt={alt} loading="lazy" />,
269
+ };
270
+
271
+ <AIMarkdown content={markdown} customComponents={components} />;
272
+ ```
273
+
274
+ ## Streaming Support
275
+
276
+ Pass `streaming={true}` when content is actively being generated (e.g. token-by-token from an LLM). The flag is propagated to all descendant components via `useAIMarkdownRenderState()`, allowing custom renderers to adapt their behavior (e.g. show a cursor, disable copy buttons, or skip animations).
277
+
278
+ ```tsx
279
+ function ChatMessage({ content, isStreaming }: { content: string; isStreaming: boolean }) {
280
+ return <AIMarkdown content={content} streaming={isStreaming} />;
281
+ }
282
+ ```
283
+
284
+ ## Metadata
285
+
286
+ The `metadata` prop lets you pass arbitrary data to deeply nested custom components without prop drilling. Metadata is stored in a **separate React context** from the render state, so updating metadata does not cause re-renders in components that only read render state (like the core `MarkdownContent`).
287
+
288
+ ```tsx
289
+ interface ChatMetadata {
290
+ messageId: string;
291
+ onCopyCode: (code: string) => void;
292
+ onRegenerate: () => void;
293
+ }
294
+
295
+ <AIMarkdown<AIMarkdownRenderConfig, ChatMetadata>
296
+ content={markdown}
297
+ metadata={{
298
+ messageId: msg.id,
299
+ onCopyCode: handleCopy,
300
+ onRegenerate: handleRegenerate,
301
+ }}
302
+ />;
303
+ ```
304
+
305
+ ## Content Preprocessors
306
+
307
+ The rendering pipeline runs a LaTeX preprocessor by default. You can append additional preprocessors that transform the raw markdown string before it enters the remark/rehype pipeline:
308
+
309
+ ```tsx
310
+ import type { AIMDContentPreprocessor } from '@ai-react-markdown/core';
311
+
312
+ const stripFrontmatter: AIMDContentPreprocessor = (content) => content.replace(/^---[\s\S]*?---\n/, '');
313
+
314
+ <AIMarkdown content={markdown} contentPreprocessors={[stripFrontmatter]} />;
315
+ ```
316
+
317
+ Preprocessors run in sequence: built-in LaTeX preprocessor first, then your custom ones in array order.
318
+
319
+ ## TypeScript Generics
320
+
321
+ The component supports two generic type parameters for type-safe config and metadata:
322
+
323
+ ```tsx
324
+ import AIMarkdown, { type AIMarkdownRenderConfig, type AIMarkdownMetadata } from '@ai-react-markdown/core';
325
+
326
+ // Extended config (e.g. adding code block options)
327
+ interface MyConfig extends AIMarkdownRenderConfig {
328
+ codeBlock: { defaultExpanded: boolean };
329
+ }
330
+
331
+ // Extended metadata
332
+ interface MyMetadata extends AIMarkdownMetadata {
333
+ messageId: string;
334
+ }
335
+
336
+ <AIMarkdown<MyConfig, MyMetadata>
337
+ content={markdown}
338
+ defaultConfig={myDefaultConfig}
339
+ config={{ codeBlock: { defaultExpanded: false } }}
340
+ metadata={{ messageId: '123' }}
341
+ />;
342
+ ```
343
+
344
+ Sub-packages like `@ai-react-markdown/mantine` use this pattern to extend the base config with additional options (e.g. `forceSameFontSize`, `codeBlock.autoDetectUnknownLanguage`) while inheriting all core functionality.
345
+
346
+ Similarly, hooks accept generic parameters for type-safe access:
347
+
348
+ ```tsx
349
+ const { config } = useAIMarkdownRenderState<MyConfig>();
350
+ const metadata = useAIMarkdownMetadata<MyMetadata>();
351
+ ```
352
+
353
+ ## Architecture Overview
354
+
355
+ ```text
356
+ <AIMarkdown>
357
+ <AIMarkdownMetadataProvider> // Separate context for metadata
358
+ <AIMarkdownRenderStateProvider> // Context for render state (streaming, config, etc.)
359
+ <Typography> // Configurable typography wrapper
360
+ <ExtraStyles?> // Optional extra style wrapper
361
+ <AIMarkdownContent /> // react-markdown with remark/rehype plugin chain
362
+ </ExtraStyles?>
363
+ </Typography>
364
+ </AIMarkdownRenderStateProvider>
365
+ </AIMarkdownMetadataProvider>
366
+ </AIMarkdown>
367
+ ```
368
+
369
+ The metadata and render state providers are deliberately separated so that metadata changes (e.g. callback updates) do not trigger re-renders in `AIMarkdownContent`, which only consumes render state.
370
+
371
+ ## Exported API
372
+
373
+ ### Default Export
374
+
375
+ - `AIMarkdown` -- the main component (memoized)
376
+
377
+ ### Types
378
+
379
+ - `AIMarkdownProps`
380
+ - `AIMarkdownCustomComponents`
381
+ - `AIMarkdownRenderConfig`
382
+ - `AIMarkdownRenderState`
383
+ - `AIMarkdownMetadata`
384
+ - `AIMarkdownTypographyProps`
385
+ - `AIMarkdownTypographyComponent`
386
+ - `AIMarkdownExtraStylesProps`
387
+ - `AIMarkdownExtraStylesComponent`
388
+ - `AIMarkdownVariant`
389
+ - `AIMarkdownColorScheme`
390
+ - `AIMDContentPreprocessor`
391
+ - `PartialDeep`
392
+
393
+ ### Enums and Constants
394
+
395
+ - `AIMarkdownRenderExtraSyntax`
396
+ - `AIMarkdownRenderDisplayOptimizeAbility`
397
+ - `defaultAIMarkdownRenderConfig`
398
+
399
+ ### Hooks (re-exported)
400
+
401
+ - `useAIMarkdownRenderState()`
402
+ - `useAIMarkdownMetadata()`
403
+ - `useStableValue()`
404
+
405
+ ## License
406
+
407
+ MIT
package/dist/index.cjs CHANGED
@@ -34,15 +34,18 @@ __export(index_exports, {
34
34
  AIMarkdownRenderDisplayOptimizeAbility: () => AIMarkdownRenderDisplayOptimizeAbility,
35
35
  AIMarkdownRenderExtraSyntax: () => AIMarkdownRenderExtraSyntax,
36
36
  default: () => index_default,
37
- useAIMarkdownRenderState: () => useAIMarkdownRenderState
37
+ defaultAIMarkdownRenderConfig: () => defaultAIMarkdownRenderConfig,
38
+ useAIMarkdownMetadata: () => useAIMarkdownMetadata,
39
+ useAIMarkdownRenderState: () => useAIMarkdownRenderState,
40
+ useStableValue: () => useStableValue
38
41
  });
39
42
  module.exports = __toCommonJS(index_exports);
40
43
  var import_react5 = require("react");
41
44
 
42
45
  // src/context.tsx
43
46
  var import_react = require("react");
44
- var import_cloneDeep = __toESM(require("lodash/cloneDeep"), 1);
45
- var import_mergeWith = __toESM(require("lodash/mergeWith"), 1);
47
+ var import_cloneDeep = __toESM(require("lodash-es/cloneDeep"), 1);
48
+ var import_mergeWith = __toESM(require("lodash-es/mergeWith"), 1);
46
49
 
47
50
  // src/defs.ts
48
51
  var AIMarkdownRenderExtraSyntax = /* @__PURE__ */ ((AIMarkdownRenderExtraSyntax2) => {
@@ -73,6 +76,7 @@ var defaultAIMarkdownRenderConfig = Object.freeze({
73
76
  // src/context.tsx
74
77
  var import_jsx_runtime = require("react/jsx-runtime");
75
78
  var AIMarkdownRenderStateContext = (0, import_react.createContext)(null);
79
+ var AIMarkdownMetadataContext = (0, import_react.createContext)(void 0);
76
80
  function useAIMarkdownRenderState() {
77
81
  const context = (0, import_react.useContext)(AIMarkdownRenderStateContext);
78
82
  if (!context) {
@@ -80,30 +84,43 @@ function useAIMarkdownRenderState() {
80
84
  }
81
85
  return context;
82
86
  }
87
+ function useAIMarkdownMetadata() {
88
+ return (0, import_react.useContext)(AIMarkdownMetadataContext);
89
+ }
83
90
  var configMergeCustomizer = (_objValue, srcValue, _key, _object, _source, _stack) => {
84
91
  if (Array.isArray(srcValue)) {
85
92
  return srcValue;
86
93
  }
87
94
  };
95
+ var AIMarkdownMetadataProvider = ({
96
+ metadata,
97
+ children
98
+ }) => {
99
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AIMarkdownMetadataContext.Provider, { value: metadata, children });
100
+ };
88
101
  var AIMarkdownRenderStateProvider = ({
89
102
  streaming,
90
103
  fontSize,
104
+ variant,
105
+ colorScheme,
106
+ defaultConfig,
91
107
  config,
92
- metadata,
93
108
  children
94
109
  }) => {
110
+ const baseConfig = defaultConfig ?? defaultAIMarkdownRenderConfig;
95
111
  const mergedConfig = (0, import_react.useMemo)(
96
- () => config ? (0, import_mergeWith.default)((0, import_cloneDeep.default)(defaultAIMarkdownRenderConfig), config, configMergeCustomizer) : defaultAIMarkdownRenderConfig,
97
- [config]
112
+ () => config ? (0, import_mergeWith.default)((0, import_cloneDeep.default)(baseConfig), config, configMergeCustomizer) : baseConfig,
113
+ [baseConfig, config]
98
114
  );
99
115
  const state = (0, import_react.useMemo)(
100
116
  () => Object.freeze({
101
117
  streaming,
102
118
  fontSize,
103
- config: mergedConfig,
104
- metadata
119
+ variant,
120
+ colorScheme,
121
+ config: mergedConfig
105
122
  }),
106
- [streaming, fontSize, mergedConfig, metadata]
123
+ [streaming, fontSize, variant, colorScheme, mergedConfig]
107
124
  );
108
125
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AIMarkdownRenderStateContext.Provider, { value: state, children });
109
126
  };
@@ -375,7 +392,7 @@ var MarkdownContent_default = AIMarkdownContent;
375
392
 
376
393
  // src/hooks/useStableValue.ts
377
394
  var import_react3 = require("react");
378
- var import_isEqual = __toESM(require("lodash/isEqual"), 1);
395
+ var import_isEqual = __toESM(require("lodash-es/isEqual"), 1);
379
396
  function useStableValue(value) {
380
397
  const ref = (0, import_react3.useRef)(value);
381
398
  const prev = ref.current;
@@ -408,14 +425,16 @@ var AIMarkdownComponent = ({
408
425
  fontSize,
409
426
  contentPreprocessors,
410
427
  customComponents,
428
+ defaultConfig,
411
429
  config,
412
430
  metadata,
413
- typography: Typography = Default_default,
414
- extraStyle: ExtraStyle,
431
+ Typography = Default_default,
432
+ ExtraStyles,
415
433
  variant = "default",
416
434
  colorScheme = "light"
417
435
  }) => {
418
436
  const usedFontSize = fontSize ? typeof fontSize === "number" ? `${fontSize}px` : fontSize : "0.875rem";
437
+ const stableDefaultConfig = useStableValue(defaultConfig);
419
438
  const stableConfig = useStableValue(config);
420
439
  const stablePreprocessors = useStableValue(contentPreprocessors);
421
440
  const stableCustomComponents = useStableValue(customComponents);
@@ -423,16 +442,18 @@ var AIMarkdownComponent = ({
423
442
  () => content ? preprocessAIMDContent(content, stablePreprocessors) : content,
424
443
  [content, stablePreprocessors]
425
444
  );
426
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
445
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AIMarkdownMetadataProvider, { metadata, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
427
446
  context_default,
428
447
  {
429
448
  streaming,
430
449
  fontSize: usedFontSize,
450
+ variant,
451
+ colorScheme,
452
+ defaultConfig: stableDefaultConfig,
431
453
  config: stableConfig,
432
- metadata,
433
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Typography, { fontSize: usedFontSize, variant, colorScheme, children: ExtraStyle ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ExtraStyle, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MarkdownContent_default, { content: usedContent, customComponents: stableCustomComponents }) }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MarkdownContent_default, { content: usedContent, customComponents: stableCustomComponents }) })
454
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Typography, { fontSize: usedFontSize, variant, colorScheme, children: ExtraStyles ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ExtraStyles, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MarkdownContent_default, { content: usedContent, customComponents: stableCustomComponents }) }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MarkdownContent_default, { content: usedContent, customComponents: stableCustomComponents }) })
434
455
  }
435
- );
456
+ ) });
436
457
  };
437
458
  var AIMarkdown = (0, import_react5.memo)(AIMarkdownComponent);
438
459
  AIMarkdown.displayName = "AIMarkdown";
@@ -441,6 +462,9 @@ var index_default = AIMarkdown;
441
462
  0 && (module.exports = {
442
463
  AIMarkdownRenderDisplayOptimizeAbility,
443
464
  AIMarkdownRenderExtraSyntax,
444
- useAIMarkdownRenderState
465
+ defaultAIMarkdownRenderConfig,
466
+ useAIMarkdownMetadata,
467
+ useAIMarkdownRenderState,
468
+ useStableValue
445
469
  });
446
470
  //# sourceMappingURL=index.cjs.map