@djangocfg/ui-tools 2.1.298 → 2.1.299
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 +126 -2
- package/dist/{DocsLayout-74WIW7L3.mjs → DocsLayout-MWRKNFXR.mjs} +3 -3
- package/dist/{DocsLayout-74WIW7L3.mjs.map → DocsLayout-MWRKNFXR.mjs.map} +1 -1
- package/dist/{DocsLayout-IA55EXRN.cjs → DocsLayout-NWJUF42A.cjs} +48 -48
- package/dist/{DocsLayout-IA55EXRN.cjs.map → DocsLayout-NWJUF42A.cjs.map} +1 -1
- package/dist/{chunk-2BBXP3DH.mjs → chunk-CKD7GNE5.mjs} +220 -187
- package/dist/chunk-CKD7GNE5.mjs.map +1 -0
- package/dist/{chunk-Q6FNLXLZ.cjs → chunk-SEXWBCLX.cjs} +256 -222
- package/dist/chunk-SEXWBCLX.cjs.map +1 -0
- package/dist/index.cjs +13 -9
- package/dist/index.d.cts +82 -59
- package/dist/index.d.ts +82 -59
- package/dist/index.mjs +4 -4
- package/package.json +6 -6
- package/src/components/markdown/MarkdownMessage/CodeBlock.tsx +69 -0
- package/src/components/markdown/MarkdownMessage/CollapseToggle.tsx +60 -0
- package/src/components/markdown/MarkdownMessage/MarkdownMessage.story.tsx +171 -0
- package/src/components/markdown/MarkdownMessage/MarkdownMessage.tsx +202 -0
- package/src/components/markdown/MarkdownMessage/components.tsx +154 -0
- package/src/components/markdown/MarkdownMessage/index.ts +13 -0
- package/src/components/markdown/MarkdownMessage/linkRules.ts +83 -0
- package/src/components/markdown/MarkdownMessage/plainText.ts +50 -0
- package/src/components/markdown/MarkdownMessage/sanitize.ts +78 -0
- package/src/components/markdown/MarkdownMessage/types.ts +104 -0
- package/src/components/markdown/index.ts +6 -1
- package/dist/chunk-2BBXP3DH.mjs.map +0 -1
- package/dist/chunk-Q6FNLXLZ.cjs.map +0 -1
- package/src/components/markdown/MarkdownMessage.tsx +0 -721
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { __name } from './chunk-CGILA3WO.mjs';
|
|
2
|
-
import
|
|
2
|
+
import React6, { lazy, createContext, useState, useMemo, useCallback, Suspense, useContext, useReducer, useRef, useEffect } from 'react';
|
|
3
3
|
import '@djangocfg/ui-core/styles/palette';
|
|
4
4
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
5
5
|
import ReactMarkdown from 'react-markdown';
|
|
@@ -7,25 +7,10 @@ import rehypeRaw from 'rehype-raw';
|
|
|
7
7
|
import rehypeSanitize, { defaultSchema } from 'rehype-sanitize';
|
|
8
8
|
import remarkGfm from 'remark-gfm';
|
|
9
9
|
import { CopyButton } from '@djangocfg/ui-core/components';
|
|
10
|
-
import {
|
|
10
|
+
import { useResolvedTheme, useSessionStorage } from '@djangocfg/ui-core/hooks';
|
|
11
11
|
import consola2 from 'consola';
|
|
12
12
|
import { sample } from 'openapi-sampler';
|
|
13
13
|
|
|
14
|
-
var MermaidClient = lazy(() => import('./Mermaid.client-XFQ74OYN.mjs'));
|
|
15
|
-
var LoadingFallback = /* @__PURE__ */ __name(() => /* @__PURE__ */ jsx("div", { className: "flex justify-center items-center min-h-[100px]", children: /* @__PURE__ */ jsx("div", { className: "animate-spin rounded-full h-6 w-6 border-b-2 border-primary" }) }), "LoadingFallback");
|
|
16
|
-
var Mermaid = /* @__PURE__ */ __name((props) => {
|
|
17
|
-
return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(LoadingFallback, {}), children: /* @__PURE__ */ jsx(MermaidClient, { ...props }) });
|
|
18
|
-
}, "Mermaid");
|
|
19
|
-
var Mermaid_default = Mermaid;
|
|
20
|
-
var PrettyCodeClient = lazy(() => import('./PrettyCode.client-SPMTQEG4.mjs'));
|
|
21
|
-
var LoadingFallback2 = /* @__PURE__ */ __name(() => /* @__PURE__ */ jsx("div", { className: "relative rounded-sm border border-border overflow-hidden bg-muted dark:bg-zinc-900", children: /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
22
|
-
/* @__PURE__ */ jsx("div", { className: "animate-pulse h-4 w-4 rounded-full bg-muted-foreground/20" }),
|
|
23
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "Loading code..." })
|
|
24
|
-
] }) }) }), "LoadingFallback");
|
|
25
|
-
var PrettyCode = /* @__PURE__ */ __name((props) => {
|
|
26
|
-
return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(LoadingFallback2, {}), children: /* @__PURE__ */ jsx(PrettyCodeClient, { ...props }) });
|
|
27
|
-
}, "PrettyCode");
|
|
28
|
-
var PrettyCode_default = PrettyCode;
|
|
29
14
|
function smartTruncate(content, maxLength) {
|
|
30
15
|
if (content.length <= maxLength) {
|
|
31
16
|
return content;
|
|
@@ -141,6 +126,72 @@ function useCollapsibleContent(content, options = {}) {
|
|
|
141
126
|
};
|
|
142
127
|
}
|
|
143
128
|
__name(useCollapsibleContent, "useCollapsibleContent");
|
|
129
|
+
function extractTextFromChildren(children) {
|
|
130
|
+
if (typeof children === "string") return children;
|
|
131
|
+
if (typeof children === "number") return String(children);
|
|
132
|
+
if (React6.isValidElement(children)) {
|
|
133
|
+
const props = children.props;
|
|
134
|
+
return extractTextFromChildren(props.children);
|
|
135
|
+
}
|
|
136
|
+
if (Array.isArray(children)) {
|
|
137
|
+
return children.map(extractTextFromChildren).join("");
|
|
138
|
+
}
|
|
139
|
+
return "";
|
|
140
|
+
}
|
|
141
|
+
__name(extractTextFromChildren, "extractTextFromChildren");
|
|
142
|
+
function hasMarkdownSyntax(text) {
|
|
143
|
+
if (text.trim().includes("\n")) return true;
|
|
144
|
+
if (/<\/?[a-zA-Z][a-zA-Z0-9-]*(\s[^>]*)?\/?>/.test(text)) return true;
|
|
145
|
+
const patterns = [
|
|
146
|
+
/^#{1,6}\s/m,
|
|
147
|
+
// Headers
|
|
148
|
+
/\*\*[^*]+\*\*/,
|
|
149
|
+
// Bold
|
|
150
|
+
/\*[^*]+\*/,
|
|
151
|
+
// Italic
|
|
152
|
+
/__[^_]+__/,
|
|
153
|
+
// Bold (underscore)
|
|
154
|
+
/_[^_]+_/,
|
|
155
|
+
// Italic (underscore)
|
|
156
|
+
/\[.+\]\(.+\)/,
|
|
157
|
+
// Links
|
|
158
|
+
/!\[.*\]\(.+\)/,
|
|
159
|
+
// Images
|
|
160
|
+
/```[\s\S]*```/,
|
|
161
|
+
// Code blocks
|
|
162
|
+
/`[^`]+`/,
|
|
163
|
+
// Inline code
|
|
164
|
+
/^\s*[-*+]\s/m,
|
|
165
|
+
// Unordered lists
|
|
166
|
+
/^\s*\d+\.\s/m,
|
|
167
|
+
// Ordered lists
|
|
168
|
+
/^\s*>/m,
|
|
169
|
+
// Blockquotes
|
|
170
|
+
/\|.+\|/,
|
|
171
|
+
// Tables
|
|
172
|
+
/^---+$/m,
|
|
173
|
+
// Horizontal rules
|
|
174
|
+
/~~[^~]+~~/
|
|
175
|
+
// Strikethrough
|
|
176
|
+
];
|
|
177
|
+
return patterns.some((p) => p.test(text));
|
|
178
|
+
}
|
|
179
|
+
__name(hasMarkdownSyntax, "hasMarkdownSyntax");
|
|
180
|
+
var MermaidClient = lazy(() => import('./Mermaid.client-XFQ74OYN.mjs'));
|
|
181
|
+
var LoadingFallback = /* @__PURE__ */ __name(() => /* @__PURE__ */ jsx("div", { className: "flex justify-center items-center min-h-[100px]", children: /* @__PURE__ */ jsx("div", { className: "animate-spin rounded-full h-6 w-6 border-b-2 border-primary" }) }), "LoadingFallback");
|
|
182
|
+
var Mermaid = /* @__PURE__ */ __name((props) => {
|
|
183
|
+
return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(LoadingFallback, {}), children: /* @__PURE__ */ jsx(MermaidClient, { ...props }) });
|
|
184
|
+
}, "Mermaid");
|
|
185
|
+
var Mermaid_default = Mermaid;
|
|
186
|
+
var PrettyCodeClient = lazy(() => import('./PrettyCode.client-SPMTQEG4.mjs'));
|
|
187
|
+
var LoadingFallback2 = /* @__PURE__ */ __name(() => /* @__PURE__ */ jsx("div", { className: "relative rounded-sm border border-border overflow-hidden bg-muted dark:bg-zinc-900", children: /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
188
|
+
/* @__PURE__ */ jsx("div", { className: "animate-pulse h-4 w-4 rounded-full bg-muted-foreground/20" }),
|
|
189
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "Loading code..." })
|
|
190
|
+
] }) }) }), "LoadingFallback");
|
|
191
|
+
var PrettyCode = /* @__PURE__ */ __name((props) => {
|
|
192
|
+
return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(LoadingFallback2, {}), children: /* @__PURE__ */ jsx(PrettyCodeClient, { ...props }) });
|
|
193
|
+
}, "PrettyCode");
|
|
194
|
+
var PrettyCode_default = PrettyCode;
|
|
144
195
|
var HTML_SCHEMA_BASE = {
|
|
145
196
|
...defaultSchema,
|
|
146
197
|
tagNames: [
|
|
@@ -189,22 +240,6 @@ function buildUrlTransform(extraProtocols) {
|
|
|
189
240
|
};
|
|
190
241
|
}
|
|
191
242
|
__name(buildUrlTransform, "buildUrlTransform");
|
|
192
|
-
var extractTextFromChildren = /* @__PURE__ */ __name((children) => {
|
|
193
|
-
if (typeof children === "string") {
|
|
194
|
-
return children;
|
|
195
|
-
}
|
|
196
|
-
if (typeof children === "number") {
|
|
197
|
-
return String(children);
|
|
198
|
-
}
|
|
199
|
-
if (React3.isValidElement(children)) {
|
|
200
|
-
const props = children.props;
|
|
201
|
-
return extractTextFromChildren(props.children);
|
|
202
|
-
}
|
|
203
|
-
if (Array.isArray(children)) {
|
|
204
|
-
return children.map(extractTextFromChildren).join("");
|
|
205
|
-
}
|
|
206
|
-
return "";
|
|
207
|
-
}, "extractTextFromChildren");
|
|
208
243
|
var CodeBlock = /* @__PURE__ */ __name(({ code, language, isUser, isCompact = false }) => {
|
|
209
244
|
const theme = useResolvedTheme();
|
|
210
245
|
return /* @__PURE__ */ jsxs("div", { className: "relative group my-3", children: [
|
|
@@ -234,25 +269,40 @@ var CodeBlock = /* @__PURE__ */ __name(({ code, language, isUser, isCompact = fa
|
|
|
234
269
|
)
|
|
235
270
|
] });
|
|
236
271
|
}, "CodeBlock");
|
|
237
|
-
var
|
|
272
|
+
var CodeBlockFallback = /* @__PURE__ */ __name(({ code, isUser }) => /* @__PURE__ */ jsxs("div", { className: "relative group my-3", children: [
|
|
273
|
+
/* @__PURE__ */ jsx(
|
|
274
|
+
CopyButton,
|
|
275
|
+
{
|
|
276
|
+
value: code,
|
|
277
|
+
variant: "ghost",
|
|
278
|
+
className: `
|
|
279
|
+
absolute top-2 right-2 z-10 opacity-0 group-hover:opacity-100 transition-opacity
|
|
280
|
+
h-8 w-8
|
|
281
|
+
${isUser ? "hover:bg-white/20 text-white" : "hover:bg-muted-foreground/20 text-muted-foreground hover:text-foreground"}
|
|
282
|
+
`,
|
|
283
|
+
title: "Copy code"
|
|
284
|
+
}
|
|
285
|
+
),
|
|
286
|
+
/* @__PURE__ */ jsx("pre", { className: `
|
|
287
|
+
p-3 rounded text-xs font-mono overflow-x-auto
|
|
288
|
+
${isUser ? "bg-white/10 text-white" : "bg-muted text-foreground"}
|
|
289
|
+
`, children: /* @__PURE__ */ jsx("code", { children: code }) })
|
|
290
|
+
] }), "CodeBlockFallback");
|
|
291
|
+
function createMarkdownComponents(isUser = false, isCompact = false) {
|
|
238
292
|
const textSize = isCompact ? "text-xs" : "text-sm";
|
|
239
293
|
const headingBase = isCompact ? "text-sm" : "text-base";
|
|
240
294
|
const headingSm = isCompact ? "text-xs" : "text-sm";
|
|
241
295
|
return {
|
|
242
|
-
// Headings - scaled for chat context
|
|
243
296
|
h1: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("h1", { className: `${headingBase} font-bold mb-2 mt-3 first:mt-0`, children }), "h1"),
|
|
244
297
|
h2: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("h2", { className: `${headingSm} font-bold mb-2 mt-3 first:mt-0`, children }), "h2"),
|
|
245
298
|
h3: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("h3", { className: `${headingSm} font-semibold mb-1 mt-2 first:mt-0`, children }), "h3"),
|
|
246
299
|
h4: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("h4", { className: `${headingSm} font-semibold mb-1 mt-2 first:mt-0`, children }), "h4"),
|
|
247
300
|
h5: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("h5", { className: `${headingSm} font-medium mb-1 mt-2 first:mt-0`, children }), "h5"),
|
|
248
301
|
h6: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("h6", { className: `${headingSm} font-medium mb-1 mt-2 first:mt-0`, children }), "h6"),
|
|
249
|
-
// Paragraphs - optimized for chat readability
|
|
250
302
|
p: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("p", { className: `${textSize} mb-4 last:mb-0 leading-7 break-words font-light`, children }), "p"),
|
|
251
|
-
// Lists - compact
|
|
252
303
|
ul: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("ul", { className: `list-disc list-inside mb-2 space-y-1 ${textSize}`, children }), "ul"),
|
|
253
304
|
ol: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("ol", { className: `list-decimal list-inside mb-2 space-y-1 ${textSize}`, children }), "ol"),
|
|
254
305
|
li: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("li", { className: "break-words", children }), "li"),
|
|
255
|
-
// Links - appropriate for chat context
|
|
256
306
|
a: /* @__PURE__ */ __name(({ href, children }) => /* @__PURE__ */ jsx(
|
|
257
307
|
"a",
|
|
258
308
|
{
|
|
@@ -263,11 +313,10 @@ var createMarkdownComponents = /* @__PURE__ */ __name((isUser = false, isCompact
|
|
|
263
313
|
children
|
|
264
314
|
}
|
|
265
315
|
), "a"),
|
|
266
|
-
// Code blocks - using CodeBlock component with copy functionality
|
|
267
316
|
pre: /* @__PURE__ */ __name(({ children }) => {
|
|
268
317
|
let codeContent = "";
|
|
269
318
|
let language = "plaintext";
|
|
270
|
-
if (
|
|
319
|
+
if (React6.isValidElement(children)) {
|
|
271
320
|
const child = children;
|
|
272
321
|
if (child.type === "code" || typeof child.type === "function" && child.type.name === "code") {
|
|
273
322
|
const codeProps = child.props;
|
|
@@ -290,92 +339,28 @@ var createMarkdownComponents = /* @__PURE__ */ __name((isUser = false, isCompact
|
|
|
290
339
|
return /* @__PURE__ */ jsx(CodeBlock, { code: codeContent, language, isUser, isCompact });
|
|
291
340
|
} catch (error) {
|
|
292
341
|
console.warn("CodeBlock failed, using fallback:", error);
|
|
293
|
-
return /* @__PURE__ */
|
|
294
|
-
/* @__PURE__ */ jsx(
|
|
295
|
-
CopyButton,
|
|
296
|
-
{
|
|
297
|
-
value: codeContent,
|
|
298
|
-
variant: "ghost",
|
|
299
|
-
className: `
|
|
300
|
-
absolute top-2 right-2 z-10 opacity-0 group-hover:opacity-100 transition-opacity
|
|
301
|
-
h-8 w-8
|
|
302
|
-
${isUser ? "hover:bg-white/20 text-white" : "hover:bg-muted-foreground/20 text-muted-foreground hover:text-foreground"}
|
|
303
|
-
`,
|
|
304
|
-
title: "Copy code"
|
|
305
|
-
}
|
|
306
|
-
),
|
|
307
|
-
/* @__PURE__ */ jsx("pre", { className: `
|
|
308
|
-
p-3 rounded text-xs font-mono overflow-x-auto
|
|
309
|
-
${isUser ? "bg-white/10 text-white" : "bg-muted text-foreground"}
|
|
310
|
-
`, children: /* @__PURE__ */ jsx("code", { children: codeContent }) })
|
|
311
|
-
] });
|
|
342
|
+
return /* @__PURE__ */ jsx(CodeBlockFallback, { code: codeContent, language, isUser, isCompact });
|
|
312
343
|
}
|
|
313
344
|
}, "pre"),
|
|
314
|
-
// Inline code
|
|
315
345
|
code: /* @__PURE__ */ __name(({ children, className }) => {
|
|
316
346
|
if (className?.includes("language-")) {
|
|
317
347
|
return /* @__PURE__ */ jsx("code", { className, children });
|
|
318
348
|
}
|
|
319
|
-
|
|
320
|
-
return /* @__PURE__ */ jsx("code", { className: "px-1.5 py-0.5 rounded text-xs font-mono bg-muted text-foreground break-all", children: codeContent });
|
|
349
|
+
return /* @__PURE__ */ jsx("code", { className: "px-1.5 py-0.5 rounded text-xs font-mono bg-muted text-foreground break-all", children: extractTextFromChildren(children) });
|
|
321
350
|
}, "code"),
|
|
322
|
-
// Blockquotes
|
|
323
351
|
blockquote: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("blockquote", { className: `${textSize} border-l-2 border-border pl-3 my-2 italic text-muted-foreground break-words`, children }), "blockquote"),
|
|
324
|
-
// Tables - compact for chat
|
|
325
352
|
table: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("div", { className: "overflow-x-auto my-3", children: /* @__PURE__ */ jsx("table", { className: `min-w-full ${textSize} border-collapse`, children }) }), "table"),
|
|
326
353
|
thead: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("thead", { className: "bg-muted/50", children }), "thead"),
|
|
327
354
|
tbody: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("tbody", { children }), "tbody"),
|
|
328
355
|
tr: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("tr", { className: "border-b border-border/50", children }), "tr"),
|
|
329
356
|
th: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("th", { className: "px-2 py-1 text-left font-medium break-words", children }), "th"),
|
|
330
357
|
td: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("td", { className: "px-2 py-1 break-words", children }), "td"),
|
|
331
|
-
// Horizontal rule
|
|
332
358
|
hr: /* @__PURE__ */ __name(() => /* @__PURE__ */ jsx("hr", { className: "my-3 border-0 h-px bg-border" }), "hr"),
|
|
333
|
-
// Strong and emphasis
|
|
334
359
|
strong: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("strong", { className: "font-semibold", children }), "strong"),
|
|
335
360
|
em: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("em", { className: "italic", children }), "em")
|
|
336
361
|
};
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
if (text.trim().includes("\n")) {
|
|
340
|
-
return true;
|
|
341
|
-
}
|
|
342
|
-
if (/<\/?[a-zA-Z][a-zA-Z0-9-]*(\s[^>]*)?\/?>/.test(text)) {
|
|
343
|
-
return true;
|
|
344
|
-
}
|
|
345
|
-
const markdownPatterns = [
|
|
346
|
-
/^#{1,6}\s/m,
|
|
347
|
-
// Headers
|
|
348
|
-
/\*\*[^*]+\*\*/,
|
|
349
|
-
// Bold
|
|
350
|
-
/\*[^*]+\*/,
|
|
351
|
-
// Italic
|
|
352
|
-
/__[^_]+__/,
|
|
353
|
-
// Bold (underscore)
|
|
354
|
-
/_[^_]+_/,
|
|
355
|
-
// Italic (underscore)
|
|
356
|
-
/\[.+\]\(.+\)/,
|
|
357
|
-
// Links
|
|
358
|
-
/!\[.*\]\(.+\)/,
|
|
359
|
-
// Images
|
|
360
|
-
/```[\s\S]*```/,
|
|
361
|
-
// Code blocks
|
|
362
|
-
/`[^`]+`/,
|
|
363
|
-
// Inline code
|
|
364
|
-
/^\s*[-*+]\s/m,
|
|
365
|
-
// Unordered lists
|
|
366
|
-
/^\s*\d+\.\s/m,
|
|
367
|
-
// Ordered lists
|
|
368
|
-
/^\s*>/m,
|
|
369
|
-
// Blockquotes
|
|
370
|
-
/\|.+\|/,
|
|
371
|
-
// Tables
|
|
372
|
-
/^---+$/m,
|
|
373
|
-
// Horizontal rules
|
|
374
|
-
/~~[^~]+~~/
|
|
375
|
-
// Strikethrough
|
|
376
|
-
];
|
|
377
|
-
return markdownPatterns.some((pattern) => pattern.test(text));
|
|
378
|
-
}, "hasMarkdownSyntax");
|
|
362
|
+
}
|
|
363
|
+
__name(createMarkdownComponents, "createMarkdownComponents");
|
|
379
364
|
var CollapseToggle = /* @__PURE__ */ __name(({
|
|
380
365
|
isCollapsed,
|
|
381
366
|
onClick,
|
|
@@ -399,48 +384,77 @@ var CollapseToggle = /* @__PURE__ */ __name(({
|
|
|
399
384
|
`,
|
|
400
385
|
children: isCollapsed ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
401
386
|
readMoreLabel,
|
|
402
|
-
/* @__PURE__ */ jsx(
|
|
403
|
-
"svg",
|
|
404
|
-
{
|
|
405
|
-
className: "w-3 h-3",
|
|
406
|
-
fill: "none",
|
|
407
|
-
stroke: "currentColor",
|
|
408
|
-
viewBox: "0 0 24 24",
|
|
409
|
-
children: /* @__PURE__ */ jsx(
|
|
410
|
-
"path",
|
|
411
|
-
{
|
|
412
|
-
strokeLinecap: "round",
|
|
413
|
-
strokeLinejoin: "round",
|
|
414
|
-
strokeWidth: 2,
|
|
415
|
-
d: "M19 9l-7 7-7-7"
|
|
416
|
-
}
|
|
417
|
-
)
|
|
418
|
-
}
|
|
419
|
-
)
|
|
387
|
+
/* @__PURE__ */ jsx(Chevron, { direction: "down" })
|
|
420
388
|
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
421
389
|
showLessLabel,
|
|
422
|
-
/* @__PURE__ */ jsx(
|
|
423
|
-
"svg",
|
|
424
|
-
{
|
|
425
|
-
className: "w-3 h-3",
|
|
426
|
-
fill: "none",
|
|
427
|
-
stroke: "currentColor",
|
|
428
|
-
viewBox: "0 0 24 24",
|
|
429
|
-
children: /* @__PURE__ */ jsx(
|
|
430
|
-
"path",
|
|
431
|
-
{
|
|
432
|
-
strokeLinecap: "round",
|
|
433
|
-
strokeLinejoin: "round",
|
|
434
|
-
strokeWidth: 2,
|
|
435
|
-
d: "M5 15l7-7 7 7"
|
|
436
|
-
}
|
|
437
|
-
)
|
|
438
|
-
}
|
|
439
|
-
)
|
|
390
|
+
/* @__PURE__ */ jsx(Chevron, { direction: "up" })
|
|
440
391
|
] })
|
|
441
392
|
}
|
|
442
393
|
);
|
|
443
394
|
}, "CollapseToggle");
|
|
395
|
+
function Chevron({ direction }) {
|
|
396
|
+
return /* @__PURE__ */ jsx("svg", { className: "w-3 h-3", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx(
|
|
397
|
+
"path",
|
|
398
|
+
{
|
|
399
|
+
strokeLinecap: "round",
|
|
400
|
+
strokeLinejoin: "round",
|
|
401
|
+
strokeWidth: 2,
|
|
402
|
+
d: direction === "down" ? "M19 9l-7 7-7-7" : "M5 15l7-7 7 7"
|
|
403
|
+
}
|
|
404
|
+
) });
|
|
405
|
+
}
|
|
406
|
+
__name(Chevron, "Chevron");
|
|
407
|
+
function applyPreprocess(source, rules) {
|
|
408
|
+
if (!rules || rules.length === 0) return source;
|
|
409
|
+
let s = source;
|
|
410
|
+
for (const rule of rules) {
|
|
411
|
+
if (!rule.preprocess) continue;
|
|
412
|
+
try {
|
|
413
|
+
s = rule.preprocess(s);
|
|
414
|
+
} catch (err) {
|
|
415
|
+
console.warn(
|
|
416
|
+
`[MarkdownMessage] linkRule "${rule.name ?? "(anonymous)"}" preprocess threw; skipping`,
|
|
417
|
+
err
|
|
418
|
+
);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
return s;
|
|
422
|
+
}
|
|
423
|
+
__name(applyPreprocess, "applyPreprocess");
|
|
424
|
+
function collectProtocols(extraHrefProtocols, rules) {
|
|
425
|
+
const set = /* @__PURE__ */ new Set();
|
|
426
|
+
if (extraHrefProtocols) for (const p of extraHrefProtocols) set.add(p);
|
|
427
|
+
if (rules) {
|
|
428
|
+
for (const r of rules) {
|
|
429
|
+
if (r.protocols) for (const p of r.protocols) set.add(p);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
return set.size === 0 ? void 0 : Array.from(set);
|
|
433
|
+
}
|
|
434
|
+
__name(collectProtocols, "collectProtocols");
|
|
435
|
+
function buildLinkRulesComponent(rules, isUser, callerA) {
|
|
436
|
+
const Renderer = /* @__PURE__ */ __name((props) => {
|
|
437
|
+
const { href, children } = props;
|
|
438
|
+
if (typeof href === "string") {
|
|
439
|
+
for (const rule of rules) {
|
|
440
|
+
if (rule.match(href)) {
|
|
441
|
+
return React6.createElement(
|
|
442
|
+
React6.Fragment,
|
|
443
|
+
null,
|
|
444
|
+
rule.render({ href, children, isUser })
|
|
445
|
+
);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
if (callerA && typeof callerA === "function") {
|
|
450
|
+
const Caller = callerA;
|
|
451
|
+
return React6.createElement(Caller, props);
|
|
452
|
+
}
|
|
453
|
+
return React6.createElement("a", props, children);
|
|
454
|
+
}, "Renderer");
|
|
455
|
+
return Renderer;
|
|
456
|
+
}
|
|
457
|
+
__name(buildLinkRulesComponent, "buildLinkRulesComponent");
|
|
444
458
|
var MarkdownMessage = /* @__PURE__ */ __name(({
|
|
445
459
|
content,
|
|
446
460
|
className = "",
|
|
@@ -448,6 +462,7 @@ var MarkdownMessage = /* @__PURE__ */ __name(({
|
|
|
448
462
|
isCompact = false,
|
|
449
463
|
customComponents,
|
|
450
464
|
extraHrefProtocols,
|
|
465
|
+
linkRules,
|
|
451
466
|
collapsible = false,
|
|
452
467
|
maxLength,
|
|
453
468
|
maxLines,
|
|
@@ -456,54 +471,71 @@ var MarkdownMessage = /* @__PURE__ */ __name(({
|
|
|
456
471
|
defaultExpanded = false,
|
|
457
472
|
onCollapseChange
|
|
458
473
|
}) => {
|
|
459
|
-
const
|
|
460
|
-
|
|
474
|
+
const preprocessed = React6.useMemo(
|
|
475
|
+
() => applyPreprocess(content, linkRules),
|
|
476
|
+
[content, linkRules]
|
|
477
|
+
);
|
|
478
|
+
const effectiveProtocols = React6.useMemo(
|
|
479
|
+
() => collectProtocols(extraHrefProtocols, linkRules),
|
|
480
|
+
[extraHrefProtocols, linkRules]
|
|
481
|
+
);
|
|
482
|
+
const effectiveCustomComponents = React6.useMemo(() => {
|
|
483
|
+
if (!linkRules || linkRules.length === 0) return customComponents;
|
|
484
|
+
const callerA = customComponents?.a;
|
|
485
|
+
const aRenderer = buildLinkRulesComponent(linkRules, isUser, callerA);
|
|
486
|
+
return { ...customComponents ?? {}, a: aRenderer };
|
|
487
|
+
}, [customComponents, linkRules, isUser]);
|
|
488
|
+
const trimmedContent = preprocessed.trim();
|
|
489
|
+
const collapsibleOptions = React6.useMemo(() => {
|
|
461
490
|
if (!collapsible) return {};
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
491
|
+
return {
|
|
492
|
+
maxLength: maxLength ?? 1e3,
|
|
493
|
+
maxLines: maxLines ?? 10,
|
|
494
|
+
defaultExpanded
|
|
495
|
+
};
|
|
465
496
|
}, [collapsible, maxLength, maxLines, defaultExpanded]);
|
|
466
|
-
const {
|
|
467
|
-
|
|
468
|
-
toggleCollapsed,
|
|
469
|
-
displayContent,
|
|
470
|
-
shouldCollapse
|
|
471
|
-
} = useCollapsibleContent(
|
|
472
|
-
trimmedContent,
|
|
473
|
-
collapsible ? collapsibleOptions : {}
|
|
474
|
-
);
|
|
475
|
-
React3.useEffect(() => {
|
|
497
|
+
const { isCollapsed, toggleCollapsed, displayContent, shouldCollapse } = useCollapsibleContent(trimmedContent, collapsible ? collapsibleOptions : {});
|
|
498
|
+
React6.useEffect(() => {
|
|
476
499
|
if (collapsible && shouldCollapse && onCollapseChange) {
|
|
477
500
|
onCollapseChange(isCollapsed);
|
|
478
501
|
}
|
|
479
502
|
}, [isCollapsed, collapsible, shouldCollapse, onCollapseChange]);
|
|
480
|
-
const components =
|
|
503
|
+
const components = React6.useMemo(() => {
|
|
481
504
|
const base = createMarkdownComponents(isUser, isCompact);
|
|
482
|
-
return
|
|
483
|
-
}, [isUser, isCompact,
|
|
484
|
-
const schema =
|
|
485
|
-
const urlTransform =
|
|
505
|
+
return effectiveCustomComponents ? { ...base, ...effectiveCustomComponents } : base;
|
|
506
|
+
}, [isUser, isCompact, effectiveCustomComponents]);
|
|
507
|
+
const schema = React6.useMemo(() => buildSchema(effectiveProtocols), [effectiveProtocols]);
|
|
508
|
+
const urlTransform = React6.useMemo(
|
|
509
|
+
() => buildUrlTransform(effectiveProtocols),
|
|
510
|
+
[effectiveProtocols]
|
|
511
|
+
);
|
|
486
512
|
const textSizeClass = isCompact ? "text-xs" : "text-sm";
|
|
487
513
|
const proseClass = isCompact ? "prose-xs" : "prose-sm";
|
|
488
|
-
const isPlainText = !
|
|
514
|
+
const isPlainText = !effectiveCustomComponents && !hasMarkdownSyntax(displayContent);
|
|
489
515
|
if (isPlainText) {
|
|
490
|
-
return /* @__PURE__ */ jsxs(
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
{
|
|
497
|
-
isCollapsed,
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
516
|
+
return /* @__PURE__ */ jsxs(
|
|
517
|
+
"span",
|
|
518
|
+
{
|
|
519
|
+
className: `${textSizeClass} leading-7 break-words whitespace-pre-line font-light ${className}`,
|
|
520
|
+
children: [
|
|
521
|
+
displayContent,
|
|
522
|
+
collapsible && shouldCollapse && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
523
|
+
isCollapsed && "... ",
|
|
524
|
+
/* @__PURE__ */ jsx(
|
|
525
|
+
CollapseToggle,
|
|
526
|
+
{
|
|
527
|
+
isCollapsed,
|
|
528
|
+
onClick: toggleCollapsed,
|
|
529
|
+
readMoreLabel,
|
|
530
|
+
showLessLabel,
|
|
531
|
+
isUser,
|
|
532
|
+
isCompact
|
|
533
|
+
}
|
|
534
|
+
)
|
|
535
|
+
] })
|
|
536
|
+
]
|
|
537
|
+
}
|
|
538
|
+
);
|
|
507
539
|
}
|
|
508
540
|
return /* @__PURE__ */ jsxs("div", { className, children: [
|
|
509
541
|
/* @__PURE__ */ jsx(
|
|
@@ -515,7 +547,8 @@ var MarkdownMessage = /* @__PURE__ */ __name(({
|
|
|
515
547
|
[&>*]:leading-7
|
|
516
548
|
`,
|
|
517
549
|
style: {
|
|
518
|
-
// Inherit colors from parent
|
|
550
|
+
// Inherit colors from parent — fixes issues with external
|
|
551
|
+
// CSS variables overriding prose tokens.
|
|
519
552
|
"--tw-prose-body": "inherit",
|
|
520
553
|
"--tw-prose-headings": "inherit",
|
|
521
554
|
"--tw-prose-bold": "inherit",
|
|
@@ -1301,7 +1334,7 @@ var usePlaygroundContext = /* @__PURE__ */ __name(() => {
|
|
|
1301
1334
|
var PlaygroundProvider = /* @__PURE__ */ __name(({ children, config }) => {
|
|
1302
1335
|
const [state, dispatch] = useReducer(reducer, void 0, createInitialState);
|
|
1303
1336
|
const abortControllerRef = useRef(null);
|
|
1304
|
-
const apiKeys =
|
|
1337
|
+
const apiKeys = React6.useMemo(
|
|
1305
1338
|
() => config.apiKeys ?? [],
|
|
1306
1339
|
[config.apiKeys]
|
|
1307
1340
|
);
|
|
@@ -1471,6 +1504,6 @@ var PlaygroundProvider = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
1471
1504
|
return /* @__PURE__ */ jsx(PlaygroundContext.Provider, { value: contextValue, children });
|
|
1472
1505
|
}, "PlaygroundProvider");
|
|
1473
1506
|
|
|
1474
|
-
export { CODE_SAMPLE_TARGETS, MarkdownMessage, Mermaid_default, PlaygroundProvider, PrettyCode_default, UrlBuilder, buildHarRequest, deduplicateEndpoints, dereferenceSchema, endpointToMarkdown, findApiKeyById, formatBytes, isValidJson, joinUrl, parseRequestHeaders, relativePath, renderSnippet, resolveAbsolute, resolveBaseUrl, sampleSchemaJson, toCompactJson, toMarkdown, toRawJson, useCollapsibleContent, usePlaygroundContext };
|
|
1475
|
-
//# sourceMappingURL=chunk-
|
|
1476
|
-
//# sourceMappingURL=chunk-
|
|
1507
|
+
export { CODE_SAMPLE_TARGETS, MarkdownMessage, Mermaid_default, PlaygroundProvider, PrettyCode_default, UrlBuilder, buildHarRequest, deduplicateEndpoints, dereferenceSchema, endpointToMarkdown, extractTextFromChildren, findApiKeyById, formatBytes, isValidJson, joinUrl, parseRequestHeaders, relativePath, renderSnippet, resolveAbsolute, resolveBaseUrl, sampleSchemaJson, toCompactJson, toMarkdown, toRawJson, useCollapsibleContent, usePlaygroundContext };
|
|
1508
|
+
//# sourceMappingURL=chunk-CKD7GNE5.mjs.map
|
|
1509
|
+
//# sourceMappingURL=chunk-CKD7GNE5.mjs.map
|