@djangocfg/ui-tools 2.1.297 → 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-3HNAQQRE.mjs → DocsLayout-MWRKNFXR.mjs} +3 -3
- package/dist/{DocsLayout-3HNAQQRE.mjs.map → DocsLayout-MWRKNFXR.mjs.map} +1 -1
- package/dist/{DocsLayout-O4ONSD67.cjs → DocsLayout-NWJUF42A.cjs} +48 -48
- package/dist/{DocsLayout-O4ONSD67.cjs.map → DocsLayout-NWJUF42A.cjs.map} +1 -1
- package/dist/{chunk-DKJTH4GE.mjs → chunk-CKD7GNE5.mjs} +236 -186
- package/dist/chunk-CKD7GNE5.mjs.map +1 -0
- package/dist/{chunk-QTO5LWMK.cjs → chunk-SEXWBCLX.cjs} +272 -221
- 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-DKJTH4GE.mjs.map +0 -1
- package/dist/chunk-QTO5LWMK.cjs.map +0 -1
- package/src/components/markdown/MarkdownMessage.tsx +0 -686
|
@@ -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: [
|
|
@@ -174,22 +225,21 @@ function buildSchema(extraProtocols) {
|
|
|
174
225
|
};
|
|
175
226
|
}
|
|
176
227
|
__name(buildSchema, "buildSchema");
|
|
177
|
-
|
|
178
|
-
if (
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
}, "extractTextFromChildren");
|
|
228
|
+
function buildUrlTransform(extraProtocols) {
|
|
229
|
+
if (!extraProtocols || extraProtocols.length === 0) return void 0;
|
|
230
|
+
const lower = extraProtocols.map((p) => p.toLowerCase() + ":");
|
|
231
|
+
return (url) => {
|
|
232
|
+
const u = url.trim().toLowerCase();
|
|
233
|
+
for (const p of lower) {
|
|
234
|
+
if (u.startsWith(p)) return url;
|
|
235
|
+
}
|
|
236
|
+
if (/^(https?:|mailto:|tel:|xmpp:|irc:|ircs:|#|\/|\.\/|\.\.\/|\?)/i.test(u) || /^[a-z0-9._~!$&'()*+,;=:@%-]+$/i.test(u)) {
|
|
237
|
+
return url;
|
|
238
|
+
}
|
|
239
|
+
return "";
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
__name(buildUrlTransform, "buildUrlTransform");
|
|
193
243
|
var CodeBlock = /* @__PURE__ */ __name(({ code, language, isUser, isCompact = false }) => {
|
|
194
244
|
const theme = useResolvedTheme();
|
|
195
245
|
return /* @__PURE__ */ jsxs("div", { className: "relative group my-3", children: [
|
|
@@ -219,25 +269,40 @@ var CodeBlock = /* @__PURE__ */ __name(({ code, language, isUser, isCompact = fa
|
|
|
219
269
|
)
|
|
220
270
|
] });
|
|
221
271
|
}, "CodeBlock");
|
|
222
|
-
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) {
|
|
223
292
|
const textSize = isCompact ? "text-xs" : "text-sm";
|
|
224
293
|
const headingBase = isCompact ? "text-sm" : "text-base";
|
|
225
294
|
const headingSm = isCompact ? "text-xs" : "text-sm";
|
|
226
295
|
return {
|
|
227
|
-
// Headings - scaled for chat context
|
|
228
296
|
h1: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("h1", { className: `${headingBase} font-bold mb-2 mt-3 first:mt-0`, children }), "h1"),
|
|
229
297
|
h2: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("h2", { className: `${headingSm} font-bold mb-2 mt-3 first:mt-0`, children }), "h2"),
|
|
230
298
|
h3: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("h3", { className: `${headingSm} font-semibold mb-1 mt-2 first:mt-0`, children }), "h3"),
|
|
231
299
|
h4: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("h4", { className: `${headingSm} font-semibold mb-1 mt-2 first:mt-0`, children }), "h4"),
|
|
232
300
|
h5: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("h5", { className: `${headingSm} font-medium mb-1 mt-2 first:mt-0`, children }), "h5"),
|
|
233
301
|
h6: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("h6", { className: `${headingSm} font-medium mb-1 mt-2 first:mt-0`, children }), "h6"),
|
|
234
|
-
// Paragraphs - optimized for chat readability
|
|
235
302
|
p: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("p", { className: `${textSize} mb-4 last:mb-0 leading-7 break-words font-light`, children }), "p"),
|
|
236
|
-
// Lists - compact
|
|
237
303
|
ul: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("ul", { className: `list-disc list-inside mb-2 space-y-1 ${textSize}`, children }), "ul"),
|
|
238
304
|
ol: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("ol", { className: `list-decimal list-inside mb-2 space-y-1 ${textSize}`, children }), "ol"),
|
|
239
305
|
li: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("li", { className: "break-words", children }), "li"),
|
|
240
|
-
// Links - appropriate for chat context
|
|
241
306
|
a: /* @__PURE__ */ __name(({ href, children }) => /* @__PURE__ */ jsx(
|
|
242
307
|
"a",
|
|
243
308
|
{
|
|
@@ -248,11 +313,10 @@ var createMarkdownComponents = /* @__PURE__ */ __name((isUser = false, isCompact
|
|
|
248
313
|
children
|
|
249
314
|
}
|
|
250
315
|
), "a"),
|
|
251
|
-
// Code blocks - using CodeBlock component with copy functionality
|
|
252
316
|
pre: /* @__PURE__ */ __name(({ children }) => {
|
|
253
317
|
let codeContent = "";
|
|
254
318
|
let language = "plaintext";
|
|
255
|
-
if (
|
|
319
|
+
if (React6.isValidElement(children)) {
|
|
256
320
|
const child = children;
|
|
257
321
|
if (child.type === "code" || typeof child.type === "function" && child.type.name === "code") {
|
|
258
322
|
const codeProps = child.props;
|
|
@@ -275,92 +339,28 @@ var createMarkdownComponents = /* @__PURE__ */ __name((isUser = false, isCompact
|
|
|
275
339
|
return /* @__PURE__ */ jsx(CodeBlock, { code: codeContent, language, isUser, isCompact });
|
|
276
340
|
} catch (error) {
|
|
277
341
|
console.warn("CodeBlock failed, using fallback:", error);
|
|
278
|
-
return /* @__PURE__ */
|
|
279
|
-
/* @__PURE__ */ jsx(
|
|
280
|
-
CopyButton,
|
|
281
|
-
{
|
|
282
|
-
value: codeContent,
|
|
283
|
-
variant: "ghost",
|
|
284
|
-
className: `
|
|
285
|
-
absolute top-2 right-2 z-10 opacity-0 group-hover:opacity-100 transition-opacity
|
|
286
|
-
h-8 w-8
|
|
287
|
-
${isUser ? "hover:bg-white/20 text-white" : "hover:bg-muted-foreground/20 text-muted-foreground hover:text-foreground"}
|
|
288
|
-
`,
|
|
289
|
-
title: "Copy code"
|
|
290
|
-
}
|
|
291
|
-
),
|
|
292
|
-
/* @__PURE__ */ jsx("pre", { className: `
|
|
293
|
-
p-3 rounded text-xs font-mono overflow-x-auto
|
|
294
|
-
${isUser ? "bg-white/10 text-white" : "bg-muted text-foreground"}
|
|
295
|
-
`, children: /* @__PURE__ */ jsx("code", { children: codeContent }) })
|
|
296
|
-
] });
|
|
342
|
+
return /* @__PURE__ */ jsx(CodeBlockFallback, { code: codeContent, language, isUser, isCompact });
|
|
297
343
|
}
|
|
298
344
|
}, "pre"),
|
|
299
|
-
// Inline code
|
|
300
345
|
code: /* @__PURE__ */ __name(({ children, className }) => {
|
|
301
346
|
if (className?.includes("language-")) {
|
|
302
347
|
return /* @__PURE__ */ jsx("code", { className, children });
|
|
303
348
|
}
|
|
304
|
-
|
|
305
|
-
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) });
|
|
306
350
|
}, "code"),
|
|
307
|
-
// Blockquotes
|
|
308
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"),
|
|
309
|
-
// Tables - compact for chat
|
|
310
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"),
|
|
311
353
|
thead: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("thead", { className: "bg-muted/50", children }), "thead"),
|
|
312
354
|
tbody: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("tbody", { children }), "tbody"),
|
|
313
355
|
tr: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("tr", { className: "border-b border-border/50", children }), "tr"),
|
|
314
356
|
th: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("th", { className: "px-2 py-1 text-left font-medium break-words", children }), "th"),
|
|
315
357
|
td: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("td", { className: "px-2 py-1 break-words", children }), "td"),
|
|
316
|
-
// Horizontal rule
|
|
317
358
|
hr: /* @__PURE__ */ __name(() => /* @__PURE__ */ jsx("hr", { className: "my-3 border-0 h-px bg-border" }), "hr"),
|
|
318
|
-
// Strong and emphasis
|
|
319
359
|
strong: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("strong", { className: "font-semibold", children }), "strong"),
|
|
320
360
|
em: /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsx("em", { className: "italic", children }), "em")
|
|
321
361
|
};
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
if (text.trim().includes("\n")) {
|
|
325
|
-
return true;
|
|
326
|
-
}
|
|
327
|
-
if (/<\/?[a-zA-Z][a-zA-Z0-9-]*(\s[^>]*)?\/?>/.test(text)) {
|
|
328
|
-
return true;
|
|
329
|
-
}
|
|
330
|
-
const markdownPatterns = [
|
|
331
|
-
/^#{1,6}\s/m,
|
|
332
|
-
// Headers
|
|
333
|
-
/\*\*[^*]+\*\*/,
|
|
334
|
-
// Bold
|
|
335
|
-
/\*[^*]+\*/,
|
|
336
|
-
// Italic
|
|
337
|
-
/__[^_]+__/,
|
|
338
|
-
// Bold (underscore)
|
|
339
|
-
/_[^_]+_/,
|
|
340
|
-
// Italic (underscore)
|
|
341
|
-
/\[.+\]\(.+\)/,
|
|
342
|
-
// Links
|
|
343
|
-
/!\[.*\]\(.+\)/,
|
|
344
|
-
// Images
|
|
345
|
-
/```[\s\S]*```/,
|
|
346
|
-
// Code blocks
|
|
347
|
-
/`[^`]+`/,
|
|
348
|
-
// Inline code
|
|
349
|
-
/^\s*[-*+]\s/m,
|
|
350
|
-
// Unordered lists
|
|
351
|
-
/^\s*\d+\.\s/m,
|
|
352
|
-
// Ordered lists
|
|
353
|
-
/^\s*>/m,
|
|
354
|
-
// Blockquotes
|
|
355
|
-
/\|.+\|/,
|
|
356
|
-
// Tables
|
|
357
|
-
/^---+$/m,
|
|
358
|
-
// Horizontal rules
|
|
359
|
-
/~~[^~]+~~/
|
|
360
|
-
// Strikethrough
|
|
361
|
-
];
|
|
362
|
-
return markdownPatterns.some((pattern) => pattern.test(text));
|
|
363
|
-
}, "hasMarkdownSyntax");
|
|
362
|
+
}
|
|
363
|
+
__name(createMarkdownComponents, "createMarkdownComponents");
|
|
364
364
|
var CollapseToggle = /* @__PURE__ */ __name(({
|
|
365
365
|
isCollapsed,
|
|
366
366
|
onClick,
|
|
@@ -384,48 +384,77 @@ var CollapseToggle = /* @__PURE__ */ __name(({
|
|
|
384
384
|
`,
|
|
385
385
|
children: isCollapsed ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
386
386
|
readMoreLabel,
|
|
387
|
-
/* @__PURE__ */ jsx(
|
|
388
|
-
"svg",
|
|
389
|
-
{
|
|
390
|
-
className: "w-3 h-3",
|
|
391
|
-
fill: "none",
|
|
392
|
-
stroke: "currentColor",
|
|
393
|
-
viewBox: "0 0 24 24",
|
|
394
|
-
children: /* @__PURE__ */ jsx(
|
|
395
|
-
"path",
|
|
396
|
-
{
|
|
397
|
-
strokeLinecap: "round",
|
|
398
|
-
strokeLinejoin: "round",
|
|
399
|
-
strokeWidth: 2,
|
|
400
|
-
d: "M19 9l-7 7-7-7"
|
|
401
|
-
}
|
|
402
|
-
)
|
|
403
|
-
}
|
|
404
|
-
)
|
|
387
|
+
/* @__PURE__ */ jsx(Chevron, { direction: "down" })
|
|
405
388
|
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
406
389
|
showLessLabel,
|
|
407
|
-
/* @__PURE__ */ jsx(
|
|
408
|
-
"svg",
|
|
409
|
-
{
|
|
410
|
-
className: "w-3 h-3",
|
|
411
|
-
fill: "none",
|
|
412
|
-
stroke: "currentColor",
|
|
413
|
-
viewBox: "0 0 24 24",
|
|
414
|
-
children: /* @__PURE__ */ jsx(
|
|
415
|
-
"path",
|
|
416
|
-
{
|
|
417
|
-
strokeLinecap: "round",
|
|
418
|
-
strokeLinejoin: "round",
|
|
419
|
-
strokeWidth: 2,
|
|
420
|
-
d: "M5 15l7-7 7 7"
|
|
421
|
-
}
|
|
422
|
-
)
|
|
423
|
-
}
|
|
424
|
-
)
|
|
390
|
+
/* @__PURE__ */ jsx(Chevron, { direction: "up" })
|
|
425
391
|
] })
|
|
426
392
|
}
|
|
427
393
|
);
|
|
428
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");
|
|
429
458
|
var MarkdownMessage = /* @__PURE__ */ __name(({
|
|
430
459
|
content,
|
|
431
460
|
className = "",
|
|
@@ -433,6 +462,7 @@ var MarkdownMessage = /* @__PURE__ */ __name(({
|
|
|
433
462
|
isCompact = false,
|
|
434
463
|
customComponents,
|
|
435
464
|
extraHrefProtocols,
|
|
465
|
+
linkRules,
|
|
436
466
|
collapsible = false,
|
|
437
467
|
maxLength,
|
|
438
468
|
maxLines,
|
|
@@ -441,53 +471,71 @@ var MarkdownMessage = /* @__PURE__ */ __name(({
|
|
|
441
471
|
defaultExpanded = false,
|
|
442
472
|
onCollapseChange
|
|
443
473
|
}) => {
|
|
444
|
-
const
|
|
445
|
-
|
|
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(() => {
|
|
446
490
|
if (!collapsible) return {};
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
491
|
+
return {
|
|
492
|
+
maxLength: maxLength ?? 1e3,
|
|
493
|
+
maxLines: maxLines ?? 10,
|
|
494
|
+
defaultExpanded
|
|
495
|
+
};
|
|
450
496
|
}, [collapsible, maxLength, maxLines, defaultExpanded]);
|
|
451
|
-
const {
|
|
452
|
-
|
|
453
|
-
toggleCollapsed,
|
|
454
|
-
displayContent,
|
|
455
|
-
shouldCollapse
|
|
456
|
-
} = useCollapsibleContent(
|
|
457
|
-
trimmedContent,
|
|
458
|
-
collapsible ? collapsibleOptions : {}
|
|
459
|
-
);
|
|
460
|
-
React3.useEffect(() => {
|
|
497
|
+
const { isCollapsed, toggleCollapsed, displayContent, shouldCollapse } = useCollapsibleContent(trimmedContent, collapsible ? collapsibleOptions : {});
|
|
498
|
+
React6.useEffect(() => {
|
|
461
499
|
if (collapsible && shouldCollapse && onCollapseChange) {
|
|
462
500
|
onCollapseChange(isCollapsed);
|
|
463
501
|
}
|
|
464
502
|
}, [isCollapsed, collapsible, shouldCollapse, onCollapseChange]);
|
|
465
|
-
const components =
|
|
503
|
+
const components = React6.useMemo(() => {
|
|
466
504
|
const base = createMarkdownComponents(isUser, isCompact);
|
|
467
|
-
return
|
|
468
|
-
}, [isUser, isCompact,
|
|
469
|
-
const schema =
|
|
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
|
+
);
|
|
470
512
|
const textSizeClass = isCompact ? "text-xs" : "text-sm";
|
|
471
513
|
const proseClass = isCompact ? "prose-xs" : "prose-sm";
|
|
472
|
-
const isPlainText = !
|
|
514
|
+
const isPlainText = !effectiveCustomComponents && !hasMarkdownSyntax(displayContent);
|
|
473
515
|
if (isPlainText) {
|
|
474
|
-
return /* @__PURE__ */ jsxs(
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
{
|
|
481
|
-
isCollapsed,
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
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
|
+
);
|
|
491
539
|
}
|
|
492
540
|
return /* @__PURE__ */ jsxs("div", { className, children: [
|
|
493
541
|
/* @__PURE__ */ jsx(
|
|
@@ -499,7 +547,8 @@ var MarkdownMessage = /* @__PURE__ */ __name(({
|
|
|
499
547
|
[&>*]:leading-7
|
|
500
548
|
`,
|
|
501
549
|
style: {
|
|
502
|
-
// Inherit colors from parent
|
|
550
|
+
// Inherit colors from parent — fixes issues with external
|
|
551
|
+
// CSS variables overriding prose tokens.
|
|
503
552
|
"--tw-prose-body": "inherit",
|
|
504
553
|
"--tw-prose-headings": "inherit",
|
|
505
554
|
"--tw-prose-bold": "inherit",
|
|
@@ -512,6 +561,7 @@ var MarkdownMessage = /* @__PURE__ */ __name(({
|
|
|
512
561
|
remarkPlugins: [remarkGfm],
|
|
513
562
|
rehypePlugins: [rehypeRaw, [rehypeSanitize, schema]],
|
|
514
563
|
components,
|
|
564
|
+
urlTransform,
|
|
515
565
|
children: displayContent
|
|
516
566
|
}
|
|
517
567
|
)
|
|
@@ -1284,7 +1334,7 @@ var usePlaygroundContext = /* @__PURE__ */ __name(() => {
|
|
|
1284
1334
|
var PlaygroundProvider = /* @__PURE__ */ __name(({ children, config }) => {
|
|
1285
1335
|
const [state, dispatch] = useReducer(reducer, void 0, createInitialState);
|
|
1286
1336
|
const abortControllerRef = useRef(null);
|
|
1287
|
-
const apiKeys =
|
|
1337
|
+
const apiKeys = React6.useMemo(
|
|
1288
1338
|
() => config.apiKeys ?? [],
|
|
1289
1339
|
[config.apiKeys]
|
|
1290
1340
|
);
|
|
@@ -1454,6 +1504,6 @@ var PlaygroundProvider = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
1454
1504
|
return /* @__PURE__ */ jsx(PlaygroundContext.Provider, { value: contextValue, children });
|
|
1455
1505
|
}, "PlaygroundProvider");
|
|
1456
1506
|
|
|
1457
|
-
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 };
|
|
1458
|
-
//# sourceMappingURL=chunk-
|
|
1459
|
-
//# 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
|