@djangocfg/ui-tools 2.1.302 → 2.1.304
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 +1 -1
- package/dist/{DocsLayout-ZHNRRAKR.mjs → DocsLayout-W5JLRNSZ.mjs} +3 -3
- package/dist/{DocsLayout-ZHNRRAKR.mjs.map → DocsLayout-W5JLRNSZ.mjs.map} +1 -1
- package/dist/{DocsLayout-4PQLBZHE.cjs → DocsLayout-ZXD2CUOH.cjs} +48 -48
- package/dist/{DocsLayout-4PQLBZHE.cjs.map → DocsLayout-ZXD2CUOH.cjs.map} +1 -1
- package/dist/{Mermaid.client-XFQ74OYN.mjs → Mermaid.client-SXRRI2YW.mjs} +43 -6
- package/dist/Mermaid.client-SXRRI2YW.mjs.map +1 -0
- package/dist/{Mermaid.client-RSWUUHIL.cjs → Mermaid.client-W76R5AKJ.cjs} +43 -6
- package/dist/Mermaid.client-W76R5AKJ.cjs.map +1 -0
- package/dist/{chunk-47NGNO5U.mjs → chunk-6HNAPVZ2.mjs} +86 -42
- package/dist/chunk-6HNAPVZ2.mjs.map +1 -0
- package/dist/{chunk-M4BLG3RZ.cjs → chunk-FYLR232K.cjs} +90 -42
- package/dist/chunk-FYLR232K.cjs.map +1 -0
- package/dist/index.cjs +11 -11
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.mjs +5 -5
- package/package.json +10 -6
- package/src/components/markdown/MarkdownMessage/CodeBlock.tsx +43 -26
- package/src/components/markdown/MarkdownMessage/MarkdownMessage.story.tsx +311 -0
- package/src/components/markdown/MarkdownMessage/MarkdownMessage.tsx +35 -5
- package/src/components/markdown/MarkdownMessage/README.md +111 -0
- package/src/components/markdown/MarkdownMessage/components.tsx +77 -17
- package/src/tools/Mermaid/Mermaid.client.tsx +10 -1
- package/src/tools/Mermaid/components/MermaidFullscreenModal.tsx +76 -3
- package/src/tools/Mermaid/index.tsx +7 -0
- package/dist/Mermaid.client-RSWUUHIL.cjs.map +0 -1
- package/dist/Mermaid.client-XFQ74OYN.mjs.map +0 -1
- package/dist/chunk-47NGNO5U.mjs.map +0 -1
- package/dist/chunk-M4BLG3RZ.cjs.map +0 -1
|
@@ -5,9 +5,13 @@ var React6 = require('react');
|
|
|
5
5
|
require('@djangocfg/ui-core/styles/palette');
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
7
|
var ReactMarkdown = require('react-markdown');
|
|
8
|
+
var rehypeExternalLinks = require('rehype-external-links');
|
|
8
9
|
var rehypeRaw = require('rehype-raw');
|
|
9
10
|
var rehypeSanitize = require('rehype-sanitize');
|
|
11
|
+
var remarkBreaks = require('remark-breaks');
|
|
12
|
+
var remarkEmoji = require('remark-emoji');
|
|
10
13
|
var remarkGfm = require('remark-gfm');
|
|
14
|
+
var remarkSmartypants = require('remark-smartypants');
|
|
11
15
|
var components = require('@djangocfg/ui-core/components');
|
|
12
16
|
var hooks = require('@djangocfg/ui-core/hooks');
|
|
13
17
|
var consola2 = require('consola');
|
|
@@ -17,9 +21,13 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
17
21
|
|
|
18
22
|
var React6__default = /*#__PURE__*/_interopDefault(React6);
|
|
19
23
|
var ReactMarkdown__default = /*#__PURE__*/_interopDefault(ReactMarkdown);
|
|
24
|
+
var rehypeExternalLinks__default = /*#__PURE__*/_interopDefault(rehypeExternalLinks);
|
|
20
25
|
var rehypeRaw__default = /*#__PURE__*/_interopDefault(rehypeRaw);
|
|
21
26
|
var rehypeSanitize__default = /*#__PURE__*/_interopDefault(rehypeSanitize);
|
|
27
|
+
var remarkBreaks__default = /*#__PURE__*/_interopDefault(remarkBreaks);
|
|
28
|
+
var remarkEmoji__default = /*#__PURE__*/_interopDefault(remarkEmoji);
|
|
22
29
|
var remarkGfm__default = /*#__PURE__*/_interopDefault(remarkGfm);
|
|
30
|
+
var remarkSmartypants__default = /*#__PURE__*/_interopDefault(remarkSmartypants);
|
|
23
31
|
var consola2__default = /*#__PURE__*/_interopDefault(consola2);
|
|
24
32
|
|
|
25
33
|
function smartTruncate(content, maxLength) {
|
|
@@ -199,7 +207,7 @@ function hasMarkdownSyntax(text) {
|
|
|
199
207
|
return patterns.some((p) => p.test(text));
|
|
200
208
|
}
|
|
201
209
|
chunkWGEGR3DF_cjs.__name(hasMarkdownSyntax, "hasMarkdownSyntax");
|
|
202
|
-
var MermaidClient = React6.lazy(() => import('./Mermaid.client-
|
|
210
|
+
var MermaidClient = React6.lazy(() => import('./Mermaid.client-W76R5AKJ.cjs'));
|
|
203
211
|
var LoadingFallback = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center items-center min-h-[100px]", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "animate-spin rounded-full h-6 w-6 border-b-2 border-primary" }) }), "LoadingFallback");
|
|
204
212
|
var Mermaid = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name((props) => {
|
|
205
213
|
return /* @__PURE__ */ jsxRuntime.jsx(React6.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(LoadingFallback, {}), children: /* @__PURE__ */ jsxRuntime.jsx(MermaidClient, { ...props }) });
|
|
@@ -262,39 +270,38 @@ function buildUrlTransform(extraProtocols) {
|
|
|
262
270
|
};
|
|
263
271
|
}
|
|
264
272
|
chunkWGEGR3DF_cjs.__name(buildUrlTransform, "buildUrlTransform");
|
|
265
|
-
var CodeBlock = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ code, language,
|
|
273
|
+
var CodeBlock = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ code, language, isCompact = false }) => {
|
|
266
274
|
const theme = hooks.useResolvedTheme();
|
|
275
|
+
const textSizeClass = isCompact ? "text-xs" : "text-sm";
|
|
267
276
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "my-3", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
268
277
|
PrettyCode_default,
|
|
269
278
|
{
|
|
270
279
|
data: code,
|
|
271
280
|
language,
|
|
272
|
-
className:
|
|
273
|
-
customBg:
|
|
281
|
+
className: textSizeClass,
|
|
282
|
+
customBg: "bg-code",
|
|
274
283
|
mode: theme,
|
|
275
|
-
isCompact
|
|
284
|
+
isCompact,
|
|
285
|
+
scrollIsolation: false
|
|
276
286
|
}
|
|
277
287
|
) });
|
|
278
288
|
}, "CodeBlock");
|
|
279
|
-
var CodeBlockFallback = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ code, isUser }) =>
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
${isUser ? "bg-white/10 text-white" : "bg-muted text-foreground"}
|
|
296
|
-
`, children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: code }) })
|
|
297
|
-
] }), "CodeBlockFallback");
|
|
289
|
+
var CodeBlockFallback = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ code, isUser }) => {
|
|
290
|
+
const copyHoverClass = isUser ? "hover:bg-white/20 text-white" : "hover:bg-muted-foreground/20 text-muted-foreground hover:text-foreground";
|
|
291
|
+
const copyButtonClass = `absolute top-2 right-2 z-10 opacity-0 group-hover:opacity-100 transition-opacity h-8 w-8 ${copyHoverClass}`;
|
|
292
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative group my-3", children: [
|
|
293
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
294
|
+
components.CopyButton,
|
|
295
|
+
{
|
|
296
|
+
value: code,
|
|
297
|
+
variant: "ghost",
|
|
298
|
+
className: copyButtonClass,
|
|
299
|
+
title: "Copy code"
|
|
300
|
+
}
|
|
301
|
+
),
|
|
302
|
+
/* @__PURE__ */ jsxRuntime.jsx("pre", { className: "p-3 rounded text-xs font-mono overflow-x-auto bg-code text-code-foreground border border-code-border", children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: code }) })
|
|
303
|
+
] });
|
|
304
|
+
}, "CodeBlockFallback");
|
|
298
305
|
function createMarkdownComponents(isUser = false, isCompact = false) {
|
|
299
306
|
const textSize = isCompact ? "text-xs" : "text-sm";
|
|
300
307
|
const headingBase = isCompact ? "text-sm" : "text-base";
|
|
@@ -310,13 +317,18 @@ function createMarkdownComponents(isUser = false, isCompact = false) {
|
|
|
310
317
|
ul: /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ul", { className: `list-disc list-inside mb-2 space-y-1 ${textSize}`, children }), "ul"),
|
|
311
318
|
ol: /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ol", { className: `list-decimal list-inside mb-2 space-y-1 ${textSize}`, children }), "ol"),
|
|
312
319
|
li: /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: "break-words", children }), "li"),
|
|
313
|
-
|
|
320
|
+
// `target` / `rel` for external links are NOT set here — the
|
|
321
|
+
// rehype-external-links plugin tags them on the rehype side, so
|
|
322
|
+
// every `<a>` that sanitize let through gets the same security
|
|
323
|
+
// treatment regardless of which renderer (default vs linkRules
|
|
324
|
+
// override) emitted it. Doing it twice here would just duplicate
|
|
325
|
+
// attributes; doing it only here would miss the linkRules path.
|
|
326
|
+
a: /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ href, children, ...rest }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
314
327
|
"a",
|
|
315
328
|
{
|
|
329
|
+
...rest,
|
|
316
330
|
href,
|
|
317
331
|
className: `${textSize} ${isUser ? "text-white/90 underline hover:text-white" : "text-primary underline hover:text-primary/80"} transition-colors break-all`,
|
|
318
|
-
target: href?.startsWith("http") ? "_blank" : void 0,
|
|
319
|
-
rel: href?.startsWith("http") ? "noopener noreferrer" : void 0,
|
|
320
332
|
children
|
|
321
333
|
}
|
|
322
334
|
), "a"),
|
|
@@ -340,7 +352,7 @@ function createMarkdownComponents(isUser = false, isCompact = false) {
|
|
|
340
352
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "my-3 p-3 bg-muted rounded text-sm text-muted-foreground", children: "No content available" });
|
|
341
353
|
}
|
|
342
354
|
if (language === "mermaid") {
|
|
343
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "my-3
|
|
355
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "my-3 w-full", children: /* @__PURE__ */ jsxRuntime.jsx(Mermaid_default, { chart: codeContent, isCompact }) });
|
|
344
356
|
}
|
|
345
357
|
try {
|
|
346
358
|
return /* @__PURE__ */ jsxRuntime.jsx(CodeBlock, { code: codeContent, language, isUser, isCompact });
|
|
@@ -353,16 +365,43 @@ function createMarkdownComponents(isUser = false, isCompact = false) {
|
|
|
353
365
|
if (className?.includes("language-")) {
|
|
354
366
|
return /* @__PURE__ */ jsxRuntime.jsx("code", { className, children });
|
|
355
367
|
}
|
|
356
|
-
|
|
368
|
+
const inlineCodeClass = isUser ? "bg-primary-foreground/15 text-primary-foreground" : "bg-code-inline text-code-inline-foreground";
|
|
369
|
+
return /* @__PURE__ */ jsxRuntime.jsx("code", { className: `px-1 py-0.5 rounded font-mono text-[0.875em] ${inlineCodeClass} break-all`, children: extractTextFromChildren(children) });
|
|
357
370
|
}, "code"),
|
|
358
|
-
|
|
371
|
+
// Modern chat convention drops italic on blockquotes — italic +
|
|
372
|
+
// tight bubble = hard to read. Border-left at 2px (4px reads
|
|
373
|
+
// heavy in a 320–480px bubble). On the saturated user bubble we
|
|
374
|
+
// use a primary-foreground tint; on the assistant bubble we use
|
|
375
|
+
// the muted-foreground role for de-emphasis.
|
|
376
|
+
blockquote: /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ children }) => {
|
|
377
|
+
const cls = isUser ? "border-primary-foreground/40 text-primary-foreground/80" : "border-border text-muted-foreground";
|
|
378
|
+
return /* @__PURE__ */ jsxRuntime.jsx("blockquote", { className: `${textSize} border-l-2 pl-3 my-3 break-words ${cls}`, children });
|
|
379
|
+
}, "blockquote"),
|
|
380
|
+
// Tables: outer wrapper handles overflow, inner `<table>`
|
|
381
|
+
// inherits the chat-density text size. Borders / header use
|
|
382
|
+
// semantic tokens — `border-code-border` for the assistant
|
|
383
|
+
// (matches the code-fence panel for visual cohesion when both
|
|
384
|
+
// appear in the same reply); primary-foreground/N for the user
|
|
385
|
+
// bubble so lines read against the saturated `bg-primary`.
|
|
359
386
|
table: /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto my-3", children: /* @__PURE__ */ jsxRuntime.jsx("table", { className: `min-w-full ${textSize} border-collapse`, children }) }), "table"),
|
|
360
|
-
thead: /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-muted/
|
|
387
|
+
thead: /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("thead", { className: isUser ? "bg-primary-foreground/10" : "bg-muted/40", children }), "thead"),
|
|
361
388
|
tbody: /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("tbody", { children }), "tbody"),
|
|
362
|
-
tr: /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "border-b border-
|
|
363
|
-
th: /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ children }) =>
|
|
364
|
-
|
|
365
|
-
|
|
389
|
+
tr: /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("tr", { className: isUser ? "border-b border-primary-foreground/15" : "border-b border-border", children }), "tr"),
|
|
390
|
+
th: /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ children }) => {
|
|
391
|
+
const borderCls = isUser ? "border-primary-foreground/25" : "border-border";
|
|
392
|
+
return /* @__PURE__ */ jsxRuntime.jsx("th", { className: `px-2 py-1.5 text-left font-semibold border-b ${borderCls} break-words`, children });
|
|
393
|
+
}, "th"),
|
|
394
|
+
td: /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-2 py-1.5 break-words", children }), "td"),
|
|
395
|
+
// Soft separator. ChatGPT / Slack / Linear strip the visible
|
|
396
|
+
// line, Claude.ai keeps a hairline. We follow Claude — present
|
|
397
|
+
// but quiet. Palette switches by role so the hairline reads on
|
|
398
|
+
// both surfaces.
|
|
399
|
+
hr: /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => /* @__PURE__ */ jsxRuntime.jsx(
|
|
400
|
+
"hr",
|
|
401
|
+
{
|
|
402
|
+
className: `my-4 border-0 h-px ${isUser ? "bg-primary-foreground/20" : "bg-border"}`
|
|
403
|
+
}
|
|
404
|
+
), "hr"),
|
|
366
405
|
strong: /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("strong", { className: "font-semibold", children }), "strong"),
|
|
367
406
|
em: /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("em", { className: "italic", children }), "em")
|
|
368
407
|
};
|
|
@@ -558,9 +597,14 @@ var MarkdownMessage = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({
|
|
|
558
597
|
${isUser ? "prose-invert" : "dark:prose-invert"}
|
|
559
598
|
[&>*]:leading-relaxed
|
|
560
599
|
[&>*:first-child]:mt-0 [&>*:last-child]:mb-0
|
|
561
|
-
[&_p]:my-
|
|
562
|
-
[&_ul]:my-2 [&_ol]:my-2 [&
|
|
563
|
-
[&
|
|
600
|
+
[&_p]:my-2
|
|
601
|
+
[&_ul]:my-2 [&_ol]:my-2 [&_ul]:pl-5 [&_ol]:pl-5
|
|
602
|
+
[&_li]:my-1 [&_li>p]:my-0
|
|
603
|
+
[&_pre]:my-3
|
|
604
|
+
[&_h1]:mt-4 [&_h1]:mb-2 [&_h1]:text-base [&_h1]:font-semibold
|
|
605
|
+
[&_h2]:mt-3.5 [&_h2]:mb-1.5 [&_h2]:text-[15px] [&_h2]:font-semibold
|
|
606
|
+
[&_h3]:mt-3 [&_h3]:mb-1 [&_h3]:text-sm [&_h3]:font-medium
|
|
607
|
+
[&_h4]:mt-3 [&_h4]:mb-1 [&_h4]:text-sm [&_h4]:font-medium
|
|
564
608
|
`,
|
|
565
609
|
style: {
|
|
566
610
|
// Inherit colors from parent — fixes issues with external
|
|
@@ -574,8 +618,12 @@ var MarkdownMessage = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({
|
|
|
574
618
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
575
619
|
ReactMarkdown__default.default,
|
|
576
620
|
{
|
|
577
|
-
remarkPlugins: [remarkGfm__default.default],
|
|
578
|
-
rehypePlugins: [
|
|
621
|
+
remarkPlugins: [remarkGfm__default.default, remarkBreaks__default.default, remarkSmartypants__default.default, remarkEmoji__default.default],
|
|
622
|
+
rehypePlugins: [
|
|
623
|
+
rehypeRaw__default.default,
|
|
624
|
+
[rehypeSanitize__default.default, schema],
|
|
625
|
+
[rehypeExternalLinks__default.default, { target: "_blank", rel: ["noopener", "noreferrer"] }]
|
|
626
|
+
],
|
|
579
627
|
components,
|
|
580
628
|
urlTransform,
|
|
581
629
|
children: displayContent
|
|
@@ -1546,5 +1594,5 @@ exports.toMarkdown = toMarkdown;
|
|
|
1546
1594
|
exports.toRawJson = toRawJson;
|
|
1547
1595
|
exports.useCollapsibleContent = useCollapsibleContent;
|
|
1548
1596
|
exports.usePlaygroundContext = usePlaygroundContext;
|
|
1549
|
-
//# sourceMappingURL=chunk-
|
|
1550
|
-
//# sourceMappingURL=chunk-
|
|
1597
|
+
//# sourceMappingURL=chunk-FYLR232K.cjs.map
|
|
1598
|
+
//# sourceMappingURL=chunk-FYLR232K.cjs.map
|