@mastra/playground-ui 49.0.0-alpha.2 → 49.0.0-alpha.4
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/CHANGELOG.md +24 -0
- package/dist/code-BJMC6T9D.cjs +78 -0
- package/dist/code-BJMC6T9D.cjs.map +1 -0
- package/dist/code-DRGJVroV.js +57 -0
- package/dist/code-DRGJVroV.js.map +1 -0
- package/dist/{code-block-Dn0K3DkE.cjs → code-block-BZUY8Fj9.cjs} +2 -2
- package/dist/{code-block-Dn0K3DkE.cjs.map → code-block-BZUY8Fj9.cjs.map} +1 -1
- package/dist/{code-block-DqKXZajq.js → code-block-V4wpmbud.js} +2 -2
- package/dist/{code-block-DqKXZajq.js.map → code-block-V4wpmbud.js.map} +1 -1
- package/dist/components/Code.cjs.js +1 -1
- package/dist/components/Code.es.js +1 -1
- package/dist/components/CodeBlock.cjs.js +1 -1
- package/dist/components/CodeBlock.es.js +1 -1
- package/dist/components/MarkdownRenderer.cjs.js +1 -1
- package/dist/components/MarkdownRenderer.es.js +1 -1
- package/dist/components/Steps.cjs.js +52 -21
- package/dist/components/Steps.cjs.js.map +1 -1
- package/dist/components/Steps.es.js +52 -21
- package/dist/components/Steps.es.js.map +1 -1
- package/dist/components/ai/plan.cjs.js +1 -1
- package/dist/components/ai/plan.es.js +1 -1
- package/dist/{markdown-renderer-DmYYQHxu.js → markdown-renderer-CB2WMnTG.js} +9 -4
- package/dist/markdown-renderer-CB2WMnTG.js.map +1 -0
- package/dist/{markdown-renderer-D1vSFfp9.cjs → markdown-renderer-DvJfqb-D.cjs} +9 -4
- package/dist/markdown-renderer-DvJfqb-D.cjs.map +1 -0
- package/dist/src/ds/components/Code/code.d.ts +5 -0
- package/dist/src/ds/components/MarkdownRenderer/markdown-renderer.d.ts +5 -1
- package/dist/style.css +8 -0
- package/package.json +7 -7
- package/dist/code-Cj09LVys.js +0 -47
- package/dist/code-Cj09LVys.js.map +0 -1
- package/dist/code-FZwLnf_f.cjs +0 -68
- package/dist/code-FZwLnf_f.cjs.map +0 -1
- package/dist/markdown-renderer-D1vSFfp9.cjs.map +0 -1
- package/dist/markdown-renderer-DmYYQHxu.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @mastra/playground-ui
|
|
2
2
|
|
|
3
|
+
## 49.0.0-alpha.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Fixed code blocks flickering between colored and plain text while an agent streams a fenced snippet. The part already highlighted now keeps its colors, and only the characters that just landed show uncolored until highlighting catches up. ([#21415](https://github.com/mastra-ai/mastra/pull/21415))
|
|
8
|
+
|
|
9
|
+
- Improved chat responsiveness on long conversations. `MarkdownRenderer` is memoized, so a streaming reply no longer re-parses the markdown of every message already on screen on each chunk it receives — only the message actually being written is re-parsed. ([#21416](https://github.com/mastra-ai/mastra/pull/21416))
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [[`be31796`](https://github.com/mastra-ai/mastra/commit/be3179624ad5f77cff5fa342cd08046bf7605283), [`79dd7c2`](https://github.com/mastra-ai/mastra/commit/79dd7c261ee6be1fafedd4651959394db21d2cba), [`b9a28ec`](https://github.com/mastra-ai/mastra/commit/b9a28ecf7acdc0cb7a543d5b660f9fbee301df9a), [`be31796`](https://github.com/mastra-ai/mastra/commit/be3179624ad5f77cff5fa342cd08046bf7605283)]:
|
|
12
|
+
- @mastra/client-js@1.40.0-alpha.4
|
|
13
|
+
- @mastra/core@1.59.0-alpha.4
|
|
14
|
+
- @mastra/react@1.4.3-alpha.4
|
|
15
|
+
|
|
16
|
+
## 49.0.0-alpha.3
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- Flattened the step markers in the `plain` variant of `ProcessStepListItem`. A completed step now shows a green check on its own instead of a filled green disc with a glow behind it, and the pending, running and completed markers finally share the same diameter — the dashed pending circle used to be 28px next to an 11px spinner. ([#21414](https://github.com/mastra-ai/mastra/pull/21414))
|
|
21
|
+
|
|
22
|
+
- Updated dependencies [[`d118873`](https://github.com/mastra-ai/mastra/commit/d118873cfd5074b1f814a1c169a97ca7a3a29174), [`161258b`](https://github.com/mastra-ai/mastra/commit/161258b3473a6d0fce00a43cab59d119a49a232f), [`8ea8038`](https://github.com/mastra-ai/mastra/commit/8ea80386fde53d26e2c0b2060c53bc9bd9be10f3)]:
|
|
23
|
+
- @mastra/core@1.59.0-alpha.3
|
|
24
|
+
- @mastra/client-js@1.40.0-alpha.3
|
|
25
|
+
- @mastra/react@1.4.3-alpha.3
|
|
26
|
+
|
|
3
27
|
## 49.0.0-alpha.2
|
|
4
28
|
|
|
5
29
|
### Minor Changes
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
const React = require('react');
|
|
5
|
+
const highlight = require('./highlight-CEt2vhD8.cjs');
|
|
6
|
+
|
|
7
|
+
function _interopNamespaceDefault(e) {
|
|
8
|
+
const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } });
|
|
9
|
+
if (e) {
|
|
10
|
+
for (const k in e) {
|
|
11
|
+
if (k !== 'default') {
|
|
12
|
+
const d = Object.getOwnPropertyDescriptor(e, k);
|
|
13
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: () => e[k]
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
n.default = e;
|
|
21
|
+
return Object.freeze(n);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
|
|
25
|
+
|
|
26
|
+
function tokenStyle(token) {
|
|
27
|
+
if (token.htmlStyle && typeof token.htmlStyle === "object") {
|
|
28
|
+
return token.htmlStyle;
|
|
29
|
+
}
|
|
30
|
+
return token.color ? { color: token.color } : void 0;
|
|
31
|
+
}
|
|
32
|
+
function usableHighlight(highlighted, code, lang) {
|
|
33
|
+
if (!highlighted || highlighted.lang !== lang) return null;
|
|
34
|
+
return code.startsWith(highlighted.code) ? highlighted : null;
|
|
35
|
+
}
|
|
36
|
+
const Code = React__namespace.memo(function Code2({ code, lang, ...props }) {
|
|
37
|
+
const [highlighted, setHighlighted] = React__namespace.useState(null);
|
|
38
|
+
React__namespace.useEffect(() => {
|
|
39
|
+
if (!lang) {
|
|
40
|
+
setHighlighted(null);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
let cancelled = false;
|
|
44
|
+
void highlight.highlight(code, lang).then((tokens) => {
|
|
45
|
+
if (!cancelled && tokens?.length) setHighlighted({ code, lang, tokens });
|
|
46
|
+
}).catch(() => {
|
|
47
|
+
});
|
|
48
|
+
return () => {
|
|
49
|
+
cancelled = true;
|
|
50
|
+
};
|
|
51
|
+
}, [code, lang]);
|
|
52
|
+
const usable = usableHighlight(highlighted, code, lang);
|
|
53
|
+
if (!usable) {
|
|
54
|
+
return /* @__PURE__ */ jsxRuntime.jsx("pre", { ...props, children: code });
|
|
55
|
+
}
|
|
56
|
+
const tail = code.slice(usable.code.length);
|
|
57
|
+
let codeOffset = 0;
|
|
58
|
+
return /* @__PURE__ */ jsxRuntime.jsx("pre", { ...props, children: /* @__PURE__ */ jsxRuntime.jsxs("code", { children: [
|
|
59
|
+
usable.tokens.map((line, lineIndex) => {
|
|
60
|
+
const lineOffset = codeOffset;
|
|
61
|
+
let tokenOffset = lineOffset;
|
|
62
|
+
const tokenSpans = line.map((token) => {
|
|
63
|
+
const key = tokenOffset;
|
|
64
|
+
tokenOffset += token.content.length;
|
|
65
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shiki-token", style: tokenStyle(token), children: token.content }, key);
|
|
66
|
+
});
|
|
67
|
+
codeOffset = tokenOffset + 1;
|
|
68
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Fragment, { children: [
|
|
69
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: tokenSpans }),
|
|
70
|
+
lineIndex !== usable.tokens.length - 1 && "\n"
|
|
71
|
+
] }, lineOffset);
|
|
72
|
+
}),
|
|
73
|
+
tail
|
|
74
|
+
] }) });
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
exports.Code = Code;
|
|
78
|
+
//# sourceMappingURL=code-BJMC6T9D.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-BJMC6T9D.cjs","sources":["../src/ds/components/Code/code.tsx"],"sourcesContent":["import * as React from 'react';\nimport type { ThemedToken } from 'shiki/core';\n\nimport { highlight } from '../CodeEditor/highlight';\n\nexport interface CodeProps extends React.HTMLAttributes<HTMLPreElement> {\n code: string;\n lang?: string;\n}\n\nfunction tokenStyle(token: ThemedToken): React.CSSProperties | undefined {\n if (token.htmlStyle && typeof token.htmlStyle === 'object') {\n return token.htmlStyle as React.CSSProperties;\n }\n\n return token.color ? { color: token.color } : undefined;\n}\n\ninterface Highlighted {\n code: string;\n lang: string;\n tokens: ThemedToken[][];\n}\n\n/** Colors from an earlier pass still hold when the new code only appends to the old. */\nfunction usableHighlight(highlighted: Highlighted | null, code: string, lang?: string): Highlighted | null {\n if (!highlighted || highlighted.lang !== lang) return null;\n return code.startsWith(highlighted.code) ? highlighted : null;\n}\n\n/**\n * Low-level shiki token renderer shared by `CodeBlock` and `MarkdownRenderer`.\n * Dual-theme colors stay as `--shiki-light` / `--shiki-dark` CSS variables on\n * each token span; the `.shiki-token` class (index.css) picks the variant from\n * the `.dark` root class, so theme switching is pure CSS — no ThemeProvider\n * required. Renders plain text while highlighting is pending or when the\n * language is missing/unknown.\n *\n * A streaming fence re-renders on every delta while highlighting stays a frame\n * behind. Dropping the previous tokens each time would strobe the whole block\n * between colored and plain, so the settled prefix keeps its colors and only\n * the newly arrived tail waits, uncolored, for the next pass.\n */\nexport const Code = React.memo(function Code({ code, lang, ...props }: CodeProps) {\n const [highlighted, setHighlighted] = React.useState<Highlighted | null>(null);\n\n React.useEffect(() => {\n if (!lang) {\n setHighlighted(null);\n return;\n }\n\n let cancelled = false;\n\n void highlight(code, lang)\n .then(tokens => {\n if (!cancelled && tokens?.length) setHighlighted({ code, lang, tokens });\n })\n .catch(() => {});\n\n return () => {\n cancelled = true;\n };\n }, [code, lang]);\n\n const usable = usableHighlight(highlighted, code, lang);\n if (!usable) {\n return <pre {...props}>{code}</pre>;\n }\n\n const tail = code.slice(usable.code.length);\n let codeOffset = 0;\n\n return (\n <pre {...props}>\n <code>\n {usable.tokens.map((line, lineIndex) => {\n const lineOffset = codeOffset;\n let tokenOffset = lineOffset;\n const tokenSpans = line.map(token => {\n const key = tokenOffset;\n tokenOffset += token.content.length;\n\n return (\n <span key={key} className=\"shiki-token\" style={tokenStyle(token)}>\n {token.content}\n </span>\n );\n });\n\n codeOffset = tokenOffset + 1;\n\n return (\n <React.Fragment key={lineOffset}>\n <span>{tokenSpans}</span>\n {lineIndex !== usable.tokens.length - 1 && '\\n'}\n </React.Fragment>\n );\n })}\n {tail}\n </code>\n </pre>\n );\n});\n"],"names":["React","Code","highlight","jsx","jsxs"],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { h as highlight } from './highlight-CSJjjoqh.js';
|
|
4
|
+
|
|
5
|
+
function tokenStyle(token) {
|
|
6
|
+
if (token.htmlStyle && typeof token.htmlStyle === "object") {
|
|
7
|
+
return token.htmlStyle;
|
|
8
|
+
}
|
|
9
|
+
return token.color ? { color: token.color } : void 0;
|
|
10
|
+
}
|
|
11
|
+
function usableHighlight(highlighted, code, lang) {
|
|
12
|
+
if (!highlighted || highlighted.lang !== lang) return null;
|
|
13
|
+
return code.startsWith(highlighted.code) ? highlighted : null;
|
|
14
|
+
}
|
|
15
|
+
const Code = React.memo(function Code2({ code, lang, ...props }) {
|
|
16
|
+
const [highlighted, setHighlighted] = React.useState(null);
|
|
17
|
+
React.useEffect(() => {
|
|
18
|
+
if (!lang) {
|
|
19
|
+
setHighlighted(null);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
let cancelled = false;
|
|
23
|
+
void highlight(code, lang).then((tokens) => {
|
|
24
|
+
if (!cancelled && tokens?.length) setHighlighted({ code, lang, tokens });
|
|
25
|
+
}).catch(() => {
|
|
26
|
+
});
|
|
27
|
+
return () => {
|
|
28
|
+
cancelled = true;
|
|
29
|
+
};
|
|
30
|
+
}, [code, lang]);
|
|
31
|
+
const usable = usableHighlight(highlighted, code, lang);
|
|
32
|
+
if (!usable) {
|
|
33
|
+
return /* @__PURE__ */ jsx("pre", { ...props, children: code });
|
|
34
|
+
}
|
|
35
|
+
const tail = code.slice(usable.code.length);
|
|
36
|
+
let codeOffset = 0;
|
|
37
|
+
return /* @__PURE__ */ jsx("pre", { ...props, children: /* @__PURE__ */ jsxs("code", { children: [
|
|
38
|
+
usable.tokens.map((line, lineIndex) => {
|
|
39
|
+
const lineOffset = codeOffset;
|
|
40
|
+
let tokenOffset = lineOffset;
|
|
41
|
+
const tokenSpans = line.map((token) => {
|
|
42
|
+
const key = tokenOffset;
|
|
43
|
+
tokenOffset += token.content.length;
|
|
44
|
+
return /* @__PURE__ */ jsx("span", { className: "shiki-token", style: tokenStyle(token), children: token.content }, key);
|
|
45
|
+
});
|
|
46
|
+
codeOffset = tokenOffset + 1;
|
|
47
|
+
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
48
|
+
/* @__PURE__ */ jsx("span", { children: tokenSpans }),
|
|
49
|
+
lineIndex !== usable.tokens.length - 1 && "\n"
|
|
50
|
+
] }, lineOffset);
|
|
51
|
+
}),
|
|
52
|
+
tail
|
|
53
|
+
] }) });
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
export { Code as C };
|
|
57
|
+
//# sourceMappingURL=code-DRGJVroV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-DRGJVroV.js","sources":["../src/ds/components/Code/code.tsx"],"sourcesContent":["import * as React from 'react';\nimport type { ThemedToken } from 'shiki/core';\n\nimport { highlight } from '../CodeEditor/highlight';\n\nexport interface CodeProps extends React.HTMLAttributes<HTMLPreElement> {\n code: string;\n lang?: string;\n}\n\nfunction tokenStyle(token: ThemedToken): React.CSSProperties | undefined {\n if (token.htmlStyle && typeof token.htmlStyle === 'object') {\n return token.htmlStyle as React.CSSProperties;\n }\n\n return token.color ? { color: token.color } : undefined;\n}\n\ninterface Highlighted {\n code: string;\n lang: string;\n tokens: ThemedToken[][];\n}\n\n/** Colors from an earlier pass still hold when the new code only appends to the old. */\nfunction usableHighlight(highlighted: Highlighted | null, code: string, lang?: string): Highlighted | null {\n if (!highlighted || highlighted.lang !== lang) return null;\n return code.startsWith(highlighted.code) ? highlighted : null;\n}\n\n/**\n * Low-level shiki token renderer shared by `CodeBlock` and `MarkdownRenderer`.\n * Dual-theme colors stay as `--shiki-light` / `--shiki-dark` CSS variables on\n * each token span; the `.shiki-token` class (index.css) picks the variant from\n * the `.dark` root class, so theme switching is pure CSS — no ThemeProvider\n * required. Renders plain text while highlighting is pending or when the\n * language is missing/unknown.\n *\n * A streaming fence re-renders on every delta while highlighting stays a frame\n * behind. Dropping the previous tokens each time would strobe the whole block\n * between colored and plain, so the settled prefix keeps its colors and only\n * the newly arrived tail waits, uncolored, for the next pass.\n */\nexport const Code = React.memo(function Code({ code, lang, ...props }: CodeProps) {\n const [highlighted, setHighlighted] = React.useState<Highlighted | null>(null);\n\n React.useEffect(() => {\n if (!lang) {\n setHighlighted(null);\n return;\n }\n\n let cancelled = false;\n\n void highlight(code, lang)\n .then(tokens => {\n if (!cancelled && tokens?.length) setHighlighted({ code, lang, tokens });\n })\n .catch(() => {});\n\n return () => {\n cancelled = true;\n };\n }, [code, lang]);\n\n const usable = usableHighlight(highlighted, code, lang);\n if (!usable) {\n return <pre {...props}>{code}</pre>;\n }\n\n const tail = code.slice(usable.code.length);\n let codeOffset = 0;\n\n return (\n <pre {...props}>\n <code>\n {usable.tokens.map((line, lineIndex) => {\n const lineOffset = codeOffset;\n let tokenOffset = lineOffset;\n const tokenSpans = line.map(token => {\n const key = tokenOffset;\n tokenOffset += token.content.length;\n\n return (\n <span key={key} className=\"shiki-token\" style={tokenStyle(token)}>\n {token.content}\n </span>\n );\n });\n\n codeOffset = tokenOffset + 1;\n\n return (\n <React.Fragment key={lineOffset}>\n <span>{tokenSpans}</span>\n {lineIndex !== usable.tokens.length - 1 && '\\n'}\n </React.Fragment>\n );\n })}\n {tail}\n </code>\n </pre>\n );\n});\n"],"names":["Code"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const jsxRuntime = require('react/jsx-runtime');
|
|
4
|
-
const code = require('./code-
|
|
4
|
+
const code = require('./code-BJMC6T9D.cjs');
|
|
5
5
|
const copyButton = require('./copy-button-BfawWA4t.cjs');
|
|
6
6
|
const select = require('./select-OAXqZLkC.cjs');
|
|
7
7
|
const tabsRoot = require('./tabs-root-VtBc6K2q.cjs');
|
|
@@ -85,4 +85,4 @@ function CodeBlock({
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
exports.CodeBlock = CodeBlock;
|
|
88
|
-
//# sourceMappingURL=code-block-
|
|
88
|
+
//# sourceMappingURL=code-block-BZUY8Fj9.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-block-
|
|
1
|
+
{"version":3,"file":"code-block-BZUY8Fj9.cjs","sources":["../src/ds/components/CodeBlock/code-block.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport { Code } from '../Code/code';\nimport { CopyButton } from '../CopyButton/copy-button';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../Select/select';\nimport { TabList } from '../Tabs/tabs-list';\nimport { Tabs } from '../Tabs/tabs-root';\nimport { Tab } from '../Tabs/tabs-tab';\nimport { transitions } from '@/ds/primitives/transitions';\nimport { cn } from '@/lib/utils';\n\nexport type CodeBlockSelector = 'select' | 'tabs';\n\nexport type CodeBlockOverflow = 'wrap' | 'scroll';\n\nexport interface CodeBlockOption {\n label: string;\n value: string;\n}\n\nexport interface CodeBlockProps {\n code: string;\n options?: CodeBlockOption[];\n value?: string;\n onValueChange?: (value: string) => void;\n selector?: CodeBlockSelector;\n fileName?: string;\n lang?: string;\n /** `wrap` (default) breaks long lines — best for commands and snippets.\n * `scroll` preserves columns behind a horizontal scroll — best for source code. */\n overflow?: CodeBlockOverflow;\n copyMessage?: string;\n copyTooltip?: string;\n actions?: ReactNode;\n className?: string;\n}\n\nexport function CodeBlock({\n code,\n options,\n value,\n onValueChange,\n selector = 'select',\n fileName,\n lang,\n overflow = 'wrap',\n copyMessage,\n copyTooltip,\n actions,\n className,\n}: CodeBlockProps) {\n const hasOptions = options && options.length > 0;\n const useTabs = hasOptions && selector === 'tabs';\n const useSelect = hasOptions && selector === 'select';\n const firstOption = options?.[0];\n const activeValue = value ?? firstOption?.value;\n\n return (\n <figure\n className={cn(\n 'group relative flex w-full flex-col overflow-hidden rounded-2xl border border-border2/40 bg-surface2',\n className,\n )}\n >\n {useTabs && firstOption && (\n <Tabs defaultTab={firstOption.value} value={activeValue} onValueChange={onValueChange ?? (() => {})}>\n <div className=\"flex items-stretch\">\n <div className=\"min-w-0 flex-1\">\n <TabList>\n {options.map(opt => (\n <Tab key={opt.value} value={opt.value}>\n {opt.label}\n </Tab>\n ))}\n </TabList>\n </div>\n {actions && <div className=\"border-border1 flex shrink-0 items-center border-b pr-2 pl-3\">{actions}</div>}\n </div>\n </Tabs>\n )}\n\n {useSelect && options && (\n <div className=\"border-border2/40 flex items-center border-b px-2 py-1.5\">\n <Select value={activeValue} onValueChange={onValueChange}>\n <SelectTrigger size=\"sm\" variant=\"ghost\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {options.map(opt => (\n <SelectItem key={opt.value} value={opt.value}>\n {opt.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {actions && <div className=\"ml-auto flex items-center\">{actions}</div>}\n </div>\n )}\n\n {!hasOptions && fileName && (\n <div className=\"border-border2/40 flex items-center border-b px-4 py-2\">\n <figcaption className=\"text-ui-sm text-neutral4 font-mono\">{fileName}</figcaption>\n {actions && <div className=\"ml-auto flex items-center\">{actions}</div>}\n </div>\n )}\n\n {!hasOptions && !fileName && actions && (\n <div className=\"border-border2/40 flex items-center justify-end border-b px-2 py-1.5\">{actions}</div>\n )}\n\n <div className=\"relative\">\n <Code\n code={code}\n lang={lang}\n className={cn(\n 'px-4 py-3 font-mono text-ui-sm text-neutral5',\n overflow === 'scroll' ? 'overflow-x-auto whitespace-pre' : 'break-all whitespace-pre-wrap',\n )}\n />\n <CopyButton\n content={code}\n copyMessage={copyMessage}\n tooltip={copyTooltip}\n size=\"sm\"\n className={cn(\n 'absolute top-2 right-2 opacity-100 group-focus-within:opacity-100 group-hover:opacity-100 pointer-fine:opacity-0',\n transitions.opacity,\n )}\n />\n </div>\n </figure>\n );\n}\n"],"names":["code","jsxs","cn","jsx","Tabs","TabList","Tab","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","Code","CopyButton","transitions"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { C as Code } from './code-
|
|
2
|
+
import { C as Code } from './code-DRGJVroV.js';
|
|
3
3
|
import { C as CopyButton } from './copy-button-BLGUkVE8.js';
|
|
4
4
|
import { S as Select, d as SelectTrigger, e as SelectValue, a as SelectContent, c as SelectItem } from './select-B_E0ADD5.js';
|
|
5
5
|
import { a as Tabs, T as TabList } from './tabs-root-BBPou4QC.js';
|
|
@@ -83,4 +83,4 @@ function CodeBlock({
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
export { CodeBlock as C };
|
|
86
|
-
//# sourceMappingURL=code-block-
|
|
86
|
+
//# sourceMappingURL=code-block-V4wpmbud.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-block-
|
|
1
|
+
{"version":3,"file":"code-block-V4wpmbud.js","sources":["../src/ds/components/CodeBlock/code-block.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport { Code } from '../Code/code';\nimport { CopyButton } from '../CopyButton/copy-button';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../Select/select';\nimport { TabList } from '../Tabs/tabs-list';\nimport { Tabs } from '../Tabs/tabs-root';\nimport { Tab } from '../Tabs/tabs-tab';\nimport { transitions } from '@/ds/primitives/transitions';\nimport { cn } from '@/lib/utils';\n\nexport type CodeBlockSelector = 'select' | 'tabs';\n\nexport type CodeBlockOverflow = 'wrap' | 'scroll';\n\nexport interface CodeBlockOption {\n label: string;\n value: string;\n}\n\nexport interface CodeBlockProps {\n code: string;\n options?: CodeBlockOption[];\n value?: string;\n onValueChange?: (value: string) => void;\n selector?: CodeBlockSelector;\n fileName?: string;\n lang?: string;\n /** `wrap` (default) breaks long lines — best for commands and snippets.\n * `scroll` preserves columns behind a horizontal scroll — best for source code. */\n overflow?: CodeBlockOverflow;\n copyMessage?: string;\n copyTooltip?: string;\n actions?: ReactNode;\n className?: string;\n}\n\nexport function CodeBlock({\n code,\n options,\n value,\n onValueChange,\n selector = 'select',\n fileName,\n lang,\n overflow = 'wrap',\n copyMessage,\n copyTooltip,\n actions,\n className,\n}: CodeBlockProps) {\n const hasOptions = options && options.length > 0;\n const useTabs = hasOptions && selector === 'tabs';\n const useSelect = hasOptions && selector === 'select';\n const firstOption = options?.[0];\n const activeValue = value ?? firstOption?.value;\n\n return (\n <figure\n className={cn(\n 'group relative flex w-full flex-col overflow-hidden rounded-2xl border border-border2/40 bg-surface2',\n className,\n )}\n >\n {useTabs && firstOption && (\n <Tabs defaultTab={firstOption.value} value={activeValue} onValueChange={onValueChange ?? (() => {})}>\n <div className=\"flex items-stretch\">\n <div className=\"min-w-0 flex-1\">\n <TabList>\n {options.map(opt => (\n <Tab key={opt.value} value={opt.value}>\n {opt.label}\n </Tab>\n ))}\n </TabList>\n </div>\n {actions && <div className=\"border-border1 flex shrink-0 items-center border-b pr-2 pl-3\">{actions}</div>}\n </div>\n </Tabs>\n )}\n\n {useSelect && options && (\n <div className=\"border-border2/40 flex items-center border-b px-2 py-1.5\">\n <Select value={activeValue} onValueChange={onValueChange}>\n <SelectTrigger size=\"sm\" variant=\"ghost\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {options.map(opt => (\n <SelectItem key={opt.value} value={opt.value}>\n {opt.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {actions && <div className=\"ml-auto flex items-center\">{actions}</div>}\n </div>\n )}\n\n {!hasOptions && fileName && (\n <div className=\"border-border2/40 flex items-center border-b px-4 py-2\">\n <figcaption className=\"text-ui-sm text-neutral4 font-mono\">{fileName}</figcaption>\n {actions && <div className=\"ml-auto flex items-center\">{actions}</div>}\n </div>\n )}\n\n {!hasOptions && !fileName && actions && (\n <div className=\"border-border2/40 flex items-center justify-end border-b px-2 py-1.5\">{actions}</div>\n )}\n\n <div className=\"relative\">\n <Code\n code={code}\n lang={lang}\n className={cn(\n 'px-4 py-3 font-mono text-ui-sm text-neutral5',\n overflow === 'scroll' ? 'overflow-x-auto whitespace-pre' : 'break-all whitespace-pre-wrap',\n )}\n />\n <CopyButton\n content={code}\n copyMessage={copyMessage}\n tooltip={copyTooltip}\n size=\"sm\"\n className={cn(\n 'absolute top-2 right-2 opacity-100 group-focus-within:opacity-100 group-hover:opacity-100 pointer-fine:opacity-0',\n transitions.opacity,\n )}\n />\n </div>\n </figure>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { C as Code } from '../code-
|
|
1
|
+
export { C as Code } from '../code-DRGJVroV.js';
|
|
2
2
|
//# sourceMappingURL=Code.es.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { C as CodeBlock } from '../code-block-
|
|
1
|
+
export { C as CodeBlock } from '../code-block-V4wpmbud.js';
|
|
2
2
|
//# sourceMappingURL=CodeBlock.es.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { M as MarkdownRenderer } from '../markdown-renderer-
|
|
1
|
+
export { M as MarkdownRenderer } from '../markdown-renderer-CB2WMnTG.js';
|
|
2
2
|
//# sourceMappingURL=MarkdownRenderer.es.js.map
|
|
@@ -21,6 +21,57 @@ function getStatusIcon(status) {
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
function PendingRing() {
|
|
25
|
+
return /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", className: "text-neutral2", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
26
|
+
"circle",
|
|
27
|
+
{
|
|
28
|
+
cx: "12",
|
|
29
|
+
cy: "12",
|
|
30
|
+
r: "8.5",
|
|
31
|
+
pathLength: "48",
|
|
32
|
+
fill: "none",
|
|
33
|
+
stroke: "currentcolor",
|
|
34
|
+
strokeWidth: "2.8",
|
|
35
|
+
strokeLinecap: "round",
|
|
36
|
+
strokeDasharray: "3 3"
|
|
37
|
+
}
|
|
38
|
+
) });
|
|
39
|
+
}
|
|
40
|
+
function StepStatusMarker({ status, variant }) {
|
|
41
|
+
if (variant === "plain") {
|
|
42
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
43
|
+
"span",
|
|
44
|
+
{
|
|
45
|
+
className: utils_cn.cn("flex size-4 items-center justify-center self-center [&>svg]:size-4", primitives_transitions.transitions.colors, {
|
|
46
|
+
"[&>svg]:text-positive1": status === "success",
|
|
47
|
+
"[&>svg]:text-negative1": status === "failed"
|
|
48
|
+
}),
|
|
49
|
+
children: status === "pending" ? /* @__PURE__ */ jsxRuntime.jsx(PendingRing, {}) : getStatusIcon(status)
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
54
|
+
"span",
|
|
55
|
+
{
|
|
56
|
+
className: utils_cn.cn(
|
|
57
|
+
"flex size-7 items-center justify-center self-center rounded-full motion-reduce:transition-none",
|
|
58
|
+
primitives_transitions.transitions.colors,
|
|
59
|
+
primitives_transitions.transitions.transform,
|
|
60
|
+
primitives_transitions.transitions.shadow,
|
|
61
|
+
{
|
|
62
|
+
"[&>svg]:text-notice-success-fg": status === "success",
|
|
63
|
+
"[&>svg]:text-notice-destructive-fg": status === "failed",
|
|
64
|
+
"border border-dashed border-neutral2": status === "pending",
|
|
65
|
+
"[&>svg]:size-4": status !== "running",
|
|
66
|
+
"bg-accent1Dark shadow-glow-accent1": status === "success",
|
|
67
|
+
"bg-accent2Dark shadow-glow-accent2": status === "failed",
|
|
68
|
+
"scale-110": status === "success" || status === "failed"
|
|
69
|
+
}
|
|
70
|
+
),
|
|
71
|
+
children: getStatusIcon(status)
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
}
|
|
24
75
|
function ProcessStepListItem({ step, isActive, position, variant = "default" }) {
|
|
25
76
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
26
77
|
"div",
|
|
@@ -62,27 +113,7 @@ function ProcessStepListItem({ step, isActive, position, variant = "default" })
|
|
|
62
113
|
step.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: utils_cn.cn("-mt-0.5 text-ui-md text-neutral2", { truncate: variant === "plain" }), children: step.description })
|
|
63
114
|
] })
|
|
64
115
|
] }),
|
|
65
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
66
|
-
"div",
|
|
67
|
-
{
|
|
68
|
-
className: utils_cn.cn(
|
|
69
|
-
"flex size-7 items-center justify-center self-center rounded-full motion-reduce:transition-none",
|
|
70
|
-
primitives_transitions.transitions.colors,
|
|
71
|
-
primitives_transitions.transitions.transform,
|
|
72
|
-
primitives_transitions.transitions.shadow,
|
|
73
|
-
{
|
|
74
|
-
"border border-dashed border-neutral2": step.status === "pending",
|
|
75
|
-
"[&>svg]:size-4": step.status !== "running",
|
|
76
|
-
"[&>svg]:text-notice-success-fg": step.status === "success",
|
|
77
|
-
"[&>svg]:text-notice-destructive-fg": step.status === "failed",
|
|
78
|
-
"bg-accent1Dark shadow-glow-accent1": step.status === "success",
|
|
79
|
-
"bg-accent2Dark shadow-glow-accent2": step.status === "failed",
|
|
80
|
-
"scale-110": step.status === "success" || step.status === "failed"
|
|
81
|
-
}
|
|
82
|
-
),
|
|
83
|
-
children: getStatusIcon(step.status)
|
|
84
|
-
}
|
|
85
|
-
)
|
|
116
|
+
/* @__PURE__ */ jsxRuntime.jsx(StepStatusMarker, { status: step.status, variant })
|
|
86
117
|
]
|
|
87
118
|
}
|
|
88
119
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Steps.cjs.js","sources":["../../src/ds/components/Steps/shared.tsx","../../src/ds/components/Steps/process-step-list-item.tsx","../../src/ds/components/Steps/process-step-list.tsx","../../src/ds/components/Steps/process-step-progress-bar.tsx"],"sourcesContent":["import { CheckIcon, XIcon } from 'lucide-react';\nimport { Spinner } from '@/ds/components/Spinner';\n\nexport function getStatusIcon(status: string) {\n switch (status) {\n case 'running':\n return <Spinner size=\"sm\" aria-hidden />;\n case 'success':\n return <CheckIcon aria-hidden />;\n case 'failed':\n return <XIcon aria-hidden />;\n default:\n return null;\n }\n}\n\nexport type ProcessStep = {\n id: string;\n status: string;\n description: string;\n title: string;\n isActive: boolean;\n};\n","import { getStatusIcon } from './shared';\nimport type { ProcessStep } from './shared';\nimport { transitions } from '@/ds/primitives/transitions';\nimport { cn } from '@/lib/utils';\n\ntype ProcessStepListItemVariant = 'default' | 'plain';\n\nexport type ProcessStepListItemProps = {\n /** @deprecated Ignored — the heading comes from `step.title`. */\n stepId?: string;\n step: ProcessStep;\n isActive: boolean;\n position: number;\n variant?: ProcessStepListItemVariant;\n};\n\nexport function ProcessStepListItem({ step, isActive, position, variant = 'default' }: ProcessStepListItemProps) {\n return (\n <div\n className={cn(\n 'grid grid-cols-[1fr_auto] gap-6 rounded-lg px-4 py-3 motion-reduce:transition-none',\n transitions.colors,\n {\n 'border border-transparent': variant === 'default',\n 'border-dashed border-neutral2 bg-surface3': isActive && variant === 'default',\n },\n )}\n >\n <div className=\"grid min-w-0 grid-cols-[auto_1fr] gap-2\">\n <span\n className={cn('flex min-w-6 justify-end text-ui-md', transitions.colors, {\n 'text-neutral5': isActive || step.status === 'success',\n 'text-neutral3': !isActive && step.status !== 'success',\n })}\n >\n {position}.\n </span>\n <div className=\"min-w-0\">\n <h4\n className={cn('text-ui-md', transitions.colors, {\n 'text-neutral5': isActive || step.status === 'success',\n 'text-neutral3': !isActive && step.status !== 'success',\n })}\n >\n {step.title}\n </h4>\n {step.description && (\n <p className={cn('-mt-0.5 text-ui-md text-neutral2', { truncate: variant === 'plain' })}>\n {step.description}\n </p>\n )}\n </div>\n </div>\n <div\n className={cn(\n 'flex size-7 items-center justify-center self-center rounded-full motion-reduce:transition-none',\n transitions.colors,\n transitions.transform,\n transitions.shadow,\n {\n 'border border-dashed border-neutral2': step.status === 'pending',\n '[&>svg]:size-4': step.status !== 'running',\n '[&>svg]:text-notice-success-fg': step.status === 'success',\n '[&>svg]:text-notice-destructive-fg': step.status === 'failed',\n 'bg-accent1Dark shadow-glow-accent1': step.status === 'success',\n 'bg-accent2Dark shadow-glow-accent2': step.status === 'failed',\n 'scale-110': step.status === 'success' || step.status === 'failed',\n },\n )}\n >\n {getStatusIcon(step.status)}\n </div>\n </div>\n );\n}\n","import { ProcessStepListItem } from './process-step-list-item';\nimport type { ProcessStep } from './shared';\nimport { cn } from '@/lib/utils';\n\nexport type ProcessStepListProps = {\n currentStep: ProcessStep | null;\n steps: ProcessStep[];\n className?: string;\n};\n\nexport function ProcessStepList({ currentStep, steps = [], className }: ProcessStepListProps) {\n return (\n <div className={cn(className)}>\n {steps.map((step: ProcessStep, idx: number) => (\n <ProcessStepListItem key={step.id} step={step} isActive={currentStep?.id === step.id} position={idx + 1} />\n ))}\n </div>\n );\n}\n","import type { ProcessStep } from './shared';\nimport { Spinner } from '@/ds/components/Spinner';\nimport { transitions } from '@/ds/primitives/transitions';\nimport { cn } from '@/lib/utils';\n\nexport type ProcessStepProgressBarProps = {\n steps: ProcessStep[];\n};\n\nexport function ProcessStepProgressBar({ steps }: ProcessStepProgressBarProps) {\n const totalSteps = steps.length;\n const completedSteps = steps.filter(step => step.status === 'success').length;\n\n return (\n <div className=\"flex w-full flex-col content-center justify-center gap-4\">\n <div className=\"grid w-full grid-cols-[0_repeat(9,1fr)]\">\n {steps.map((step: ProcessStep, idx: number) => {\n return (\n <div\n key={step.id}\n className={cn('relative flex h-8 items-center justify-end', transitions.colors, {\n 'bg-accent1Dark': step.status === 'success' && steps?.[idx - 1]?.status === 'success',\n })}\n >\n <div\n className={cn(\n 'absolute right-0 z-10 flex size-8 translate-x-1/2 items-center justify-center self-center rounded-full bg-surface3 text-ui-sm font-bold text-neutral3 motion-reduce:transition-none',\n transitions.colors,\n transitions.transform,\n transitions.shadow,\n {\n 'border border-dashed border-neutral2': step.status === 'pending',\n 'bg-accent1Dark text-notice-success-fg shadow-glow-accent1 scale-110': step.status === 'success',\n 'bg-accent2Dark text-notice-destructive-fg shadow-glow-accent2 scale-110': step.status === 'failed',\n },\n )}\n >\n {step.status === 'running' ? <Spinner /> : idx + 1}\n </div>\n </div>\n );\n })}\n </div>\n <div className={cn('text-center text-xs text-neutral3', transitions.colors)}>\n {completedSteps} of {totalSteps} steps completed\n </div>\n </div>\n );\n}\n"],"names":["jsx","Spinner","CheckIcon","XIcon","jsxs","cn","transitions"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Steps.cjs.js","sources":["../../src/ds/components/Steps/shared.tsx","../../src/ds/components/Steps/process-step-list-item.tsx","../../src/ds/components/Steps/process-step-list.tsx","../../src/ds/components/Steps/process-step-progress-bar.tsx"],"sourcesContent":["import { CheckIcon, XIcon } from 'lucide-react';\nimport { Spinner } from '@/ds/components/Spinner';\n\nexport function getStatusIcon(status: string) {\n switch (status) {\n case 'running':\n return <Spinner size=\"sm\" aria-hidden />;\n case 'success':\n return <CheckIcon aria-hidden />;\n case 'failed':\n return <XIcon aria-hidden />;\n default:\n return null;\n }\n}\n\nexport type ProcessStep = {\n id: string;\n status: string;\n description: string;\n title: string;\n isActive: boolean;\n};\n","import { getStatusIcon } from './shared';\nimport type { ProcessStep } from './shared';\nimport { transitions } from '@/ds/primitives/transitions';\nimport { cn } from '@/lib/utils';\n\ntype ProcessStepListItemVariant = 'default' | 'plain';\n\n/** Same ring geometry and stroke as `<Spinner size=\"sm\" />`, so pending and running read as one shape. */\nfunction PendingRing() {\n return (\n <svg viewBox=\"0 0 24 24\" className=\"text-neutral2\" aria-hidden>\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"8.5\"\n pathLength=\"48\"\n fill=\"none\"\n stroke=\"currentcolor\"\n strokeWidth=\"2.8\"\n strokeLinecap=\"round\"\n strokeDasharray=\"3 3\"\n />\n </svg>\n );\n}\n\nfunction StepStatusMarker({ status, variant }: { status: string; variant: ProcessStepListItemVariant }) {\n if (variant === 'plain') {\n return (\n <span\n className={cn('flex size-4 items-center justify-center self-center [&>svg]:size-4', transitions.colors, {\n '[&>svg]:text-positive1': status === 'success',\n '[&>svg]:text-negative1': status === 'failed',\n })}\n >\n {status === 'pending' ? <PendingRing /> : getStatusIcon(status)}\n </span>\n );\n }\n\n return (\n <span\n className={cn(\n 'flex size-7 items-center justify-center self-center rounded-full motion-reduce:transition-none',\n transitions.colors,\n transitions.transform,\n transitions.shadow,\n {\n '[&>svg]:text-notice-success-fg': status === 'success',\n '[&>svg]:text-notice-destructive-fg': status === 'failed',\n 'border border-dashed border-neutral2': status === 'pending',\n '[&>svg]:size-4': status !== 'running',\n 'bg-accent1Dark shadow-glow-accent1': status === 'success',\n 'bg-accent2Dark shadow-glow-accent2': status === 'failed',\n 'scale-110': status === 'success' || status === 'failed',\n },\n )}\n >\n {getStatusIcon(status)}\n </span>\n );\n}\n\nexport type ProcessStepListItemProps = {\n /** @deprecated Ignored — the heading comes from `step.title`. */\n stepId?: string;\n step: ProcessStep;\n isActive: boolean;\n position: number;\n variant?: ProcessStepListItemVariant;\n};\n\nexport function ProcessStepListItem({ step, isActive, position, variant = 'default' }: ProcessStepListItemProps) {\n return (\n <div\n className={cn(\n 'grid grid-cols-[1fr_auto] gap-6 rounded-lg px-4 py-3 motion-reduce:transition-none',\n transitions.colors,\n {\n 'border border-transparent': variant === 'default',\n 'border-dashed border-neutral2 bg-surface3': isActive && variant === 'default',\n },\n )}\n >\n <div className=\"grid min-w-0 grid-cols-[auto_1fr] gap-2\">\n <span\n className={cn('flex min-w-6 justify-end text-ui-md', transitions.colors, {\n 'text-neutral5': isActive || step.status === 'success',\n 'text-neutral3': !isActive && step.status !== 'success',\n })}\n >\n {position}.\n </span>\n <div className=\"min-w-0\">\n <h4\n className={cn('text-ui-md', transitions.colors, {\n 'text-neutral5': isActive || step.status === 'success',\n 'text-neutral3': !isActive && step.status !== 'success',\n })}\n >\n {step.title}\n </h4>\n {step.description && (\n <p className={cn('-mt-0.5 text-ui-md text-neutral2', { truncate: variant === 'plain' })}>\n {step.description}\n </p>\n )}\n </div>\n </div>\n <StepStatusMarker status={step.status} variant={variant} />\n </div>\n );\n}\n","import { ProcessStepListItem } from './process-step-list-item';\nimport type { ProcessStep } from './shared';\nimport { cn } from '@/lib/utils';\n\nexport type ProcessStepListProps = {\n currentStep: ProcessStep | null;\n steps: ProcessStep[];\n className?: string;\n};\n\nexport function ProcessStepList({ currentStep, steps = [], className }: ProcessStepListProps) {\n return (\n <div className={cn(className)}>\n {steps.map((step: ProcessStep, idx: number) => (\n <ProcessStepListItem key={step.id} step={step} isActive={currentStep?.id === step.id} position={idx + 1} />\n ))}\n </div>\n );\n}\n","import type { ProcessStep } from './shared';\nimport { Spinner } from '@/ds/components/Spinner';\nimport { transitions } from '@/ds/primitives/transitions';\nimport { cn } from '@/lib/utils';\n\nexport type ProcessStepProgressBarProps = {\n steps: ProcessStep[];\n};\n\nexport function ProcessStepProgressBar({ steps }: ProcessStepProgressBarProps) {\n const totalSteps = steps.length;\n const completedSteps = steps.filter(step => step.status === 'success').length;\n\n return (\n <div className=\"flex w-full flex-col content-center justify-center gap-4\">\n <div className=\"grid w-full grid-cols-[0_repeat(9,1fr)]\">\n {steps.map((step: ProcessStep, idx: number) => {\n return (\n <div\n key={step.id}\n className={cn('relative flex h-8 items-center justify-end', transitions.colors, {\n 'bg-accent1Dark': step.status === 'success' && steps?.[idx - 1]?.status === 'success',\n })}\n >\n <div\n className={cn(\n 'absolute right-0 z-10 flex size-8 translate-x-1/2 items-center justify-center self-center rounded-full bg-surface3 text-ui-sm font-bold text-neutral3 motion-reduce:transition-none',\n transitions.colors,\n transitions.transform,\n transitions.shadow,\n {\n 'border border-dashed border-neutral2': step.status === 'pending',\n 'bg-accent1Dark text-notice-success-fg shadow-glow-accent1 scale-110': step.status === 'success',\n 'bg-accent2Dark text-notice-destructive-fg shadow-glow-accent2 scale-110': step.status === 'failed',\n },\n )}\n >\n {step.status === 'running' ? <Spinner /> : idx + 1}\n </div>\n </div>\n );\n })}\n </div>\n <div className={cn('text-center text-xs text-neutral3', transitions.colors)}>\n {completedSteps} of {totalSteps} steps completed\n </div>\n </div>\n );\n}\n"],"names":["jsx","Spinner","CheckIcon","XIcon","cn","transitions","jsxs"],"mappings":"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"}
|
|
@@ -17,6 +17,57 @@ function getStatusIcon(status) {
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
function PendingRing() {
|
|
21
|
+
return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", className: "text-neutral2", "aria-hidden": true, children: /* @__PURE__ */ jsx(
|
|
22
|
+
"circle",
|
|
23
|
+
{
|
|
24
|
+
cx: "12",
|
|
25
|
+
cy: "12",
|
|
26
|
+
r: "8.5",
|
|
27
|
+
pathLength: "48",
|
|
28
|
+
fill: "none",
|
|
29
|
+
stroke: "currentcolor",
|
|
30
|
+
strokeWidth: "2.8",
|
|
31
|
+
strokeLinecap: "round",
|
|
32
|
+
strokeDasharray: "3 3"
|
|
33
|
+
}
|
|
34
|
+
) });
|
|
35
|
+
}
|
|
36
|
+
function StepStatusMarker({ status, variant }) {
|
|
37
|
+
if (variant === "plain") {
|
|
38
|
+
return /* @__PURE__ */ jsx(
|
|
39
|
+
"span",
|
|
40
|
+
{
|
|
41
|
+
className: cn("flex size-4 items-center justify-center self-center [&>svg]:size-4", transitions.colors, {
|
|
42
|
+
"[&>svg]:text-positive1": status === "success",
|
|
43
|
+
"[&>svg]:text-negative1": status === "failed"
|
|
44
|
+
}),
|
|
45
|
+
children: status === "pending" ? /* @__PURE__ */ jsx(PendingRing, {}) : getStatusIcon(status)
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
return /* @__PURE__ */ jsx(
|
|
50
|
+
"span",
|
|
51
|
+
{
|
|
52
|
+
className: cn(
|
|
53
|
+
"flex size-7 items-center justify-center self-center rounded-full motion-reduce:transition-none",
|
|
54
|
+
transitions.colors,
|
|
55
|
+
transitions.transform,
|
|
56
|
+
transitions.shadow,
|
|
57
|
+
{
|
|
58
|
+
"[&>svg]:text-notice-success-fg": status === "success",
|
|
59
|
+
"[&>svg]:text-notice-destructive-fg": status === "failed",
|
|
60
|
+
"border border-dashed border-neutral2": status === "pending",
|
|
61
|
+
"[&>svg]:size-4": status !== "running",
|
|
62
|
+
"bg-accent1Dark shadow-glow-accent1": status === "success",
|
|
63
|
+
"bg-accent2Dark shadow-glow-accent2": status === "failed",
|
|
64
|
+
"scale-110": status === "success" || status === "failed"
|
|
65
|
+
}
|
|
66
|
+
),
|
|
67
|
+
children: getStatusIcon(status)
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
}
|
|
20
71
|
function ProcessStepListItem({ step, isActive, position, variant = "default" }) {
|
|
21
72
|
return /* @__PURE__ */ jsxs(
|
|
22
73
|
"div",
|
|
@@ -58,27 +109,7 @@ function ProcessStepListItem({ step, isActive, position, variant = "default" })
|
|
|
58
109
|
step.description && /* @__PURE__ */ jsx("p", { className: cn("-mt-0.5 text-ui-md text-neutral2", { truncate: variant === "plain" }), children: step.description })
|
|
59
110
|
] })
|
|
60
111
|
] }),
|
|
61
|
-
/* @__PURE__ */ jsx(
|
|
62
|
-
"div",
|
|
63
|
-
{
|
|
64
|
-
className: cn(
|
|
65
|
-
"flex size-7 items-center justify-center self-center rounded-full motion-reduce:transition-none",
|
|
66
|
-
transitions.colors,
|
|
67
|
-
transitions.transform,
|
|
68
|
-
transitions.shadow,
|
|
69
|
-
{
|
|
70
|
-
"border border-dashed border-neutral2": step.status === "pending",
|
|
71
|
-
"[&>svg]:size-4": step.status !== "running",
|
|
72
|
-
"[&>svg]:text-notice-success-fg": step.status === "success",
|
|
73
|
-
"[&>svg]:text-notice-destructive-fg": step.status === "failed",
|
|
74
|
-
"bg-accent1Dark shadow-glow-accent1": step.status === "success",
|
|
75
|
-
"bg-accent2Dark shadow-glow-accent2": step.status === "failed",
|
|
76
|
-
"scale-110": step.status === "success" || step.status === "failed"
|
|
77
|
-
}
|
|
78
|
-
),
|
|
79
|
-
children: getStatusIcon(step.status)
|
|
80
|
-
}
|
|
81
|
-
)
|
|
112
|
+
/* @__PURE__ */ jsx(StepStatusMarker, { status: step.status, variant })
|
|
82
113
|
]
|
|
83
114
|
}
|
|
84
115
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Steps.es.js","sources":["../../src/ds/components/Steps/shared.tsx","../../src/ds/components/Steps/process-step-list-item.tsx","../../src/ds/components/Steps/process-step-list.tsx","../../src/ds/components/Steps/process-step-progress-bar.tsx"],"sourcesContent":["import { CheckIcon, XIcon } from 'lucide-react';\nimport { Spinner } from '@/ds/components/Spinner';\n\nexport function getStatusIcon(status: string) {\n switch (status) {\n case 'running':\n return <Spinner size=\"sm\" aria-hidden />;\n case 'success':\n return <CheckIcon aria-hidden />;\n case 'failed':\n return <XIcon aria-hidden />;\n default:\n return null;\n }\n}\n\nexport type ProcessStep = {\n id: string;\n status: string;\n description: string;\n title: string;\n isActive: boolean;\n};\n","import { getStatusIcon } from './shared';\nimport type { ProcessStep } from './shared';\nimport { transitions } from '@/ds/primitives/transitions';\nimport { cn } from '@/lib/utils';\n\ntype ProcessStepListItemVariant = 'default' | 'plain';\n\nexport type ProcessStepListItemProps = {\n /** @deprecated Ignored — the heading comes from `step.title`. */\n stepId?: string;\n step: ProcessStep;\n isActive: boolean;\n position: number;\n variant?: ProcessStepListItemVariant;\n};\n\nexport function ProcessStepListItem({ step, isActive, position, variant = 'default' }: ProcessStepListItemProps) {\n return (\n <div\n className={cn(\n 'grid grid-cols-[1fr_auto] gap-6 rounded-lg px-4 py-3 motion-reduce:transition-none',\n transitions.colors,\n {\n 'border border-transparent': variant === 'default',\n 'border-dashed border-neutral2 bg-surface3': isActive && variant === 'default',\n },\n )}\n >\n <div className=\"grid min-w-0 grid-cols-[auto_1fr] gap-2\">\n <span\n className={cn('flex min-w-6 justify-end text-ui-md', transitions.colors, {\n 'text-neutral5': isActive || step.status === 'success',\n 'text-neutral3': !isActive && step.status !== 'success',\n })}\n >\n {position}.\n </span>\n <div className=\"min-w-0\">\n <h4\n className={cn('text-ui-md', transitions.colors, {\n 'text-neutral5': isActive || step.status === 'success',\n 'text-neutral3': !isActive && step.status !== 'success',\n })}\n >\n {step.title}\n </h4>\n {step.description && (\n <p className={cn('-mt-0.5 text-ui-md text-neutral2', { truncate: variant === 'plain' })}>\n {step.description}\n </p>\n )}\n </div>\n </div>\n <div\n className={cn(\n 'flex size-7 items-center justify-center self-center rounded-full motion-reduce:transition-none',\n transitions.colors,\n transitions.transform,\n transitions.shadow,\n {\n 'border border-dashed border-neutral2': step.status === 'pending',\n '[&>svg]:size-4': step.status !== 'running',\n '[&>svg]:text-notice-success-fg': step.status === 'success',\n '[&>svg]:text-notice-destructive-fg': step.status === 'failed',\n 'bg-accent1Dark shadow-glow-accent1': step.status === 'success',\n 'bg-accent2Dark shadow-glow-accent2': step.status === 'failed',\n 'scale-110': step.status === 'success' || step.status === 'failed',\n },\n )}\n >\n {getStatusIcon(step.status)}\n </div>\n </div>\n );\n}\n","import { ProcessStepListItem } from './process-step-list-item';\nimport type { ProcessStep } from './shared';\nimport { cn } from '@/lib/utils';\n\nexport type ProcessStepListProps = {\n currentStep: ProcessStep | null;\n steps: ProcessStep[];\n className?: string;\n};\n\nexport function ProcessStepList({ currentStep, steps = [], className }: ProcessStepListProps) {\n return (\n <div className={cn(className)}>\n {steps.map((step: ProcessStep, idx: number) => (\n <ProcessStepListItem key={step.id} step={step} isActive={currentStep?.id === step.id} position={idx + 1} />\n ))}\n </div>\n );\n}\n","import type { ProcessStep } from './shared';\nimport { Spinner } from '@/ds/components/Spinner';\nimport { transitions } from '@/ds/primitives/transitions';\nimport { cn } from '@/lib/utils';\n\nexport type ProcessStepProgressBarProps = {\n steps: ProcessStep[];\n};\n\nexport function ProcessStepProgressBar({ steps }: ProcessStepProgressBarProps) {\n const totalSteps = steps.length;\n const completedSteps = steps.filter(step => step.status === 'success').length;\n\n return (\n <div className=\"flex w-full flex-col content-center justify-center gap-4\">\n <div className=\"grid w-full grid-cols-[0_repeat(9,1fr)]\">\n {steps.map((step: ProcessStep, idx: number) => {\n return (\n <div\n key={step.id}\n className={cn('relative flex h-8 items-center justify-end', transitions.colors, {\n 'bg-accent1Dark': step.status === 'success' && steps?.[idx - 1]?.status === 'success',\n })}\n >\n <div\n className={cn(\n 'absolute right-0 z-10 flex size-8 translate-x-1/2 items-center justify-center self-center rounded-full bg-surface3 text-ui-sm font-bold text-neutral3 motion-reduce:transition-none',\n transitions.colors,\n transitions.transform,\n transitions.shadow,\n {\n 'border border-dashed border-neutral2': step.status === 'pending',\n 'bg-accent1Dark text-notice-success-fg shadow-glow-accent1 scale-110': step.status === 'success',\n 'bg-accent2Dark text-notice-destructive-fg shadow-glow-accent2 scale-110': step.status === 'failed',\n },\n )}\n >\n {step.status === 'running' ? <Spinner /> : idx + 1}\n </div>\n </div>\n );\n })}\n </div>\n <div className={cn('text-center text-xs text-neutral3', transitions.colors)}>\n {completedSteps} of {totalSteps} steps completed\n </div>\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Steps.es.js","sources":["../../src/ds/components/Steps/shared.tsx","../../src/ds/components/Steps/process-step-list-item.tsx","../../src/ds/components/Steps/process-step-list.tsx","../../src/ds/components/Steps/process-step-progress-bar.tsx"],"sourcesContent":["import { CheckIcon, XIcon } from 'lucide-react';\nimport { Spinner } from '@/ds/components/Spinner';\n\nexport function getStatusIcon(status: string) {\n switch (status) {\n case 'running':\n return <Spinner size=\"sm\" aria-hidden />;\n case 'success':\n return <CheckIcon aria-hidden />;\n case 'failed':\n return <XIcon aria-hidden />;\n default:\n return null;\n }\n}\n\nexport type ProcessStep = {\n id: string;\n status: string;\n description: string;\n title: string;\n isActive: boolean;\n};\n","import { getStatusIcon } from './shared';\nimport type { ProcessStep } from './shared';\nimport { transitions } from '@/ds/primitives/transitions';\nimport { cn } from '@/lib/utils';\n\ntype ProcessStepListItemVariant = 'default' | 'plain';\n\n/** Same ring geometry and stroke as `<Spinner size=\"sm\" />`, so pending and running read as one shape. */\nfunction PendingRing() {\n return (\n <svg viewBox=\"0 0 24 24\" className=\"text-neutral2\" aria-hidden>\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"8.5\"\n pathLength=\"48\"\n fill=\"none\"\n stroke=\"currentcolor\"\n strokeWidth=\"2.8\"\n strokeLinecap=\"round\"\n strokeDasharray=\"3 3\"\n />\n </svg>\n );\n}\n\nfunction StepStatusMarker({ status, variant }: { status: string; variant: ProcessStepListItemVariant }) {\n if (variant === 'plain') {\n return (\n <span\n className={cn('flex size-4 items-center justify-center self-center [&>svg]:size-4', transitions.colors, {\n '[&>svg]:text-positive1': status === 'success',\n '[&>svg]:text-negative1': status === 'failed',\n })}\n >\n {status === 'pending' ? <PendingRing /> : getStatusIcon(status)}\n </span>\n );\n }\n\n return (\n <span\n className={cn(\n 'flex size-7 items-center justify-center self-center rounded-full motion-reduce:transition-none',\n transitions.colors,\n transitions.transform,\n transitions.shadow,\n {\n '[&>svg]:text-notice-success-fg': status === 'success',\n '[&>svg]:text-notice-destructive-fg': status === 'failed',\n 'border border-dashed border-neutral2': status === 'pending',\n '[&>svg]:size-4': status !== 'running',\n 'bg-accent1Dark shadow-glow-accent1': status === 'success',\n 'bg-accent2Dark shadow-glow-accent2': status === 'failed',\n 'scale-110': status === 'success' || status === 'failed',\n },\n )}\n >\n {getStatusIcon(status)}\n </span>\n );\n}\n\nexport type ProcessStepListItemProps = {\n /** @deprecated Ignored — the heading comes from `step.title`. */\n stepId?: string;\n step: ProcessStep;\n isActive: boolean;\n position: number;\n variant?: ProcessStepListItemVariant;\n};\n\nexport function ProcessStepListItem({ step, isActive, position, variant = 'default' }: ProcessStepListItemProps) {\n return (\n <div\n className={cn(\n 'grid grid-cols-[1fr_auto] gap-6 rounded-lg px-4 py-3 motion-reduce:transition-none',\n transitions.colors,\n {\n 'border border-transparent': variant === 'default',\n 'border-dashed border-neutral2 bg-surface3': isActive && variant === 'default',\n },\n )}\n >\n <div className=\"grid min-w-0 grid-cols-[auto_1fr] gap-2\">\n <span\n className={cn('flex min-w-6 justify-end text-ui-md', transitions.colors, {\n 'text-neutral5': isActive || step.status === 'success',\n 'text-neutral3': !isActive && step.status !== 'success',\n })}\n >\n {position}.\n </span>\n <div className=\"min-w-0\">\n <h4\n className={cn('text-ui-md', transitions.colors, {\n 'text-neutral5': isActive || step.status === 'success',\n 'text-neutral3': !isActive && step.status !== 'success',\n })}\n >\n {step.title}\n </h4>\n {step.description && (\n <p className={cn('-mt-0.5 text-ui-md text-neutral2', { truncate: variant === 'plain' })}>\n {step.description}\n </p>\n )}\n </div>\n </div>\n <StepStatusMarker status={step.status} variant={variant} />\n </div>\n );\n}\n","import { ProcessStepListItem } from './process-step-list-item';\nimport type { ProcessStep } from './shared';\nimport { cn } from '@/lib/utils';\n\nexport type ProcessStepListProps = {\n currentStep: ProcessStep | null;\n steps: ProcessStep[];\n className?: string;\n};\n\nexport function ProcessStepList({ currentStep, steps = [], className }: ProcessStepListProps) {\n return (\n <div className={cn(className)}>\n {steps.map((step: ProcessStep, idx: number) => (\n <ProcessStepListItem key={step.id} step={step} isActive={currentStep?.id === step.id} position={idx + 1} />\n ))}\n </div>\n );\n}\n","import type { ProcessStep } from './shared';\nimport { Spinner } from '@/ds/components/Spinner';\nimport { transitions } from '@/ds/primitives/transitions';\nimport { cn } from '@/lib/utils';\n\nexport type ProcessStepProgressBarProps = {\n steps: ProcessStep[];\n};\n\nexport function ProcessStepProgressBar({ steps }: ProcessStepProgressBarProps) {\n const totalSteps = steps.length;\n const completedSteps = steps.filter(step => step.status === 'success').length;\n\n return (\n <div className=\"flex w-full flex-col content-center justify-center gap-4\">\n <div className=\"grid w-full grid-cols-[0_repeat(9,1fr)]\">\n {steps.map((step: ProcessStep, idx: number) => {\n return (\n <div\n key={step.id}\n className={cn('relative flex h-8 items-center justify-end', transitions.colors, {\n 'bg-accent1Dark': step.status === 'success' && steps?.[idx - 1]?.status === 'success',\n })}\n >\n <div\n className={cn(\n 'absolute right-0 z-10 flex size-8 translate-x-1/2 items-center justify-center self-center rounded-full bg-surface3 text-ui-sm font-bold text-neutral3 motion-reduce:transition-none',\n transitions.colors,\n transitions.transform,\n transitions.shadow,\n {\n 'border border-dashed border-neutral2': step.status === 'pending',\n 'bg-accent1Dark text-notice-success-fg shadow-glow-accent1 scale-110': step.status === 'success',\n 'bg-accent2Dark text-notice-destructive-fg shadow-glow-accent2 scale-110': step.status === 'failed',\n },\n )}\n >\n {step.status === 'running' ? <Spinner /> : idx + 1}\n </div>\n </div>\n );\n })}\n </div>\n <div className={cn('text-center text-xs text-neutral3', transitions.colors)}>\n {completedSteps} of {totalSteps} steps completed\n </div>\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -7,7 +7,7 @@ const lucideReact = require('lucide-react');
|
|
|
7
7
|
const React = require('react');
|
|
8
8
|
const Badge = require('../../Badge-BlJpI3fY.cjs');
|
|
9
9
|
const Button = require('../../Button-B4Ixj2aW.cjs');
|
|
10
|
-
const markdownRenderer = require('../../markdown-renderer-
|
|
10
|
+
const markdownRenderer = require('../../markdown-renderer-DvJfqb-D.cjs');
|
|
11
11
|
const Txt = require('../../Txt-I5lK8zy7.cjs');
|
|
12
12
|
const icons_Icon = require('../../icons/Icon.cjs.js');
|
|
13
13
|
const hooks_useCopyToClipboard = require('../../hooks/use-copy-to-clipboard.cjs.js');
|
|
@@ -3,7 +3,7 @@ import { CheckIcon, CopyIcon, Minimize2, Maximize2, ClipboardList } from 'lucide
|
|
|
3
3
|
import { useState, createContext, useContext } from 'react';
|
|
4
4
|
import { B as Badge } from '../../Badge-woV6OD8k.js';
|
|
5
5
|
import { B as Button } from '../../Button-C-9Pzy-Z.js';
|
|
6
|
-
import { M as MarkdownRenderer } from '../../markdown-renderer-
|
|
6
|
+
import { M as MarkdownRenderer } from '../../markdown-renderer-CB2WMnTG.js';
|
|
7
7
|
import { T as Txt } from '../../Txt-Df42XG5p.js';
|
|
8
8
|
import { Icon } from '../../icons/Icon.es.js';
|
|
9
9
|
import { useCopyToClipboard } from '../../hooks/use-copy-to-clipboard.es.js';
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { memo } from 'react';
|
|
2
3
|
import Markdown from 'react-markdown';
|
|
3
4
|
import remarkGfm from 'remark-gfm';
|
|
4
|
-
import { C as CodeBlock } from './code-block-
|
|
5
|
+
import { C as CodeBlock } from './code-block-V4wpmbud.js';
|
|
5
6
|
import { c as cn } from './cn-BakJzhuv.js';
|
|
6
7
|
|
|
7
|
-
import './markdown-renderer.css';
|
|
8
|
+
import './markdown-renderer.css';const MarkdownRenderer = memo(function MarkdownRenderer2({
|
|
9
|
+
children,
|
|
10
|
+
className,
|
|
11
|
+
externalLinkTarget = "tab"
|
|
12
|
+
}) {
|
|
8
13
|
return /* @__PURE__ */ jsx(
|
|
9
14
|
Markdown,
|
|
10
15
|
{
|
|
@@ -14,7 +19,7 @@ import './markdown-renderer.css';function MarkdownRenderer({ children, className
|
|
|
14
19
|
children: decodeEscapedNewlines(children)
|
|
15
20
|
}
|
|
16
21
|
);
|
|
17
|
-
}
|
|
22
|
+
});
|
|
18
23
|
function decodeEscapedNewlines(text) {
|
|
19
24
|
return text.includes("\n") ? text : text.replace(/\\n/g, "\n");
|
|
20
25
|
}
|
|
@@ -81,4 +86,4 @@ const WINDOW_COMPONENTS = {
|
|
|
81
86
|
};
|
|
82
87
|
|
|
83
88
|
export { MarkdownRenderer as M };
|
|
84
|
-
//# sourceMappingURL=markdown-renderer-
|
|
89
|
+
//# sourceMappingURL=markdown-renderer-CB2WMnTG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown-renderer-CB2WMnTG.js","sources":["../src/ds/components/MarkdownRenderer/markdown-renderer.tsx"],"sourcesContent":["import { memo } from 'react';\nimport type { MouseEvent, MouseEventHandler, ReactNode } from 'react';\nimport Markdown from 'react-markdown';\nimport type { Components, ExtraProps } from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\n\nimport { CodeBlock } from '@/ds/components/CodeBlock';\nimport { cn } from '@/lib/utils';\n\nimport './markdown-renderer.css';\n\nexport type MarkdownExternalLinkTarget = 'tab' | 'window';\n\nexport interface MarkdownRendererProps {\n children: string;\n className?: string;\n externalLinkTarget?: MarkdownExternalLinkTarget;\n}\n\n/**\n * Renders a markdown string. Agent output can carry attacker-influenced text\n * (file contents, tool output, web pages): react-markdown escapes raw HTML and\n * drops dangerous link schemes, so nothing here reaches the DOM as markup.\n *\n * Memoized because react-markdown re-parses on every render and a streaming\n * reply re-renders its whole transcript on every delta: without this, each\n * chunk re-parses every settled message on the page as well as the live one.\n */\nexport const MarkdownRenderer = memo(function MarkdownRenderer({\n children,\n className,\n externalLinkTarget = 'tab',\n}: MarkdownRendererProps) {\n return (\n <Markdown\n remarkPlugins={[remarkGfm]}\n components={externalLinkTarget === 'window' ? WINDOW_COMPONENTS : COMPONENTS}\n className={cn('mastra-markdown', className)}\n >\n {decodeEscapedNewlines(children)}\n </Markdown>\n );\n});\n\n// Agent networks emit their text with literal `\\n`. Only unescape when the text\n// has no real newline, otherwise a `\"a\\nb\"` inside a code fence gets shredded.\nfunction decodeEscapedNewlines(text: string): string {\n return text.includes('\\n') ? text : text.replace(/\\\\n/g, '\\n');\n}\n\ntype MarkdownNode = NonNullable<ExtraProps['node']>;\n\nfunction languageOf(node: MarkdownNode): string | undefined {\n const classNames = node.properties.className;\n if (!Array.isArray(classNames)) return undefined;\n\n const language = classNames.find(entry => typeof entry === 'string' && entry.startsWith('language-'));\n return typeof language === 'string' ? language.slice('language-'.length) : undefined;\n}\n\nfunction fencedCode(node: MarkdownNode | undefined): { code: string; language?: string } | undefined {\n const child = node?.children.find(entry => entry.type === 'element' && entry.tagName === 'code');\n if (child?.type !== 'element') return undefined;\n\n const code = child.children.map(entry => (entry.type === 'text' ? entry.value : '')).join('');\n return { code: code.replace(/\\n$/, ''), language: languageOf(child) };\n}\n\nfunction MarkdownCodeBlock({ node, children }: { node?: MarkdownNode; children?: ReactNode }) {\n const fenced = fencedCode(node);\n if (!fenced) return <pre>{children}</pre>;\n\n return (\n <CodeBlock\n code={fenced.code}\n lang={fenced.language}\n overflow=\"scroll\"\n className=\"bg-surface1 my-3\"\n copyMessage=\"Copied code to clipboard\"\n />\n );\n}\n\nconst POPUP_WINDOW_FEATURES = 'popup=yes,width=720,height=800,resizable=yes,scrollbars=yes';\n\nfunction isPlainLeftClick(event: MouseEvent): boolean {\n return event.button === 0 && !event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey;\n}\n\nfunction markdownLink(externalLinkTarget: MarkdownExternalLinkTarget): NonNullable<Components['a']> {\n return function MarkdownLink({ href, title, children }) {\n const isExternal = /^https?:\\/\\//i.test(href ?? '');\n\n const openInPopup: MouseEventHandler<HTMLAnchorElement> = event => {\n if (!isExternal || externalLinkTarget !== 'window' || !isPlainLeftClick(event)) return;\n\n const popup = window.open(href, '_blank', POPUP_WINDOW_FEATURES);\n if (!popup) return;\n\n popup.opener = null;\n event.preventDefault();\n };\n\n return (\n <a\n href={href}\n title={title}\n onClick={openInPopup}\n target={isExternal ? '_blank' : undefined}\n rel={isExternal ? 'noopener noreferrer' : undefined}\n >\n {children}\n </a>\n );\n };\n}\n\n// Elements are listed one by one: react-markdown also passes its `node`, which\n// React would forward to the DOM as a stray attribute. Everything else is\n// styled from markdown-renderer.css.\nconst COMPONENTS: Components = {\n pre: MarkdownCodeBlock,\n a: markdownLink('tab'),\n};\n\nconst WINDOW_COMPONENTS: Components = {\n ...COMPONENTS,\n a: markdownLink('window'),\n};\n"],"names":["MarkdownRenderer"],"mappings":"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"}
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
require('./markdown-renderer.css');const jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
const React = require('react');
|
|
4
5
|
const Markdown = require('react-markdown');
|
|
5
6
|
const remarkGfm = require('remark-gfm');
|
|
6
|
-
const codeBlock = require('./code-block-
|
|
7
|
+
const codeBlock = require('./code-block-BZUY8Fj9.cjs');
|
|
7
8
|
const utils_cn = require('./cn-vA5sWo9W.cjs');
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
const MarkdownRenderer = React.memo(function MarkdownRenderer2({
|
|
11
|
+
children,
|
|
12
|
+
className,
|
|
13
|
+
externalLinkTarget = "tab"
|
|
14
|
+
}) {
|
|
10
15
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
11
16
|
Markdown,
|
|
12
17
|
{
|
|
@@ -16,7 +21,7 @@ function MarkdownRenderer({ children, className, externalLinkTarget = "tab" }) {
|
|
|
16
21
|
children: decodeEscapedNewlines(children)
|
|
17
22
|
}
|
|
18
23
|
);
|
|
19
|
-
}
|
|
24
|
+
});
|
|
20
25
|
function decodeEscapedNewlines(text) {
|
|
21
26
|
return text.includes("\n") ? text : text.replace(/\\n/g, "\n");
|
|
22
27
|
}
|
|
@@ -83,4 +88,4 @@ const WINDOW_COMPONENTS = {
|
|
|
83
88
|
};
|
|
84
89
|
|
|
85
90
|
exports.MarkdownRenderer = MarkdownRenderer;
|
|
86
|
-
//# sourceMappingURL=markdown-renderer-
|
|
91
|
+
//# sourceMappingURL=markdown-renderer-DvJfqb-D.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown-renderer-DvJfqb-D.cjs","sources":["../src/ds/components/MarkdownRenderer/markdown-renderer.tsx"],"sourcesContent":["import { memo } from 'react';\nimport type { MouseEvent, MouseEventHandler, ReactNode } from 'react';\nimport Markdown from 'react-markdown';\nimport type { Components, ExtraProps } from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\n\nimport { CodeBlock } from '@/ds/components/CodeBlock';\nimport { cn } from '@/lib/utils';\n\nimport './markdown-renderer.css';\n\nexport type MarkdownExternalLinkTarget = 'tab' | 'window';\n\nexport interface MarkdownRendererProps {\n children: string;\n className?: string;\n externalLinkTarget?: MarkdownExternalLinkTarget;\n}\n\n/**\n * Renders a markdown string. Agent output can carry attacker-influenced text\n * (file contents, tool output, web pages): react-markdown escapes raw HTML and\n * drops dangerous link schemes, so nothing here reaches the DOM as markup.\n *\n * Memoized because react-markdown re-parses on every render and a streaming\n * reply re-renders its whole transcript on every delta: without this, each\n * chunk re-parses every settled message on the page as well as the live one.\n */\nexport const MarkdownRenderer = memo(function MarkdownRenderer({\n children,\n className,\n externalLinkTarget = 'tab',\n}: MarkdownRendererProps) {\n return (\n <Markdown\n remarkPlugins={[remarkGfm]}\n components={externalLinkTarget === 'window' ? WINDOW_COMPONENTS : COMPONENTS}\n className={cn('mastra-markdown', className)}\n >\n {decodeEscapedNewlines(children)}\n </Markdown>\n );\n});\n\n// Agent networks emit their text with literal `\\n`. Only unescape when the text\n// has no real newline, otherwise a `\"a\\nb\"` inside a code fence gets shredded.\nfunction decodeEscapedNewlines(text: string): string {\n return text.includes('\\n') ? text : text.replace(/\\\\n/g, '\\n');\n}\n\ntype MarkdownNode = NonNullable<ExtraProps['node']>;\n\nfunction languageOf(node: MarkdownNode): string | undefined {\n const classNames = node.properties.className;\n if (!Array.isArray(classNames)) return undefined;\n\n const language = classNames.find(entry => typeof entry === 'string' && entry.startsWith('language-'));\n return typeof language === 'string' ? language.slice('language-'.length) : undefined;\n}\n\nfunction fencedCode(node: MarkdownNode | undefined): { code: string; language?: string } | undefined {\n const child = node?.children.find(entry => entry.type === 'element' && entry.tagName === 'code');\n if (child?.type !== 'element') return undefined;\n\n const code = child.children.map(entry => (entry.type === 'text' ? entry.value : '')).join('');\n return { code: code.replace(/\\n$/, ''), language: languageOf(child) };\n}\n\nfunction MarkdownCodeBlock({ node, children }: { node?: MarkdownNode; children?: ReactNode }) {\n const fenced = fencedCode(node);\n if (!fenced) return <pre>{children}</pre>;\n\n return (\n <CodeBlock\n code={fenced.code}\n lang={fenced.language}\n overflow=\"scroll\"\n className=\"bg-surface1 my-3\"\n copyMessage=\"Copied code to clipboard\"\n />\n );\n}\n\nconst POPUP_WINDOW_FEATURES = 'popup=yes,width=720,height=800,resizable=yes,scrollbars=yes';\n\nfunction isPlainLeftClick(event: MouseEvent): boolean {\n return event.button === 0 && !event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey;\n}\n\nfunction markdownLink(externalLinkTarget: MarkdownExternalLinkTarget): NonNullable<Components['a']> {\n return function MarkdownLink({ href, title, children }) {\n const isExternal = /^https?:\\/\\//i.test(href ?? '');\n\n const openInPopup: MouseEventHandler<HTMLAnchorElement> = event => {\n if (!isExternal || externalLinkTarget !== 'window' || !isPlainLeftClick(event)) return;\n\n const popup = window.open(href, '_blank', POPUP_WINDOW_FEATURES);\n if (!popup) return;\n\n popup.opener = null;\n event.preventDefault();\n };\n\n return (\n <a\n href={href}\n title={title}\n onClick={openInPopup}\n target={isExternal ? '_blank' : undefined}\n rel={isExternal ? 'noopener noreferrer' : undefined}\n >\n {children}\n </a>\n );\n };\n}\n\n// Elements are listed one by one: react-markdown also passes its `node`, which\n// React would forward to the DOM as a stray attribute. Everything else is\n// styled from markdown-renderer.css.\nconst COMPONENTS: Components = {\n pre: MarkdownCodeBlock,\n a: markdownLink('tab'),\n};\n\nconst WINDOW_COMPONENTS: Components = {\n ...COMPONENTS,\n a: markdownLink('window'),\n};\n"],"names":["memo","MarkdownRenderer","jsx","cn","CodeBlock"],"mappings":"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"}
|
|
@@ -10,5 +10,10 @@ export interface CodeProps extends React.HTMLAttributes<HTMLPreElement> {
|
|
|
10
10
|
* the `.dark` root class, so theme switching is pure CSS — no ThemeProvider
|
|
11
11
|
* required. Renders plain text while highlighting is pending or when the
|
|
12
12
|
* language is missing/unknown.
|
|
13
|
+
*
|
|
14
|
+
* A streaming fence re-renders on every delta while highlighting stays a frame
|
|
15
|
+
* behind. Dropping the previous tokens each time would strobe the whole block
|
|
16
|
+
* between colored and plain, so the settled prefix keeps its colors and only
|
|
17
|
+
* the newly arrived tail waits, uncolored, for the next pass.
|
|
13
18
|
*/
|
|
14
19
|
export declare const Code: React.MemoExoticComponent<({ code, lang, ...props }: CodeProps) => React.JSX.Element>;
|
|
@@ -8,5 +8,9 @@ export interface MarkdownRendererProps {
|
|
|
8
8
|
* Renders a markdown string. Agent output can carry attacker-influenced text
|
|
9
9
|
* (file contents, tool output, web pages): react-markdown escapes raw HTML and
|
|
10
10
|
* drops dangerous link schemes, so nothing here reaches the DOM as markup.
|
|
11
|
+
*
|
|
12
|
+
* Memoized because react-markdown re-parses on every render and a streaming
|
|
13
|
+
* reply re-renders its whole transcript on every delta: without this, each
|
|
14
|
+
* chunk re-parses every settled message on the page as well as the live one.
|
|
11
15
|
*/
|
|
12
|
-
export declare
|
|
16
|
+
export declare const MarkdownRenderer: import('react').MemoExoticComponent<({ children, className, externalLinkTarget, }: MarkdownRendererProps) => import("react").JSX.Element>;
|
package/dist/style.css
CHANGED
|
@@ -9936,6 +9936,10 @@
|
|
|
9936
9936
|
color: var(--color-accent1);
|
|
9937
9937
|
}
|
|
9938
9938
|
|
|
9939
|
+
.\[\&\>svg\]\:text-negative1 > svg {
|
|
9940
|
+
color: var(--color-negative1);
|
|
9941
|
+
}
|
|
9942
|
+
|
|
9939
9943
|
.\[\&\>svg\]\:text-neutral3 > svg {
|
|
9940
9944
|
color: var(--color-neutral3);
|
|
9941
9945
|
}
|
|
@@ -9948,6 +9952,10 @@
|
|
|
9948
9952
|
color: var(--color-notice-success-fg);
|
|
9949
9953
|
}
|
|
9950
9954
|
|
|
9955
|
+
.\[\&\>svg\]\:text-positive1 > svg {
|
|
9956
|
+
color: var(--color-positive1);
|
|
9957
|
+
}
|
|
9958
|
+
|
|
9951
9959
|
.\[\&\>svg\]\:text-red-400 > svg {
|
|
9952
9960
|
color: var(--color-red-400);
|
|
9953
9961
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/playground-ui",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "49.0.0-alpha.
|
|
4
|
+
"version": "49.0.0-alpha.4",
|
|
5
5
|
"description": "Mastra Playground components",
|
|
6
6
|
"sideEffects": [
|
|
7
7
|
"**/*.css"
|
|
@@ -150,8 +150,8 @@
|
|
|
150
150
|
"react": ">=19.0.0",
|
|
151
151
|
"react-dom": ">=19.0.0",
|
|
152
152
|
"tailwindcss": "^4.0.0",
|
|
153
|
-
"@mastra/client-js": "^1.40.0-alpha.
|
|
154
|
-
"@mastra/react": "1.4.3-alpha.
|
|
153
|
+
"@mastra/client-js": "^1.40.0-alpha.4",
|
|
154
|
+
"@mastra/react": "1.4.3-alpha.4"
|
|
155
155
|
},
|
|
156
156
|
"devDependencies": {
|
|
157
157
|
"@storybook/addon-a11y": "^10.4.1",
|
|
@@ -189,11 +189,11 @@
|
|
|
189
189
|
"vite-plugin-dts": "^4.5.4",
|
|
190
190
|
"vite-plugin-lib-inject-css": "^2.2.2",
|
|
191
191
|
"vitest": "4.1.10",
|
|
192
|
-
"@mastra/memory": "1.26.2-alpha.1",
|
|
193
192
|
"@internal/lint": "0.0.122",
|
|
194
|
-
"@mastra/
|
|
195
|
-
"@mastra/core": "1.59.0-alpha.
|
|
196
|
-
"@mastra/
|
|
193
|
+
"@mastra/memory": "1.26.2-alpha.1",
|
|
194
|
+
"@mastra/core": "1.59.0-alpha.4",
|
|
195
|
+
"@mastra/react": "1.4.3-alpha.4",
|
|
196
|
+
"@mastra/client-js": "^1.40.0-alpha.4"
|
|
197
197
|
},
|
|
198
198
|
"homepage": "https://mastra.ai",
|
|
199
199
|
"repository": {
|
package/dist/code-Cj09LVys.js
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
-
import * as React from 'react';
|
|
3
|
-
import { h as highlight } from './highlight-CSJjjoqh.js';
|
|
4
|
-
|
|
5
|
-
function tokenStyle(token) {
|
|
6
|
-
if (token.htmlStyle && typeof token.htmlStyle === "object") {
|
|
7
|
-
return token.htmlStyle;
|
|
8
|
-
}
|
|
9
|
-
return token.color ? { color: token.color } : void 0;
|
|
10
|
-
}
|
|
11
|
-
const Code = React.memo(function Code2({ code, lang, ...props }) {
|
|
12
|
-
const [tokens, setTokens] = React.useState(null);
|
|
13
|
-
React.useEffect(() => {
|
|
14
|
-
setTokens(null);
|
|
15
|
-
if (!lang) return;
|
|
16
|
-
let cancelled = false;
|
|
17
|
-
void highlight(code, lang).then((result) => {
|
|
18
|
-
if (!cancelled) setTokens(result);
|
|
19
|
-
}).catch(() => {
|
|
20
|
-
if (!cancelled) setTokens(null);
|
|
21
|
-
});
|
|
22
|
-
return () => {
|
|
23
|
-
cancelled = true;
|
|
24
|
-
};
|
|
25
|
-
}, [code, lang]);
|
|
26
|
-
if (!tokens?.length) {
|
|
27
|
-
return /* @__PURE__ */ jsx("pre", { ...props, children: code });
|
|
28
|
-
}
|
|
29
|
-
let codeOffset = 0;
|
|
30
|
-
return /* @__PURE__ */ jsx("pre", { ...props, children: /* @__PURE__ */ jsx("code", { children: tokens.map((line, lineIndex) => {
|
|
31
|
-
const lineOffset = codeOffset;
|
|
32
|
-
let tokenOffset = lineOffset;
|
|
33
|
-
const tokenSpans = line.map((token) => {
|
|
34
|
-
const key = tokenOffset;
|
|
35
|
-
tokenOffset += token.content.length;
|
|
36
|
-
return /* @__PURE__ */ jsx("span", { className: "shiki-token", style: tokenStyle(token), children: token.content }, key);
|
|
37
|
-
});
|
|
38
|
-
codeOffset = tokenOffset + 1;
|
|
39
|
-
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
40
|
-
/* @__PURE__ */ jsx("span", { children: tokenSpans }),
|
|
41
|
-
lineIndex !== tokens.length - 1 && "\n"
|
|
42
|
-
] }, lineOffset);
|
|
43
|
-
}) }) });
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
export { Code as C };
|
|
47
|
-
//# sourceMappingURL=code-Cj09LVys.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"code-Cj09LVys.js","sources":["../src/ds/components/Code/code.tsx"],"sourcesContent":["import * as React from 'react';\nimport type { ThemedToken } from 'shiki/core';\n\nimport { highlight } from '../CodeEditor/highlight';\n\nexport interface CodeProps extends React.HTMLAttributes<HTMLPreElement> {\n code: string;\n lang?: string;\n}\n\nfunction tokenStyle(token: ThemedToken): React.CSSProperties | undefined {\n if (token.htmlStyle && typeof token.htmlStyle === 'object') {\n return token.htmlStyle as React.CSSProperties;\n }\n\n return token.color ? { color: token.color } : undefined;\n}\n\n/**\n * Low-level shiki token renderer shared by `CodeBlock` and `MarkdownRenderer`.\n * Dual-theme colors stay as `--shiki-light` / `--shiki-dark` CSS variables on\n * each token span; the `.shiki-token` class (index.css) picks the variant from\n * the `.dark` root class, so theme switching is pure CSS — no ThemeProvider\n * required. Renders plain text while highlighting is pending or when the\n * language is missing/unknown.\n */\nexport const Code = React.memo(function Code({ code, lang, ...props }: CodeProps) {\n const [tokens, setTokens] = React.useState<ThemedToken[][] | null>(null);\n\n React.useEffect(() => {\n setTokens(null);\n if (!lang) return;\n\n let cancelled = false;\n\n void highlight(code, lang)\n .then(result => {\n if (!cancelled) setTokens(result);\n })\n .catch(() => {\n if (!cancelled) setTokens(null);\n });\n\n return () => {\n cancelled = true;\n };\n }, [code, lang]);\n\n if (!tokens?.length) {\n return <pre {...props}>{code}</pre>;\n }\n\n let codeOffset = 0;\n\n return (\n <pre {...props}>\n <code>\n {tokens.map((line, lineIndex) => {\n const lineOffset = codeOffset;\n let tokenOffset = lineOffset;\n const tokenSpans = line.map(token => {\n const key = tokenOffset;\n tokenOffset += token.content.length;\n\n return (\n <span key={key} className=\"shiki-token\" style={tokenStyle(token)}>\n {token.content}\n </span>\n );\n });\n\n codeOffset = tokenOffset + 1;\n\n return (\n <React.Fragment key={lineOffset}>\n <span>{tokenSpans}</span>\n {lineIndex !== tokens.length - 1 && '\\n'}\n </React.Fragment>\n );\n })}\n </code>\n </pre>\n );\n});\n"],"names":["Code"],"mappings":";;;;AAUA,SAAS,WAAW,KAAA,EAAqD;AACvE,EAAA,IAAI,KAAA,CAAM,SAAA,IAAa,OAAO,KAAA,CAAM,cAAc,QAAA,EAAU;AAC1D,IAAA,OAAO,KAAA,CAAM,SAAA;AAAA,EACf;AAEA,EAAA,OAAO,MAAM,KAAA,GAAQ,EAAE,KAAA,EAAO,KAAA,CAAM,OAAM,GAAI,MAAA;AAChD;AAUO,MAAM,IAAA,GAAO,KAAA,CAAM,IAAA,CAAK,SAASA,KAAAA,CAAK,EAAE,IAAA,EAAM,IAAA,EAAM,GAAG,KAAA,EAAM,EAAc;AAChF,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,KAAA,CAAM,SAAiC,IAAI,CAAA;AAEvE,EAAA,KAAA,CAAM,UAAU,MAAM;AACpB,IAAA,SAAA,CAAU,IAAI,CAAA;AACd,IAAA,IAAI,CAAC,IAAA,EAAM;AAEX,IAAA,IAAI,SAAA,GAAY,KAAA;AAEhB,IAAA,KAAK,SAAA,CAAU,IAAA,EAAM,IAAI,CAAA,CACtB,KAAK,CAAA,MAAA,KAAU;AACd,MAAA,IAAI,CAAC,SAAA,EAAW,SAAA,CAAU,MAAM,CAAA;AAAA,IAClC,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AACX,MAAA,IAAI,CAAC,SAAA,EAAW,SAAA,CAAU,IAAI,CAAA;AAAA,IAChC,CAAC,CAAA;AAEH,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,IAAA;AAAA,IACd,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,IAAA,EAAM,IAAI,CAAC,CAAA;AAEf,EAAA,IAAI,CAAC,QAAQ,MAAA,EAAQ;AACnB,IAAA,uBAAO,GAAA,CAAC,KAAA,EAAA,EAAK,GAAG,KAAA,EAAQ,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,EAC/B;AAEA,EAAA,IAAI,UAAA,GAAa,CAAA;AAEjB,EAAA,uBACE,GAAA,CAAC,KAAA,EAAA,EAAK,GAAG,KAAA,EACP,QAAA,kBAAA,GAAA,CAAC,UACE,QAAA,EAAA,MAAA,CAAO,GAAA,CAAI,CAAC,IAAA,EAAM,SAAA,KAAc;AAC/B,IAAA,MAAM,UAAA,GAAa,UAAA;AACnB,IAAA,IAAI,WAAA,GAAc,UAAA;AAClB,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,CAAI,CAAA,KAAA,KAAS;AACnC,MAAA,MAAM,GAAA,GAAM,WAAA;AACZ,MAAA,WAAA,IAAe,MAAM,OAAA,CAAQ,MAAA;AAE7B,MAAA,uBACE,GAAA,CAAC,MAAA,EAAA,EAAe,SAAA,EAAU,aAAA,EAAc,KAAA,EAAO,WAAW,KAAK,CAAA,EAC5D,QAAA,EAAA,KAAA,CAAM,OAAA,EAAA,EADE,GAEX,CAAA;AAAA,IAEJ,CAAC,CAAA;AAED,IAAA,UAAA,GAAa,WAAA,GAAc,CAAA;AAE3B,IAAA,uBACE,IAAA,CAAC,KAAA,CAAM,QAAA,EAAN,EACC,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,UAAM,QAAA,EAAA,UAAA,EAAW,CAAA;AAAA,MACjB,SAAA,KAAc,MAAA,CAAO,MAAA,GAAS,CAAA,IAAK;AAAA,KAAA,EAAA,EAFjB,UAGrB,CAAA;AAAA,EAEJ,CAAC,GACH,CAAA,EACF,CAAA;AAEJ,CAAC;;;;"}
|
package/dist/code-FZwLnf_f.cjs
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const jsxRuntime = require('react/jsx-runtime');
|
|
4
|
-
const React = require('react');
|
|
5
|
-
const highlight = require('./highlight-CEt2vhD8.cjs');
|
|
6
|
-
|
|
7
|
-
function _interopNamespaceDefault(e) {
|
|
8
|
-
const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } });
|
|
9
|
-
if (e) {
|
|
10
|
-
for (const k in e) {
|
|
11
|
-
if (k !== 'default') {
|
|
12
|
-
const d = Object.getOwnPropertyDescriptor(e, k);
|
|
13
|
-
Object.defineProperty(n, k, d.get ? d : {
|
|
14
|
-
enumerable: true,
|
|
15
|
-
get: () => e[k]
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
n.default = e;
|
|
21
|
-
return Object.freeze(n);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
|
|
25
|
-
|
|
26
|
-
function tokenStyle(token) {
|
|
27
|
-
if (token.htmlStyle && typeof token.htmlStyle === "object") {
|
|
28
|
-
return token.htmlStyle;
|
|
29
|
-
}
|
|
30
|
-
return token.color ? { color: token.color } : void 0;
|
|
31
|
-
}
|
|
32
|
-
const Code = React__namespace.memo(function Code2({ code, lang, ...props }) {
|
|
33
|
-
const [tokens, setTokens] = React__namespace.useState(null);
|
|
34
|
-
React__namespace.useEffect(() => {
|
|
35
|
-
setTokens(null);
|
|
36
|
-
if (!lang) return;
|
|
37
|
-
let cancelled = false;
|
|
38
|
-
void highlight.highlight(code, lang).then((result) => {
|
|
39
|
-
if (!cancelled) setTokens(result);
|
|
40
|
-
}).catch(() => {
|
|
41
|
-
if (!cancelled) setTokens(null);
|
|
42
|
-
});
|
|
43
|
-
return () => {
|
|
44
|
-
cancelled = true;
|
|
45
|
-
};
|
|
46
|
-
}, [code, lang]);
|
|
47
|
-
if (!tokens?.length) {
|
|
48
|
-
return /* @__PURE__ */ jsxRuntime.jsx("pre", { ...props, children: code });
|
|
49
|
-
}
|
|
50
|
-
let codeOffset = 0;
|
|
51
|
-
return /* @__PURE__ */ jsxRuntime.jsx("pre", { ...props, children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: tokens.map((line, lineIndex) => {
|
|
52
|
-
const lineOffset = codeOffset;
|
|
53
|
-
let tokenOffset = lineOffset;
|
|
54
|
-
const tokenSpans = line.map((token) => {
|
|
55
|
-
const key = tokenOffset;
|
|
56
|
-
tokenOffset += token.content.length;
|
|
57
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shiki-token", style: tokenStyle(token), children: token.content }, key);
|
|
58
|
-
});
|
|
59
|
-
codeOffset = tokenOffset + 1;
|
|
60
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Fragment, { children: [
|
|
61
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: tokenSpans }),
|
|
62
|
-
lineIndex !== tokens.length - 1 && "\n"
|
|
63
|
-
] }, lineOffset);
|
|
64
|
-
}) }) });
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
exports.Code = Code;
|
|
68
|
-
//# sourceMappingURL=code-FZwLnf_f.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"code-FZwLnf_f.cjs","sources":["../src/ds/components/Code/code.tsx"],"sourcesContent":["import * as React from 'react';\nimport type { ThemedToken } from 'shiki/core';\n\nimport { highlight } from '../CodeEditor/highlight';\n\nexport interface CodeProps extends React.HTMLAttributes<HTMLPreElement> {\n code: string;\n lang?: string;\n}\n\nfunction tokenStyle(token: ThemedToken): React.CSSProperties | undefined {\n if (token.htmlStyle && typeof token.htmlStyle === 'object') {\n return token.htmlStyle as React.CSSProperties;\n }\n\n return token.color ? { color: token.color } : undefined;\n}\n\n/**\n * Low-level shiki token renderer shared by `CodeBlock` and `MarkdownRenderer`.\n * Dual-theme colors stay as `--shiki-light` / `--shiki-dark` CSS variables on\n * each token span; the `.shiki-token` class (index.css) picks the variant from\n * the `.dark` root class, so theme switching is pure CSS — no ThemeProvider\n * required. Renders plain text while highlighting is pending or when the\n * language is missing/unknown.\n */\nexport const Code = React.memo(function Code({ code, lang, ...props }: CodeProps) {\n const [tokens, setTokens] = React.useState<ThemedToken[][] | null>(null);\n\n React.useEffect(() => {\n setTokens(null);\n if (!lang) return;\n\n let cancelled = false;\n\n void highlight(code, lang)\n .then(result => {\n if (!cancelled) setTokens(result);\n })\n .catch(() => {\n if (!cancelled) setTokens(null);\n });\n\n return () => {\n cancelled = true;\n };\n }, [code, lang]);\n\n if (!tokens?.length) {\n return <pre {...props}>{code}</pre>;\n }\n\n let codeOffset = 0;\n\n return (\n <pre {...props}>\n <code>\n {tokens.map((line, lineIndex) => {\n const lineOffset = codeOffset;\n let tokenOffset = lineOffset;\n const tokenSpans = line.map(token => {\n const key = tokenOffset;\n tokenOffset += token.content.length;\n\n return (\n <span key={key} className=\"shiki-token\" style={tokenStyle(token)}>\n {token.content}\n </span>\n );\n });\n\n codeOffset = tokenOffset + 1;\n\n return (\n <React.Fragment key={lineOffset}>\n <span>{tokenSpans}</span>\n {lineIndex !== tokens.length - 1 && '\\n'}\n </React.Fragment>\n );\n })}\n </code>\n </pre>\n );\n});\n"],"names":["React","Code","highlight","jsx","jsxs"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAUA,SAAS,WAAW,KAAA,EAAqD;AACvE,EAAA,IAAI,KAAA,CAAM,SAAA,IAAa,OAAO,KAAA,CAAM,cAAc,QAAA,EAAU;AAC1D,IAAA,OAAO,KAAA,CAAM,SAAA;AAAA,EACf;AAEA,EAAA,OAAO,MAAM,KAAA,GAAQ,EAAE,KAAA,EAAO,KAAA,CAAM,OAAM,GAAI,MAAA;AAChD;AAUO,MAAM,IAAA,GAAOA,gBAAA,CAAM,IAAA,CAAK,SAASC,KAAAA,CAAK,EAAE,IAAA,EAAM,IAAA,EAAM,GAAG,KAAA,EAAM,EAAc;AAChF,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAID,gBAAA,CAAM,SAAiC,IAAI,CAAA;AAEvE,EAAAA,gBAAA,CAAM,UAAU,MAAM;AACpB,IAAA,SAAA,CAAU,IAAI,CAAA;AACd,IAAA,IAAI,CAAC,IAAA,EAAM;AAEX,IAAA,IAAI,SAAA,GAAY,KAAA;AAEhB,IAAA,KAAKE,mBAAA,CAAU,IAAA,EAAM,IAAI,CAAA,CACtB,KAAK,CAAA,MAAA,KAAU;AACd,MAAA,IAAI,CAAC,SAAA,EAAW,SAAA,CAAU,MAAM,CAAA;AAAA,IAClC,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AACX,MAAA,IAAI,CAAC,SAAA,EAAW,SAAA,CAAU,IAAI,CAAA;AAAA,IAChC,CAAC,CAAA;AAEH,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,IAAA;AAAA,IACd,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,IAAA,EAAM,IAAI,CAAC,CAAA;AAEf,EAAA,IAAI,CAAC,QAAQ,MAAA,EAAQ;AACnB,IAAA,uBAAOC,cAAA,CAAC,KAAA,EAAA,EAAK,GAAG,KAAA,EAAQ,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,EAC/B;AAEA,EAAA,IAAI,UAAA,GAAa,CAAA;AAEjB,EAAA,uBACEA,cAAA,CAAC,KAAA,EAAA,EAAK,GAAG,KAAA,EACP,QAAA,kBAAAA,cAAA,CAAC,UACE,QAAA,EAAA,MAAA,CAAO,GAAA,CAAI,CAAC,IAAA,EAAM,SAAA,KAAc;AAC/B,IAAA,MAAM,UAAA,GAAa,UAAA;AACnB,IAAA,IAAI,WAAA,GAAc,UAAA;AAClB,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,CAAI,CAAA,KAAA,KAAS;AACnC,MAAA,MAAM,GAAA,GAAM,WAAA;AACZ,MAAA,WAAA,IAAe,MAAM,OAAA,CAAQ,MAAA;AAE7B,MAAA,uBACEA,cAAA,CAAC,MAAA,EAAA,EAAe,SAAA,EAAU,aAAA,EAAc,KAAA,EAAO,WAAW,KAAK,CAAA,EAC5D,QAAA,EAAA,KAAA,CAAM,OAAA,EAAA,EADE,GAEX,CAAA;AAAA,IAEJ,CAAC,CAAA;AAED,IAAA,UAAA,GAAa,WAAA,GAAc,CAAA;AAE3B,IAAA,uBACEC,eAAA,CAACJ,gBAAA,CAAM,QAAA,EAAN,EACC,QAAA,EAAA;AAAA,sBAAAG,cAAA,CAAC,UAAM,QAAA,EAAA,UAAA,EAAW,CAAA;AAAA,MACjB,SAAA,KAAc,MAAA,CAAO,MAAA,GAAS,CAAA,IAAK;AAAA,KAAA,EAAA,EAFjB,UAGrB,CAAA;AAAA,EAEJ,CAAC,GACH,CAAA,EACF,CAAA;AAEJ,CAAC;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"markdown-renderer-D1vSFfp9.cjs","sources":["../src/ds/components/MarkdownRenderer/markdown-renderer.tsx"],"sourcesContent":["import type { MouseEvent, MouseEventHandler, ReactNode } from 'react';\nimport Markdown from 'react-markdown';\nimport type { Components, ExtraProps } from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\n\nimport { CodeBlock } from '@/ds/components/CodeBlock';\nimport { cn } from '@/lib/utils';\n\nimport './markdown-renderer.css';\n\nexport type MarkdownExternalLinkTarget = 'tab' | 'window';\n\nexport interface MarkdownRendererProps {\n children: string;\n className?: string;\n externalLinkTarget?: MarkdownExternalLinkTarget;\n}\n\n/**\n * Renders a markdown string. Agent output can carry attacker-influenced text\n * (file contents, tool output, web pages): react-markdown escapes raw HTML and\n * drops dangerous link schemes, so nothing here reaches the DOM as markup.\n */\nexport function MarkdownRenderer({ children, className, externalLinkTarget = 'tab' }: MarkdownRendererProps) {\n return (\n <Markdown\n remarkPlugins={[remarkGfm]}\n components={externalLinkTarget === 'window' ? WINDOW_COMPONENTS : COMPONENTS}\n className={cn('mastra-markdown', className)}\n >\n {decodeEscapedNewlines(children)}\n </Markdown>\n );\n}\n\n// Agent networks emit their text with literal `\\n`. Only unescape when the text\n// has no real newline, otherwise a `\"a\\nb\"` inside a code fence gets shredded.\nfunction decodeEscapedNewlines(text: string): string {\n return text.includes('\\n') ? text : text.replace(/\\\\n/g, '\\n');\n}\n\ntype MarkdownNode = NonNullable<ExtraProps['node']>;\n\nfunction languageOf(node: MarkdownNode): string | undefined {\n const classNames = node.properties.className;\n if (!Array.isArray(classNames)) return undefined;\n\n const language = classNames.find(entry => typeof entry === 'string' && entry.startsWith('language-'));\n return typeof language === 'string' ? language.slice('language-'.length) : undefined;\n}\n\nfunction fencedCode(node: MarkdownNode | undefined): { code: string; language?: string } | undefined {\n const child = node?.children.find(entry => entry.type === 'element' && entry.tagName === 'code');\n if (child?.type !== 'element') return undefined;\n\n const code = child.children.map(entry => (entry.type === 'text' ? entry.value : '')).join('');\n return { code: code.replace(/\\n$/, ''), language: languageOf(child) };\n}\n\nfunction MarkdownCodeBlock({ node, children }: { node?: MarkdownNode; children?: ReactNode }) {\n const fenced = fencedCode(node);\n if (!fenced) return <pre>{children}</pre>;\n\n return (\n <CodeBlock\n code={fenced.code}\n lang={fenced.language}\n overflow=\"scroll\"\n className=\"bg-surface1 my-3\"\n copyMessage=\"Copied code to clipboard\"\n />\n );\n}\n\nconst POPUP_WINDOW_FEATURES = 'popup=yes,width=720,height=800,resizable=yes,scrollbars=yes';\n\nfunction isPlainLeftClick(event: MouseEvent): boolean {\n return event.button === 0 && !event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey;\n}\n\nfunction markdownLink(externalLinkTarget: MarkdownExternalLinkTarget): NonNullable<Components['a']> {\n return function MarkdownLink({ href, title, children }) {\n const isExternal = /^https?:\\/\\//i.test(href ?? '');\n\n const openInPopup: MouseEventHandler<HTMLAnchorElement> = event => {\n if (!isExternal || externalLinkTarget !== 'window' || !isPlainLeftClick(event)) return;\n\n const popup = window.open(href, '_blank', POPUP_WINDOW_FEATURES);\n if (!popup) return;\n\n popup.opener = null;\n event.preventDefault();\n };\n\n return (\n <a\n href={href}\n title={title}\n onClick={openInPopup}\n target={isExternal ? '_blank' : undefined}\n rel={isExternal ? 'noopener noreferrer' : undefined}\n >\n {children}\n </a>\n );\n };\n}\n\n// Elements are listed one by one: react-markdown also passes its `node`, which\n// React would forward to the DOM as a stray attribute. Everything else is\n// styled from markdown-renderer.css.\nconst COMPONENTS: Components = {\n pre: MarkdownCodeBlock,\n a: markdownLink('tab'),\n};\n\nconst WINDOW_COMPONENTS: Components = {\n ...COMPONENTS,\n a: markdownLink('window'),\n};\n"],"names":["jsx","cn","CodeBlock"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"markdown-renderer-DmYYQHxu.js","sources":["../src/ds/components/MarkdownRenderer/markdown-renderer.tsx"],"sourcesContent":["import type { MouseEvent, MouseEventHandler, ReactNode } from 'react';\nimport Markdown from 'react-markdown';\nimport type { Components, ExtraProps } from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\n\nimport { CodeBlock } from '@/ds/components/CodeBlock';\nimport { cn } from '@/lib/utils';\n\nimport './markdown-renderer.css';\n\nexport type MarkdownExternalLinkTarget = 'tab' | 'window';\n\nexport interface MarkdownRendererProps {\n children: string;\n className?: string;\n externalLinkTarget?: MarkdownExternalLinkTarget;\n}\n\n/**\n * Renders a markdown string. Agent output can carry attacker-influenced text\n * (file contents, tool output, web pages): react-markdown escapes raw HTML and\n * drops dangerous link schemes, so nothing here reaches the DOM as markup.\n */\nexport function MarkdownRenderer({ children, className, externalLinkTarget = 'tab' }: MarkdownRendererProps) {\n return (\n <Markdown\n remarkPlugins={[remarkGfm]}\n components={externalLinkTarget === 'window' ? WINDOW_COMPONENTS : COMPONENTS}\n className={cn('mastra-markdown', className)}\n >\n {decodeEscapedNewlines(children)}\n </Markdown>\n );\n}\n\n// Agent networks emit their text with literal `\\n`. Only unescape when the text\n// has no real newline, otherwise a `\"a\\nb\"` inside a code fence gets shredded.\nfunction decodeEscapedNewlines(text: string): string {\n return text.includes('\\n') ? text : text.replace(/\\\\n/g, '\\n');\n}\n\ntype MarkdownNode = NonNullable<ExtraProps['node']>;\n\nfunction languageOf(node: MarkdownNode): string | undefined {\n const classNames = node.properties.className;\n if (!Array.isArray(classNames)) return undefined;\n\n const language = classNames.find(entry => typeof entry === 'string' && entry.startsWith('language-'));\n return typeof language === 'string' ? language.slice('language-'.length) : undefined;\n}\n\nfunction fencedCode(node: MarkdownNode | undefined): { code: string; language?: string } | undefined {\n const child = node?.children.find(entry => entry.type === 'element' && entry.tagName === 'code');\n if (child?.type !== 'element') return undefined;\n\n const code = child.children.map(entry => (entry.type === 'text' ? entry.value : '')).join('');\n return { code: code.replace(/\\n$/, ''), language: languageOf(child) };\n}\n\nfunction MarkdownCodeBlock({ node, children }: { node?: MarkdownNode; children?: ReactNode }) {\n const fenced = fencedCode(node);\n if (!fenced) return <pre>{children}</pre>;\n\n return (\n <CodeBlock\n code={fenced.code}\n lang={fenced.language}\n overflow=\"scroll\"\n className=\"bg-surface1 my-3\"\n copyMessage=\"Copied code to clipboard\"\n />\n );\n}\n\nconst POPUP_WINDOW_FEATURES = 'popup=yes,width=720,height=800,resizable=yes,scrollbars=yes';\n\nfunction isPlainLeftClick(event: MouseEvent): boolean {\n return event.button === 0 && !event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey;\n}\n\nfunction markdownLink(externalLinkTarget: MarkdownExternalLinkTarget): NonNullable<Components['a']> {\n return function MarkdownLink({ href, title, children }) {\n const isExternal = /^https?:\\/\\//i.test(href ?? '');\n\n const openInPopup: MouseEventHandler<HTMLAnchorElement> = event => {\n if (!isExternal || externalLinkTarget !== 'window' || !isPlainLeftClick(event)) return;\n\n const popup = window.open(href, '_blank', POPUP_WINDOW_FEATURES);\n if (!popup) return;\n\n popup.opener = null;\n event.preventDefault();\n };\n\n return (\n <a\n href={href}\n title={title}\n onClick={openInPopup}\n target={isExternal ? '_blank' : undefined}\n rel={isExternal ? 'noopener noreferrer' : undefined}\n >\n {children}\n </a>\n );\n };\n}\n\n// Elements are listed one by one: react-markdown also passes its `node`, which\n// React would forward to the DOM as a stray attribute. Everything else is\n// styled from markdown-renderer.css.\nconst COMPONENTS: Components = {\n pre: MarkdownCodeBlock,\n a: markdownLink('tab'),\n};\n\nconst WINDOW_COMPONENTS: Components = {\n ...COMPONENTS,\n a: markdownLink('window'),\n};\n"],"names":[],"mappings":"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"}
|