@ai-react-markdown/core 1.2.9 → 1.4.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.md +87 -25
- package/dist/index.cjs +2293 -848
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +336 -19
- package/dist/index.d.ts +336 -19
- package/dist/index.js +2301 -858
- package/dist/index.js.map +1 -1
- package/package.json +20 -4
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ A batteries-included React component for rendering AI-generated markdown with fi
|
|
|
12
12
|
- **LaTeX math** -- inline and display math rendered with KaTeX; smart preprocessing handles currency `$` signs, bracket delimiters (`\[...\]`, `\(...\)`), pipe escaping, and mhchem commands
|
|
13
13
|
- **Emoji** -- shortcode support (`:smile:`) via `remark-emoji`
|
|
14
14
|
- **CJK-friendly** -- proper line breaking and spacing for Chinese, Japanese, and Korean text
|
|
15
|
-
- **Extra syntax** -- highlight (`==text==`), definition lists
|
|
15
|
+
- **Extra syntax** -- highlight (`==text==`), definition lists
|
|
16
16
|
- **Display optimizations** -- SmartyPants typography, pangu CJK spacing, HTML comment removal
|
|
17
17
|
- **Streaming-aware** -- built-in `streaming` flag propagated via context for custom components
|
|
18
18
|
- **Customizable** -- swap typography, color scheme, individual markdown element renderers, and inject extra style wrappers
|
|
@@ -81,20 +81,21 @@ function StreamingChat({ content, isStreaming }: { content: string; isStreaming:
|
|
|
81
81
|
|
|
82
82
|
### `AIMarkdownProps<TConfig, TRenderData>`
|
|
83
83
|
|
|
84
|
-
| Prop | Type | Default | Description
|
|
85
|
-
| ---------------------- | -------------------------------- | ------------------------------- |
|
|
86
|
-
| `content` | `string` | **(required)** | Raw markdown content to render.
|
|
87
|
-
| `streaming` | `boolean` | `false` | Whether content is actively being streamed (e.g. from an LLM).
|
|
88
|
-
| `fontSize` | `number \| string` | `'0.9375rem'` | Base font size. Numbers are treated as pixels.
|
|
89
|
-
| `variant` | `AIMarkdownVariant` | `'default'` | Typography variant name.
|
|
90
|
-
| `colorScheme` | `AIMarkdownColorScheme` | `'light'` | Color scheme name (`'light'`, `'dark'`, or custom).
|
|
91
|
-
| `config` | `PartialDeep<TConfig>` | `undefined` | Partial render config, deep-merged with defaults.
|
|
92
|
-
| `defaultConfig` | `TConfig` | `defaultAIMarkdownRenderConfig` | Base config to merge against. Sub-packages can pass extended defaults.
|
|
93
|
-
| `metadata` | `TRenderData` | `undefined` | Arbitrary data passed to custom components via a dedicated context.
|
|
94
|
-
| `contentPreprocessors` | `AIMDContentPreprocessor[]` | `[]` | Additional preprocessors run after the built-in LaTeX preprocessor.
|
|
95
|
-
| `customComponents` | `AIMarkdownCustomComponents` | `undefined` | `react-markdown` component overrides for specific HTML elements.
|
|
96
|
-
| `Typography` | `AIMarkdownTypographyComponent` | `DefaultTypography` | Typography wrapper component.
|
|
97
|
-
| `ExtraStyles` | `AIMarkdownExtraStylesComponent` | `undefined` | Optional extra style wrapper rendered between typography and content.
|
|
84
|
+
| Prop | Type | Default | Description |
|
|
85
|
+
| ---------------------- | -------------------------------- | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
86
|
+
| `content` | `string` | **(required)** | Raw markdown content to render. |
|
|
87
|
+
| `streaming` | `boolean` | `false` | Whether content is actively being streamed (e.g. from an LLM). |
|
|
88
|
+
| `fontSize` | `number \| string` | `'0.9375rem'` | Base font size. Numbers are treated as pixels. |
|
|
89
|
+
| `variant` | `AIMarkdownVariant` | `'default'` | Typography variant name. |
|
|
90
|
+
| `colorScheme` | `AIMarkdownColorScheme` | `'light'` | Color scheme name (`'light'`, `'dark'`, or custom). |
|
|
91
|
+
| `config` | `PartialDeep<TConfig>` | `undefined` | Partial render config, deep-merged with defaults. |
|
|
92
|
+
| `defaultConfig` | `TConfig` | `defaultAIMarkdownRenderConfig` | Base config to merge against. Sub-packages can pass extended defaults. |
|
|
93
|
+
| `metadata` | `TRenderData` | `undefined` | Arbitrary data passed to custom components via a dedicated context. |
|
|
94
|
+
| `contentPreprocessors` | `AIMDContentPreprocessor[]` | `[]` | Additional preprocessors run after the built-in LaTeX preprocessor. |
|
|
95
|
+
| `customComponents` | `AIMarkdownCustomComponents` | `undefined` | `react-markdown` component overrides for specific HTML elements. |
|
|
96
|
+
| `Typography` | `AIMarkdownTypographyComponent` | `DefaultTypography` | Typography wrapper component. |
|
|
97
|
+
| `ExtraStyles` | `AIMarkdownExtraStylesComponent` | `undefined` | Optional extra style wrapper rendered between typography and content. |
|
|
98
|
+
| `documentId` | `string` | auto via `useId()` | Stable id for the _logical markdown document_ this `<AIMarkdown>` is rendering. Used as the id namespace for clobberable attributes (`id`, hash hrefs) so two documents on the same page do not cross-link (footnote `[^1]` in message A won't scroll to `[^1]` in message B). When one document is split into chunks rendered by multiple `<AIMarkdown>` instances, pass the SAME `documentId` to every chunk so prefixes align. The value is passed through `encodeURIComponent` before being injected into HTML attributes, so any string is safe (React's `useId()` output, your own opaque ids, user-supplied UUIDs). |
|
|
98
99
|
|
|
99
100
|
## Configuration
|
|
100
101
|
|
|
@@ -108,7 +109,6 @@ Enable via `config.extraSyntaxSupported`. All are enabled by default.
|
|
|
108
109
|
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
|
|
109
110
|
| `AIMarkdownRenderExtraSyntax.HIGHLIGHT` | `==Highlight==` syntax support |
|
|
110
111
|
| `AIMarkdownRenderExtraSyntax.DEFINITION_LIST` | Definition list syntax ([PHP Markdown Extra](https://michelf.ca/projects/php-markdown/extra/#def-list)) |
|
|
111
|
-
| `AIMarkdownRenderExtraSyntax.SUBSCRIPT` | Superscript (`^text^`) and subscript (`~text~`) |
|
|
112
112
|
|
|
113
113
|
### Display Optimization Abilities
|
|
114
114
|
|
|
@@ -137,7 +137,60 @@ import AIMarkdown, {
|
|
|
137
137
|
/>;
|
|
138
138
|
```
|
|
139
139
|
|
|
140
|
-
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
|
|
140
|
+
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.
|
|
141
|
+
|
|
142
|
+
### Other Config Fields
|
|
143
|
+
|
|
144
|
+
| Field | Type | Default | Description |
|
|
145
|
+
| -------------------------- | --------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
146
|
+
| `blockMemoEnabled` | `boolean` | `true` | Enables block-level memoization: the renderer splits each document into per-block units and memoizes each block's React subtree by source identity, so unchanged blocks skip `toJsxRuntime` and React reconcile work during streaming. Output is byte-identical to the disabled path. Set `false` as an escape hatch for debugging. |
|
|
147
|
+
| `preserveOrphanReferences` | `boolean` | `true` | Protects orphan `[^x]: …` footnote definitions from being silently dropped by `mdast-util-to-hast` when no matching `[^x]` reference exists. Useful for streamed content where the reference may arrive in a later chunk. Inside `<AIMarkdownDocuments>`, the wrapper's `preserveOrphanReferences` prop overrides this field unconditionally. |
|
|
148
|
+
|
|
149
|
+
## Cross-chunk Coordination
|
|
150
|
+
|
|
151
|
+
When a single logical markdown document is split across multiple
|
|
152
|
+
`<AIMarkdown>` instances (chunked streaming for chat UIs, etc.), wrap
|
|
153
|
+
them in `<AIMarkdownDocuments>` and pass the SAME `documentId` to every
|
|
154
|
+
chunk to coordinate footnotes, link references, and image references
|
|
155
|
+
across chunks:
|
|
156
|
+
|
|
157
|
+
```tsx
|
|
158
|
+
import AIMarkdown, { AIMarkdownDocuments } from '@ai-react-markdown/core';
|
|
159
|
+
|
|
160
|
+
<AIMarkdownDocuments>
|
|
161
|
+
{message.chunks.map((c, i) => (
|
|
162
|
+
<AIMarkdown key={i} content={c} documentId={message.id} />
|
|
163
|
+
))}
|
|
164
|
+
</AIMarkdownDocuments>;
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Without the wrapper, each `<AIMarkdown>` is independent — its
|
|
168
|
+
references resolve only within its own content (current standalone
|
|
169
|
+
behavior).
|
|
170
|
+
|
|
171
|
+
### `<AIMarkdownDocuments>` Props
|
|
172
|
+
|
|
173
|
+
| Prop | Type | Default | Description |
|
|
174
|
+
| -------------------------- | ----------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
175
|
+
| `preserveOrphanReferences` | `boolean` | `true` | Controls orphan-reference protection for every chunk under this wrapper. Unconditionally overrides each chunk's `config.preserveOrphanReferences`. Does not gate cross-chunk coordination itself (that's gated by wrapper + `documentId`). |
|
|
176
|
+
| `children` | `ReactNode` | - | The `<AIMarkdown>` instances to coordinate. Nesting `<AIMarkdownDocuments>` inside another `<AIMarkdownDocuments>` throws. |
|
|
177
|
+
|
|
178
|
+
### `useDocumentRegistry(documentId)`
|
|
179
|
+
|
|
180
|
+
Returns the cross-chunk `Registry` for the given `documentId`, or
|
|
181
|
+
`null` when called outside `<AIMarkdownDocuments>` or when
|
|
182
|
+
`documentId` is empty. The `Registry` shape is exported and stable
|
|
183
|
+
across minor versions — use it when writing typed helpers that operate
|
|
184
|
+
on the cross-chunk registry directly.
|
|
185
|
+
|
|
186
|
+
```tsx
|
|
187
|
+
import { useDocumentRegistry, type Registry } from '@ai-react-markdown/core';
|
|
188
|
+
|
|
189
|
+
function MyHelper({ documentId }: { documentId: string }) {
|
|
190
|
+
const registry: Registry | null = useDocumentRegistry(documentId);
|
|
191
|
+
// null when no <AIMarkdownDocuments> ancestor — treat as "run standalone".
|
|
192
|
+
}
|
|
193
|
+
```
|
|
141
194
|
|
|
142
195
|
## Hooks
|
|
143
196
|
|
|
@@ -160,13 +213,15 @@ function CustomCodeBlock({ children }: PropsWithChildren) {
|
|
|
160
213
|
|
|
161
214
|
**Returns** `AIMarkdownRenderState<TConfig>`:
|
|
162
215
|
|
|
163
|
-
| Field
|
|
164
|
-
|
|
|
165
|
-
| `streaming`
|
|
166
|
-
| `fontSize`
|
|
167
|
-
| `variant`
|
|
168
|
-
| `colorScheme`
|
|
169
|
-
| `
|
|
216
|
+
| Field | Type | Description |
|
|
217
|
+
| --------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
218
|
+
| `streaming` | `boolean` | Whether content is being streamed. |
|
|
219
|
+
| `fontSize` | `string` | Resolved CSS font-size value. |
|
|
220
|
+
| `variant` | `AIMarkdownVariant` | Active typography variant. |
|
|
221
|
+
| `colorScheme` | `AIMarkdownColorScheme` | Active color scheme. |
|
|
222
|
+
| `documentId` | `string` | Stable id for the logical markdown document — caller-supplied or auto-generated via `useId()`. |
|
|
223
|
+
| `clobberPrefix` | `string` | URI-safe id prefix derived from `documentId`, used by every clobberable HTML attribute (`id=…` / `href="#…"`). Read this from the render state rather than recomputing locally when writing components that emit anchors. |
|
|
224
|
+
| `config` | `TConfig` | Active render configuration (merged with defaults). |
|
|
170
225
|
|
|
171
226
|
### `useAIMarkdownMetadata<TMetadata>()`
|
|
172
227
|
|
|
@@ -355,7 +410,7 @@ interface MyMetadata extends AIMarkdownMetadata {
|
|
|
355
410
|
/>;
|
|
356
411
|
```
|
|
357
412
|
|
|
358
|
-
Sub-packages like `@ai-react-markdown/mantine` use this pattern to extend the base config with additional options (e.g. `
|
|
413
|
+
Sub-packages like `@ai-react-markdown/mantine` use this pattern to extend the base config with additional options (e.g. `codeBlock.defaultExpanded`, `codeBlock.autoDetectUnknownLanguage`) while inheriting all core functionality.
|
|
359
414
|
|
|
360
415
|
Similarly, hooks accept generic parameters for type-safe access:
|
|
361
416
|
|
|
@@ -388,9 +443,14 @@ The metadata and render state providers are deliberately separated so that metad
|
|
|
388
443
|
|
|
389
444
|
- `AIMarkdown` -- the main component (memoized)
|
|
390
445
|
|
|
446
|
+
### Components
|
|
447
|
+
|
|
448
|
+
- `AIMarkdownDocuments` -- optional outer wrapper enabling cross-chunk coordination
|
|
449
|
+
|
|
391
450
|
### Types
|
|
392
451
|
|
|
393
452
|
- `AIMarkdownProps`
|
|
453
|
+
- `AIMarkdownDocumentsProps`
|
|
394
454
|
- `AIMarkdownCustomComponents`
|
|
395
455
|
- `AIMarkdownRenderConfig`
|
|
396
456
|
- `AIMarkdownRenderState`
|
|
@@ -403,6 +463,7 @@ The metadata and render state providers are deliberately separated so that metad
|
|
|
403
463
|
- `AIMarkdownColorScheme`
|
|
404
464
|
- `AIMDContentPreprocessor`
|
|
405
465
|
- `PartialDeep`
|
|
466
|
+
- Cross-chunk registry types: `Registry`, `ChunkData`, `FootnoteDef`, `LinkDef`, `RefRecord`, `RefKind`
|
|
406
467
|
|
|
407
468
|
### Enums and Constants
|
|
408
469
|
|
|
@@ -414,6 +475,7 @@ The metadata and render state providers are deliberately separated so that metad
|
|
|
414
475
|
|
|
415
476
|
- `useAIMarkdownRenderState()`
|
|
416
477
|
- `useAIMarkdownMetadata()`
|
|
478
|
+
- `useDocumentRegistry()`
|
|
417
479
|
- `useStableValue()`
|
|
418
480
|
|
|
419
481
|
## License
|