@shapesos/clay 0.16.0 → 0.18.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 +976 -69
- 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 +13 -5
- package/dist/blocks.cjs +690 -85
- package/dist/blocks.cjs.map +1 -1
- package/dist/blocks.css +1 -1
- package/dist/blocks.d.cts +3 -3
- package/dist/blocks.d.ts +3 -3
- package/dist/blocks.js +5 -5
- 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 +16 -36
- package/dist/chart.cjs.map +1 -1
- package/dist/chart.d.cts +3 -11
- package/dist/chart.d.ts +3 -11
- package/dist/chart.js +2 -2
- package/dist/chat.cjs +714 -109
- 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 +6 -6
- package/dist/{chunk-UZKNSAAD.js → chunk-7MY4X4YL.js} +3 -3
- package/dist/chunk-BHHJOG5X.js +1 -0
- package/dist/{chunk-GAZRZZRF.js → chunk-CATIRDZP.js} +5 -5
- package/dist/{chunk-B4U37WIH.js → chunk-CFCLVJIO.js} +2 -2
- package/dist/{chunk-PYDVANWI.js → chunk-E36VI2HA.js} +2 -2
- package/dist/{chunk-U3IXCSV6.js → chunk-G4NXVFXU.js} +18 -40
- package/dist/chunk-G4NXVFXU.js.map +1 -0
- package/dist/{chunk-JAGNXEWK.js → chunk-GK4XW4BC.js} +2 -2
- package/dist/{chunk-4VE6ZXXW.js → chunk-MQP57DOP.js} +3 -3
- package/dist/{chunk-2YCBDSPK.js → chunk-QR4VBGK4.js} +673 -42
- package/dist/chunk-QR4VBGK4.js.map +1 -0
- 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/{dom-to-image-NATF3446.js → dom-to-image-QB7KMTAE.js} +3 -3
- package/dist/icon.cjs +3 -1
- package/dist/icon.cjs.map +1 -1
- package/dist/icon.js +2 -2
- package/dist/index.cjs +780 -167
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +19 -11
- package/dist/keyboard-shortcut.cjs +3 -1
- package/dist/keyboard-shortcut.cjs.map +1 -1
- package/dist/keyboard-shortcut.js +2 -2
- 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-BDYPVP2N.d.cts} +1 -1
- package/dist/{types-D1b8v7EY.d.ts → types-BMwa4bPW.d.ts} +1 -1
- 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/package.json +1 -1
- package/dist/chunk-2YCBDSPK.js.map +0 -1
- package/dist/chunk-RSRNSWJN.js +0 -1
- package/dist/chunk-U3IXCSV6.js.map +0 -1
- /package/dist/{chunk-UZKNSAAD.js.map → chunk-7MY4X4YL.js.map} +0 -0
- /package/dist/{chunk-RSRNSWJN.js.map → chunk-BHHJOG5X.js.map} +0 -0
- /package/dist/{chunk-GAZRZZRF.js.map → chunk-CATIRDZP.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-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
- /package/dist/{dom-to-image-NATF3446.js.map → dom-to-image-QB7KMTAE.js.map} +0 -0
package/dist/blocks.cjs
CHANGED
|
@@ -128,7 +128,9 @@ var init_colors = __esm({
|
|
|
128
128
|
"red-200": "#FECACA",
|
|
129
129
|
"red-400": "#F7776C",
|
|
130
130
|
"red-500": "#EF4444",
|
|
131
|
-
"red-600": "#DC2626"
|
|
131
|
+
"red-600": "#DC2626",
|
|
132
|
+
// Deck
|
|
133
|
+
"deck-canvas": "#faf8f5"
|
|
132
134
|
};
|
|
133
135
|
}
|
|
134
136
|
});
|
|
@@ -286,7 +288,8 @@ var blockTypes = {
|
|
|
286
288
|
// src/components/artifacts/artifact-base.ts
|
|
287
289
|
var artifactTypes = {
|
|
288
290
|
TABLE: "TABLE",
|
|
289
|
-
CHART: "CHART"
|
|
291
|
+
CHART: "CHART",
|
|
292
|
+
DECK: "DECK"
|
|
290
293
|
};
|
|
291
294
|
|
|
292
295
|
// src/components/artifacts/chart-artifact/types.ts
|
|
@@ -311,6 +314,34 @@ var DEFAULT_TABLE_ARTIFACT_LABELS = {
|
|
|
311
314
|
empty: "No rows to display."
|
|
312
315
|
};
|
|
313
316
|
|
|
317
|
+
// src/components/artifacts/deck-artifact/types.ts
|
|
318
|
+
var deckBlockTypes = {
|
|
319
|
+
TEXT: "TEXT",
|
|
320
|
+
CHART: "CHART",
|
|
321
|
+
TABLE: "TABLE"
|
|
322
|
+
};
|
|
323
|
+
var deckSlideKinds = {
|
|
324
|
+
TITLE: "TITLE",
|
|
325
|
+
AGENDA: "AGENDA",
|
|
326
|
+
SECTION: "SECTION",
|
|
327
|
+
CONTENT: "CONTENT",
|
|
328
|
+
CLOSING: "CLOSING"
|
|
329
|
+
};
|
|
330
|
+
var DEFAULT_DECK_ARTIFACT_LABELS = {
|
|
331
|
+
previous: "Previous slide",
|
|
332
|
+
next: "Next slide",
|
|
333
|
+
position: "Slide {current} of {total}",
|
|
334
|
+
download: "Download",
|
|
335
|
+
unavailable: "Deck content is unavailable.",
|
|
336
|
+
enterFullscreen: "Fullscreen",
|
|
337
|
+
exitFullscreen: "Exit fullscreen",
|
|
338
|
+
thankYou: "Thank you",
|
|
339
|
+
questions: "Questions?",
|
|
340
|
+
agenda: "Agenda",
|
|
341
|
+
chart: DEFAULT_CHART_ARTIFACT_LABELS,
|
|
342
|
+
table: DEFAULT_TABLE_ARTIFACT_LABELS
|
|
343
|
+
};
|
|
344
|
+
|
|
314
345
|
// src/components/artifacts/chart-artifact/chart-artifact.tsx
|
|
315
346
|
var import_react13 = require("react");
|
|
316
347
|
|
|
@@ -403,29 +434,45 @@ var createReactComponent = (type, iconName, iconNamePascal, iconNode) => {
|
|
|
403
434
|
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" }]];
|
|
404
435
|
var IconAlertCircle = createReactComponent("outline", "alert-circle", "AlertCircle", __iconNode);
|
|
405
436
|
|
|
437
|
+
// node_modules/@tabler/icons-react/dist/esm/icons/IconArrowsMaximize.mjs
|
|
438
|
+
var __iconNode2 = [["path", { "d": "M16 4l4 0l0 4", "key": "svg-0" }], ["path", { "d": "M14 10l6 -6", "key": "svg-1" }], ["path", { "d": "M8 20l-4 0l0 -4", "key": "svg-2" }], ["path", { "d": "M4 20l6 -6", "key": "svg-3" }], ["path", { "d": "M16 20l4 0l0 -4", "key": "svg-4" }], ["path", { "d": "M14 14l6 6", "key": "svg-5" }], ["path", { "d": "M8 4l-4 0l0 4", "key": "svg-6" }], ["path", { "d": "M4 4l6 6", "key": "svg-7" }]];
|
|
439
|
+
var IconArrowsMaximize = createReactComponent("outline", "arrows-maximize", "ArrowsMaximize", __iconNode2);
|
|
440
|
+
|
|
441
|
+
// node_modules/@tabler/icons-react/dist/esm/icons/IconArrowsMinimize.mjs
|
|
442
|
+
var __iconNode3 = [["path", { "d": "M5 9l4 0l0 -4", "key": "svg-0" }], ["path", { "d": "M3 3l6 6", "key": "svg-1" }], ["path", { "d": "M5 15l4 0l0 4", "key": "svg-2" }], ["path", { "d": "M3 21l6 -6", "key": "svg-3" }], ["path", { "d": "M19 9l-4 0l0 -4", "key": "svg-4" }], ["path", { "d": "M15 9l6 -6", "key": "svg-5" }], ["path", { "d": "M19 15l-4 0l0 4", "key": "svg-6" }], ["path", { "d": "M15 15l6 6", "key": "svg-7" }]];
|
|
443
|
+
var IconArrowsMinimize = createReactComponent("outline", "arrows-minimize", "ArrowsMinimize", __iconNode3);
|
|
444
|
+
|
|
406
445
|
// node_modules/@tabler/icons-react/dist/esm/icons/IconCheck.mjs
|
|
407
|
-
var
|
|
408
|
-
var IconCheck = createReactComponent("outline", "check", "Check",
|
|
446
|
+
var __iconNode4 = [["path", { "d": "M5 12l5 5l10 -10", "key": "svg-0" }]];
|
|
447
|
+
var IconCheck = createReactComponent("outline", "check", "Check", __iconNode4);
|
|
448
|
+
|
|
449
|
+
// node_modules/@tabler/icons-react/dist/esm/icons/IconChevronLeft.mjs
|
|
450
|
+
var __iconNode5 = [["path", { "d": "M15 6l-6 6l6 6", "key": "svg-0" }]];
|
|
451
|
+
var IconChevronLeft = createReactComponent("outline", "chevron-left", "ChevronLeft", __iconNode5);
|
|
452
|
+
|
|
453
|
+
// node_modules/@tabler/icons-react/dist/esm/icons/IconChevronRight.mjs
|
|
454
|
+
var __iconNode6 = [["path", { "d": "M9 6l6 6l-6 6", "key": "svg-0" }]];
|
|
455
|
+
var IconChevronRight = createReactComponent("outline", "chevron-right", "ChevronRight", __iconNode6);
|
|
409
456
|
|
|
410
457
|
// node_modules/@tabler/icons-react/dist/esm/icons/IconCopy.mjs
|
|
411
|
-
var
|
|
412
|
-
var IconCopy = createReactComponent("outline", "copy", "Copy",
|
|
458
|
+
var __iconNode7 = [["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" }]];
|
|
459
|
+
var IconCopy = createReactComponent("outline", "copy", "Copy", __iconNode7);
|
|
413
460
|
|
|
414
461
|
// node_modules/@tabler/icons-react/dist/esm/icons/IconDownload.mjs
|
|
415
|
-
var
|
|
416
|
-
var IconDownload = createReactComponent("outline", "download", "Download",
|
|
462
|
+
var __iconNode8 = [["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" }]];
|
|
463
|
+
var IconDownload = createReactComponent("outline", "download", "Download", __iconNode8);
|
|
417
464
|
|
|
418
465
|
// node_modules/@tabler/icons-react/dist/esm/icons/IconFileSpreadsheet.mjs
|
|
419
|
-
var
|
|
420
|
-
var IconFileSpreadsheet = createReactComponent("outline", "file-spreadsheet", "FileSpreadsheet",
|
|
466
|
+
var __iconNode9 = [["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" }]];
|
|
467
|
+
var IconFileSpreadsheet = createReactComponent("outline", "file-spreadsheet", "FileSpreadsheet", __iconNode9);
|
|
421
468
|
|
|
422
469
|
// node_modules/@tabler/icons-react/dist/esm/icons/IconLoader2.mjs
|
|
423
|
-
var
|
|
424
|
-
var IconLoader2 = createReactComponent("outline", "loader-2", "Loader2",
|
|
470
|
+
var __iconNode10 = [["path", { "d": "M12 3a9 9 0 1 0 9 9", "key": "svg-0" }]];
|
|
471
|
+
var IconLoader2 = createReactComponent("outline", "loader-2", "Loader2", __iconNode10);
|
|
425
472
|
|
|
426
473
|
// node_modules/@tabler/icons-react/dist/esm/icons/IconPhoto.mjs
|
|
427
|
-
var
|
|
428
|
-
var IconPhoto = createReactComponent("outline", "photo", "Photo",
|
|
474
|
+
var __iconNode11 = [["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" }]];
|
|
475
|
+
var IconPhoto = createReactComponent("outline", "photo", "Photo", __iconNode11);
|
|
429
476
|
|
|
430
477
|
// src/components/artifacts/artifact-copy-as-image-button/artifact-copy-as-image-button.tsx
|
|
431
478
|
var import_react6 = require("react");
|
|
@@ -1395,11 +1442,6 @@ function coerceNumericColumns(rows, numericKeys) {
|
|
|
1395
1442
|
|
|
1396
1443
|
// src/components/chart/bar-chart/bar-chart.tsx
|
|
1397
1444
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1398
|
-
var STACK_TOTAL_KEY = "__stackTotal";
|
|
1399
|
-
var VALUE_LABEL_HEADROOM = 20;
|
|
1400
|
-
function sumSeries(row, keys) {
|
|
1401
|
-
return keys.reduce((sum, key) => sum + (Number(row[key]) || 0), 0);
|
|
1402
|
-
}
|
|
1403
1445
|
function BarChart({
|
|
1404
1446
|
data,
|
|
1405
1447
|
xKey,
|
|
@@ -1414,7 +1456,6 @@ function BarChart({
|
|
|
1414
1456
|
showGrid = true,
|
|
1415
1457
|
showXAxis = true,
|
|
1416
1458
|
showYAxis = true,
|
|
1417
|
-
showValueLabels,
|
|
1418
1459
|
xAxisInterval = 0,
|
|
1419
1460
|
xAxisAngle,
|
|
1420
1461
|
xAxisTickFormatter
|
|
@@ -1425,24 +1466,14 @@ function BarChart({
|
|
|
1425
1466
|
[data, seriesKeys]
|
|
1426
1467
|
);
|
|
1427
1468
|
const resolvedShowLegend = showLegend ?? series.length > 1;
|
|
1428
|
-
const resolvedShowValueLabels = showValueLabels ?? true;
|
|
1429
|
-
const plotData = (0, import_react9.useMemo)(() => {
|
|
1430
|
-
if (!stacked || !resolvedShowValueLabels) return coercedData;
|
|
1431
|
-
return coercedData.map((row) => ({ ...row, [STACK_TOTAL_KEY]: sumSeries(row, seriesKeys) }));
|
|
1432
|
-
}, [coercedData, stacked, resolvedShowValueLabels, seriesKeys]);
|
|
1433
1469
|
const resolvedAngle = xAxisAngle ?? (coercedData.length >= 8 ? -30 : 0);
|
|
1434
1470
|
const resolvedTickFormatter = (0, import_react9.useMemo)(
|
|
1435
1471
|
() => xAxisTickFormatter ?? defaultBarTickFormatter(coercedData.length),
|
|
1436
1472
|
[xAxisTickFormatter, coercedData.length]
|
|
1437
1473
|
);
|
|
1438
1474
|
const angledLabelPad = resolvedAngle === 0 ? 0 : Math.min(Math.abs(resolvedAngle) * 0.7, 40);
|
|
1439
|
-
const
|
|
1440
|
-
|
|
1441
|
-
...CHART_MARGIN,
|
|
1442
|
-
top: CHART_MARGIN.top + valueLabelHeadroom,
|
|
1443
|
-
bottom: CHART_MARGIN.bottom + angledLabelPad
|
|
1444
|
-
};
|
|
1445
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ChartContainer, { height, width, className, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_recharts2.BarChart, { data: plotData, margin: chartMargin, barCategoryGap: "22%", children: [
|
|
1475
|
+
const chartMargin = { ...CHART_MARGIN, bottom: CHART_MARGIN.bottom + angledLabelPad };
|
|
1476
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ChartContainer, { height, width, className, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_recharts2.BarChart, { data: coercedData, margin: chartMargin, barCategoryGap: "22%", children: [
|
|
1446
1477
|
showGrid ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_recharts2.CartesianGrid, { ...CHART_GRID_PROPS }) : null,
|
|
1447
1478
|
showXAxis ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1448
1479
|
import_recharts2.XAxis,
|
|
@@ -1469,23 +1500,17 @@ function BarChart({
|
|
|
1469
1500
|
content: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ChartLegendContent, { iconType: "square" })
|
|
1470
1501
|
}
|
|
1471
1502
|
) : null,
|
|
1472
|
-
series.map((s, i) =>
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
radius: barRadius(stacked, i, series.length),
|
|
1484
|
-
children: showLabel ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_recharts2.LabelList, { dataKey: labelDataKey, position: "top", style: CHART_VALUE_LABEL_STYLE }) : null
|
|
1485
|
-
},
|
|
1486
|
-
s.key
|
|
1487
|
-
);
|
|
1488
|
-
})
|
|
1503
|
+
series.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1504
|
+
import_recharts2.Bar,
|
|
1505
|
+
{
|
|
1506
|
+
dataKey: s.key,
|
|
1507
|
+
name: s.label,
|
|
1508
|
+
fill: colorForSeriesIndex(i, palette),
|
|
1509
|
+
stackId: stacked ? "default" : s.key,
|
|
1510
|
+
radius: barRadius(stacked, i, series.length)
|
|
1511
|
+
},
|
|
1512
|
+
s.key
|
|
1513
|
+
))
|
|
1489
1514
|
] }) });
|
|
1490
1515
|
}
|
|
1491
1516
|
function barRadius(stacked, seriesIndex, seriesCount) {
|
|
@@ -2020,8 +2045,13 @@ var ChartArtifactService = {
|
|
|
2020
2045
|
toClipboardText: chartArtifactToClipboardText
|
|
2021
2046
|
};
|
|
2022
2047
|
|
|
2023
|
-
// src/components/artifacts/
|
|
2024
|
-
var
|
|
2048
|
+
// src/components/artifacts/deck-artifact/deck-artifact.tsx
|
|
2049
|
+
var import_react17 = require("react");
|
|
2050
|
+
var import_react_dom = require("react-dom");
|
|
2051
|
+
init_capture_exclude_attribute();
|
|
2052
|
+
|
|
2053
|
+
// src/components/artifacts/deck-artifact/deck-artifact-content.tsx
|
|
2054
|
+
var import_react16 = require("react");
|
|
2025
2055
|
|
|
2026
2056
|
// src/components/ui/table.tsx
|
|
2027
2057
|
var React3 = __toESM(require("react"), 1);
|
|
@@ -2168,9 +2198,333 @@ function renderEmptyRow(colSpan, emptyMessage) {
|
|
|
2168
2198
|
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TableRow, { className: "hover:bg-transparent", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TableCell, { colSpan, className: "py-6 text-center text-sm text-muted-foreground", children: emptyMessage }) });
|
|
2169
2199
|
}
|
|
2170
2200
|
|
|
2171
|
-
// src/components/artifacts/
|
|
2172
|
-
|
|
2173
|
-
|
|
2201
|
+
// src/components/artifacts/deck-artifact/deck-markdown.tsx
|
|
2202
|
+
var import_react_markdown = __toESM(require("react-markdown"), 1);
|
|
2203
|
+
var import_remark_breaks = __toESM(require("remark-breaks"), 1);
|
|
2204
|
+
var import_remark_gfm = __toESM(require("remark-gfm"), 1);
|
|
2205
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
2206
|
+
function sanitize(text) {
|
|
2207
|
+
return text.split("\n").filter((line) => {
|
|
2208
|
+
const t = line.trim();
|
|
2209
|
+
return !(t.startsWith("<!-- table-title:") && t.endsWith("-->"));
|
|
2210
|
+
}).join("\n");
|
|
2211
|
+
}
|
|
2212
|
+
var MARKDOWN_COMPONENTS = {
|
|
2213
|
+
h1: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h1", { className: "text-[30px] font-semibold leading-tight text-foreground mb-3", ...props }),
|
|
2214
|
+
h2: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h2", { className: "text-[26px] font-semibold leading-tight text-foreground mb-2", ...props }),
|
|
2215
|
+
h3: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
|
|
2216
|
+
h4: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h4", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
|
|
2217
|
+
h5: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h5", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
|
|
2218
|
+
h6: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h6", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
|
|
2219
|
+
p: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-[22px] leading-relaxed text-foreground my-2", ...props }),
|
|
2220
|
+
ul: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("ul", { className: "list-disc pl-7 text-[22px] leading-relaxed text-foreground my-2", ...props }),
|
|
2221
|
+
ol: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("ol", { className: "list-decimal pl-7 text-[22px] leading-relaxed text-foreground my-2", ...props }),
|
|
2222
|
+
// react-markdown injects list metadata (`ordered` / `index` / `checked`) that must not leak to the DOM.
|
|
2223
|
+
li: ({ node: _node, ordered: _ordered, index: _index, checked: _checked, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("li", { className: "my-1", ...props }),
|
|
2224
|
+
strong: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("strong", { className: "font-semibold", ...props }),
|
|
2225
|
+
em: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("em", { className: "italic", ...props }),
|
|
2226
|
+
// Gate `<img src>` against an http(s) allowlist. react-markdown v8 percent-encodes the URL but
|
|
2227
|
+
// does NOT protocol-filter image src (unlike link href), so an LLM-authored
|
|
2228
|
+
// `` / `` or a tracking-pixel `` would otherwise render
|
|
2229
|
+
// with the raw URL. Unsafe src → render nothing.
|
|
2230
|
+
img: ({ node: _node, src, ...props }) => typeof src === "string" && isSafeDownloadUrl(src) ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("img", { src, className: "max-w-full", ...props }) : null,
|
|
2231
|
+
a: ({ node: _node, ...props }) => (
|
|
2232
|
+
// `rel` is forced AFTER `{...props}` so it can't be overridden — if a consumer ever adds
|
|
2233
|
+
// `linkTarget="_blank"`, LLM-authored links still can't reach `window.opener`.
|
|
2234
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("a", { className: "underline underline-offset-2", ...props, rel: "noopener noreferrer" })
|
|
2235
|
+
),
|
|
2236
|
+
// react-markdown passes `inline` to distinguish inline code from fenced blocks — strip it from the DOM.
|
|
2237
|
+
code: ({ node: _node, inline: _inline, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("code", { className: "rounded bg-muted px-1.5 py-0.5 font-mono text-[18px]", ...props }),
|
|
2238
|
+
blockquote: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("blockquote", { className: "border-l-2 border-brown-alpha-12 pl-4 text-[22px] text-muted-foreground", ...props }),
|
|
2239
|
+
hr: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("hr", { className: "my-4 border-brown-alpha-12", ...props }),
|
|
2240
|
+
table: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("table", { className: "w-full border-collapse text-[20px]", ...props }) }),
|
|
2241
|
+
// react-markdown passes `isHeader` to cell renderers — strip it so it never reaches the DOM.
|
|
2242
|
+
th: ({ node: _node, isHeader: _isHeader, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("th", { className: "border-b border-brown-alpha-12 px-3 py-1.5 text-left font-medium", ...props }),
|
|
2243
|
+
td: ({ node: _node, isHeader: _isHeader, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("td", { className: "border-b border-brown-alpha-12 px-3 py-1.5", ...props })
|
|
2244
|
+
};
|
|
2245
|
+
function DeckMarkdown({ markdown }) {
|
|
2246
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_markdown.default, { remarkPlugins: [import_remark_gfm.default, import_remark_breaks.default], components: MARKDOWN_COMPONENTS, children: sanitize(markdown) });
|
|
2247
|
+
}
|
|
2248
|
+
|
|
2249
|
+
// src/components/artifacts/deck-artifact/slide-renderers.tsx
|
|
2250
|
+
var import_react15 = require("react");
|
|
2251
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
2252
|
+
function safeLogoUrl(meta) {
|
|
2253
|
+
return meta?.logoUrl && isSafeDownloadUrl(meta.logoUrl) ? meta.logoUrl : null;
|
|
2254
|
+
}
|
|
2255
|
+
var DESIGN_W = 1280;
|
|
2256
|
+
var DESIGN_H = 720;
|
|
2257
|
+
var EYEBROW_H = 84;
|
|
2258
|
+
var CANVAS_LOGO_MAX_H = 48;
|
|
2259
|
+
var ACCENT_FONT = { fontFamily: `"${fontFamilies.CRIMSON_PRO}", serif`, fontStyle: "italic" };
|
|
2260
|
+
function SlideFrame({ meta, children, accent = false, bare = false }) {
|
|
2261
|
+
const frameRef = (0, import_react15.useRef)(null);
|
|
2262
|
+
const [scale, setScale] = (0, import_react15.useState)(null);
|
|
2263
|
+
(0, import_react15.useLayoutEffect)(() => {
|
|
2264
|
+
const el = frameRef.current;
|
|
2265
|
+
if (!el) return;
|
|
2266
|
+
const apply = (width) => {
|
|
2267
|
+
if (width > 0) setScale(width / DESIGN_W);
|
|
2268
|
+
};
|
|
2269
|
+
apply(el.clientWidth);
|
|
2270
|
+
const ro = new ResizeObserver((entries) => apply(entries[0]?.contentRect.width ?? 0));
|
|
2271
|
+
ro.observe(el);
|
|
2272
|
+
return () => ro.disconnect();
|
|
2273
|
+
}, []);
|
|
2274
|
+
const bg = accent ? "bg-indigo-600" : "bg-deck-canvas";
|
|
2275
|
+
const eyebrowColor = accent ? "text-white/70" : "text-brown-60";
|
|
2276
|
+
const borderColor = accent ? "border-white/20" : "border-brown-alpha-12";
|
|
2277
|
+
const logoSrc = safeLogoUrl(meta);
|
|
2278
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { ref: frameRef, className: `relative aspect-[16/9] w-full overflow-hidden rounded-lg ${bg}`, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
2279
|
+
"div",
|
|
2280
|
+
{
|
|
2281
|
+
className: "absolute left-0 top-0 origin-top-left",
|
|
2282
|
+
style: {
|
|
2283
|
+
width: DESIGN_W,
|
|
2284
|
+
height: DESIGN_H,
|
|
2285
|
+
transform: `scale(${scale ?? 0})`,
|
|
2286
|
+
visibility: scale === null ? "hidden" : "visible"
|
|
2287
|
+
},
|
|
2288
|
+
children: [
|
|
2289
|
+
!bare ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
2290
|
+
"div",
|
|
2291
|
+
{
|
|
2292
|
+
className: `absolute inset-x-0 top-0 flex items-center justify-between border-b px-16 ${borderColor}`,
|
|
2293
|
+
style: { height: EYEBROW_H },
|
|
2294
|
+
children: [
|
|
2295
|
+
meta?.eyebrow ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: eyebrowColor, style: { ...ACCENT_FONT, fontSize: 22 }, children: meta.eyebrow }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", {}),
|
|
2296
|
+
logoSrc ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: logoSrc, alt: "", className: "object-contain", style: { maxHeight: CANVAS_LOGO_MAX_H } }) : null
|
|
2297
|
+
]
|
|
2298
|
+
}
|
|
2299
|
+
) : null,
|
|
2300
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "absolute inset-x-0 bottom-0 overflow-hidden", style: { top: bare ? 0 : EYEBROW_H }, children })
|
|
2301
|
+
]
|
|
2302
|
+
}
|
|
2303
|
+
) });
|
|
2304
|
+
}
|
|
2305
|
+
function TitleSlide({ slide, meta }) {
|
|
2306
|
+
const logoSrc = safeLogoUrl(meta);
|
|
2307
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SlideFrame, { meta, bare: true, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex h-full flex-col justify-center px-24 py-16", children: [
|
|
2308
|
+
logoSrc ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2309
|
+
"img",
|
|
2310
|
+
{
|
|
2311
|
+
src: logoSrc,
|
|
2312
|
+
alt: "",
|
|
2313
|
+
className: "mb-16 object-contain object-left",
|
|
2314
|
+
style: { maxHeight: 56, maxWidth: 380 }
|
|
2315
|
+
}
|
|
2316
|
+
) : null,
|
|
2317
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2318
|
+
"h1",
|
|
2319
|
+
{
|
|
2320
|
+
className: "font-bold tracking-tight text-brown-100",
|
|
2321
|
+
style: { fontSize: 92, lineHeight: 1.04, maxWidth: 1060 },
|
|
2322
|
+
children: slide.title
|
|
2323
|
+
}
|
|
2324
|
+
),
|
|
2325
|
+
slide.subtitle ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "mt-7 text-brown-70", style: { ...ACCENT_FONT, fontSize: 34 }, children: slide.subtitle }) : null,
|
|
2326
|
+
slide.description ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "mt-4 leading-relaxed text-brown-70", style: { fontSize: 24, maxWidth: 880 }, children: slide.description }) : null,
|
|
2327
|
+
meta?.date ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "mt-10 text-brown-70", style: { ...ACCENT_FONT, fontSize: 30 }, children: meta.date }) : null
|
|
2328
|
+
] }) });
|
|
2329
|
+
}
|
|
2330
|
+
function AgendaSlide({ slide, meta, labels }) {
|
|
2331
|
+
const items = slide.items ?? [];
|
|
2332
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SlideFrame, { meta, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "h-full px-24 py-14", children: [
|
|
2333
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h2", { className: "mb-10 font-bold text-brown-90", style: { fontSize: 40 }, children: slide.title || labels.agenda }),
|
|
2334
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex flex-col", children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-baseline gap-6 border-b border-brown-alpha-12 py-5", children: [
|
|
2335
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "shrink-0 text-indigo-600", style: { ...ACCENT_FONT, fontSize: 28, width: 64 }, children: String(i + 1).padStart(2, "0") }),
|
|
2336
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-brown-90", style: { fontSize: 28 }, children: item })
|
|
2337
|
+
] }, i)) })
|
|
2338
|
+
] }) });
|
|
2339
|
+
}
|
|
2340
|
+
function SectionSlide({ slide, meta }) {
|
|
2341
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SlideFrame, { meta, accent: true, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex h-full flex-col justify-center gap-6 px-24", children: [
|
|
2342
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h2", { className: "font-bold text-white", style: { fontSize: 72, lineHeight: 1.05, maxWidth: 940 }, children: slide.title }),
|
|
2343
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "mt-2 bg-white/50", style: { width: 96, height: 5 } })
|
|
2344
|
+
] }) });
|
|
2345
|
+
}
|
|
2346
|
+
function ClosingSlide({ meta, labels }) {
|
|
2347
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SlideFrame, { meta, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex h-full flex-col items-center justify-center gap-6 px-24 text-center", children: [
|
|
2348
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h1", { className: "font-bold text-brown-100", style: { fontSize: 72 }, children: labels.thankYou }),
|
|
2349
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-indigo-600", style: { ...ACCENT_FONT, fontSize: 36 }, children: labels.questions })
|
|
2350
|
+
] }) });
|
|
2351
|
+
}
|
|
2352
|
+
|
|
2353
|
+
// src/components/artifacts/deck-artifact/deck-artifact-content.tsx
|
|
2354
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
2355
|
+
var TABLE_BLOCK_MAX_SHIMMER_ROWS = 10;
|
|
2356
|
+
var TABLE_CHROME_RESERVE = 56;
|
|
2357
|
+
var VISUAL_FALLBACK_HEIGHT = 360;
|
|
2358
|
+
function DeckArtifactContent({
|
|
2359
|
+
slides,
|
|
2360
|
+
labels,
|
|
2361
|
+
onNavigate,
|
|
2362
|
+
meta,
|
|
2363
|
+
onDark = false,
|
|
2364
|
+
currentSlide,
|
|
2365
|
+
onSlideChange
|
|
2366
|
+
}) {
|
|
2367
|
+
const navBtnClass = onDark ? "[&_svg]:!text-white hover:!bg-white/20 disabled:opacity-40" : void 0;
|
|
2368
|
+
const navBtnSize = onDark ? "medium" : "small";
|
|
2369
|
+
const isControlled = currentSlide !== void 0;
|
|
2370
|
+
const [internalIndex, setInternalIndex] = (0, import_react16.useState)(0);
|
|
2371
|
+
const index = isControlled ? currentSlide : internalIndex;
|
|
2372
|
+
const current = Math.min(index, slides.length - 1);
|
|
2373
|
+
const slide = slides[current];
|
|
2374
|
+
const goTo = (0, import_react16.useCallback)(
|
|
2375
|
+
(next) => {
|
|
2376
|
+
const clamped = Math.max(0, Math.min(next, slides.length - 1));
|
|
2377
|
+
if (isControlled) onSlideChange?.(clamped);
|
|
2378
|
+
else setInternalIndex(clamped);
|
|
2379
|
+
onNavigate?.(clamped);
|
|
2380
|
+
},
|
|
2381
|
+
[slides.length, onNavigate, isControlled, onSlideChange]
|
|
2382
|
+
);
|
|
2383
|
+
const position = labels.position.replace("{current}", String(current + 1)).replace("{total}", String(slides.length));
|
|
2384
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col gap-3 p-4", children: [
|
|
2385
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SlideDispatch, { slide, labels, meta }),
|
|
2386
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
2387
|
+
"div",
|
|
2388
|
+
{
|
|
2389
|
+
className: `flex items-center justify-between border-t pt-2 ${onDark ? "border-white/20" : "border-brown-alpha-12"}`,
|
|
2390
|
+
children: [
|
|
2391
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2392
|
+
IconButton,
|
|
2393
|
+
{
|
|
2394
|
+
icon: IconChevronLeft,
|
|
2395
|
+
size: navBtnSize,
|
|
2396
|
+
className: navBtnClass,
|
|
2397
|
+
"aria-label": labels.previous,
|
|
2398
|
+
disabled: current === 0,
|
|
2399
|
+
onClick: () => goTo(current - 1)
|
|
2400
|
+
}
|
|
2401
|
+
),
|
|
2402
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: `text-xs font-medium ${onDark ? "text-white/70" : "text-brown-70"}`, children: position }),
|
|
2403
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2404
|
+
IconButton,
|
|
2405
|
+
{
|
|
2406
|
+
icon: IconChevronRight,
|
|
2407
|
+
size: navBtnSize,
|
|
2408
|
+
className: navBtnClass,
|
|
2409
|
+
"aria-label": labels.next,
|
|
2410
|
+
disabled: current === slides.length - 1,
|
|
2411
|
+
onClick: () => goTo(current + 1)
|
|
2412
|
+
}
|
|
2413
|
+
)
|
|
2414
|
+
]
|
|
2415
|
+
}
|
|
2416
|
+
)
|
|
2417
|
+
] });
|
|
2418
|
+
}
|
|
2419
|
+
function SlideDispatch({ slide, labels, meta }) {
|
|
2420
|
+
const kind = slide.kind ?? deckSlideKinds.CONTENT;
|
|
2421
|
+
switch (kind) {
|
|
2422
|
+
case deckSlideKinds.TITLE:
|
|
2423
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TitleSlide, { slide, meta });
|
|
2424
|
+
case deckSlideKinds.AGENDA:
|
|
2425
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(AgendaSlide, { slide, meta, labels });
|
|
2426
|
+
case deckSlideKinds.SECTION:
|
|
2427
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SectionSlide, { slide, meta });
|
|
2428
|
+
case deckSlideKinds.CLOSING:
|
|
2429
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ClosingSlide, { meta, labels });
|
|
2430
|
+
case deckSlideKinds.CONTENT:
|
|
2431
|
+
default:
|
|
2432
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ContentSlide, { slide, meta, labels });
|
|
2433
|
+
}
|
|
2434
|
+
}
|
|
2435
|
+
function isVisualBlock(block) {
|
|
2436
|
+
return block.type === deckBlockTypes.CHART || block.type === deckBlockTypes.TABLE;
|
|
2437
|
+
}
|
|
2438
|
+
function ContentSlide({ slide, meta, labels }) {
|
|
2439
|
+
const content = slide.content ?? [];
|
|
2440
|
+
const visuals = content.filter(isVisualBlock);
|
|
2441
|
+
const texts = content.filter(
|
|
2442
|
+
(b) => b.type === deckBlockTypes.TEXT
|
|
2443
|
+
);
|
|
2444
|
+
if (visuals.length === 1 && texts.length > 0) {
|
|
2445
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SlideFrame, { meta, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex h-full items-stretch gap-12 px-16 py-12", children: [
|
|
2446
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex w-[42%] shrink-0 flex-col overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(AutoFit, { children: [
|
|
2447
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h3", { className: "mb-5 font-bold leading-tight text-foreground", style: { fontSize: 34 }, children: slide.title }),
|
|
2448
|
+
texts.map((block, i) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(DeckMarkdown, { markdown: block.markdown }, i))
|
|
2449
|
+
] }) }),
|
|
2450
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "min-h-0 min-w-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(FillVisual, { block: visuals[0], labels }) })
|
|
2451
|
+
] }) });
|
|
2452
|
+
}
|
|
2453
|
+
if (visuals.length > 0) {
|
|
2454
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SlideFrame, { meta, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex h-full flex-col gap-5 px-16 py-10", children: [
|
|
2455
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h3", { className: "shrink-0 font-bold leading-tight text-foreground", style: { fontSize: 32 }, children: slide.title }),
|
|
2456
|
+
content.map(
|
|
2457
|
+
(block, i) => isVisualBlock(block) ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "min-h-0 min-w-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(FillVisual, { block, labels }) }, i) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "shrink-0 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(DeckMarkdown, { markdown: block.markdown }) }, i)
|
|
2458
|
+
)
|
|
2459
|
+
] }) });
|
|
2460
|
+
}
|
|
2461
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SlideFrame, { meta, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "h-full px-24 py-12", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(AutoFit, { children: [
|
|
2462
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h3", { className: "mb-6 font-bold leading-tight text-foreground", style: { fontSize: 38 }, children: slide.title }),
|
|
2463
|
+
texts.map((block, i) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(DeckMarkdown, { markdown: block.markdown }, i))
|
|
2464
|
+
] }) }) });
|
|
2465
|
+
}
|
|
2466
|
+
function AutoFit({ children }) {
|
|
2467
|
+
const boxRef = (0, import_react16.useRef)(null);
|
|
2468
|
+
const contentRef = (0, import_react16.useRef)(null);
|
|
2469
|
+
const [fit, setFit] = (0, import_react16.useState)({ scale: 1, height: 0 });
|
|
2470
|
+
(0, import_react16.useLayoutEffect)(() => {
|
|
2471
|
+
const boxEl = boxRef.current;
|
|
2472
|
+
const contentEl = contentRef.current;
|
|
2473
|
+
if (!boxEl || !contentEl) return;
|
|
2474
|
+
const measure = () => {
|
|
2475
|
+
const avail = boxEl.clientHeight;
|
|
2476
|
+
const natural = contentEl.offsetHeight;
|
|
2477
|
+
const scale = avail > 0 && natural > avail ? avail / natural : 1;
|
|
2478
|
+
setFit({ scale, height: natural * scale });
|
|
2479
|
+
};
|
|
2480
|
+
measure();
|
|
2481
|
+
const ro = new ResizeObserver(measure);
|
|
2482
|
+
ro.observe(boxEl);
|
|
2483
|
+
ro.observe(contentEl);
|
|
2484
|
+
return () => ro.disconnect();
|
|
2485
|
+
}, []);
|
|
2486
|
+
const scaled = fit.scale < 1;
|
|
2487
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { ref: boxRef, className: "flex h-full min-h-0 w-full flex-col justify-center overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: scaled ? { height: fit.height } : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2488
|
+
"div",
|
|
2489
|
+
{
|
|
2490
|
+
ref: contentRef,
|
|
2491
|
+
className: "w-full origin-top-left",
|
|
2492
|
+
style: scaled ? { transform: `scale(${fit.scale})` } : void 0,
|
|
2493
|
+
children
|
|
2494
|
+
}
|
|
2495
|
+
) }) });
|
|
2496
|
+
}
|
|
2497
|
+
function FillVisual({ block, labels }) {
|
|
2498
|
+
const ref = (0, import_react16.useRef)(null);
|
|
2499
|
+
const [height, setHeight] = (0, import_react16.useState)(VISUAL_FALLBACK_HEIGHT);
|
|
2500
|
+
(0, import_react16.useLayoutEffect)(() => {
|
|
2501
|
+
const el = ref.current;
|
|
2502
|
+
if (!el) return;
|
|
2503
|
+
const apply = (h) => {
|
|
2504
|
+
if (h > 0) setHeight(h);
|
|
2505
|
+
};
|
|
2506
|
+
apply(el.clientHeight);
|
|
2507
|
+
const ro = new ResizeObserver((entries) => apply(entries[0]?.contentRect.height ?? 0));
|
|
2508
|
+
ro.observe(el);
|
|
2509
|
+
return () => ro.disconnect();
|
|
2510
|
+
}, []);
|
|
2511
|
+
const chartLabels = labels.chart ?? DEFAULT_CHART_ARTIFACT_LABELS;
|
|
2512
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { ref, className: "h-full min-h-0 w-full overflow-hidden", children: block.type === deckBlockTypes.CHART ? (
|
|
2513
|
+
// ChartArtifactContent assumes a non-empty rowset (the standalone ChartArtifact guards
|
|
2514
|
+
// `rows.length > 0` upstream); mirror that guard here so an empty inline chart shows the
|
|
2515
|
+
// localized empty status instead of a blank chart area.
|
|
2516
|
+
block.rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(StatusMessage, { $tone: "info", children: chartLabels.empty }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { height }, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ChartArtifactContent, { config: block.config, rows: block.rows, labels: chartLabels }) })
|
|
2517
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2518
|
+
TableArtifactContent,
|
|
2519
|
+
{
|
|
2520
|
+
columns: block.config.columns,
|
|
2521
|
+
data: { status: "ready", rows: block.rows, error: null },
|
|
2522
|
+
knownRowCount: block.config.stats?.rowCount ?? block.rows.length,
|
|
2523
|
+
maxShimmerRows: TABLE_BLOCK_MAX_SHIMMER_ROWS,
|
|
2524
|
+
maxBodyHeight: Math.max(0, height - TABLE_CHROME_RESERVE),
|
|
2525
|
+
labels: labels.table ?? DEFAULT_TABLE_ARTIFACT_LABELS
|
|
2526
|
+
}
|
|
2527
|
+
) });
|
|
2174
2528
|
}
|
|
2175
2529
|
|
|
2176
2530
|
// src/components/artifacts/table-artifact/validate.ts
|
|
@@ -2189,19 +2543,265 @@ function isValidTableColumn(column) {
|
|
|
2189
2543
|
return true;
|
|
2190
2544
|
}
|
|
2191
2545
|
|
|
2192
|
-
// src/components/artifacts/
|
|
2193
|
-
|
|
2546
|
+
// src/components/artifacts/deck-artifact/validate.ts
|
|
2547
|
+
function isValidDeckConfig(config) {
|
|
2548
|
+
if (!config || typeof config !== "object") return false;
|
|
2549
|
+
const candidate = config;
|
|
2550
|
+
if (!Array.isArray(candidate.slides)) return false;
|
|
2551
|
+
if (candidate.slides.length === 0) return false;
|
|
2552
|
+
return candidate.slides.every(isValidDeckSlide);
|
|
2553
|
+
}
|
|
2554
|
+
function isValidDeckSlide(slide) {
|
|
2555
|
+
if (!slide || typeof slide !== "object") return false;
|
|
2556
|
+
const candidate = slide;
|
|
2557
|
+
if (typeof candidate.title !== "string") return false;
|
|
2558
|
+
const kind = typeof candidate.kind === "string" ? candidate.kind : deckSlideKinds.CONTENT;
|
|
2559
|
+
if (kind === deckSlideKinds.CONTENT && !Array.isArray(candidate.content)) return false;
|
|
2560
|
+
const content = Array.isArray(candidate.content) ? candidate.content : [];
|
|
2561
|
+
if (candidate.items != null) {
|
|
2562
|
+
if (!Array.isArray(candidate.items)) return false;
|
|
2563
|
+
if (!candidate.items.every((item) => typeof item === "string")) return false;
|
|
2564
|
+
}
|
|
2565
|
+
return content.every(isValidDeckBlock);
|
|
2566
|
+
}
|
|
2567
|
+
function isValidDeckBlock(block) {
|
|
2568
|
+
if (!block || typeof block !== "object") return false;
|
|
2569
|
+
const candidate = block;
|
|
2570
|
+
switch (candidate.type) {
|
|
2571
|
+
case deckBlockTypes.TEXT:
|
|
2572
|
+
return typeof candidate.markdown === "string";
|
|
2573
|
+
case deckBlockTypes.CHART:
|
|
2574
|
+
return isValidChartConfig(candidate.config) && Array.isArray(candidate.rows);
|
|
2575
|
+
case deckBlockTypes.TABLE:
|
|
2576
|
+
return isValidTableConfig(candidate.config) && Array.isArray(candidate.rows);
|
|
2577
|
+
default:
|
|
2578
|
+
return false;
|
|
2579
|
+
}
|
|
2580
|
+
}
|
|
2581
|
+
|
|
2582
|
+
// src/components/artifacts/deck-artifact/deck-artifact.tsx
|
|
2583
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
2194
2584
|
var TITLE_CLASSES2 = "text-sm font-semibold text-foreground";
|
|
2585
|
+
function DeckArtifact({ artifact, labels, callbacks }) {
|
|
2586
|
+
const validConfig = isValidDeckConfig(artifact.config);
|
|
2587
|
+
const [isFullscreen, setIsFullscreen] = (0, import_react17.useState)(false);
|
|
2588
|
+
const [currentSlide, setCurrentSlide] = (0, import_react17.useState)(0);
|
|
2589
|
+
(0, import_react17.useEffect)(() => {
|
|
2590
|
+
if (validConfig) return;
|
|
2591
|
+
console.warn("[clay] DeckArtifact: malformed `config` \u2014 skipping render.");
|
|
2592
|
+
}, [validConfig]);
|
|
2593
|
+
(0, import_react17.useEffect)(() => {
|
|
2594
|
+
if (!isFullscreen) return;
|
|
2595
|
+
const handleKey = (e) => {
|
|
2596
|
+
if (e.key === "Escape") setIsFullscreen(false);
|
|
2597
|
+
};
|
|
2598
|
+
document.addEventListener("keydown", handleKey);
|
|
2599
|
+
const previousOverflow = document.documentElement.style.overflow;
|
|
2600
|
+
document.documentElement.style.overflow = "hidden";
|
|
2601
|
+
return () => {
|
|
2602
|
+
document.removeEventListener("keydown", handleKey);
|
|
2603
|
+
document.documentElement.style.overflow = previousOverflow;
|
|
2604
|
+
};
|
|
2605
|
+
}, [isFullscreen]);
|
|
2606
|
+
const resolvedLabels = (0, import_react17.useMemo)(
|
|
2607
|
+
() => ({
|
|
2608
|
+
...DEFAULT_DECK_ARTIFACT_LABELS,
|
|
2609
|
+
...labels ?? {},
|
|
2610
|
+
chart: { ...DEFAULT_CHART_ARTIFACT_LABELS, ...labels?.chart ?? {} },
|
|
2611
|
+
table: { ...DEFAULT_TABLE_ARTIFACT_LABELS, ...labels?.table ?? {} }
|
|
2612
|
+
}),
|
|
2613
|
+
[labels]
|
|
2614
|
+
);
|
|
2615
|
+
const onNavigate = callbacks?.onNavigate;
|
|
2616
|
+
const handleNavigate = onNavigate ? (slideIndex) => onNavigate(artifact, slideIndex) : void 0;
|
|
2617
|
+
const onDownload = callbacks?.onDownload;
|
|
2618
|
+
const handleDownload = onDownload ? () => onDownload(artifact) : void 0;
|
|
2619
|
+
const presignedUrl = artifact.protectedAsset?.presignedUrl ?? null;
|
|
2620
|
+
const showDownload = presignedUrl !== null && isSafeDownloadUrl(presignedUrl);
|
|
2621
|
+
const meta = artifact.config?.meta;
|
|
2622
|
+
const handleOpenFullscreen = () => setIsFullscreen(true);
|
|
2623
|
+
const handleCloseFullscreen = () => setIsFullscreen(false);
|
|
2624
|
+
const actions = /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(ArtifactActions, { ...{ [CAPTURE_EXCLUDE_ATTRIBUTE]: "" }, children: [
|
|
2625
|
+
showDownload ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ArtifactDownloadButton, { href: presignedUrl ?? "", label: resolvedLabels.download, onClick: handleDownload }) : null,
|
|
2626
|
+
validConfig ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
2627
|
+
IconButton,
|
|
2628
|
+
{
|
|
2629
|
+
icon: IconArrowsMaximize,
|
|
2630
|
+
size: "small",
|
|
2631
|
+
"aria-label": resolvedLabels.enterFullscreen,
|
|
2632
|
+
onClick: handleOpenFullscreen
|
|
2633
|
+
}
|
|
2634
|
+
) : null
|
|
2635
|
+
] });
|
|
2636
|
+
if (!validConfig) {
|
|
2637
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
|
|
2638
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
|
|
2639
|
+
artifact.title ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ArtifactTitle, { className: TITLE_CLASSES2, children: artifact.title }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", {}),
|
|
2640
|
+
actions
|
|
2641
|
+
] }),
|
|
2642
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ArtifactContent, { className: "p-0", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(StatusMessage, { $tone: "info", children: resolvedLabels.unavailable }) })
|
|
2643
|
+
] });
|
|
2644
|
+
}
|
|
2645
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
|
|
2646
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
|
|
2647
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
|
|
2648
|
+
artifact.title ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ArtifactTitle, { className: TITLE_CLASSES2, children: artifact.title }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", {}),
|
|
2649
|
+
actions
|
|
2650
|
+
] }),
|
|
2651
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ArtifactContent, { className: "p-0", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
2652
|
+
DeckArtifactContent,
|
|
2653
|
+
{
|
|
2654
|
+
slides: artifact.config.slides,
|
|
2655
|
+
labels: resolvedLabels,
|
|
2656
|
+
onNavigate: handleNavigate,
|
|
2657
|
+
meta,
|
|
2658
|
+
currentSlide,
|
|
2659
|
+
onSlideChange: setCurrentSlide
|
|
2660
|
+
}
|
|
2661
|
+
) })
|
|
2662
|
+
] }),
|
|
2663
|
+
isFullscreen && (0, import_react_dom.createPortal)(
|
|
2664
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
2665
|
+
FullscreenOverlay,
|
|
2666
|
+
{
|
|
2667
|
+
artifact,
|
|
2668
|
+
resolvedLabels,
|
|
2669
|
+
onNavigate: handleNavigate,
|
|
2670
|
+
currentSlide,
|
|
2671
|
+
onSlideChange: setCurrentSlide,
|
|
2672
|
+
onClose: handleCloseFullscreen
|
|
2673
|
+
}
|
|
2674
|
+
),
|
|
2675
|
+
document.body
|
|
2676
|
+
)
|
|
2677
|
+
] });
|
|
2678
|
+
}
|
|
2679
|
+
function FullscreenOverlay({
|
|
2680
|
+
artifact,
|
|
2681
|
+
resolvedLabels,
|
|
2682
|
+
onNavigate,
|
|
2683
|
+
currentSlide,
|
|
2684
|
+
onSlideChange,
|
|
2685
|
+
onClose
|
|
2686
|
+
}) {
|
|
2687
|
+
const meta = artifact.config?.meta;
|
|
2688
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
2689
|
+
"div",
|
|
2690
|
+
{
|
|
2691
|
+
className: "fixed inset-0 z-[2147483647] flex items-center justify-center bg-black/80",
|
|
2692
|
+
role: "dialog",
|
|
2693
|
+
"aria-modal": "true",
|
|
2694
|
+
"aria-label": resolvedLabels.exitFullscreen,
|
|
2695
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "relative", style: { width: "min(94vw, calc(82vh * 16 / 9))" }, children: [
|
|
2696
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
2697
|
+
DeckArtifactContent,
|
|
2698
|
+
{
|
|
2699
|
+
slides: artifact.config.slides,
|
|
2700
|
+
labels: resolvedLabels,
|
|
2701
|
+
onNavigate,
|
|
2702
|
+
meta,
|
|
2703
|
+
currentSlide,
|
|
2704
|
+
onSlideChange,
|
|
2705
|
+
onDark: true
|
|
2706
|
+
}
|
|
2707
|
+
),
|
|
2708
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
2709
|
+
"button",
|
|
2710
|
+
{
|
|
2711
|
+
className: "absolute -top-10 right-6 flex items-center gap-1.5 text-sm text-white/80 hover:text-white",
|
|
2712
|
+
"aria-label": resolvedLabels.exitFullscreen,
|
|
2713
|
+
onClick: onClose,
|
|
2714
|
+
children: [
|
|
2715
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(IconArrowsMinimize, { size: 16 }),
|
|
2716
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: resolvedLabels.exitFullscreen })
|
|
2717
|
+
]
|
|
2718
|
+
}
|
|
2719
|
+
)
|
|
2720
|
+
] })
|
|
2721
|
+
}
|
|
2722
|
+
);
|
|
2723
|
+
}
|
|
2724
|
+
|
|
2725
|
+
// src/components/artifacts/deck-artifact/to-clipboard-text.ts
|
|
2726
|
+
function deckArtifactToClipboardText(artifact) {
|
|
2727
|
+
const header = artifact.title?.trim() || "Deck";
|
|
2728
|
+
const slides = artifact.config?.slides ?? [];
|
|
2729
|
+
const body = slides.map((slide, i) => slideToText(slide, i)).join("\n\n");
|
|
2730
|
+
return body ? `${header}
|
|
2731
|
+
|
|
2732
|
+
${body}` : header;
|
|
2733
|
+
}
|
|
2734
|
+
function slideToText(slide, index) {
|
|
2735
|
+
const kind = slide.kind ?? deckSlideKinds.CONTENT;
|
|
2736
|
+
const prefix = `Slide ${index + 1}: `;
|
|
2737
|
+
switch (kind) {
|
|
2738
|
+
case deckSlideKinds.TITLE: {
|
|
2739
|
+
const parts = [slide.title];
|
|
2740
|
+
if (slide.subtitle) parts.push(slide.subtitle);
|
|
2741
|
+
if (slide.description) parts.push(slide.description);
|
|
2742
|
+
return `${prefix}${parts.join(" \u2014 ")}`.trim();
|
|
2743
|
+
}
|
|
2744
|
+
case deckSlideKinds.AGENDA: {
|
|
2745
|
+
const items = (slide.items ?? []).map((item, i) => ` ${String(i + 1).padStart(2, "0")}. ${item}`).join("\n");
|
|
2746
|
+
return `${prefix}${slide.title || "Agenda"}${items ? `
|
|
2747
|
+
${items}` : ""}`.trim();
|
|
2748
|
+
}
|
|
2749
|
+
case deckSlideKinds.SECTION:
|
|
2750
|
+
return `${prefix}${slide.title}`.trim();
|
|
2751
|
+
case deckSlideKinds.CLOSING:
|
|
2752
|
+
return `${prefix}Thank you`.trim();
|
|
2753
|
+
case deckSlideKinds.CONTENT:
|
|
2754
|
+
default: {
|
|
2755
|
+
const blocks = (slide.content ?? []).map(blockToText).filter(Boolean).join("\n\n");
|
|
2756
|
+
return `${prefix}${slide.title}${blocks ? `
|
|
2757
|
+
${blocks}` : ""}`.trim();
|
|
2758
|
+
}
|
|
2759
|
+
}
|
|
2760
|
+
}
|
|
2761
|
+
function blockToText(block) {
|
|
2762
|
+
switch (block.type) {
|
|
2763
|
+
case deckBlockTypes.TEXT:
|
|
2764
|
+
return block.markdown.trim();
|
|
2765
|
+
case deckBlockTypes.CHART:
|
|
2766
|
+
return `[Chart: ${block.config.variant}]`;
|
|
2767
|
+
case deckBlockTypes.TABLE: {
|
|
2768
|
+
const columnCount = block.config.columns.length;
|
|
2769
|
+
const rowCount = block.rows.length;
|
|
2770
|
+
return `[Table: ${columnCount} column${columnCount === 1 ? "" : "s"} \xD7 ${rowCount} row${rowCount === 1 ? "" : "s"}]`;
|
|
2771
|
+
}
|
|
2772
|
+
default:
|
|
2773
|
+
return "";
|
|
2774
|
+
}
|
|
2775
|
+
}
|
|
2776
|
+
|
|
2777
|
+
// src/components/artifacts/artifact-services/deck-artifact-service.ts
|
|
2778
|
+
var DeckArtifactService = {
|
|
2779
|
+
type: artifactTypes.DECK,
|
|
2780
|
+
Component: DeckArtifact,
|
|
2781
|
+
toClipboardText: deckArtifactToClipboardText
|
|
2782
|
+
};
|
|
2783
|
+
|
|
2784
|
+
// src/components/artifacts/table-artifact/table-artifact.tsx
|
|
2785
|
+
var import_react18 = require("react");
|
|
2786
|
+
|
|
2787
|
+
// src/components/artifacts/table-artifact/use-table-artifact-data.ts
|
|
2788
|
+
function useTableArtifactData(presignedUrl, columns) {
|
|
2789
|
+
return useRowsArtifactData(presignedUrl, columns, parseCsv);
|
|
2790
|
+
}
|
|
2791
|
+
|
|
2792
|
+
// src/components/artifacts/table-artifact/table-artifact.tsx
|
|
2793
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
2794
|
+
var TITLE_CLASSES3 = "text-sm font-semibold text-foreground";
|
|
2195
2795
|
var TABLE_MAX_BODY_HEIGHT = 480;
|
|
2196
2796
|
var MAX_SHIMMER_ROWS = 10;
|
|
2197
2797
|
function TableArtifact({ artifact, labels, callbacks }) {
|
|
2198
2798
|
const validConfig = isValidTableConfig(artifact.config);
|
|
2199
2799
|
const validColumns = validConfig ? artifact.config.columns : null;
|
|
2200
|
-
(0,
|
|
2800
|
+
(0, import_react18.useEffect)(() => {
|
|
2201
2801
|
if (validConfig) return;
|
|
2202
2802
|
console.warn("[clay] TableArtifact: malformed `config` \u2014 skipping render.");
|
|
2203
2803
|
}, [validConfig]);
|
|
2204
|
-
const resolvedLabels = (0,
|
|
2804
|
+
const resolvedLabels = (0, import_react18.useMemo)(
|
|
2205
2805
|
() => ({ ...DEFAULT_TABLE_ARTIFACT_LABELS, ...labels ?? {} }),
|
|
2206
2806
|
[labels]
|
|
2207
2807
|
);
|
|
@@ -2213,10 +2813,10 @@ function TableArtifact({ artifact, labels, callbacks }) {
|
|
|
2213
2813
|
const onDownload = callbacks?.onDownload;
|
|
2214
2814
|
const handleDownloadClick = onDownload ? () => onDownload(artifact) : void 0;
|
|
2215
2815
|
if (!validConfig || !validColumns) {
|
|
2216
|
-
return /* @__PURE__ */ (0,
|
|
2217
|
-
/* @__PURE__ */ (0,
|
|
2218
|
-
artifact.title ? /* @__PURE__ */ (0,
|
|
2219
|
-
presignedUrl ? /* @__PURE__ */ (0,
|
|
2816
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
|
|
2817
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
|
|
2818
|
+
artifact.title ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ArtifactTitle, { className: TITLE_CLASSES3, children: artifact.title }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", {}),
|
|
2819
|
+
presignedUrl ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ArtifactActions, { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
2220
2820
|
ArtifactDownloadButton,
|
|
2221
2821
|
{
|
|
2222
2822
|
href: presignedUrl,
|
|
@@ -2225,17 +2825,17 @@ function TableArtifact({ artifact, labels, callbacks }) {
|
|
|
2225
2825
|
}
|
|
2226
2826
|
) }) : null
|
|
2227
2827
|
] }),
|
|
2228
|
-
/* @__PURE__ */ (0,
|
|
2828
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ArtifactContent, { className: "p-0 overflow-auto", style: { maxHeight: TABLE_MAX_BODY_HEIGHT }, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(StatusMessage, { $tone: "info", children: resolvedLabels.unavailable }) })
|
|
2229
2829
|
] });
|
|
2230
2830
|
}
|
|
2231
2831
|
return (
|
|
2232
2832
|
// The table body owns its own scroll container (`ArtifactTable` inside `TableArtifactContent`).
|
|
2233
2833
|
// Disable the outer overflow container so only one scroll context exists — this prevents
|
|
2234
2834
|
// double-scroll nesting and lets `useScrollShadow` find the correct scroll ancestor.
|
|
2235
|
-
/* @__PURE__ */ (0,
|
|
2236
|
-
/* @__PURE__ */ (0,
|
|
2237
|
-
artifact.title ? /* @__PURE__ */ (0,
|
|
2238
|
-
/* @__PURE__ */ (0,
|
|
2835
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
|
|
2836
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
|
|
2837
|
+
artifact.title ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ArtifactTitle, { className: TITLE_CLASSES3, children: artifact.title }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", {}),
|
|
2838
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ArtifactActions, { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
2239
2839
|
ArtifactDownloadButton,
|
|
2240
2840
|
{
|
|
2241
2841
|
href: presignedUrl ?? "",
|
|
@@ -2244,7 +2844,7 @@ function TableArtifact({ artifact, labels, callbacks }) {
|
|
|
2244
2844
|
}
|
|
2245
2845
|
) })
|
|
2246
2846
|
] }),
|
|
2247
|
-
/* @__PURE__ */ (0,
|
|
2847
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ArtifactContent, { className: "p-0 overflow-visible", style: { maxHeight: "none" }, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
2248
2848
|
TableArtifactContent,
|
|
2249
2849
|
{
|
|
2250
2850
|
columns: validColumns,
|
|
@@ -2275,7 +2875,8 @@ var TableArtifactService = {
|
|
|
2275
2875
|
// src/components/artifacts/artifact-services/index.ts
|
|
2276
2876
|
var ArtifactServices = {
|
|
2277
2877
|
[artifactTypes.TABLE]: TableArtifactService,
|
|
2278
|
-
[artifactTypes.CHART]: ChartArtifactService
|
|
2878
|
+
[artifactTypes.CHART]: ChartArtifactService,
|
|
2879
|
+
[artifactTypes.DECK]: DeckArtifactService
|
|
2279
2880
|
};
|
|
2280
2881
|
function artifactToClipboardText(artifact) {
|
|
2281
2882
|
const entry = ArtifactServices[artifact.type];
|
|
@@ -2286,13 +2887,13 @@ function artifactToClipboardText(artifact) {
|
|
|
2286
2887
|
}
|
|
2287
2888
|
|
|
2288
2889
|
// src/components/blocks/artifact-ref-block/artifact-ref-block.tsx
|
|
2289
|
-
var
|
|
2890
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
2290
2891
|
function ArtifactRefBlock({ block }) {
|
|
2291
2892
|
const { artifact, labels, callbacks } = block.payload;
|
|
2292
2893
|
const entry = ArtifactServices[artifact.type];
|
|
2293
2894
|
if (!entry) return null;
|
|
2294
2895
|
const Component = entry.Component;
|
|
2295
|
-
return /* @__PURE__ */ (0,
|
|
2896
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Component, { artifact, labels, callbacks });
|
|
2296
2897
|
}
|
|
2297
2898
|
|
|
2298
2899
|
// src/components/blocks/block-services/artifact-ref-block-service.ts
|
|
@@ -2327,9 +2928,9 @@ function markdownToPlainText(markdown) {
|
|
|
2327
2928
|
}
|
|
2328
2929
|
|
|
2329
2930
|
// src/components/blocks/text-block/text-block.tsx
|
|
2330
|
-
var
|
|
2331
|
-
var
|
|
2332
|
-
var
|
|
2931
|
+
var import_react_markdown2 = __toESM(require("react-markdown"), 1);
|
|
2932
|
+
var import_remark_breaks2 = __toESM(require("remark-breaks"), 1);
|
|
2933
|
+
var import_remark_gfm2 = __toESM(require("remark-gfm"), 1);
|
|
2333
2934
|
|
|
2334
2935
|
// src/components/blocks/scrollable-table/scrollable-table-styles.ts
|
|
2335
2936
|
var import_styled_components3 = __toESM(require("styled-components"), 1);
|
|
@@ -2344,13 +2945,13 @@ var TableScroll = import_styled_components3.default.div`
|
|
|
2344
2945
|
`;
|
|
2345
2946
|
|
|
2346
2947
|
// src/components/blocks/scrollable-table/scrollable-table.tsx
|
|
2347
|
-
var
|
|
2948
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
2348
2949
|
function ScrollableTable({ node: _node, ...props }) {
|
|
2349
|
-
return /* @__PURE__ */ (0,
|
|
2950
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(TableContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(TableScroll, { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("table", { ...props }) }) });
|
|
2350
2951
|
}
|
|
2351
2952
|
|
|
2352
2953
|
// src/components/blocks/text-block/sanitize.ts
|
|
2353
|
-
function
|
|
2954
|
+
function sanitize2(text) {
|
|
2354
2955
|
return text.split("\n").filter((line) => {
|
|
2355
2956
|
const t = line.trim();
|
|
2356
2957
|
return !(t.startsWith("<!-- table-title:") && t.endsWith("-->"));
|
|
@@ -2490,12 +3091,12 @@ var TextBlockWrapper = import_styled_components4.default.div`
|
|
|
2490
3091
|
`;
|
|
2491
3092
|
|
|
2492
3093
|
// src/components/blocks/text-block/text-block.tsx
|
|
2493
|
-
var
|
|
3094
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
2494
3095
|
var markdownComponents = {
|
|
2495
|
-
table: ((tableProps) => /* @__PURE__ */ (0,
|
|
3096
|
+
table: ((tableProps) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ScrollableTable, { ...tableProps }))
|
|
2496
3097
|
};
|
|
2497
3098
|
function TextBlock({ block }) {
|
|
2498
|
-
return /* @__PURE__ */ (0,
|
|
3099
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TextBlockWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_markdown2.default, { remarkPlugins: [import_remark_gfm2.default, import_remark_breaks2.default], components: markdownComponents, children: sanitize2(block.payload.text) }) });
|
|
2499
3100
|
}
|
|
2500
3101
|
|
|
2501
3102
|
// src/components/blocks/block-services/text-block-service.ts
|
|
@@ -2517,19 +3118,19 @@ var BlockServices = {
|
|
|
2517
3118
|
};
|
|
2518
3119
|
|
|
2519
3120
|
// src/components/blocks/block/block.tsx
|
|
2520
|
-
var
|
|
3121
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
2521
3122
|
function Block({ block }) {
|
|
2522
3123
|
const service = BlockServices[block.type];
|
|
2523
3124
|
if (!service) return null;
|
|
2524
3125
|
const { Component } = service;
|
|
2525
|
-
return /* @__PURE__ */ (0,
|
|
3126
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Component, { block });
|
|
2526
3127
|
}
|
|
2527
3128
|
|
|
2528
3129
|
// src/components/blocks/block-context/block-context.tsx
|
|
2529
|
-
var
|
|
2530
|
-
var BlockContext = (0,
|
|
3130
|
+
var import_react19 = require("react");
|
|
3131
|
+
var BlockContext = (0, import_react19.createContext)(null);
|
|
2531
3132
|
function useBlockContext() {
|
|
2532
|
-
return (0,
|
|
3133
|
+
return (0, import_react19.useContext)(BlockContext) ?? {};
|
|
2533
3134
|
}
|
|
2534
3135
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2535
3136
|
0 && (module.exports = {
|
|
@@ -2547,7 +3148,11 @@ function useBlockContext() {
|
|
|
2547
3148
|
@tabler/icons-react/dist/esm/defaultAttributes.mjs:
|
|
2548
3149
|
@tabler/icons-react/dist/esm/createReactComponent.mjs:
|
|
2549
3150
|
@tabler/icons-react/dist/esm/icons/IconAlertCircle.mjs:
|
|
3151
|
+
@tabler/icons-react/dist/esm/icons/IconArrowsMaximize.mjs:
|
|
3152
|
+
@tabler/icons-react/dist/esm/icons/IconArrowsMinimize.mjs:
|
|
2550
3153
|
@tabler/icons-react/dist/esm/icons/IconCheck.mjs:
|
|
3154
|
+
@tabler/icons-react/dist/esm/icons/IconChevronLeft.mjs:
|
|
3155
|
+
@tabler/icons-react/dist/esm/icons/IconChevronRight.mjs:
|
|
2551
3156
|
@tabler/icons-react/dist/esm/icons/IconCopy.mjs:
|
|
2552
3157
|
@tabler/icons-react/dist/esm/icons/IconDownload.mjs:
|
|
2553
3158
|
@tabler/icons-react/dist/esm/icons/IconFileSpreadsheet.mjs:
|