@ai-react-markdown/mantine 2.4.3 → 2.5.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 CHANGED
@@ -1,23 +1,54 @@
1
1
  # @ai-react-markdown/mantine
2
2
 
3
- [![npm](https://img.shields.io/npm/v/@ai-react-markdown/mantine)](https://www.npmjs.com/package/@ai-react-markdown/mantine)
4
- [![npm downloads](https://img.shields.io/npm/dm/@ai-react-markdown/mantine)](https://www.npmjs.com/package/@ai-react-markdown/mantine)
5
- [![license](https://img.shields.io/npm/l/@ai-react-markdown/mantine)](../../LICENSE)
3
+ [![npm version](https://img.shields.io/npm/v/@ai-react-markdown/mantine?logo=npm&color=cb3837)](https://www.npmjs.com/package/@ai-react-markdown/mantine)
4
+ [![npm downloads](https://img.shields.io/npm/dm/@ai-react-markdown/mantine?color=blue)](https://www.npmjs.com/package/@ai-react-markdown/mantine)
5
+ [![minzipped size](https://img.shields.io/bundlephobia/minzip/@ai-react-markdown/mantine?label=minzip)](https://bundlephobia.com/package/@ai-react-markdown/mantine)
6
+ [![types](https://img.shields.io/npm/types/@ai-react-markdown/mantine?logo=typescript&logoColor=white&color=3178c6)](https://www.typescriptlang.org/)
7
+
8
+ [![React ≥19](https://img.shields.io/badge/React-%E2%89%A519-149eca?logo=react&logoColor=white)](https://react.dev/)
9
+ [![Node ≥20](https://img.shields.io/badge/Node-%E2%89%A520-339933?logo=nodedotjs&logoColor=white)](https://nodejs.org/)
10
+ [![ESM + CJS](https://img.shields.io/badge/module-ESM%20%2B%20CJS-f7df1e?logo=javascript&logoColor=black)](#installation)
11
+ [![Mantine ≥9](https://img.shields.io/badge/Mantine-%E2%89%A59-339af0?logo=mantine&logoColor=white)](https://mantine.dev/)
12
+ [![license](https://img.shields.io/npm/l/@ai-react-markdown/mantine?color=green)](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/LICENSE)
13
+
14
+ [![CI](https://img.shields.io/github/actions/workflow/status/AIEPhoenix/ai-react-markdown/ci.yml?branch=main&label=CI&logo=githubactions&logoColor=white)](https://github.com/AIEPhoenix/ai-react-markdown/actions/workflows/ci.yml)
15
+ [![Release](https://img.shields.io/github/actions/workflow/status/AIEPhoenix/ai-react-markdown/release.yml?label=release&logo=githubactions&logoColor=white)](https://github.com/AIEPhoenix/ai-react-markdown/actions/workflows/release.yml)
16
+ [![part of ai-react-markdown](https://img.shields.io/badge/monorepo-ai--react--markdown-8a2be2?logo=github)](https://github.com/AIEPhoenix/ai-react-markdown)
6
17
 
7
18
  Mantine UI integration for `@ai-react-markdown/core`. Provides a drop-in `<MantineAIMarkdown>` component that renders AI-generated markdown with Mantine-themed typography, syntax-highlighted code blocks, Mermaid diagrams, and automatic color scheme detection.
8
19
 
9
- > **Upgrading from 1.x?** v2.0.0 removes the 1.x object-based `config` channel — the Mantine code-block options move to a flat `codeBlock` prop, and the render-state hook is replaced by narrow hooks plus `useMantineCodeBlockOptions()`. See the [migration guide](../../docs/migrating-to-v2.md).
20
+ > **Upgrading from 1.x?** v2.0.0 removes the 1.x object-based `config` channel — the Mantine code-block options move to a flat `codeBlock` prop, and the render-state hook is replaced by narrow hooks plus `useMantineCodeBlockOptions()`. See the [migration guide](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/docs/migrating-to-v2.md).
10
21
 
11
22
  ## What It Adds on Top of Core
12
23
 
13
24
  - **Mantine typography** -- markdown content is wrapped in Mantine's `<Typography>` so it inherits the active theme's font family, line height, and color tokens
14
25
  - **Syntax highlighting** -- code blocks render via `@mantine/code-highlight` (powered by highlight.js), with language-labelled tabs, expand/collapse, and optional auto-detection for unlabelled blocks
15
26
  - **Mermaid diagrams** -- fenced `mermaid` code blocks render as interactive SVG diagrams with dark/light theme support, source toggle, copy, and open-in-new-window
16
- - **JSON pretty-print** -- fenced `json` code blocks are deep-parsed (nested JSON-encoded strings are expanded) and re-serialized with 2-space indent before highlighting
27
+ - **JSON pretty-print** -- fenced `json` code blocks are parsed and re-serialized with 2-space indent before highlighting; string values that are themselves JSON documents (an object or array — the tool-call transcript shape) are expanded too, primitive-looking strings (`"true"`, `"123"`) are left as written
17
28
  - **Automatic color scheme** -- detects Mantine's computed color scheme (`useComputedColorScheme`) and forwards it to the core renderer when no explicit `colorScheme` prop is supplied
18
29
  - **Mantine-scoped CSS** -- extra-styles wrapper overrides Mantine spacing/font-size custom properties to use relative `em` units, giving consistent scaling at any base font size
19
30
 
20
- All core features (GFM, LaTeX math, CJK support, streaming, metadata context, content preprocessors, custom components, cross-chunk coordination via `<AIMarkdownDocuments>`) are inherited unchanged from `@ai-react-markdown/core`. See the [core README](../core/README.md) for the base API.
31
+ All core features (GFM, LaTeX math, CJK support, streaming, metadata context, content preprocessors, custom components, cross-chunk coordination via `<AIMarkdownDocuments>`) are inherited unchanged from `@ai-react-markdown/core`. See the [core README](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/packages/core/README.md) for the base API.
32
+
33
+ ## Package family
34
+
35
+ | Package | Role | Version policy |
36
+ | -------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
37
+ | [`@ai-react-markdown/core`](https://www.npmjs.com/package/@ai-react-markdown/core) | The React renderer — `<AIMarkdown>`, `<AIMarkdownSmoothStream>`, `<AIMarkdownDocuments>`, hooks, providers | Release train |
38
+ | [`@ai-react-markdown/mantine`](https://www.npmjs.com/package/@ai-react-markdown/mantine) | Mantine UI bindings — themed typography, code-highlight tabs, Mermaid, color-scheme wiring | Release train (lockstep with core) |
39
+ | [`@ai-react-markdown/engine`](https://www.npmjs.com/package/@ai-react-markdown/engine) | Framework-agnostic engine — incremental parsing, LaTeX preprocessing, plugin pipeline, cross-chunk registry | Release train (lockstep, pinned exactly by core; internal supplier) |
40
+ | [`@ai-react-markdown/remark-mark-highlight`](https://www.npmjs.com/package/@ai-react-markdown/remark-mark-highlight) | remark plugin for `==mark==` highlight syntax | Independent semver |
41
+
42
+ ## Compatibility
43
+
44
+ | | |
45
+ | -------------- | ------------------------------------------------------------------------------------------------------ |
46
+ | Mantine | `@mantine/core` ^9 and `@mantine/code-highlight` ^9 (peer dependencies) |
47
+ | highlight.js | ^11.11 (peer; loaded on demand for auto-detection, otherwise via your adapter) |
48
+ | React | ≥ 19 |
49
+ | Node | ≥ 20 (`engines.node`) |
50
+ | Module formats | ESM and CJS with types; the compiled stylesheet is exported as `@ai-react-markdown/mantine/styles.css` |
51
+ | Core | Pinned by peer range to the same release train (`@ai-react-markdown/core ^2.x`) |
21
52
 
22
53
  ## Installation
23
54
 
@@ -38,7 +69,7 @@ yarn add @ai-react-markdown/mantine @ai-react-markdown/core
38
69
  {
39
70
  "react": ">=19",
40
71
  "react-dom": ">=19",
41
- "@ai-react-markdown/core": "^2.4.3",
72
+ "@ai-react-markdown/core": "^2.5.0",
42
73
  "@mantine/core": "^9.0.0",
43
74
  "@mantine/code-highlight": "^9.0.0",
44
75
  "highlight.js": "^11.11.2"
@@ -96,22 +127,22 @@ function StreamingChat({ content, isStreaming }: { content: string; isStreaming:
96
127
 
97
128
  ### `MantineAIMarkdownProps<TMetadata>`
98
129
 
99
- `MantineAIMarkdownProps<TMetadata>` extends `AIMarkdownProps<TMetadata>` -- every core prop (`enginePlugins`, `blockMemo`, `incrementalParse`, `preserveOrphanReferences`, `streamingCursor`, …) is supported, plus the Mantine-specific `codeBlock` prop. The table below lists the props with a Mantine-specific default override or addition (props not listed here inherit core defaults unchanged — see the [core props table](../core/README.md#aimarkdownpropstmetadata)).
100
-
101
- | Prop | Type | Default | Description |
102
- | ---------------------- | ---------------------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
103
- | `content` | `string` | **(required)** | Raw markdown content to render. |
104
- | `streaming` | `boolean` | `false` | Whether content is actively being streamed. |
105
- | `fontSize` | `number \| string` | `'0.9375rem'` | Base font size. Numbers are treated as pixels. Inherited from core. |
106
- | `variant` | `AIMarkdownVariant` | `'default'` | Typography variant name. |
107
- | `colorScheme` | `AIMarkdownColorScheme` | Auto-detected | Color scheme. When omitted, defaults to Mantine's computed color scheme via `useComputedColorScheme('light')`. |
108
- | `metadata` | `TMetadata` | `undefined` | Arbitrary data for custom components via dedicated context. |
109
- | `contentPreprocessors` | `AIMDContentPreprocessor[]` | `undefined` | Additional preprocessors run after the built-in LaTeX preprocessor. |
110
- | `customComponents` | `AIMarkdownCustomComponents` | Mantine defaults | Component overrides, merged with Mantine's built-in `<pre>` handler. Caller overrides take precedence -- including `pre` here disables Mantine's code-block features. |
111
- | `Typography` | `AIMarkdownTypographyComponent` | `MantineAIMarkdownTypography` | Typography wrapper component. |
112
- | `ExtraStyles` | `AIMarkdownExtraStylesComponent` | `MantineAIMDefaultExtraStyles` | Extra style wrapper rendered between typography and content. |
113
- | `documentId` | `string` | auto via `useId()` | Stable id namespace for clobberable attributes. See the [core docs](../core/README.md#aimarkdownpropstmetadata) for full semantics. Required for cross-chunk mode. |
114
- | `codeBlock` | `Partial<MantineCodeBlockOptions>` | `defaultMantineCodeBlockOptions` | Code-block behavior group (Mantine-specific). The group value replaces atomically; omitted fields resolve to the shipped defaults inside `useMantineCodeBlockOptions()`. `null` counts as absent. |
130
+ `MantineAIMarkdownProps<TMetadata>` extends `AIMarkdownProps<TMetadata>` -- every core prop (`enginePlugins`, `blockMemo`, `incrementalParse`, `preserveOrphanReferences`, `streamingCursor`, …) is supported, plus the Mantine-specific `codeBlock` prop. The table below lists the props with a Mantine-specific default override or addition (props not listed here inherit core defaults unchanged — see the [core props table](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/packages/core/README.md#aimarkdownpropstmetadata)).
131
+
132
+ | Prop | Type | Default | Description |
133
+ | ---------------------- | ---------------------------------- | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
134
+ | `content` | `string` | **(required)** | Raw markdown content to render. |
135
+ | `streaming` | `boolean` | `false` | Whether content is actively being streamed. |
136
+ | `fontSize` | `number \| string` | `'0.9375rem'` | Base font size. Numbers are treated as pixels. Inherited from core. |
137
+ | `variant` | `AIMarkdownVariant` | `'default'` | Typography variant name. |
138
+ | `colorScheme` | `AIMarkdownColorScheme` | Auto-detected | Color scheme. When omitted, defaults to Mantine's computed color scheme via `useComputedColorScheme('light')`. |
139
+ | `metadata` | `TMetadata` | `undefined` | Arbitrary data for custom components via dedicated context. |
140
+ | `contentPreprocessors` | `AIMDContentPreprocessor[]` | `undefined` | Additional preprocessors run after the built-in LaTeX preprocessor. |
141
+ | `customComponents` | `AIMarkdownCustomComponents` | Mantine defaults | Component overrides, merged with Mantine's built-in `<pre>` handler. Caller overrides take precedence -- including `pre` here disables Mantine's code-block features. |
142
+ | `Typography` | `AIMarkdownTypographyComponent` | `MantineAIMarkdownTypography` | Typography wrapper component. |
143
+ | `ExtraStyles` | `AIMarkdownExtraStylesComponent` | `MantineAIMDefaultExtraStyles` | Extra style wrapper rendered between typography and content. |
144
+ | `documentId` | `string` | auto via `useId()` | Stable id namespace for clobberable attributes. See the [core docs](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/packages/core/README.md#aimarkdownpropstmetadata) for full semantics. Required for cross-chunk mode. |
145
+ | `codeBlock` | `Partial<MantineCodeBlockOptions>` | `defaultMantineCodeBlockOptions` | Code-block behavior group (Mantine-specific). The group value replaces atomically; omitted fields resolve to the shipped defaults inside `useMantineCodeBlockOptions()`. `null` counts as absent. |
115
146
 
116
147
  ## Configuration
117
148
 
@@ -157,7 +188,7 @@ function MyCodeBlock() {
157
188
  }
158
189
  ```
159
190
 
160
- For everything else (streaming state, theme, document ids, core behavior switches), use core's narrow hooks directly -- `useAIMarkdownState()`, `useAIMarkdownTheme()`, `useAIMarkdownDocument()`, `useAIMarkdownBehaviors()` -- or the aggregate `useAIMarkdown()` for low-frequency components. See the [core hooks reference](../core/README.md#hooks).
191
+ For everything else (streaming state, theme, document ids, core behavior switches), use core's narrow hooks directly -- `useAIMarkdownState()`, `useAIMarkdownTheme()`, `useAIMarkdownDocument()`, `useAIMarkdownBehaviors()` -- or the aggregate `useAIMarkdown()` for low-frequency components. See the [core hooks reference](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/packages/core/README.md#hooks).
161
192
 
162
193
  ```tsx
163
194
  import { useAIMarkdownState, useAIMarkdownTheme } from '@ai-react-markdown/core';
@@ -206,13 +237,13 @@ Activated by importing `@ai-react-markdown/mantine/styles.css` in your app entry
206
237
 
207
238
  The Mantine package installs a default `<pre>` renderer (`MantineAIMPreCode`) that powers all code-block features. Behavior by code-block flavor:
208
239
 
209
- | Code-block flavor | Rendered as | Notes |
210
- | ------------------------------------------ | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
211
- | Annotated, known language (e.g. ` ```ts `) | `<CodeHighlightTabs>` | Tab label = language name (lower-cased) |
212
- | Annotated, unknown language identifier | `<CodeHighlightTabs>` | Tab label = the identifier (lower-cased); Mantine's highlight adapter degrades an unknown language to plaintext |
213
- | No language annotation | `<CodeHighlight>` plaintext | Label = `"unknown"`. With `codeBlock.autoDetectUnknownLanguage: true`, `hljs.highlightAuto` guesses early, re-checks as the block grows, and settles at end of stream — label/highlighting upgrade in place |
214
- | ` ```mermaid ` (any case) | Interactive Mermaid diagram | See [Mermaid Diagrams](#mermaid-diagrams); the language match is case-insensitive |
215
- | ` ```json ` (any case) | Pretty-printed JSON | As soon as the block looks complete (ends in `}`/`]` with balanced brackets outside strings), deep-parsed via `deep-parse-json` to expand any nested JSON-encoded strings, then re-serialized with 2-space indent before rendering |
240
+ | Code-block flavor | Rendered as | Notes |
241
+ | ------------------------------------------ | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
242
+ | Annotated, known language (e.g. ` ```ts `) | `<CodeHighlightTabs>` | Tab label = language name (lower-cased) |
243
+ | Annotated, unknown language identifier | `<CodeHighlightTabs>` | Tab label = the identifier (lower-cased); Mantine's highlight adapter degrades an unknown language to plaintext |
244
+ | No language annotation | `<CodeHighlight>` plaintext | Label = `"unknown"`. With `codeBlock.autoDetectUnknownLanguage: true`, `hljs.highlightAuto` guesses early, re-checks as the block grows, and settles at end of stream — label/highlighting upgrade in place |
245
+ | ` ```mermaid ` (any case) | Interactive Mermaid diagram | See [Mermaid Diagrams](#mermaid-diagrams); the language match is case-insensitive |
246
+ | ` ```json ` (any case) | Pretty-printed JSON | As soon as the block looks complete (ends in `}`/`]` with balanced brackets outside strings), parsed, string values holding a nested JSON object/array expanded (primitive-looking strings such as `"true"` stay strings), then re-serialized with 2-space indent before rendering |
216
247
 
217
248
  All non-special blocks render with `withBorder` and `withExpandButton`, collapsing to `maxCollapsedHeight="320px"` until expanded.
218
249
 
@@ -339,7 +370,7 @@ import MantineAIMarkdown from '@ai-react-markdown/mantine';
339
370
  </AIMarkdownDocuments>;
340
371
  ```
341
372
 
342
- See the [core README's cross-chunk section](../core/README.md#cross-chunk-coordination) for the full `<AIMarkdownDocuments>` API and `useDocumentRegistry` hook.
373
+ See the [core README's cross-chunk section](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/packages/core/README.md#cross-chunk-coordination) for the full `<AIMarkdownDocuments>` API and `useDocumentRegistry` hook.
343
374
 
344
375
  ## Smooth Streaming
345
376
 
@@ -366,7 +397,7 @@ function ChatChunk({ id, markdown, pending }: { id: string; markdown: string; pe
366
397
  }
367
398
  ```
368
399
 
369
- See [docs/smooth-streaming.md](../../docs/smooth-streaming.md) for the pacing model, presets, and footguns.
400
+ See [docs/smooth-streaming.md](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/docs/smooth-streaming.md) for the pacing model, presets, and footguns.
370
401
 
371
402
  ## Architecture Overview
372
403
 
@@ -379,7 +410,7 @@ See [docs/smooth-streaming.md](../../docs/smooth-streaming.md) for the pacing mo
379
410
  colorScheme = useComputedColorScheme('light') (when not overridden)
380
411
  ```
381
412
 
382
- Caller-provided `Typography`, `ExtraStyles`, and `customComponents` props override the Mantine defaults at their respective slots. Inside the wrapped `<AIMarkdown>`, the rest of the render pipeline (the five per-system contexts, content preprocessors, remark/rehype plugin chain) is identical to standalone core -- see the [core architecture overview](../core/README.md#architecture-overview).
413
+ Caller-provided `Typography`, `ExtraStyles`, and `customComponents` props override the Mantine defaults at their respective slots. Inside the wrapped `<AIMarkdown>`, the rest of the render pipeline (the five per-system contexts, content preprocessors, remark/rehype plugin chain) is identical to standalone core -- see the [core architecture overview](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/packages/core/README.md#architecture-overview).
383
414
 
384
415
  ## Exported API
385
416
 
@@ -412,9 +443,28 @@ Caller-provided `Typography`, `ExtraStyles`, and `customComponents` props overri
412
443
  - `useMantineCodeBlockOptions()` -- typed access to the `codeBlock` group with defaults applied
413
444
  - `useMantineAIMarkdownMetadata<TMetadata>()` -- typed metadata access
414
445
 
446
+ ## Documentation
447
+
448
+ Everything below applies unchanged through `<MantineAIMarkdown>`; the mantine-specific parts are the sections above.
449
+
450
+ | Guide | What it covers |
451
+ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
452
+ | [Streaming & performance](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/docs/streaming-and-performance.md) | Block memoization, incremental (prefix-freeze) parsing, what to pass while tokens arrive |
453
+ | [Smooth streaming](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/docs/smooth-streaming.md) | `<AIMarkdownSmoothStream>` typewriter reveal, pacing presets, document turn-taking |
454
+ | [Streaming cursor](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/docs/streaming-cursor.md) | The overlay cursor that tracks the streaming tail |
455
+ | [Cross-chunk coordination](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/docs/cross-chunk-coordination.md) | `<AIMarkdownDocuments>`, footnotes and link references across chunks, the registry |
456
+ | [URL sanitization & custom schemes](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/docs/url-sanitization.md) | The two-gate model, `urlTransform`, `extendSanitizeSchema` |
457
+ | [Custom components](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/docs/custom-components.md) · [Custom typography](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/docs/custom-typography.md) · [Design tokens](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/docs/design-tokens.md) | Swapping renderers, theming, the `--aim-*` variables |
458
+ | [CJK typography](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/docs/cjk-typography.md) | Line breaking, spacing, pangu |
459
+ | [Metadata context](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/docs/metadata-context.md) · [TypeScript generics](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/docs/typescript-generics.md) | Passing typed metadata to custom components |
460
+ | [Content preprocessors](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/docs/content-preprocessors.md) | Rewriting the source before it parses |
461
+ | [Extending via subpackage](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/docs/extending-via-subpackage.md) | Building your own UI-kit binding (the mantine package is the reference) |
462
+ | [Architecture](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/docs/architecture.md) · [Benchmark](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/docs/benchmark.md) | How the packages fit together, measured numbers |
463
+ | [Migrating to v2](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/docs/migrating-to-v2.md) · [Release highlights](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/docs/release-highlights.md) | Old → new API mapping, what changed per version |
464
+
415
465
  ## Core Package
416
466
 
417
- For base features, configuration options, content preprocessors, TypeScript generics, and architecture details, see the [`@ai-react-markdown/core` README](../core/README.md).
467
+ For base features, configuration options, content preprocessors, TypeScript generics, and architecture details, see the [`@ai-react-markdown/core` README](https://github.com/AIEPhoenix/ai-react-markdown/blob/main/packages/core/README.md).
418
468
 
419
469
  ## License
420
470
 
package/dist/index.cjs CHANGED
@@ -64,7 +64,6 @@ var DefaultExtraStyles_default = MantineAIMDefaultExtraStyles;
64
64
  // src/components/customized/PreCode.tsx
65
65
  var import_react4 = require("react");
66
66
  var import_code_highlight2 = require("@mantine/code-highlight");
67
- var import_deep_parse_json = require("deep-parse-json");
68
67
  var import_core5 = require("@ai-react-markdown/core");
69
68
 
70
69
  // src/hooks/useMantineCodeBlockOptions.ts
@@ -115,7 +114,9 @@ var loadMermaid = () => {
115
114
  var initializedTheme = null;
116
115
  var ensureMermaidInitialized = (mermaid, isDark) => {
117
116
  const theme = isDark ? "dark" : "light";
118
- if (initializedTheme === theme) return;
117
+ const api = mermaid.mermaidAPI;
118
+ const currentLevel = api?.getConfig?.().securityLevel;
119
+ if (initializedTheme === theme && currentLevel === "strict") return;
119
120
  mermaid.initialize({
120
121
  startOnLoad: false,
121
122
  securityLevel: "strict",
@@ -140,8 +141,8 @@ var handleViewSVGInNewWindow = (svgElement, isDark) => {
140
141
  const text = new XMLSerializer().serializeToString(targetSvg);
141
142
  const blob = new Blob([text], { type: "image/svg+xml" });
142
143
  const url = URL.createObjectURL(blob);
143
- const win = window.open(url);
144
- setTimeout(() => URL.revokeObjectURL(url), win ? 5e3 : 0);
144
+ window.open(url, "_blank", "noopener");
145
+ setTimeout(() => URL.revokeObjectURL(url), 5e3);
145
146
  };
146
147
  var MantineAIMMermaidCode = (0, import_react3.memo)((props) => {
147
148
  const { colorScheme, fontSize } = (0, import_core4.useAIMarkdownTheme)();
@@ -313,6 +314,37 @@ var MantineAIMMermaidCode = (0, import_react3.memo)((props) => {
313
314
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "chart-header", children: [
314
315
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "chart-type-tag", children: view.kind === "diagram" ? view.chartType : "unknown" }),
315
316
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_core3.Flex, { align: "center", justify: "flex-end", gap: 0, children: [
317
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core3.Tooltip, { label: "Open in new window", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
318
+ import_core3.ActionIcon,
319
+ {
320
+ size: 28,
321
+ className: "action-icon",
322
+ variant: "transparent",
323
+ "aria-label": "Open Mermaid diagram in a new window",
324
+ onClick: viewSvgInNewWindow,
325
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
326
+ "svg",
327
+ {
328
+ xmlns: "http://www.w3.org/2000/svg",
329
+ viewBox: "0 0 24 24",
330
+ strokeWidth: "2",
331
+ stroke: "currentColor",
332
+ fill: "none",
333
+ strokeLinecap: "round",
334
+ strokeLinejoin: "round",
335
+ width: "18px",
336
+ height: "18px",
337
+ "aria-hidden": "true",
338
+ children: [
339
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { stroke: "none", d: "M0 0h24v24H0z", fill: "none" }),
340
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 6h-6a2 2 0 0 0 -2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-6" }),
341
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M11 13l9 -9" }),
342
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M15 4h5v5" })
343
+ ]
344
+ }
345
+ )
346
+ }
347
+ ) }),
316
348
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core3.Tooltip, { label: "Show Mermaid Code", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
317
349
  import_core3.ActionIcon,
318
350
  {
@@ -357,23 +389,7 @@ var MantineAIMMermaidCode = (0, import_react3.memo)((props) => {
357
389
  ) }) })
358
390
  ] })
359
391
  ] }),
360
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
361
- "pre",
362
- {
363
- ref,
364
- style: PRE_STYLE,
365
- role: "button",
366
- tabIndex: 0,
367
- "aria-label": "Open Mermaid diagram in a new window",
368
- onClick: viewSvgInNewWindow,
369
- onKeyDown: (event) => {
370
- if (event.key === "Enter" || event.key === " ") {
371
- event.preventDefault();
372
- viewSvgInNewWindow();
373
- }
374
- }
375
- }
376
- )
392
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("pre", { ref, style: PRE_STYLE, onClick: viewSvgInNewWindow })
377
393
  ]
378
394
  }
379
395
  )
@@ -445,6 +461,35 @@ function preloadMantineCodeAssets() {
445
461
  () => void 0
446
462
  );
447
463
  }
464
+ function prettyPrintJson(text) {
465
+ let parsed;
466
+ try {
467
+ parsed = JSON.parse(text);
468
+ } catch {
469
+ return text;
470
+ }
471
+ return JSON.stringify(expandNestedJson(parsed), null, 2);
472
+ }
473
+ function expandNestedJson(value) {
474
+ if (typeof value === "string") {
475
+ const t = value.trim();
476
+ if (t.length > 1 && (t[0] === "{" || t[0] === "[")) {
477
+ try {
478
+ const inner = JSON.parse(t);
479
+ if (inner !== null && typeof inner === "object") return expandNestedJson(inner);
480
+ } catch {
481
+ }
482
+ }
483
+ return value;
484
+ }
485
+ if (Array.isArray(value)) return value.map(expandNestedJson);
486
+ if (value !== null && typeof value === "object") {
487
+ const out = /* @__PURE__ */ Object.create(null);
488
+ for (const [k, v] of Object.entries(value)) out[k] = expandNestedJson(v);
489
+ return out;
490
+ }
491
+ return value;
492
+ }
448
493
  function jsonLooksComplete(text) {
449
494
  if (!/[}\]]\s*$/.test(text)) return false;
450
495
  let depth = 0;
@@ -490,8 +535,7 @@ var MantineAIMPreCode = (0, import_react4.memo)(
490
535
  if (isSpecialCodeBlock) return null;
491
536
  let usedCodeStr = props.codeText;
492
537
  if (usedCodeStr && usedCodeLanguage === "json" && (!streaming || jsonLooksComplete(usedCodeStr))) {
493
- const deepParsedResult = (0, import_deep_parse_json.deepParseJson)(usedCodeStr);
494
- usedCodeStr = typeof deepParsedResult === "string" ? deepParsedResult : JSON.stringify(deepParsedResult, null, 2);
538
+ usedCodeStr = prettyPrintJson(usedCodeStr);
495
539
  }
496
540
  return usedFileName === "unknown" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
497
541
  import_code_highlight2.CodeHighlight,
@@ -553,7 +597,9 @@ var DefaultCustomComponents = {
553
597
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("pre", { ...usefulProps });
554
598
  }
555
599
  const key = `pre-code-${node?.position?.start?.offset || 0}`;
556
- const detectedLanguage = code.properties?.className?.find((className) => className.startsWith("language-"))?.substring("language-".length);
600
+ const classNames = code.properties?.className;
601
+ const classList = Array.isArray(classNames) ? classNames.filter((c) => typeof c === "string") : typeof classNames === "string" ? classNames.split(/\s+/) : [];
602
+ const detectedLanguage = classList.find((className) => className.startsWith("language-"))?.substring("language-".length);
557
603
  const codeText = code.children.map((child) => child.value ?? "").join("");
558
604
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PreCode_default, { codeText, existLanguage: detectedLanguage }, key);
559
605
  }