@shapesos/clay 0.17.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-elements.cjs +3 -1
- package/dist/ai-elements.cjs.map +1 -1
- package/dist/ai-elements.js +4 -4
- package/dist/artifacts.cjs +1010 -60
- package/dist/artifacts.cjs.map +1 -1
- package/dist/artifacts.d.cts +20 -3
- package/dist/artifacts.d.ts +20 -3
- package/dist/artifacts.js +15 -6
- package/dist/badge.cjs +70 -0
- package/dist/badge.cjs.map +1 -0
- package/dist/badge.d.cts +28 -0
- package/dist/badge.d.ts +28 -0
- package/dist/badge.js +9 -0
- package/dist/blocks.cjs +981 -96
- package/dist/blocks.cjs.map +1 -1
- package/dist/blocks.css +1 -1
- package/dist/blocks.d.cts +15 -4
- package/dist/blocks.d.ts +15 -4
- package/dist/blocks.js +20 -8
- package/dist/button.cjs +3 -1
- package/dist/button.cjs.map +1 -1
- package/dist/button.js +2 -2
- package/dist/capture.cjs +3 -1
- package/dist/capture.cjs.map +1 -1
- package/dist/capture.js +2 -2
- package/dist/chart.cjs +3 -1
- package/dist/chart.cjs.map +1 -1
- package/dist/chart.js +2 -2
- package/dist/chat.cjs +986 -151
- package/dist/chat.cjs.map +1 -1
- package/dist/chat.d.cts +2 -2
- package/dist/chat.d.ts +2 -2
- package/dist/chat.js +13 -8
- package/dist/{chunk-JGMN6W72.js → chunk-2X4KUXYP.js} +1 -1
- package/dist/chunk-BHHJOG5X.js +1 -0
- package/dist/{chunk-B4U37WIH.js → chunk-CFCLVJIO.js} +2 -2
- package/dist/chunk-CSTCTO3B.js +161 -0
- package/dist/chunk-CSTCTO3B.js.map +1 -0
- package/dist/{chunk-6YZ65KPW.js → chunk-DC5KYT2G.js} +669 -171
- package/dist/chunk-DC5KYT2G.js.map +1 -0
- package/dist/{chunk-PYDVANWI.js → chunk-E36VI2HA.js} +2 -2
- package/dist/chunk-EIAWZXE4.js +69 -0
- package/dist/chunk-EIAWZXE4.js.map +1 -0
- package/dist/chunk-EXRNGIQ2.js +41 -0
- package/dist/chunk-EXRNGIQ2.js.map +1 -0
- package/dist/{chunk-B6GAPZ2R.js → chunk-FCSYVF4Z.js} +12 -46
- package/dist/chunk-FCSYVF4Z.js.map +1 -0
- package/dist/{chunk-PUVZ2S3F.js → chunk-G4NXVFXU.js} +2 -2
- package/dist/{chunk-JAGNXEWK.js → chunk-GK4XW4BC.js} +2 -2
- package/dist/{chunk-4MZZH3WX.js → chunk-HU5W7CGE.js} +37 -2
- package/dist/chunk-HU5W7CGE.js.map +1 -0
- package/dist/chunk-JMHE3Q5K.js +406 -0
- package/dist/chunk-JMHE3Q5K.js.map +1 -0
- package/dist/{chunk-4VE6ZXXW.js → chunk-MQP57DOP.js} +3 -3
- package/dist/{chunk-JF3P66JF.js → chunk-SN3ORQSJ.js} +4 -2
- package/dist/{chunk-JF3P66JF.js.map → chunk-SN3ORQSJ.js.map} +1 -1
- package/dist/{chunk-PGR2MDDU.js → chunk-W66OJM55.js} +2 -2
- package/dist/{chunk-7OYIDM42.js → chunk-XKURJ72I.js} +2 -2
- package/dist/copy-button.cjs +439 -0
- package/dist/copy-button.cjs.map +1 -0
- package/dist/copy-button.d.cts +20 -0
- package/dist/copy-button.d.ts +20 -0
- package/dist/copy-button.js +12 -0
- package/dist/copy-button.js.map +1 -0
- package/dist/{dom-to-image-NATF3446.js → dom-to-image-QB7KMTAE.js} +3 -3
- package/dist/dom-to-image-QB7KMTAE.js.map +1 -0
- package/dist/icon.cjs +3 -1
- package/dist/icon.cjs.map +1 -1
- package/dist/icon.js +2 -2
- package/dist/index.cjs +1070 -209
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -4
- package/dist/index.d.ts +6 -4
- package/dist/index.js +42 -17
- package/dist/keyboard-shortcut.cjs +3 -1
- package/dist/keyboard-shortcut.cjs.map +1 -1
- package/dist/keyboard-shortcut.js +2 -2
- package/dist/table.cjs +40 -0
- package/dist/table.cjs.map +1 -1
- package/dist/table.d.cts +37 -2
- package/dist/table.d.ts +37 -2
- package/dist/table.js +11 -1
- package/dist/text-area.cjs +3 -1
- package/dist/text-area.cjs.map +1 -1
- package/dist/text-area.js +2 -2
- package/dist/tokens.cjs +3 -1
- package/dist/tokens.cjs.map +1 -1
- package/dist/tokens.d.cts +1 -0
- package/dist/tokens.d.ts +1 -0
- package/dist/tokens.js +1 -1
- package/dist/{types-CW45GBXl.d.cts → types-Bhg0_ES8.d.cts} +75 -3
- package/dist/{types-GCkXbyFm.d.ts → types-C8JtnwNY.d.ts} +200 -4
- package/dist/{types-BzXPBy6s.d.cts → types-DTdDFU3O.d.cts} +200 -4
- package/dist/{types-D1b8v7EY.d.ts → types-orOQcI2z.d.ts} +75 -3
- package/package.json +11 -1
- package/dist/chunk-46ZYTBX5.js +0 -250
- package/dist/chunk-46ZYTBX5.js.map +0 -1
- package/dist/chunk-4MZZH3WX.js.map +0 -1
- package/dist/chunk-6YZ65KPW.js.map +0 -1
- package/dist/chunk-B6GAPZ2R.js.map +0 -1
- package/dist/chunk-RSRNSWJN.js +0 -1
- /package/dist/{chunk-RSRNSWJN.js.map → badge.js.map} +0 -0
- /package/dist/{chunk-JGMN6W72.js.map → chunk-2X4KUXYP.js.map} +0 -0
- /package/dist/{dom-to-image-NATF3446.js.map → chunk-BHHJOG5X.js.map} +0 -0
- /package/dist/{chunk-B4U37WIH.js.map → chunk-CFCLVJIO.js.map} +0 -0
- /package/dist/{chunk-PYDVANWI.js.map → chunk-E36VI2HA.js.map} +0 -0
- /package/dist/{chunk-PUVZ2S3F.js.map → chunk-G4NXVFXU.js.map} +0 -0
- /package/dist/{chunk-JAGNXEWK.js.map → chunk-GK4XW4BC.js.map} +0 -0
- /package/dist/{chunk-4VE6ZXXW.js.map → chunk-MQP57DOP.js.map} +0 -0
- /package/dist/{chunk-PGR2MDDU.js.map → chunk-W66OJM55.js.map} +0 -0
- /package/dist/{chunk-7OYIDM42.js.map → chunk-XKURJ72I.js.map} +0 -0
|
@@ -1,6 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
IconAlertCircle,
|
|
3
|
+
IconArrowsMaximize,
|
|
4
|
+
IconArrowsMinimize,
|
|
5
|
+
IconCheck,
|
|
6
|
+
IconChevronLeft,
|
|
7
|
+
IconChevronRight,
|
|
8
|
+
IconCopy,
|
|
9
|
+
IconDownload,
|
|
10
|
+
IconFileSpreadsheet,
|
|
11
|
+
IconLoader2,
|
|
12
|
+
IconPhoto
|
|
13
|
+
} from "./chunk-CSTCTO3B.js";
|
|
1
14
|
import {
|
|
2
15
|
IconButton
|
|
3
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-E36VI2HA.js";
|
|
4
17
|
import {
|
|
5
18
|
CAPTURE_EXCLUDE_ATTRIBUTE
|
|
6
19
|
} from "./chunk-LXYCT4YO.js";
|
|
@@ -8,16 +21,19 @@ import {
|
|
|
8
21
|
BarChart,
|
|
9
22
|
LineChart,
|
|
10
23
|
PieChart
|
|
11
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-G4NXVFXU.js";
|
|
12
25
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
26
|
+
fontFamilies
|
|
27
|
+
} from "./chunk-UXT2H3FM.js";
|
|
28
|
+
import {
|
|
29
|
+
DATA_TABLE_CELL_CLASS,
|
|
30
|
+
DATA_TABLE_HEAD_CLASS,
|
|
31
|
+
DATA_TABLE_ROW_CLASS,
|
|
32
|
+
DataTable,
|
|
15
33
|
TableCell,
|
|
16
34
|
TableHead,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
useScrollShadow
|
|
20
|
-
} from "./chunk-4MZZH3WX.js";
|
|
35
|
+
TableRow
|
|
36
|
+
} from "./chunk-HU5W7CGE.js";
|
|
21
37
|
import {
|
|
22
38
|
cn
|
|
23
39
|
} from "./chunk-P6GUNIAE.js";
|
|
@@ -25,7 +41,8 @@ import {
|
|
|
25
41
|
// src/components/artifacts/artifact-base.ts
|
|
26
42
|
var artifactTypes = {
|
|
27
43
|
TABLE: "TABLE",
|
|
28
|
-
CHART: "CHART"
|
|
44
|
+
CHART: "CHART",
|
|
45
|
+
DECK: "DECK"
|
|
29
46
|
};
|
|
30
47
|
|
|
31
48
|
// src/components/artifacts/chart-artifact/types.ts
|
|
@@ -50,97 +67,33 @@ var DEFAULT_TABLE_ARTIFACT_LABELS = {
|
|
|
50
67
|
empty: "No rows to display."
|
|
51
68
|
};
|
|
52
69
|
|
|
53
|
-
//
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
outline: {
|
|
59
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
60
|
-
width: 24,
|
|
61
|
-
height: 24,
|
|
62
|
-
viewBox: "0 0 24 24",
|
|
63
|
-
fill: "none",
|
|
64
|
-
stroke: "currentColor",
|
|
65
|
-
strokeWidth: 2,
|
|
66
|
-
strokeLinecap: "round",
|
|
67
|
-
strokeLinejoin: "round"
|
|
68
|
-
},
|
|
69
|
-
filled: {
|
|
70
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
71
|
-
width: 24,
|
|
72
|
-
height: 24,
|
|
73
|
-
viewBox: "0 0 24 24",
|
|
74
|
-
fill: "currentColor",
|
|
75
|
-
stroke: "none"
|
|
76
|
-
}
|
|
70
|
+
// src/components/artifacts/deck-artifact/types.ts
|
|
71
|
+
var deckBlockTypes = {
|
|
72
|
+
TEXT: "TEXT",
|
|
73
|
+
CHART: "CHART",
|
|
74
|
+
TABLE: "TABLE"
|
|
77
75
|
};
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
[
|
|
99
|
-
title && createElement("title", { key: "svg-title" }, title),
|
|
100
|
-
...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),
|
|
101
|
-
...Array.isArray(children) ? children : [children]
|
|
102
|
-
]
|
|
103
|
-
)
|
|
104
|
-
);
|
|
105
|
-
Component.displayName = `${iconNamePascal}`;
|
|
106
|
-
return Component;
|
|
76
|
+
var deckSlideKinds = {
|
|
77
|
+
TITLE: "TITLE",
|
|
78
|
+
AGENDA: "AGENDA",
|
|
79
|
+
SECTION: "SECTION",
|
|
80
|
+
CONTENT: "CONTENT",
|
|
81
|
+
CLOSING: "CLOSING"
|
|
82
|
+
};
|
|
83
|
+
var DEFAULT_DECK_ARTIFACT_LABELS = {
|
|
84
|
+
previous: "Previous slide",
|
|
85
|
+
next: "Next slide",
|
|
86
|
+
position: "Slide {current} of {total}",
|
|
87
|
+
download: "Download",
|
|
88
|
+
unavailable: "Deck content is unavailable.",
|
|
89
|
+
enterFullscreen: "Fullscreen",
|
|
90
|
+
exitFullscreen: "Exit fullscreen",
|
|
91
|
+
thankYou: "Thank you",
|
|
92
|
+
questions: "Questions?",
|
|
93
|
+
agenda: "Agenda",
|
|
94
|
+
chart: DEFAULT_CHART_ARTIFACT_LABELS,
|
|
95
|
+
table: DEFAULT_TABLE_ARTIFACT_LABELS
|
|
107
96
|
};
|
|
108
|
-
|
|
109
|
-
// node_modules/@tabler/icons-react/dist/esm/icons/IconAlertCircle.mjs
|
|
110
|
-
var __iconNode = [["path", { "d": "M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0", "key": "svg-0" }], ["path", { "d": "M12 8v4", "key": "svg-1" }], ["path", { "d": "M12 16h.01", "key": "svg-2" }]];
|
|
111
|
-
var IconAlertCircle = createReactComponent("outline", "alert-circle", "AlertCircle", __iconNode);
|
|
112
|
-
|
|
113
|
-
// node_modules/@tabler/icons-react/dist/esm/icons/IconCheck.mjs
|
|
114
|
-
var __iconNode2 = [["path", { "d": "M5 12l5 5l10 -10", "key": "svg-0" }]];
|
|
115
|
-
var IconCheck = createReactComponent("outline", "check", "Check", __iconNode2);
|
|
116
|
-
|
|
117
|
-
// node_modules/@tabler/icons-react/dist/esm/icons/IconCopy.mjs
|
|
118
|
-
var __iconNode3 = [["path", { "d": "M7 9.667a2.667 2.667 0 0 1 2.667 -2.667h8.666a2.667 2.667 0 0 1 2.667 2.667v8.666a2.667 2.667 0 0 1 -2.667 2.667h-8.666a2.667 2.667 0 0 1 -2.667 -2.667l0 -8.666", "key": "svg-0" }], ["path", { "d": "M4.012 16.737a2.005 2.005 0 0 1 -1.012 -1.737v-10c0 -1.1 .9 -2 2 -2h10c.75 0 1.158 .385 1.5 1", "key": "svg-1" }]];
|
|
119
|
-
var IconCopy = createReactComponent("outline", "copy", "Copy", __iconNode3);
|
|
120
|
-
|
|
121
|
-
// node_modules/@tabler/icons-react/dist/esm/icons/IconDownload.mjs
|
|
122
|
-
var __iconNode4 = [["path", { "d": "M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-2", "key": "svg-0" }], ["path", { "d": "M7 11l5 5l5 -5", "key": "svg-1" }], ["path", { "d": "M12 4l0 12", "key": "svg-2" }]];
|
|
123
|
-
var IconDownload = createReactComponent("outline", "download", "Download", __iconNode4);
|
|
124
|
-
|
|
125
|
-
// node_modules/@tabler/icons-react/dist/esm/icons/IconFileSpreadsheet.mjs
|
|
126
|
-
var __iconNode5 = [["path", { "d": "M14 3v4a1 1 0 0 0 1 1h4", "key": "svg-0" }], ["path", { "d": "M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2", "key": "svg-1" }], ["path", { "d": "M8 11h8v7h-8l0 -7", "key": "svg-2" }], ["path", { "d": "M8 15h8", "key": "svg-3" }], ["path", { "d": "M11 11v7", "key": "svg-4" }]];
|
|
127
|
-
var IconFileSpreadsheet = createReactComponent("outline", "file-spreadsheet", "FileSpreadsheet", __iconNode5);
|
|
128
|
-
|
|
129
|
-
// node_modules/@tabler/icons-react/dist/esm/icons/IconLoader2.mjs
|
|
130
|
-
var __iconNode6 = [["path", { "d": "M12 3a9 9 0 1 0 9 9", "key": "svg-0" }]];
|
|
131
|
-
var IconLoader2 = createReactComponent("outline", "loader-2", "Loader2", __iconNode6);
|
|
132
|
-
|
|
133
|
-
// node_modules/@tabler/icons-react/dist/esm/icons/IconPhoto.mjs
|
|
134
|
-
var __iconNode7 = [["path", { "d": "M15 8h.01", "key": "svg-0" }], ["path", { "d": "M3 6a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v12a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3v-12", "key": "svg-1" }], ["path", { "d": "M3 16l5 -5c.928 -.893 2.072 -.893 3 0l5 5", "key": "svg-2" }], ["path", { "d": "M14 14l1 -1c.928 -.893 2.072 -.893 3 0l3 3", "key": "svg-3" }]];
|
|
135
|
-
var IconPhoto = createReactComponent("outline", "photo", "Photo", __iconNode7);
|
|
136
|
-
|
|
137
|
-
// node_modules/@tabler/icons-react/dist/esm/icons/IconThumbDown.mjs
|
|
138
|
-
var __iconNode8 = [["path", { "d": "M7 13v-8a1 1 0 0 0 -1 -1h-2a1 1 0 0 0 -1 1v7a1 1 0 0 0 1 1h3a4 4 0 0 1 4 4v1a2 2 0 0 0 4 0v-5h3a2 2 0 0 0 2 -2l-1 -5a2 3 0 0 0 -2 -2h-7a3 3 0 0 0 -3 3", "key": "svg-0" }]];
|
|
139
|
-
var IconThumbDown = createReactComponent("outline", "thumb-down", "ThumbDown", __iconNode8);
|
|
140
|
-
|
|
141
|
-
// node_modules/@tabler/icons-react/dist/esm/icons/IconThumbUp.mjs
|
|
142
|
-
var __iconNode9 = [["path", { "d": "M7 11v8a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1v-7a1 1 0 0 1 1 -1h3a4 4 0 0 0 4 -4v-1a2 2 0 0 1 4 0v5h3a2 2 0 0 1 2 2l-1 5a2 3 0 0 1 -2 2h-7a3 3 0 0 1 -3 -3", "key": "svg-0" }]];
|
|
143
|
-
var IconThumbUp = createReactComponent("outline", "thumb-up", "ThumbUp", __iconNode9);
|
|
144
97
|
|
|
145
98
|
// src/components/artifacts/artifact-copy-as-image-button/artifact-copy-as-image-button.tsx
|
|
146
99
|
import { useCallback as useCallback2 } from "react";
|
|
@@ -203,7 +156,7 @@ function useCopyAsImage(targetRef, options = {}) {
|
|
|
203
156
|
setError(null);
|
|
204
157
|
setStatus("working");
|
|
205
158
|
try {
|
|
206
|
-
const { copyNodeAsPng } = await import("./dom-to-image-
|
|
159
|
+
const { copyNodeAsPng } = await import("./dom-to-image-QB7KMTAE.js");
|
|
207
160
|
await copyNodeAsPng(node, nodeOptions);
|
|
208
161
|
setStatus("success");
|
|
209
162
|
scheduleReset();
|
|
@@ -382,7 +335,7 @@ function ArtifactDownloadMenu({
|
|
|
382
335
|
if (!node) return;
|
|
383
336
|
const filename = `${png.filename ?? DEFAULT_PNG_BASENAME}.png`;
|
|
384
337
|
try {
|
|
385
|
-
const { downloadNodeAsPng } = await import("./dom-to-image-
|
|
338
|
+
const { downloadNodeAsPng } = await import("./dom-to-image-QB7KMTAE.js");
|
|
386
339
|
await downloadNodeAsPng(node, filename);
|
|
387
340
|
} catch (err) {
|
|
388
341
|
console.warn("[clay] ArtifactDownloadMenu: PNG download failed", err);
|
|
@@ -417,9 +370,9 @@ function ArtifactDownloadMenu({
|
|
|
417
370
|
import { useEffect as useEffect3, useMemo as useMemo2, useRef as useRef2 } from "react";
|
|
418
371
|
|
|
419
372
|
// src/components/ai-elements/artifact.tsx
|
|
420
|
-
import { forwardRef as
|
|
373
|
+
import { forwardRef as forwardRef3 } from "react";
|
|
421
374
|
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
422
|
-
var Artifact =
|
|
375
|
+
var Artifact = forwardRef3(({ className, ...props }, ref) => /* @__PURE__ */ jsx6(
|
|
423
376
|
"div",
|
|
424
377
|
{
|
|
425
378
|
ref,
|
|
@@ -434,9 +387,9 @@ var ArtifactActions = ({ className, ...props }) => /* @__PURE__ */ jsx6("div", {
|
|
|
434
387
|
var ArtifactContent = ({ className, ...props }) => /* @__PURE__ */ jsx6("div", { className: cn("flex-1 overflow-auto p-4", className), ...props });
|
|
435
388
|
|
|
436
389
|
// src/components/artifacts/status-message.tsx
|
|
437
|
-
import { createElement
|
|
390
|
+
import { createElement } from "react";
|
|
438
391
|
function StatusMessage({ $tone, children }) {
|
|
439
|
-
return
|
|
392
|
+
return createElement(
|
|
440
393
|
"div",
|
|
441
394
|
{
|
|
442
395
|
className: `py-6 px-2 text-center text-sm font-medium leading-5 ${$tone === "error" ? "text-red-600" : "text-brown-70"}`
|
|
@@ -762,8 +715,12 @@ function renderBody(validConfig, artifact, data, labels) {
|
|
|
762
715
|
return /* @__PURE__ */ jsx11(ChartArtifactContent, { config: artifact.config, rows: data.rows, labels });
|
|
763
716
|
}
|
|
764
717
|
|
|
765
|
-
// src/components/artifacts/
|
|
766
|
-
import { useEffect as useEffect4, useMemo as useMemo3 } from "react";
|
|
718
|
+
// src/components/artifacts/deck-artifact/deck-artifact.tsx
|
|
719
|
+
import { useEffect as useEffect4, useMemo as useMemo3, useState as useState5 } from "react";
|
|
720
|
+
import { createPortal } from "react-dom";
|
|
721
|
+
|
|
722
|
+
// src/components/artifacts/deck-artifact/deck-artifact-content.tsx
|
|
723
|
+
import { useCallback as useCallback4, useLayoutEffect as useLayoutEffect2, useRef as useRef4, useState as useState4 } from "react";
|
|
767
724
|
|
|
768
725
|
// src/components/artifacts/table-artifact/table-artifact-content.constants.ts
|
|
769
726
|
var TABLE_STATUS = {
|
|
@@ -777,14 +734,10 @@ var TABLE_STATUS = {
|
|
|
777
734
|
function formatCell(row, column) {
|
|
778
735
|
return row[column.key] ?? "";
|
|
779
736
|
}
|
|
780
|
-
var
|
|
781
|
-
var CELL_CLASS = "p-4 text-sm font-normal text-foreground align-top min-w-[150px] text-left";
|
|
782
|
-
var ROW_CLASSES = "border-b-brown-30 bg-background/70 hover:bg-secondary";
|
|
783
|
-
var DATA_ROW_CLASSES = `${ROW_CLASSES} animate-in fade-in duration-300`;
|
|
784
|
-
var SCROLL_SHADOW = "0 1px 2px rgb(0 0 0 / 0.01), 0 6px 12px -2px rgb(0 0 0 / 0.03)";
|
|
737
|
+
var DATA_ROW_CLASSES = `${DATA_TABLE_ROW_CLASS} animate-in fade-in duration-300`;
|
|
785
738
|
|
|
786
739
|
// src/components/artifacts/table-artifact/table-artifact-content.tsx
|
|
787
|
-
import { jsx as jsx12
|
|
740
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
788
741
|
function TableArtifactContent({
|
|
789
742
|
columns,
|
|
790
743
|
data,
|
|
@@ -809,33 +762,352 @@ function TableArtifactContent({
|
|
|
809
762
|
return /* @__PURE__ */ jsx12(ArtifactTable, { columns, maxBodyHeight, children: data.rows.length === 0 ? renderEmptyRow(columns.length, labels.empty) : renderDataRows(columns, data.rows) });
|
|
810
763
|
}
|
|
811
764
|
function ArtifactTable({ columns, maxBodyHeight, children }) {
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
{
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
children: /* @__PURE__ */ jsx12(TableRow, { className: "hover:bg-transparent", children: columns.map((column) => /* @__PURE__ */ jsx12(TableHead, { scope: "col", className: HEAD_CLASS, children: column.label }, column.key)) })
|
|
821
|
-
}
|
|
822
|
-
),
|
|
823
|
-
/* @__PURE__ */ jsx12(TableBody, { children })
|
|
824
|
-
] }) });
|
|
765
|
+
return /* @__PURE__ */ jsx12(
|
|
766
|
+
DataTable,
|
|
767
|
+
{
|
|
768
|
+
maxBodyHeight,
|
|
769
|
+
header: /* @__PURE__ */ jsx12(TableRow, { className: "hover:bg-transparent", children: columns.map((column) => /* @__PURE__ */ jsx12(TableHead, { scope: "col", className: DATA_TABLE_HEAD_CLASS, children: column.label }, column.key)) }),
|
|
770
|
+
children
|
|
771
|
+
}
|
|
772
|
+
);
|
|
825
773
|
}
|
|
826
774
|
function renderShimmerRows(columns, count) {
|
|
827
|
-
return Array.from({ length: count }).map((_, index) => /* @__PURE__ */ jsx12(TableRow, { className:
|
|
775
|
+
return Array.from({ length: count }).map((_, index) => /* @__PURE__ */ jsx12(TableRow, { className: DATA_TABLE_ROW_CLASS, "aria-hidden": "true", children: columns.map((column) => /* @__PURE__ */ jsx12(TableCell, { className: DATA_TABLE_CELL_CLASS, children: /* @__PURE__ */ jsx12("span", { className: "block h-3 w-3/4 animate-pulse rounded bg-muted-foreground/20" }) }, column.key)) }, `shimmer-${index}`));
|
|
828
776
|
}
|
|
829
777
|
function renderDataRows(columns, rows) {
|
|
830
|
-
return rows.map((row, index) => /* @__PURE__ */ jsx12(TableRow, { className: DATA_ROW_CLASSES, children: columns.map((column) => /* @__PURE__ */ jsx12(TableCell, { className:
|
|
778
|
+
return rows.map((row, index) => /* @__PURE__ */ jsx12(TableRow, { className: DATA_ROW_CLASSES, children: columns.map((column) => /* @__PURE__ */ jsx12(TableCell, { className: DATA_TABLE_CELL_CLASS, children: formatCell(row, column) }, column.key)) }, index));
|
|
831
779
|
}
|
|
832
780
|
function renderEmptyRow(colSpan, emptyMessage) {
|
|
833
781
|
return /* @__PURE__ */ jsx12(TableRow, { className: "hover:bg-transparent", children: /* @__PURE__ */ jsx12(TableCell, { colSpan, className: "py-6 text-center text-sm text-muted-foreground", children: emptyMessage }) });
|
|
834
782
|
}
|
|
835
783
|
|
|
836
|
-
// src/components/artifacts/
|
|
837
|
-
|
|
838
|
-
|
|
784
|
+
// src/components/artifacts/deck-artifact/deck-markdown.tsx
|
|
785
|
+
import ReactMarkdown from "react-markdown";
|
|
786
|
+
import remarkBreaks from "remark-breaks";
|
|
787
|
+
import remarkGfm from "remark-gfm";
|
|
788
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
789
|
+
function sanitize(text) {
|
|
790
|
+
return text.split("\n").filter((line) => {
|
|
791
|
+
const t = line.trim();
|
|
792
|
+
return !(t.startsWith("<!-- table-title:") && t.endsWith("-->"));
|
|
793
|
+
}).join("\n");
|
|
794
|
+
}
|
|
795
|
+
var MARKDOWN_COMPONENTS = {
|
|
796
|
+
h1: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("h1", { className: "text-[30px] font-semibold leading-tight text-foreground mb-3", ...props }),
|
|
797
|
+
h2: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("h2", { className: "text-[26px] font-semibold leading-tight text-foreground mb-2", ...props }),
|
|
798
|
+
h3: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("h3", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
|
|
799
|
+
h4: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("h4", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
|
|
800
|
+
h5: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("h5", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
|
|
801
|
+
h6: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("h6", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
|
|
802
|
+
p: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("p", { className: "text-[22px] leading-relaxed text-foreground my-2", ...props }),
|
|
803
|
+
ul: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("ul", { className: "list-disc pl-7 text-[22px] leading-relaxed text-foreground my-2", ...props }),
|
|
804
|
+
ol: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("ol", { className: "list-decimal pl-7 text-[22px] leading-relaxed text-foreground my-2", ...props }),
|
|
805
|
+
// react-markdown injects list metadata (`ordered` / `index` / `checked`) that must not leak to the DOM.
|
|
806
|
+
li: ({ node: _node, ordered: _ordered, index: _index, checked: _checked, ...props }) => /* @__PURE__ */ jsx13("li", { className: "my-1", ...props }),
|
|
807
|
+
strong: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("strong", { className: "font-semibold", ...props }),
|
|
808
|
+
em: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("em", { className: "italic", ...props }),
|
|
809
|
+
// Gate `<img src>` against an http(s) allowlist. react-markdown v8 percent-encodes the URL but
|
|
810
|
+
// does NOT protocol-filter image src (unlike link href), so an LLM-authored
|
|
811
|
+
// `` / `` or a tracking-pixel `` would otherwise render
|
|
812
|
+
// with the raw URL. Unsafe src → render nothing.
|
|
813
|
+
img: ({ node: _node, src, ...props }) => typeof src === "string" && isSafeDownloadUrl(src) ? /* @__PURE__ */ jsx13("img", { src, className: "max-w-full", ...props }) : null,
|
|
814
|
+
a: ({ node: _node, ...props }) => (
|
|
815
|
+
// `rel` is forced AFTER `{...props}` so it can't be overridden — if a consumer ever adds
|
|
816
|
+
// `linkTarget="_blank"`, LLM-authored links still can't reach `window.opener`.
|
|
817
|
+
/* @__PURE__ */ jsx13("a", { className: "underline underline-offset-2", ...props, rel: "noopener noreferrer" })
|
|
818
|
+
),
|
|
819
|
+
// react-markdown passes `inline` to distinguish inline code from fenced blocks — strip it from the DOM.
|
|
820
|
+
code: ({ node: _node, inline: _inline, ...props }) => /* @__PURE__ */ jsx13("code", { className: "rounded bg-muted px-1.5 py-0.5 font-mono text-[18px]", ...props }),
|
|
821
|
+
blockquote: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("blockquote", { className: "border-l-2 border-brown-alpha-12 pl-4 text-[22px] text-muted-foreground", ...props }),
|
|
822
|
+
hr: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("hr", { className: "my-4 border-brown-alpha-12", ...props }),
|
|
823
|
+
table: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsx13("table", { className: "w-full border-collapse text-[20px]", ...props }) }),
|
|
824
|
+
// react-markdown passes `isHeader` to cell renderers — strip it so it never reaches the DOM.
|
|
825
|
+
th: ({ node: _node, isHeader: _isHeader, ...props }) => /* @__PURE__ */ jsx13("th", { className: "border-b border-brown-alpha-12 px-3 py-1.5 text-left font-medium", ...props }),
|
|
826
|
+
td: ({ node: _node, isHeader: _isHeader, ...props }) => /* @__PURE__ */ jsx13("td", { className: "border-b border-brown-alpha-12 px-3 py-1.5", ...props })
|
|
827
|
+
};
|
|
828
|
+
function DeckMarkdown({ markdown }) {
|
|
829
|
+
return /* @__PURE__ */ jsx13(ReactMarkdown, { remarkPlugins: [remarkGfm, remarkBreaks], components: MARKDOWN_COMPONENTS, children: sanitize(markdown) });
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
// src/components/artifacts/deck-artifact/slide-renderers.tsx
|
|
833
|
+
import { useLayoutEffect, useRef as useRef3, useState as useState3 } from "react";
|
|
834
|
+
import { jsx as jsx14, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
835
|
+
function safeLogoUrl(meta) {
|
|
836
|
+
return meta?.logoUrl && isSafeDownloadUrl(meta.logoUrl) ? meta.logoUrl : null;
|
|
837
|
+
}
|
|
838
|
+
var DESIGN_W = 1280;
|
|
839
|
+
var DESIGN_H = 720;
|
|
840
|
+
var EYEBROW_H = 84;
|
|
841
|
+
var CANVAS_LOGO_MAX_H = 48;
|
|
842
|
+
var ACCENT_FONT = { fontFamily: `"${fontFamilies.CRIMSON_PRO}", serif`, fontStyle: "italic" };
|
|
843
|
+
function SlideFrame({ meta, children, accent = false, bare = false }) {
|
|
844
|
+
const frameRef = useRef3(null);
|
|
845
|
+
const [scale, setScale] = useState3(null);
|
|
846
|
+
useLayoutEffect(() => {
|
|
847
|
+
const el = frameRef.current;
|
|
848
|
+
if (!el) return;
|
|
849
|
+
const apply = (width) => {
|
|
850
|
+
if (width > 0) setScale(width / DESIGN_W);
|
|
851
|
+
};
|
|
852
|
+
apply(el.clientWidth);
|
|
853
|
+
const ro = new ResizeObserver((entries) => apply(entries[0]?.contentRect.width ?? 0));
|
|
854
|
+
ro.observe(el);
|
|
855
|
+
return () => ro.disconnect();
|
|
856
|
+
}, []);
|
|
857
|
+
const bg = accent ? "bg-indigo-600" : "bg-deck-canvas";
|
|
858
|
+
const eyebrowColor = accent ? "text-white/70" : "text-brown-60";
|
|
859
|
+
const borderColor = accent ? "border-white/20" : "border-brown-alpha-12";
|
|
860
|
+
const logoSrc = safeLogoUrl(meta);
|
|
861
|
+
return /* @__PURE__ */ jsx14("div", { ref: frameRef, className: `relative aspect-[16/9] w-full overflow-hidden rounded-lg ${bg}`, children: /* @__PURE__ */ jsxs5(
|
|
862
|
+
"div",
|
|
863
|
+
{
|
|
864
|
+
className: "absolute left-0 top-0 origin-top-left",
|
|
865
|
+
style: {
|
|
866
|
+
width: DESIGN_W,
|
|
867
|
+
height: DESIGN_H,
|
|
868
|
+
transform: `scale(${scale ?? 0})`,
|
|
869
|
+
visibility: scale === null ? "hidden" : "visible"
|
|
870
|
+
},
|
|
871
|
+
children: [
|
|
872
|
+
!bare ? /* @__PURE__ */ jsxs5(
|
|
873
|
+
"div",
|
|
874
|
+
{
|
|
875
|
+
className: `absolute inset-x-0 top-0 flex items-center justify-between border-b px-16 ${borderColor}`,
|
|
876
|
+
style: { height: EYEBROW_H },
|
|
877
|
+
children: [
|
|
878
|
+
meta?.eyebrow ? /* @__PURE__ */ jsx14("span", { className: eyebrowColor, style: { ...ACCENT_FONT, fontSize: 22 }, children: meta.eyebrow }) : /* @__PURE__ */ jsx14("span", {}),
|
|
879
|
+
logoSrc ? /* @__PURE__ */ jsx14("img", { src: logoSrc, alt: "", className: "object-contain", style: { maxHeight: CANVAS_LOGO_MAX_H } }) : null
|
|
880
|
+
]
|
|
881
|
+
}
|
|
882
|
+
) : null,
|
|
883
|
+
/* @__PURE__ */ jsx14("div", { className: "absolute inset-x-0 bottom-0 overflow-hidden", style: { top: bare ? 0 : EYEBROW_H }, children })
|
|
884
|
+
]
|
|
885
|
+
}
|
|
886
|
+
) });
|
|
887
|
+
}
|
|
888
|
+
function TitleSlide({ slide, meta }) {
|
|
889
|
+
const logoSrc = safeLogoUrl(meta);
|
|
890
|
+
return /* @__PURE__ */ jsx14(SlideFrame, { meta, bare: true, children: /* @__PURE__ */ jsxs5("div", { className: "flex h-full flex-col justify-center px-24 py-16", children: [
|
|
891
|
+
logoSrc ? /* @__PURE__ */ jsx14(
|
|
892
|
+
"img",
|
|
893
|
+
{
|
|
894
|
+
src: logoSrc,
|
|
895
|
+
alt: "",
|
|
896
|
+
className: "mb-16 object-contain object-left",
|
|
897
|
+
style: { maxHeight: 56, maxWidth: 380 }
|
|
898
|
+
}
|
|
899
|
+
) : null,
|
|
900
|
+
/* @__PURE__ */ jsx14(
|
|
901
|
+
"h1",
|
|
902
|
+
{
|
|
903
|
+
className: "font-bold tracking-tight text-brown-100",
|
|
904
|
+
style: { fontSize: 92, lineHeight: 1.04, maxWidth: 1060 },
|
|
905
|
+
children: slide.title
|
|
906
|
+
}
|
|
907
|
+
),
|
|
908
|
+
slide.subtitle ? /* @__PURE__ */ jsx14("p", { className: "mt-7 text-brown-70", style: { ...ACCENT_FONT, fontSize: 34 }, children: slide.subtitle }) : null,
|
|
909
|
+
slide.description ? /* @__PURE__ */ jsx14("p", { className: "mt-4 leading-relaxed text-brown-70", style: { fontSize: 24, maxWidth: 880 }, children: slide.description }) : null,
|
|
910
|
+
meta?.date ? /* @__PURE__ */ jsx14("p", { className: "mt-10 text-brown-70", style: { ...ACCENT_FONT, fontSize: 30 }, children: meta.date }) : null
|
|
911
|
+
] }) });
|
|
912
|
+
}
|
|
913
|
+
function AgendaSlide({ slide, meta, labels }) {
|
|
914
|
+
const items = slide.items ?? [];
|
|
915
|
+
return /* @__PURE__ */ jsx14(SlideFrame, { meta, children: /* @__PURE__ */ jsxs5("div", { className: "h-full px-24 py-14", children: [
|
|
916
|
+
/* @__PURE__ */ jsx14("h2", { className: "mb-10 font-bold text-brown-90", style: { fontSize: 40 }, children: slide.title || labels.agenda }),
|
|
917
|
+
/* @__PURE__ */ jsx14("div", { className: "flex flex-col", children: items.map((item, i) => /* @__PURE__ */ jsxs5("div", { className: "flex items-baseline gap-6 border-b border-brown-alpha-12 py-5", children: [
|
|
918
|
+
/* @__PURE__ */ jsx14("span", { className: "shrink-0 text-indigo-600", style: { ...ACCENT_FONT, fontSize: 28, width: 64 }, children: String(i + 1).padStart(2, "0") }),
|
|
919
|
+
/* @__PURE__ */ jsx14("span", { className: "text-brown-90", style: { fontSize: 28 }, children: item })
|
|
920
|
+
] }, i)) })
|
|
921
|
+
] }) });
|
|
922
|
+
}
|
|
923
|
+
function SectionSlide({ slide, meta }) {
|
|
924
|
+
return /* @__PURE__ */ jsx14(SlideFrame, { meta, accent: true, children: /* @__PURE__ */ jsxs5("div", { className: "flex h-full flex-col justify-center gap-6 px-24", children: [
|
|
925
|
+
/* @__PURE__ */ jsx14("h2", { className: "font-bold text-white", style: { fontSize: 72, lineHeight: 1.05, maxWidth: 940 }, children: slide.title }),
|
|
926
|
+
/* @__PURE__ */ jsx14("div", { className: "mt-2 bg-white/50", style: { width: 96, height: 5 } })
|
|
927
|
+
] }) });
|
|
928
|
+
}
|
|
929
|
+
function ClosingSlide({ meta, labels }) {
|
|
930
|
+
return /* @__PURE__ */ jsx14(SlideFrame, { meta, children: /* @__PURE__ */ jsxs5("div", { className: "flex h-full flex-col items-center justify-center gap-6 px-24 text-center", children: [
|
|
931
|
+
/* @__PURE__ */ jsx14("h1", { className: "font-bold text-brown-100", style: { fontSize: 72 }, children: labels.thankYou }),
|
|
932
|
+
/* @__PURE__ */ jsx14("p", { className: "text-indigo-600", style: { ...ACCENT_FONT, fontSize: 36 }, children: labels.questions })
|
|
933
|
+
] }) });
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
// src/components/artifacts/deck-artifact/deck-artifact-content.tsx
|
|
937
|
+
import { jsx as jsx15, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
938
|
+
var TABLE_BLOCK_MAX_SHIMMER_ROWS = 10;
|
|
939
|
+
var TABLE_CHROME_RESERVE = 56;
|
|
940
|
+
var VISUAL_FALLBACK_HEIGHT = 360;
|
|
941
|
+
function DeckArtifactContent({
|
|
942
|
+
slides,
|
|
943
|
+
labels,
|
|
944
|
+
onNavigate,
|
|
945
|
+
meta,
|
|
946
|
+
onDark = false,
|
|
947
|
+
currentSlide,
|
|
948
|
+
onSlideChange
|
|
949
|
+
}) {
|
|
950
|
+
const navBtnClass = onDark ? "[&_svg]:!text-white hover:!bg-white/20 disabled:opacity-40" : void 0;
|
|
951
|
+
const navBtnSize = onDark ? "medium" : "small";
|
|
952
|
+
const isControlled = currentSlide !== void 0;
|
|
953
|
+
const [internalIndex, setInternalIndex] = useState4(0);
|
|
954
|
+
const index = isControlled ? currentSlide : internalIndex;
|
|
955
|
+
const current = Math.min(index, slides.length - 1);
|
|
956
|
+
const slide = slides[current];
|
|
957
|
+
const goTo = useCallback4(
|
|
958
|
+
(next) => {
|
|
959
|
+
const clamped = Math.max(0, Math.min(next, slides.length - 1));
|
|
960
|
+
if (isControlled) onSlideChange?.(clamped);
|
|
961
|
+
else setInternalIndex(clamped);
|
|
962
|
+
onNavigate?.(clamped);
|
|
963
|
+
},
|
|
964
|
+
[slides.length, onNavigate, isControlled, onSlideChange]
|
|
965
|
+
);
|
|
966
|
+
const position = labels.position.replace("{current}", String(current + 1)).replace("{total}", String(slides.length));
|
|
967
|
+
return /* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-3 p-4", children: [
|
|
968
|
+
/* @__PURE__ */ jsx15(SlideDispatch, { slide, labels, meta }),
|
|
969
|
+
/* @__PURE__ */ jsxs6(
|
|
970
|
+
"div",
|
|
971
|
+
{
|
|
972
|
+
className: `flex items-center justify-between border-t pt-2 ${onDark ? "border-white/20" : "border-brown-alpha-12"}`,
|
|
973
|
+
children: [
|
|
974
|
+
/* @__PURE__ */ jsx15(
|
|
975
|
+
IconButton,
|
|
976
|
+
{
|
|
977
|
+
icon: IconChevronLeft,
|
|
978
|
+
size: navBtnSize,
|
|
979
|
+
className: navBtnClass,
|
|
980
|
+
"aria-label": labels.previous,
|
|
981
|
+
disabled: current === 0,
|
|
982
|
+
onClick: () => goTo(current - 1)
|
|
983
|
+
}
|
|
984
|
+
),
|
|
985
|
+
/* @__PURE__ */ jsx15("span", { className: `text-xs font-medium ${onDark ? "text-white/70" : "text-brown-70"}`, children: position }),
|
|
986
|
+
/* @__PURE__ */ jsx15(
|
|
987
|
+
IconButton,
|
|
988
|
+
{
|
|
989
|
+
icon: IconChevronRight,
|
|
990
|
+
size: navBtnSize,
|
|
991
|
+
className: navBtnClass,
|
|
992
|
+
"aria-label": labels.next,
|
|
993
|
+
disabled: current === slides.length - 1,
|
|
994
|
+
onClick: () => goTo(current + 1)
|
|
995
|
+
}
|
|
996
|
+
)
|
|
997
|
+
]
|
|
998
|
+
}
|
|
999
|
+
)
|
|
1000
|
+
] });
|
|
1001
|
+
}
|
|
1002
|
+
function SlideDispatch({ slide, labels, meta }) {
|
|
1003
|
+
const kind = slide.kind ?? deckSlideKinds.CONTENT;
|
|
1004
|
+
switch (kind) {
|
|
1005
|
+
case deckSlideKinds.TITLE:
|
|
1006
|
+
return /* @__PURE__ */ jsx15(TitleSlide, { slide, meta });
|
|
1007
|
+
case deckSlideKinds.AGENDA:
|
|
1008
|
+
return /* @__PURE__ */ jsx15(AgendaSlide, { slide, meta, labels });
|
|
1009
|
+
case deckSlideKinds.SECTION:
|
|
1010
|
+
return /* @__PURE__ */ jsx15(SectionSlide, { slide, meta });
|
|
1011
|
+
case deckSlideKinds.CLOSING:
|
|
1012
|
+
return /* @__PURE__ */ jsx15(ClosingSlide, { meta, labels });
|
|
1013
|
+
case deckSlideKinds.CONTENT:
|
|
1014
|
+
default:
|
|
1015
|
+
return /* @__PURE__ */ jsx15(ContentSlide, { slide, meta, labels });
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
function isVisualBlock(block) {
|
|
1019
|
+
return block.type === deckBlockTypes.CHART || block.type === deckBlockTypes.TABLE;
|
|
1020
|
+
}
|
|
1021
|
+
function ContentSlide({ slide, meta, labels }) {
|
|
1022
|
+
const content = slide.content ?? [];
|
|
1023
|
+
const visuals = content.filter(isVisualBlock);
|
|
1024
|
+
const texts = content.filter(
|
|
1025
|
+
(b) => b.type === deckBlockTypes.TEXT
|
|
1026
|
+
);
|
|
1027
|
+
if (visuals.length === 1 && texts.length > 0) {
|
|
1028
|
+
return /* @__PURE__ */ jsx15(SlideFrame, { meta, children: /* @__PURE__ */ jsxs6("div", { className: "flex h-full items-stretch gap-12 px-16 py-12", children: [
|
|
1029
|
+
/* @__PURE__ */ jsx15("div", { className: "flex w-[42%] shrink-0 flex-col overflow-hidden", children: /* @__PURE__ */ jsxs6(AutoFit, { children: [
|
|
1030
|
+
/* @__PURE__ */ jsx15("h3", { className: "mb-5 font-bold leading-tight text-foreground", style: { fontSize: 34 }, children: slide.title }),
|
|
1031
|
+
texts.map((block, i) => /* @__PURE__ */ jsx15(DeckMarkdown, { markdown: block.markdown }, i))
|
|
1032
|
+
] }) }),
|
|
1033
|
+
/* @__PURE__ */ jsx15("div", { className: "min-h-0 min-w-0 flex-1", children: /* @__PURE__ */ jsx15(FillVisual, { block: visuals[0], labels }) })
|
|
1034
|
+
] }) });
|
|
1035
|
+
}
|
|
1036
|
+
if (visuals.length > 0) {
|
|
1037
|
+
return /* @__PURE__ */ jsx15(SlideFrame, { meta, children: /* @__PURE__ */ jsxs6("div", { className: "flex h-full flex-col gap-5 px-16 py-10", children: [
|
|
1038
|
+
/* @__PURE__ */ jsx15("h3", { className: "shrink-0 font-bold leading-tight text-foreground", style: { fontSize: 32 }, children: slide.title }),
|
|
1039
|
+
content.map(
|
|
1040
|
+
(block, i) => isVisualBlock(block) ? /* @__PURE__ */ jsx15("div", { className: "min-h-0 min-w-0 flex-1", children: /* @__PURE__ */ jsx15(FillVisual, { block, labels }) }, i) : /* @__PURE__ */ jsx15("div", { className: "shrink-0 overflow-hidden", children: /* @__PURE__ */ jsx15(DeckMarkdown, { markdown: block.markdown }) }, i)
|
|
1041
|
+
)
|
|
1042
|
+
] }) });
|
|
1043
|
+
}
|
|
1044
|
+
return /* @__PURE__ */ jsx15(SlideFrame, { meta, children: /* @__PURE__ */ jsx15("div", { className: "h-full px-24 py-12", children: /* @__PURE__ */ jsxs6(AutoFit, { children: [
|
|
1045
|
+
/* @__PURE__ */ jsx15("h3", { className: "mb-6 font-bold leading-tight text-foreground", style: { fontSize: 38 }, children: slide.title }),
|
|
1046
|
+
texts.map((block, i) => /* @__PURE__ */ jsx15(DeckMarkdown, { markdown: block.markdown }, i))
|
|
1047
|
+
] }) }) });
|
|
1048
|
+
}
|
|
1049
|
+
function AutoFit({ children }) {
|
|
1050
|
+
const boxRef = useRef4(null);
|
|
1051
|
+
const contentRef = useRef4(null);
|
|
1052
|
+
const [fit, setFit] = useState4({ scale: 1, height: 0 });
|
|
1053
|
+
useLayoutEffect2(() => {
|
|
1054
|
+
const boxEl = boxRef.current;
|
|
1055
|
+
const contentEl = contentRef.current;
|
|
1056
|
+
if (!boxEl || !contentEl) return;
|
|
1057
|
+
const measure = () => {
|
|
1058
|
+
const avail = boxEl.clientHeight;
|
|
1059
|
+
const natural = contentEl.offsetHeight;
|
|
1060
|
+
const scale = avail > 0 && natural > avail ? avail / natural : 1;
|
|
1061
|
+
setFit({ scale, height: natural * scale });
|
|
1062
|
+
};
|
|
1063
|
+
measure();
|
|
1064
|
+
const ro = new ResizeObserver(measure);
|
|
1065
|
+
ro.observe(boxEl);
|
|
1066
|
+
ro.observe(contentEl);
|
|
1067
|
+
return () => ro.disconnect();
|
|
1068
|
+
}, []);
|
|
1069
|
+
const scaled = fit.scale < 1;
|
|
1070
|
+
return /* @__PURE__ */ jsx15("div", { ref: boxRef, className: "flex h-full min-h-0 w-full flex-col justify-center overflow-hidden", children: /* @__PURE__ */ jsx15("div", { style: scaled ? { height: fit.height } : void 0, children: /* @__PURE__ */ jsx15(
|
|
1071
|
+
"div",
|
|
1072
|
+
{
|
|
1073
|
+
ref: contentRef,
|
|
1074
|
+
className: "w-full origin-top-left",
|
|
1075
|
+
style: scaled ? { transform: `scale(${fit.scale})` } : void 0,
|
|
1076
|
+
children
|
|
1077
|
+
}
|
|
1078
|
+
) }) });
|
|
1079
|
+
}
|
|
1080
|
+
function FillVisual({ block, labels }) {
|
|
1081
|
+
const ref = useRef4(null);
|
|
1082
|
+
const [height, setHeight] = useState4(VISUAL_FALLBACK_HEIGHT);
|
|
1083
|
+
useLayoutEffect2(() => {
|
|
1084
|
+
const el = ref.current;
|
|
1085
|
+
if (!el) return;
|
|
1086
|
+
const apply = (h) => {
|
|
1087
|
+
if (h > 0) setHeight(h);
|
|
1088
|
+
};
|
|
1089
|
+
apply(el.clientHeight);
|
|
1090
|
+
const ro = new ResizeObserver((entries) => apply(entries[0]?.contentRect.height ?? 0));
|
|
1091
|
+
ro.observe(el);
|
|
1092
|
+
return () => ro.disconnect();
|
|
1093
|
+
}, []);
|
|
1094
|
+
const chartLabels = labels.chart ?? DEFAULT_CHART_ARTIFACT_LABELS;
|
|
1095
|
+
return /* @__PURE__ */ jsx15("div", { ref, className: "h-full min-h-0 w-full overflow-hidden", children: block.type === deckBlockTypes.CHART ? (
|
|
1096
|
+
// ChartArtifactContent assumes a non-empty rowset (the standalone ChartArtifact guards
|
|
1097
|
+
// `rows.length > 0` upstream); mirror that guard here so an empty inline chart shows the
|
|
1098
|
+
// localized empty status instead of a blank chart area.
|
|
1099
|
+
block.rows.length === 0 ? /* @__PURE__ */ jsx15(StatusMessage, { $tone: "info", children: chartLabels.empty }) : /* @__PURE__ */ jsx15("div", { style: { height }, children: /* @__PURE__ */ jsx15(ChartArtifactContent, { config: block.config, rows: block.rows, labels: chartLabels }) })
|
|
1100
|
+
) : /* @__PURE__ */ jsx15(
|
|
1101
|
+
TableArtifactContent,
|
|
1102
|
+
{
|
|
1103
|
+
columns: block.config.columns,
|
|
1104
|
+
data: { status: "ready", rows: block.rows, error: null },
|
|
1105
|
+
knownRowCount: block.config.stats?.rowCount ?? block.rows.length,
|
|
1106
|
+
maxShimmerRows: TABLE_BLOCK_MAX_SHIMMER_ROWS,
|
|
1107
|
+
maxBodyHeight: Math.max(0, height - TABLE_CHROME_RESERVE),
|
|
1108
|
+
labels: labels.table ?? DEFAULT_TABLE_ARTIFACT_LABELS
|
|
1109
|
+
}
|
|
1110
|
+
) });
|
|
839
1111
|
}
|
|
840
1112
|
|
|
841
1113
|
// src/components/artifacts/table-artifact/validate.ts
|
|
@@ -854,19 +1126,206 @@ function isValidTableColumn(column) {
|
|
|
854
1126
|
return true;
|
|
855
1127
|
}
|
|
856
1128
|
|
|
857
|
-
// src/components/artifacts/
|
|
858
|
-
|
|
1129
|
+
// src/components/artifacts/deck-artifact/validate.ts
|
|
1130
|
+
function isValidDeckConfig(config) {
|
|
1131
|
+
if (!config || typeof config !== "object") return false;
|
|
1132
|
+
const candidate = config;
|
|
1133
|
+
if (!Array.isArray(candidate.slides)) return false;
|
|
1134
|
+
if (candidate.slides.length === 0) return false;
|
|
1135
|
+
return candidate.slides.every(isValidDeckSlide);
|
|
1136
|
+
}
|
|
1137
|
+
function isValidDeckSlide(slide) {
|
|
1138
|
+
if (!slide || typeof slide !== "object") return false;
|
|
1139
|
+
const candidate = slide;
|
|
1140
|
+
if (typeof candidate.title !== "string") return false;
|
|
1141
|
+
const kind = typeof candidate.kind === "string" ? candidate.kind : deckSlideKinds.CONTENT;
|
|
1142
|
+
if (kind === deckSlideKinds.CONTENT && !Array.isArray(candidate.content)) return false;
|
|
1143
|
+
const content = Array.isArray(candidate.content) ? candidate.content : [];
|
|
1144
|
+
if (candidate.items != null) {
|
|
1145
|
+
if (!Array.isArray(candidate.items)) return false;
|
|
1146
|
+
if (!candidate.items.every((item) => typeof item === "string")) return false;
|
|
1147
|
+
}
|
|
1148
|
+
return content.every(isValidDeckBlock);
|
|
1149
|
+
}
|
|
1150
|
+
function isValidDeckBlock(block) {
|
|
1151
|
+
if (!block || typeof block !== "object") return false;
|
|
1152
|
+
const candidate = block;
|
|
1153
|
+
switch (candidate.type) {
|
|
1154
|
+
case deckBlockTypes.TEXT:
|
|
1155
|
+
return typeof candidate.markdown === "string";
|
|
1156
|
+
case deckBlockTypes.CHART:
|
|
1157
|
+
return isValidChartConfig(candidate.config) && Array.isArray(candidate.rows);
|
|
1158
|
+
case deckBlockTypes.TABLE:
|
|
1159
|
+
return isValidTableConfig(candidate.config) && Array.isArray(candidate.rows);
|
|
1160
|
+
default:
|
|
1161
|
+
return false;
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
// src/components/artifacts/deck-artifact/deck-artifact.tsx
|
|
1166
|
+
import { Fragment, jsx as jsx16, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
859
1167
|
var TITLE_CLASSES2 = "text-sm font-semibold text-foreground";
|
|
1168
|
+
function DeckArtifact({ artifact, labels, callbacks }) {
|
|
1169
|
+
const validConfig = isValidDeckConfig(artifact.config);
|
|
1170
|
+
const [isFullscreen, setIsFullscreen] = useState5(false);
|
|
1171
|
+
const [currentSlide, setCurrentSlide] = useState5(0);
|
|
1172
|
+
useEffect4(() => {
|
|
1173
|
+
if (validConfig) return;
|
|
1174
|
+
console.warn("[clay] DeckArtifact: malformed `config` \u2014 skipping render.");
|
|
1175
|
+
}, [validConfig]);
|
|
1176
|
+
useEffect4(() => {
|
|
1177
|
+
if (!isFullscreen) return;
|
|
1178
|
+
const handleKey = (e) => {
|
|
1179
|
+
if (e.key === "Escape") setIsFullscreen(false);
|
|
1180
|
+
};
|
|
1181
|
+
document.addEventListener("keydown", handleKey);
|
|
1182
|
+
const previousOverflow = document.documentElement.style.overflow;
|
|
1183
|
+
document.documentElement.style.overflow = "hidden";
|
|
1184
|
+
return () => {
|
|
1185
|
+
document.removeEventListener("keydown", handleKey);
|
|
1186
|
+
document.documentElement.style.overflow = previousOverflow;
|
|
1187
|
+
};
|
|
1188
|
+
}, [isFullscreen]);
|
|
1189
|
+
const resolvedLabels = useMemo3(
|
|
1190
|
+
() => ({
|
|
1191
|
+
...DEFAULT_DECK_ARTIFACT_LABELS,
|
|
1192
|
+
...labels ?? {},
|
|
1193
|
+
chart: { ...DEFAULT_CHART_ARTIFACT_LABELS, ...labels?.chart ?? {} },
|
|
1194
|
+
table: { ...DEFAULT_TABLE_ARTIFACT_LABELS, ...labels?.table ?? {} }
|
|
1195
|
+
}),
|
|
1196
|
+
[labels]
|
|
1197
|
+
);
|
|
1198
|
+
const onNavigate = callbacks?.onNavigate;
|
|
1199
|
+
const handleNavigate = onNavigate ? (slideIndex) => onNavigate(artifact, slideIndex) : void 0;
|
|
1200
|
+
const onDownload = callbacks?.onDownload;
|
|
1201
|
+
const handleDownload = onDownload ? () => onDownload(artifact) : void 0;
|
|
1202
|
+
const presignedUrl = artifact.protectedAsset?.presignedUrl ?? null;
|
|
1203
|
+
const showDownload = presignedUrl !== null && isSafeDownloadUrl(presignedUrl);
|
|
1204
|
+
const meta = artifact.config?.meta;
|
|
1205
|
+
const handleOpenFullscreen = () => setIsFullscreen(true);
|
|
1206
|
+
const handleCloseFullscreen = () => setIsFullscreen(false);
|
|
1207
|
+
const actions = /* @__PURE__ */ jsxs7(ArtifactActions, { ...{ [CAPTURE_EXCLUDE_ATTRIBUTE]: "" }, children: [
|
|
1208
|
+
showDownload ? /* @__PURE__ */ jsx16(ArtifactDownloadButton, { href: presignedUrl ?? "", label: resolvedLabels.download, onClick: handleDownload }) : null,
|
|
1209
|
+
validConfig ? /* @__PURE__ */ jsx16(
|
|
1210
|
+
IconButton,
|
|
1211
|
+
{
|
|
1212
|
+
icon: IconArrowsMaximize,
|
|
1213
|
+
size: "small",
|
|
1214
|
+
"aria-label": resolvedLabels.enterFullscreen,
|
|
1215
|
+
onClick: handleOpenFullscreen
|
|
1216
|
+
}
|
|
1217
|
+
) : null
|
|
1218
|
+
] });
|
|
1219
|
+
if (!validConfig) {
|
|
1220
|
+
return /* @__PURE__ */ jsxs7(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
|
|
1221
|
+
/* @__PURE__ */ jsxs7(ArtifactHeader, { className: "bg-background/70", children: [
|
|
1222
|
+
artifact.title ? /* @__PURE__ */ jsx16(ArtifactTitle, { className: TITLE_CLASSES2, children: artifact.title }) : /* @__PURE__ */ jsx16("span", {}),
|
|
1223
|
+
actions
|
|
1224
|
+
] }),
|
|
1225
|
+
/* @__PURE__ */ jsx16(ArtifactContent, { className: "p-0", children: /* @__PURE__ */ jsx16(StatusMessage, { $tone: "info", children: resolvedLabels.unavailable }) })
|
|
1226
|
+
] });
|
|
1227
|
+
}
|
|
1228
|
+
return /* @__PURE__ */ jsxs7(Fragment, { children: [
|
|
1229
|
+
/* @__PURE__ */ jsxs7(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
|
|
1230
|
+
/* @__PURE__ */ jsxs7(ArtifactHeader, { className: "bg-background/70", children: [
|
|
1231
|
+
artifact.title ? /* @__PURE__ */ jsx16(ArtifactTitle, { className: TITLE_CLASSES2, children: artifact.title }) : /* @__PURE__ */ jsx16("span", {}),
|
|
1232
|
+
actions
|
|
1233
|
+
] }),
|
|
1234
|
+
/* @__PURE__ */ jsx16(ArtifactContent, { className: "p-0", children: /* @__PURE__ */ jsx16(
|
|
1235
|
+
DeckArtifactContent,
|
|
1236
|
+
{
|
|
1237
|
+
slides: artifact.config.slides,
|
|
1238
|
+
labels: resolvedLabels,
|
|
1239
|
+
onNavigate: handleNavigate,
|
|
1240
|
+
meta,
|
|
1241
|
+
currentSlide,
|
|
1242
|
+
onSlideChange: setCurrentSlide
|
|
1243
|
+
}
|
|
1244
|
+
) })
|
|
1245
|
+
] }),
|
|
1246
|
+
isFullscreen && createPortal(
|
|
1247
|
+
/* @__PURE__ */ jsx16(
|
|
1248
|
+
FullscreenOverlay,
|
|
1249
|
+
{
|
|
1250
|
+
artifact,
|
|
1251
|
+
resolvedLabels,
|
|
1252
|
+
onNavigate: handleNavigate,
|
|
1253
|
+
currentSlide,
|
|
1254
|
+
onSlideChange: setCurrentSlide,
|
|
1255
|
+
onClose: handleCloseFullscreen
|
|
1256
|
+
}
|
|
1257
|
+
),
|
|
1258
|
+
document.body
|
|
1259
|
+
)
|
|
1260
|
+
] });
|
|
1261
|
+
}
|
|
1262
|
+
function FullscreenOverlay({
|
|
1263
|
+
artifact,
|
|
1264
|
+
resolvedLabels,
|
|
1265
|
+
onNavigate,
|
|
1266
|
+
currentSlide,
|
|
1267
|
+
onSlideChange,
|
|
1268
|
+
onClose
|
|
1269
|
+
}) {
|
|
1270
|
+
const meta = artifact.config?.meta;
|
|
1271
|
+
return /* @__PURE__ */ jsx16(
|
|
1272
|
+
"div",
|
|
1273
|
+
{
|
|
1274
|
+
className: "fixed inset-0 z-[2147483647] flex items-center justify-center bg-black/80",
|
|
1275
|
+
role: "dialog",
|
|
1276
|
+
"aria-modal": "true",
|
|
1277
|
+
"aria-label": resolvedLabels.exitFullscreen,
|
|
1278
|
+
children: /* @__PURE__ */ jsxs7("div", { className: "relative", style: { width: "min(94vw, calc(82vh * 16 / 9))" }, children: [
|
|
1279
|
+
/* @__PURE__ */ jsx16(
|
|
1280
|
+
DeckArtifactContent,
|
|
1281
|
+
{
|
|
1282
|
+
slides: artifact.config.slides,
|
|
1283
|
+
labels: resolvedLabels,
|
|
1284
|
+
onNavigate,
|
|
1285
|
+
meta,
|
|
1286
|
+
currentSlide,
|
|
1287
|
+
onSlideChange,
|
|
1288
|
+
onDark: true
|
|
1289
|
+
}
|
|
1290
|
+
),
|
|
1291
|
+
/* @__PURE__ */ jsxs7(
|
|
1292
|
+
"button",
|
|
1293
|
+
{
|
|
1294
|
+
className: "absolute -top-10 right-6 flex items-center gap-1.5 text-sm text-white/80 hover:text-white",
|
|
1295
|
+
"aria-label": resolvedLabels.exitFullscreen,
|
|
1296
|
+
onClick: onClose,
|
|
1297
|
+
children: [
|
|
1298
|
+
/* @__PURE__ */ jsx16(IconArrowsMinimize, { size: 16 }),
|
|
1299
|
+
/* @__PURE__ */ jsx16("span", { children: resolvedLabels.exitFullscreen })
|
|
1300
|
+
]
|
|
1301
|
+
}
|
|
1302
|
+
)
|
|
1303
|
+
] })
|
|
1304
|
+
}
|
|
1305
|
+
);
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
// src/components/artifacts/table-artifact/table-artifact.tsx
|
|
1309
|
+
import { useEffect as useEffect5, useMemo as useMemo4 } from "react";
|
|
1310
|
+
|
|
1311
|
+
// src/components/artifacts/table-artifact/use-table-artifact-data.ts
|
|
1312
|
+
function useTableArtifactData(presignedUrl, columns) {
|
|
1313
|
+
return useRowsArtifactData(presignedUrl, columns, parseCsv);
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
// src/components/artifacts/table-artifact/table-artifact.tsx
|
|
1317
|
+
import { jsx as jsx17, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1318
|
+
var TITLE_CLASSES3 = "text-sm font-semibold text-foreground";
|
|
860
1319
|
var TABLE_MAX_BODY_HEIGHT = 480;
|
|
861
1320
|
var MAX_SHIMMER_ROWS = 10;
|
|
862
1321
|
function TableArtifact({ artifact, labels, callbacks }) {
|
|
863
1322
|
const validConfig = isValidTableConfig(artifact.config);
|
|
864
1323
|
const validColumns = validConfig ? artifact.config.columns : null;
|
|
865
|
-
|
|
1324
|
+
useEffect5(() => {
|
|
866
1325
|
if (validConfig) return;
|
|
867
1326
|
console.warn("[clay] TableArtifact: malformed `config` \u2014 skipping render.");
|
|
868
1327
|
}, [validConfig]);
|
|
869
|
-
const resolvedLabels =
|
|
1328
|
+
const resolvedLabels = useMemo4(
|
|
870
1329
|
() => ({ ...DEFAULT_TABLE_ARTIFACT_LABELS, ...labels ?? {} }),
|
|
871
1330
|
[labels]
|
|
872
1331
|
);
|
|
@@ -878,10 +1337,10 @@ function TableArtifact({ artifact, labels, callbacks }) {
|
|
|
878
1337
|
const onDownload = callbacks?.onDownload;
|
|
879
1338
|
const handleDownloadClick = onDownload ? () => onDownload(artifact) : void 0;
|
|
880
1339
|
if (!validConfig || !validColumns) {
|
|
881
|
-
return /* @__PURE__ */
|
|
882
|
-
/* @__PURE__ */
|
|
883
|
-
artifact.title ? /* @__PURE__ */
|
|
884
|
-
presignedUrl ? /* @__PURE__ */
|
|
1340
|
+
return /* @__PURE__ */ jsxs8(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
|
|
1341
|
+
/* @__PURE__ */ jsxs8(ArtifactHeader, { className: "bg-background/70", children: [
|
|
1342
|
+
artifact.title ? /* @__PURE__ */ jsx17(ArtifactTitle, { className: TITLE_CLASSES3, children: artifact.title }) : /* @__PURE__ */ jsx17("span", {}),
|
|
1343
|
+
presignedUrl ? /* @__PURE__ */ jsx17(ArtifactActions, { children: /* @__PURE__ */ jsx17(
|
|
885
1344
|
ArtifactDownloadButton,
|
|
886
1345
|
{
|
|
887
1346
|
href: presignedUrl,
|
|
@@ -890,17 +1349,17 @@ function TableArtifact({ artifact, labels, callbacks }) {
|
|
|
890
1349
|
}
|
|
891
1350
|
) }) : null
|
|
892
1351
|
] }),
|
|
893
|
-
/* @__PURE__ */
|
|
1352
|
+
/* @__PURE__ */ jsx17(ArtifactContent, { className: "p-0 overflow-auto", style: { maxHeight: TABLE_MAX_BODY_HEIGHT }, children: /* @__PURE__ */ jsx17(StatusMessage, { $tone: "info", children: resolvedLabels.unavailable }) })
|
|
894
1353
|
] });
|
|
895
1354
|
}
|
|
896
1355
|
return (
|
|
897
1356
|
// The table body owns its own scroll container (`ArtifactTable` inside `TableArtifactContent`).
|
|
898
1357
|
// Disable the outer overflow container so only one scroll context exists — this prevents
|
|
899
1358
|
// double-scroll nesting and lets `useScrollShadow` find the correct scroll ancestor.
|
|
900
|
-
/* @__PURE__ */
|
|
901
|
-
/* @__PURE__ */
|
|
902
|
-
artifact.title ? /* @__PURE__ */
|
|
903
|
-
/* @__PURE__ */
|
|
1359
|
+
/* @__PURE__ */ jsxs8(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
|
|
1360
|
+
/* @__PURE__ */ jsxs8(ArtifactHeader, { className: "bg-background/70", children: [
|
|
1361
|
+
artifact.title ? /* @__PURE__ */ jsx17(ArtifactTitle, { className: TITLE_CLASSES3, children: artifact.title }) : /* @__PURE__ */ jsx17("span", {}),
|
|
1362
|
+
/* @__PURE__ */ jsx17(ArtifactActions, { children: /* @__PURE__ */ jsx17(
|
|
904
1363
|
ArtifactDownloadButton,
|
|
905
1364
|
{
|
|
906
1365
|
href: presignedUrl ?? "",
|
|
@@ -909,7 +1368,7 @@ function TableArtifact({ artifact, labels, callbacks }) {
|
|
|
909
1368
|
}
|
|
910
1369
|
) })
|
|
911
1370
|
] }),
|
|
912
|
-
/* @__PURE__ */
|
|
1371
|
+
/* @__PURE__ */ jsx17(ArtifactContent, { className: "p-0 overflow-visible", style: { maxHeight: "none" }, children: /* @__PURE__ */ jsx17(
|
|
913
1372
|
TableArtifactContent,
|
|
914
1373
|
{
|
|
915
1374
|
columns: validColumns,
|
|
@@ -937,6 +1396,65 @@ var ChartArtifactService = {
|
|
|
937
1396
|
toClipboardText: chartArtifactToClipboardText
|
|
938
1397
|
};
|
|
939
1398
|
|
|
1399
|
+
// src/components/artifacts/deck-artifact/to-clipboard-text.ts
|
|
1400
|
+
function deckArtifactToClipboardText(artifact) {
|
|
1401
|
+
const header = artifact.title?.trim() || "Deck";
|
|
1402
|
+
const slides = artifact.config?.slides ?? [];
|
|
1403
|
+
const body = slides.map((slide, i) => slideToText(slide, i)).join("\n\n");
|
|
1404
|
+
return body ? `${header}
|
|
1405
|
+
|
|
1406
|
+
${body}` : header;
|
|
1407
|
+
}
|
|
1408
|
+
function slideToText(slide, index) {
|
|
1409
|
+
const kind = slide.kind ?? deckSlideKinds.CONTENT;
|
|
1410
|
+
const prefix = `Slide ${index + 1}: `;
|
|
1411
|
+
switch (kind) {
|
|
1412
|
+
case deckSlideKinds.TITLE: {
|
|
1413
|
+
const parts = [slide.title];
|
|
1414
|
+
if (slide.subtitle) parts.push(slide.subtitle);
|
|
1415
|
+
if (slide.description) parts.push(slide.description);
|
|
1416
|
+
return `${prefix}${parts.join(" \u2014 ")}`.trim();
|
|
1417
|
+
}
|
|
1418
|
+
case deckSlideKinds.AGENDA: {
|
|
1419
|
+
const items = (slide.items ?? []).map((item, i) => ` ${String(i + 1).padStart(2, "0")}. ${item}`).join("\n");
|
|
1420
|
+
return `${prefix}${slide.title || "Agenda"}${items ? `
|
|
1421
|
+
${items}` : ""}`.trim();
|
|
1422
|
+
}
|
|
1423
|
+
case deckSlideKinds.SECTION:
|
|
1424
|
+
return `${prefix}${slide.title}`.trim();
|
|
1425
|
+
case deckSlideKinds.CLOSING:
|
|
1426
|
+
return `${prefix}Thank you`.trim();
|
|
1427
|
+
case deckSlideKinds.CONTENT:
|
|
1428
|
+
default: {
|
|
1429
|
+
const blocks = (slide.content ?? []).map(blockToText).filter(Boolean).join("\n\n");
|
|
1430
|
+
return `${prefix}${slide.title}${blocks ? `
|
|
1431
|
+
${blocks}` : ""}`.trim();
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
function blockToText(block) {
|
|
1436
|
+
switch (block.type) {
|
|
1437
|
+
case deckBlockTypes.TEXT:
|
|
1438
|
+
return block.markdown.trim();
|
|
1439
|
+
case deckBlockTypes.CHART:
|
|
1440
|
+
return `[Chart: ${block.config.variant}]`;
|
|
1441
|
+
case deckBlockTypes.TABLE: {
|
|
1442
|
+
const columnCount = block.config.columns.length;
|
|
1443
|
+
const rowCount = block.rows.length;
|
|
1444
|
+
return `[Table: ${columnCount} column${columnCount === 1 ? "" : "s"} \xD7 ${rowCount} row${rowCount === 1 ? "" : "s"}]`;
|
|
1445
|
+
}
|
|
1446
|
+
default:
|
|
1447
|
+
return "";
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
// src/components/artifacts/artifact-services/deck-artifact-service.ts
|
|
1452
|
+
var DeckArtifactService = {
|
|
1453
|
+
type: artifactTypes.DECK,
|
|
1454
|
+
Component: DeckArtifact,
|
|
1455
|
+
toClipboardText: deckArtifactToClipboardText
|
|
1456
|
+
};
|
|
1457
|
+
|
|
940
1458
|
// src/components/artifacts/table-artifact/to-clipboard-text.ts
|
|
941
1459
|
function tableArtifactToClipboardText(artifact) {
|
|
942
1460
|
const trimmedTitle = artifact.title?.trim();
|
|
@@ -953,7 +1471,8 @@ var TableArtifactService = {
|
|
|
953
1471
|
// src/components/artifacts/artifact-services/index.ts
|
|
954
1472
|
var ArtifactServices = {
|
|
955
1473
|
[artifactTypes.TABLE]: TableArtifactService,
|
|
956
|
-
[artifactTypes.CHART]: ChartArtifactService
|
|
1474
|
+
[artifactTypes.CHART]: ChartArtifactService,
|
|
1475
|
+
[artifactTypes.DECK]: DeckArtifactService
|
|
957
1476
|
};
|
|
958
1477
|
function artifactToClipboardText(artifact) {
|
|
959
1478
|
const entry = ArtifactServices[artifact.type];
|
|
@@ -967,38 +1486,17 @@ export {
|
|
|
967
1486
|
artifactTypes,
|
|
968
1487
|
DEFAULT_CHART_ARTIFACT_LABELS,
|
|
969
1488
|
DEFAULT_TABLE_ARTIFACT_LABELS,
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
IconThumbUp,
|
|
1489
|
+
deckBlockTypes,
|
|
1490
|
+
deckSlideKinds,
|
|
1491
|
+
DEFAULT_DECK_ARTIFACT_LABELS,
|
|
974
1492
|
ArtifactCopyAsImageButton,
|
|
975
1493
|
ArtifactDownloadButton,
|
|
976
1494
|
isSafeDownloadUrl,
|
|
977
1495
|
ArtifactDownloadMenu,
|
|
978
1496
|
ChartArtifact,
|
|
1497
|
+
DeckArtifact,
|
|
979
1498
|
TableArtifact,
|
|
980
1499
|
ArtifactServices,
|
|
981
1500
|
artifactToClipboardText
|
|
982
1501
|
};
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
@tabler/icons-react/dist/esm/defaultAttributes.mjs:
|
|
986
|
-
@tabler/icons-react/dist/esm/createReactComponent.mjs:
|
|
987
|
-
@tabler/icons-react/dist/esm/icons/IconAlertCircle.mjs:
|
|
988
|
-
@tabler/icons-react/dist/esm/icons/IconCheck.mjs:
|
|
989
|
-
@tabler/icons-react/dist/esm/icons/IconCopy.mjs:
|
|
990
|
-
@tabler/icons-react/dist/esm/icons/IconDownload.mjs:
|
|
991
|
-
@tabler/icons-react/dist/esm/icons/IconFileSpreadsheet.mjs:
|
|
992
|
-
@tabler/icons-react/dist/esm/icons/IconLoader2.mjs:
|
|
993
|
-
@tabler/icons-react/dist/esm/icons/IconPhoto.mjs:
|
|
994
|
-
@tabler/icons-react/dist/esm/icons/IconThumbDown.mjs:
|
|
995
|
-
@tabler/icons-react/dist/esm/icons/IconThumbUp.mjs:
|
|
996
|
-
@tabler/icons-react/dist/esm/tabler-icons-react.mjs:
|
|
997
|
-
(**
|
|
998
|
-
* @license @tabler/icons-react v3.37.1 - MIT
|
|
999
|
-
*
|
|
1000
|
-
* This source code is licensed under the MIT license.
|
|
1001
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
1002
|
-
*)
|
|
1003
|
-
*/
|
|
1004
|
-
//# sourceMappingURL=chunk-6YZ65KPW.js.map
|
|
1502
|
+
//# sourceMappingURL=chunk-DC5KYT2G.js.map
|