@shapesos/clay 0.12.0 → 0.13.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/artifacts.cjs +695 -246
- package/dist/artifacts.cjs.map +1 -1
- package/dist/artifacts.d.cts +133 -5
- package/dist/artifacts.d.ts +133 -5
- package/dist/artifacts.js +7 -2
- package/dist/blocks.cjs +705 -259
- package/dist/blocks.cjs.map +1 -1
- package/dist/blocks.css +1 -1
- package/dist/blocks.d.cts +8 -10
- package/dist/blocks.d.ts +8 -10
- package/dist/blocks.js +3 -2
- package/dist/capture.cjs +220 -0
- package/dist/capture.cjs.map +1 -0
- package/dist/capture.d.cts +113 -0
- package/dist/capture.d.ts +113 -0
- package/dist/capture.js +17 -0
- package/dist/chat.cjs +724 -287
- 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 +4 -3
- package/dist/{chunk-36CB624W.js → chunk-26XVDY6Z.js} +3 -3
- package/dist/chunk-26XVDY6Z.js.map +1 -0
- package/dist/{chunk-Z5JWF24N.js → chunk-DT44KNCV.js} +367 -82
- package/dist/chunk-DT44KNCV.js.map +1 -0
- package/dist/chunk-JAGNXEWK.js +116 -0
- package/dist/chunk-JAGNXEWK.js.map +1 -0
- package/dist/chunk-LXYCT4YO.js +7 -0
- package/dist/chunk-LXYCT4YO.js.map +1 -0
- package/dist/{chunk-FFX3CAOX.js → chunk-QH2WW2MW.js} +3 -3
- package/dist/chunk-RSRNSWJN.js +1 -0
- package/dist/chunk-RSRNSWJN.js.map +1 -0
- package/dist/dom-to-image-NATF3446.js +21 -0
- package/dist/dom-to-image-NATF3446.js.map +1 -0
- package/dist/index.cjs +763 -317
- 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 +9 -4
- package/dist/{types-C0BvwliI.d.cts → types-BzXPBy6s.d.cts} +39 -41
- package/dist/{types-uPfn67Dc.d.ts → types-CW45GBXl.d.cts} +25 -13
- package/dist/{types-DCutaXjZ.d.cts → types-D1b8v7EY.d.ts} +25 -13
- package/dist/{types-C5bFH4v3.d.ts → types-GCkXbyFm.d.ts} +39 -41
- package/package.json +12 -2
- package/dist/chunk-36CB624W.js.map +0 -1
- package/dist/chunk-AQEJRMRN.js +0 -1
- package/dist/chunk-Z5JWF24N.js.map +0 -1
- /package/dist/{chunk-AQEJRMRN.js.map → capture.js.map} +0 -0
- /package/dist/{chunk-FFX3CAOX.js.map → chunk-QH2WW2MW.js.map} +0 -0
package/dist/index.d.cts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export { ColorToken, TypographyStyle, TypographyType, colors, fontFamilies, typographyMixin, typographyStyles, typographyTypes } from './tokens.cjs';
|
|
2
2
|
export { ArtifactRefBlock, ArtifactRefBlockService, Block, BlockContext, BlockContextValue, BlockServices, TextBlockService, useBlockContext } from './blocks.cjs';
|
|
3
|
-
export { A as ArtifactRefBlockRecord, B as BlockComponentProps, a as BlockRecord, b as BlockService, c as BlockType, T as TextBlockRecord, d as blockTypes } from './types-
|
|
4
|
-
export { A as
|
|
5
|
-
export { ArtifactDownloadButton, ArtifactDownloadButtonProps, ArtifactServices, ChartArtifact, TableArtifact, artifactToClipboardText, isSafeDownloadUrl } from './artifacts.cjs';
|
|
3
|
+
export { A as ArtifactRefBlockRecord, B as BlockComponentProps, a as BlockRecord, b as BlockService, c as BlockType, T as TextBlockRecord, d as blockTypes } from './types-CW45GBXl.cjs';
|
|
4
|
+
export { A as ArtifactCallbacksOf, a as ArtifactDataRow, b as ArtifactLabelsOf, c as ArtifactRecord, d as ArtifactService, e as ArtifactServiceProps, f as ArtifactType, B as BarChartConfig, C as ChartArtifactLabels, g as ChartArtifactRecord, h as ChartConfig, i as ChartStats, D as DEFAULT_CHART_ARTIFACT_LABELS, j as DEFAULT_TABLE_ARTIFACT_LABELS, L as LineChartConfig, P as PieChartConfig, T as TableArtifactLabels, k as TableArtifactRecord, l as TableColumn, m as TableConfig, n as TableRow, o as TableStats, p as artifactTypes } from './types-BzXPBy6s.cjs';
|
|
5
|
+
export { ArtifactCopyAsImageButton, ArtifactCopyAsImageButtonProps, ArtifactDownloadButton, ArtifactDownloadButtonProps, ArtifactDownloadMenu, ArtifactDownloadMenuCsvAction, ArtifactDownloadMenuPngAction, ArtifactDownloadMenuProps, ArtifactServices, ChartArtifact, TableArtifact, artifactToClipboardText, isSafeDownloadUrl } from './artifacts.cjs';
|
|
6
6
|
export { ChatContext, ChatContextValue, ChatMessage, ChatMessageType, MESSAGE_ROLE, MessageRole, copyMessageText, useChatContext, useCopyToClipboard } from './chat.cjs';
|
|
7
7
|
export { Icon, IconButton, IconButtonProps, IconButtonSize, IconButtonVariant, IconProps } from './icon.cjs';
|
|
8
8
|
export { IconCtrl, KEYBOARD_SHORTCUT_VARIANTS, KeyIcon, KeyboardShortcut, KeyboardShortcutProps, KeyboardShortcutVariant } from './keyboard-shortcut.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export { ColorToken, TypographyStyle, TypographyType, colors, fontFamilies, typographyMixin, typographyStyles, typographyTypes } from './tokens.js';
|
|
2
2
|
export { ArtifactRefBlock, ArtifactRefBlockService, Block, BlockContext, BlockContextValue, BlockServices, TextBlockService, useBlockContext } from './blocks.js';
|
|
3
|
-
export { A as ArtifactRefBlockRecord, B as BlockComponentProps, a as BlockRecord, b as BlockService, c as BlockType, T as TextBlockRecord, d as blockTypes } from './types-
|
|
4
|
-
export { A as
|
|
5
|
-
export { ArtifactDownloadButton, ArtifactDownloadButtonProps, ArtifactServices, ChartArtifact, TableArtifact, artifactToClipboardText, isSafeDownloadUrl } from './artifacts.js';
|
|
3
|
+
export { A as ArtifactRefBlockRecord, B as BlockComponentProps, a as BlockRecord, b as BlockService, c as BlockType, T as TextBlockRecord, d as blockTypes } from './types-D1b8v7EY.js';
|
|
4
|
+
export { A as ArtifactCallbacksOf, a as ArtifactDataRow, b as ArtifactLabelsOf, c as ArtifactRecord, d as ArtifactService, e as ArtifactServiceProps, f as ArtifactType, B as BarChartConfig, C as ChartArtifactLabels, g as ChartArtifactRecord, h as ChartConfig, i as ChartStats, D as DEFAULT_CHART_ARTIFACT_LABELS, j as DEFAULT_TABLE_ARTIFACT_LABELS, L as LineChartConfig, P as PieChartConfig, T as TableArtifactLabels, k as TableArtifactRecord, l as TableColumn, m as TableConfig, n as TableRow, o as TableStats, p as artifactTypes } from './types-GCkXbyFm.js';
|
|
5
|
+
export { ArtifactCopyAsImageButton, ArtifactCopyAsImageButtonProps, ArtifactDownloadButton, ArtifactDownloadButtonProps, ArtifactDownloadMenu, ArtifactDownloadMenuCsvAction, ArtifactDownloadMenuPngAction, ArtifactDownloadMenuProps, ArtifactServices, ChartArtifact, TableArtifact, artifactToClipboardText, isSafeDownloadUrl } from './artifacts.js';
|
|
6
6
|
export { ChatContext, ChatContextValue, ChatMessage, ChatMessageType, MESSAGE_ROLE, MessageRole, copyMessageText, useChatContext, useCopyToClipboard } from './chat.js';
|
|
7
7
|
export { Icon, IconButton, IconButtonProps, IconButtonSize, IconButtonVariant, IconProps } from './icon.js';
|
|
8
8
|
export { IconCtrl, KEYBOARD_SHORTCUT_VARIANTS, KeyIcon, KeyboardShortcut, KeyboardShortcutProps, KeyboardShortcutVariant } from './keyboard-shortcut.js';
|
package/dist/index.js
CHANGED
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
copyMessageText,
|
|
32
32
|
useChatContext,
|
|
33
33
|
useCopyToClipboard
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-QH2WW2MW.js";
|
|
35
35
|
import {
|
|
36
36
|
BlockContext,
|
|
37
37
|
useBlockContext
|
|
@@ -43,13 +43,15 @@ import {
|
|
|
43
43
|
BlockServices,
|
|
44
44
|
TextBlockService,
|
|
45
45
|
blockTypes
|
|
46
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-26XVDY6Z.js";
|
|
47
47
|
import {
|
|
48
48
|
markdownToPlainText
|
|
49
49
|
} from "./chunk-NMKKU2UG.js";
|
|
50
|
-
import "./chunk-
|
|
50
|
+
import "./chunk-RSRNSWJN.js";
|
|
51
51
|
import {
|
|
52
|
+
ArtifactCopyAsImageButton,
|
|
52
53
|
ArtifactDownloadButton,
|
|
54
|
+
ArtifactDownloadMenu,
|
|
53
55
|
ArtifactServices,
|
|
54
56
|
ChartArtifact,
|
|
55
57
|
DEFAULT_CHART_ARTIFACT_LABELS,
|
|
@@ -58,7 +60,8 @@ import {
|
|
|
58
60
|
artifactToClipboardText,
|
|
59
61
|
artifactTypes,
|
|
60
62
|
isSafeDownloadUrl
|
|
61
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-DT44KNCV.js";
|
|
64
|
+
import "./chunk-LXYCT4YO.js";
|
|
62
65
|
import "./chunk-QXGYMDIA.js";
|
|
63
66
|
import "./chunk-C77QMQNT.js";
|
|
64
67
|
import {
|
|
@@ -81,7 +84,9 @@ import {
|
|
|
81
84
|
} from "./chunk-JF3P66JF.js";
|
|
82
85
|
import "./chunk-5WRI5ZAA.js";
|
|
83
86
|
export {
|
|
87
|
+
ArtifactCopyAsImageButton,
|
|
84
88
|
ArtifactDownloadButton,
|
|
89
|
+
ArtifactDownloadMenu,
|
|
85
90
|
ArtifactRefBlock,
|
|
86
91
|
ArtifactRefBlockService,
|
|
87
92
|
ArtifactServices,
|
|
@@ -120,8 +120,18 @@ type ChartArtifactRecord = ArtifactBase<typeof artifactTypes.CHART, ChartConfig>
|
|
|
120
120
|
* anticipated additions without forcing every consumer to provide them today.
|
|
121
121
|
*/
|
|
122
122
|
interface ChartArtifactLabels {
|
|
123
|
-
/** Tooltip + aria-label on the Download
|
|
123
|
+
/** Tooltip + aria-label on the Download menu's trigger button (icon-only, opens the format
|
|
124
|
+
* picker). The trigger is action-shaped (just "Download"); the menu items spell out the
|
|
125
|
+
* format. */
|
|
124
126
|
download: string;
|
|
127
|
+
/** Label for the "Download CSV" item inside the Download menu. */
|
|
128
|
+
downloadCsv: string;
|
|
129
|
+
/** Label for the "Download PNG" item inside the Download menu. */
|
|
130
|
+
downloadPng: string;
|
|
131
|
+
/** Tooltip + aria-label on the "Copy Image" button in the chart artifact header (idle state).
|
|
132
|
+
* Transient working / success / error tooltips remain in English — they flash for ~1.5s and the
|
|
133
|
+
* cost of translating them is rarely worth it. */
|
|
134
|
+
copyAsImage: string;
|
|
125
135
|
/** Status message shown when no presigned URL is available or the chart config is malformed. */
|
|
126
136
|
unavailable: string;
|
|
127
137
|
/** Status message shown when the fetch / parse fails at runtime. */
|
|
@@ -153,8 +163,15 @@ declare const DEFAULT_CHART_ARTIFACT_LABELS: ChartArtifactLabels;
|
|
|
153
163
|
* prevent the anchor's download navigation) — it's purely for analytics / observability hooks.
|
|
154
164
|
*/
|
|
155
165
|
interface ChartArtifactCallbacks {
|
|
156
|
-
/** Fires when the Download CSV
|
|
166
|
+
/** Fires when the "Download CSV" menu item is selected. Browser-native download still happens. */
|
|
157
167
|
onDownload?: (artifact: ChartArtifactRecord) => void;
|
|
168
|
+
/** Fires when the "Download PNG" menu item is selected. Runs alongside the rasterise — fires
|
|
169
|
+
* regardless of whether the rasterise ultimately succeeds (failures surface via console.warn). */
|
|
170
|
+
onDownloadPng?: (artifact: ChartArtifactRecord) => void;
|
|
171
|
+
/** Fires when the Copy Image button is clicked. Fires regardless of whether the copy ultimately
|
|
172
|
+
* succeeds (the result is reported via the button's own state flash) — use this only for
|
|
173
|
+
* analytics / observability, not for retrying failed copies. */
|
|
174
|
+
onCopyAsImage?: (artifact: ChartArtifactRecord) => void;
|
|
158
175
|
}
|
|
159
176
|
|
|
160
177
|
/**
|
|
@@ -255,32 +272,6 @@ interface TableArtifactCallbacks {
|
|
|
255
272
|
* plan, §6.4 (table contract).
|
|
256
273
|
*/
|
|
257
274
|
|
|
258
|
-
/**
|
|
259
|
-
* Per-artifact-type labels map. Lets a consumer pass labels for every artifact kind in a single
|
|
260
|
-
* bag at the block layer (`<ArtifactRefBlock>` payload); the dispatcher routes the matching slice
|
|
261
|
-
* (`labels[artifact.type]`) to the concrete artifact component.
|
|
262
|
-
*
|
|
263
|
-
* Extension pattern: add a new field here when adding a new artifact type. Keep the field
|
|
264
|
-
* optional so older consumers don't break on upgrade.
|
|
265
|
-
*/
|
|
266
|
-
interface ArtifactLabelsMap {
|
|
267
|
-
TABLE: TableArtifactLabels;
|
|
268
|
-
CHART: ChartArtifactLabels;
|
|
269
|
-
}
|
|
270
|
-
/**
|
|
271
|
-
* Per-artifact-type callbacks map. Sibling to `ArtifactLabelsMap` — consumer passes a single
|
|
272
|
-
* bag at the block layer covering every artifact type's action callbacks (today: `onDownload`).
|
|
273
|
-
* Used for analytics / observability hooks — every callback is optional and fires alongside
|
|
274
|
-
* the default browser behaviour (it does NOT replace it).
|
|
275
|
-
*
|
|
276
|
-
* Each callback receives its artifact-type's `ArtifactBase`-derived record so consumers can
|
|
277
|
-
* derive analytics context (title, config, etc.) from one wiring at the chat-surface level
|
|
278
|
-
* instead of per-block closures.
|
|
279
|
-
*/
|
|
280
|
-
interface ArtifactCallbacksMap {
|
|
281
|
-
TABLE: TableArtifactCallbacks;
|
|
282
|
-
CHART: ChartArtifactCallbacks;
|
|
283
|
-
}
|
|
284
275
|
/**
|
|
285
276
|
* Discriminated union of all supported artifacts. Extension pattern: add the new branch here AND
|
|
286
277
|
* in the `ArtifactServices` map (single source of truth for the type→component mapping). Older
|
|
@@ -288,30 +279,37 @@ interface ArtifactCallbacksMap {
|
|
|
288
279
|
* guard.
|
|
289
280
|
*/
|
|
290
281
|
type ArtifactRecord = TableArtifactRecord | ChartArtifactRecord;
|
|
282
|
+
/**
|
|
283
|
+
* Type-level lookup from an `ArtifactRecord` branch to its labels / callbacks slice. The block
|
|
284
|
+
* layer already carries the discriminator on `artifact.type`, so the renderer-side `labels` and
|
|
285
|
+
* `callbacks` props expose exactly one type's slice — never a union-bag keyed by type. Consumers
|
|
286
|
+
* emit a flat object; the dispatcher narrows it implicitly via `TArtifact`.
|
|
287
|
+
*/
|
|
288
|
+
type ArtifactLabelsOf<TArtifact extends ArtifactRecord> = TArtifact extends ChartArtifactRecord ? ChartArtifactLabels : TArtifact extends TableArtifactRecord ? TableArtifactLabels : never;
|
|
289
|
+
/** Sibling to `ArtifactLabelsOf` — callbacks slice matching the artifact branch. */
|
|
290
|
+
type ArtifactCallbacksOf<TArtifact extends ArtifactRecord> = TArtifact extends ChartArtifactRecord ? ChartArtifactCallbacks : TArtifact extends TableArtifactRecord ? TableArtifactCallbacks : never;
|
|
291
291
|
/**
|
|
292
292
|
* Props every concrete artifact component receives from the dispatcher.
|
|
293
293
|
*
|
|
294
|
-
* `labels`
|
|
295
|
-
*
|
|
296
|
-
*
|
|
297
|
-
*
|
|
294
|
+
* `labels` and `callbacks` are the renderer's OWN flat slice — narrowed by `TArtifact` so a
|
|
295
|
+
* `ChartArtifact` reads `ChartArtifactLabels` directly. The block layer (`ArtifactRefBlockRecord`)
|
|
296
|
+
* is a *distributed* union over `ArtifactRecord` branches, so wrong-shape labels for a given
|
|
297
|
+
* artifact.type are caught at the consumer's construction site — not silently forwarded here.
|
|
298
298
|
*/
|
|
299
299
|
interface ArtifactServiceProps<TArtifact extends ArtifactRecord = ArtifactRecord> {
|
|
300
300
|
/** The artifact metadata (config + presigned URL). */
|
|
301
301
|
artifact: TArtifact;
|
|
302
302
|
/**
|
|
303
|
-
* Optional localized labels
|
|
304
|
-
*
|
|
305
|
-
* default (per-key `Partial` merge against `DEFAULT_*_ARTIFACT_LABELS`).
|
|
303
|
+
* Optional localized labels for this artifact's action buttons + status messages. Per-key
|
|
304
|
+
* `Partial` merge against `DEFAULT_*_ARTIFACT_LABELS` — anything omitted falls back to English.
|
|
306
305
|
*/
|
|
307
|
-
labels?: Partial<
|
|
306
|
+
labels?: Partial<ArtifactLabelsOf<TArtifact>>;
|
|
308
307
|
/**
|
|
309
|
-
* Optional side-effect callbacks
|
|
310
|
-
* (e.g. tracking a download event).
|
|
311
|
-
* (`callbacks?.TABLE`, `callbacks?.CHART`). Callbacks fire alongside the default browser
|
|
308
|
+
* Optional side-effect callbacks for actions on this artifact — for analytics / observability
|
|
309
|
+
* hooks (e.g. tracking a download event). Callbacks fire alongside the default browser
|
|
312
310
|
* behaviour and do not replace it.
|
|
313
311
|
*/
|
|
314
|
-
callbacks?: Partial<
|
|
312
|
+
callbacks?: Partial<ArtifactCallbacksOf<TArtifact>>;
|
|
315
313
|
}
|
|
316
314
|
/** Per-artifact-type service — registry entry that pairs a discriminator with its concrete component. */
|
|
317
315
|
interface ArtifactService<TArtifact extends ArtifactRecord = ArtifactRecord> {
|
|
@@ -329,4 +327,4 @@ interface ArtifactService<TArtifact extends ArtifactRecord = ArtifactRecord> {
|
|
|
329
327
|
toClipboardText: (artifact: TArtifact) => string;
|
|
330
328
|
}
|
|
331
329
|
|
|
332
|
-
export { type
|
|
330
|
+
export { type ArtifactCallbacksOf as A, type BarChartConfig as B, type ChartArtifactLabels as C, DEFAULT_CHART_ARTIFACT_LABELS as D, type LineChartConfig as L, type PieChartConfig as P, type TableArtifactLabels as T, type ArtifactDataRow as a, type ArtifactLabelsOf as b, type ArtifactRecord as c, type ArtifactService as d, type ArtifactServiceProps as e, type ArtifactType as f, type ChartArtifactRecord as g, type ChartConfig as h, type ChartStats as i, DEFAULT_TABLE_ARTIFACT_LABELS as j, type TableArtifactRecord as k, type TableColumn as l, type TableConfig as m, type TableRow as n, type TableStats as o, artifactTypes as p };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ComponentType } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { c as ArtifactRecord, b as ArtifactLabelsOf, A as ArtifactCallbacksOf } from './types-BzXPBy6s.cjs';
|
|
3
3
|
|
|
4
4
|
/** Block-type discriminator constants. Mirrors the wire shape from io-server / shapes-agent. */
|
|
5
5
|
declare const blockTypes: {
|
|
@@ -25,8 +25,15 @@ interface TextBlockRecord {
|
|
|
25
25
|
* `@/components/artifacts/types` so the artifact layer can be consumed independently of the
|
|
26
26
|
* block layer (e.g. by a future surface that renders an artifact outside chat). The block layer
|
|
27
27
|
* imports them here to wrap an artifact in an `ARTIFACT_REF` block.
|
|
28
|
+
*
|
|
29
|
+
* `ArtifactRefBlockRecord` is a *distributed* union over `ArtifactRecord` branches — TS narrows
|
|
30
|
+
* `labels` and `callbacks` to the slice matching `artifact.type` via `ArtifactLabelsOf<T>` /
|
|
31
|
+
* `ArtifactCallbacksOf<T>`. Without this distribution, `Partial<ChartLabels | TableLabels>`
|
|
32
|
+
* collapses to `Partial<ChartLabels> | Partial<TableLabels>` and TS accepts chart-only keys on
|
|
33
|
+
* a TABLE block's payload (the discriminator becomes load-bearing only at runtime, not in the
|
|
34
|
+
* type system).
|
|
28
35
|
*/
|
|
29
|
-
|
|
36
|
+
type ArtifactRefBlockRecord = ArtifactRecord extends infer TArtifact ? TArtifact extends ArtifactRecord ? {
|
|
30
37
|
/** Block-type discriminator. */
|
|
31
38
|
type: typeof blockTypes.ARTIFACT_REF;
|
|
32
39
|
/** Type-specific data; kept as `payload` to match the wire shape 1:1. */
|
|
@@ -34,24 +41,29 @@ interface ArtifactRefBlockRecord {
|
|
|
34
41
|
/** The artifact's stable identifier, used for keying / future cross-message reuse. */
|
|
35
42
|
artifactId: string;
|
|
36
43
|
/** Inlined artifact metadata — clients fetch the underlying data via `artifact.protectedAsset.presignedUrl`. */
|
|
37
|
-
artifact:
|
|
44
|
+
artifact: TArtifact;
|
|
38
45
|
/**
|
|
39
46
|
* Optional consumer-supplied labels for the rendered artifact's action buttons + status
|
|
40
|
-
* messages
|
|
41
|
-
* their i18n layer when materialising the block-record from the
|
|
42
|
-
* the augmented block to `<Block>`. The dispatcher
|
|
43
|
-
*
|
|
44
|
-
*
|
|
47
|
+
* messages — a flat slice narrowed by `artifact.type`. NOT a wire field; the consumer
|
|
48
|
+
* constructs this from their i18n layer when materialising the block-record from the
|
|
49
|
+
* server payload, then passes the augmented block to `<Block>`. The dispatcher forwards
|
|
50
|
+
* the slice directly to the matching renderer — no per-type key wrapping (the block
|
|
51
|
+
* already carries the discriminator).
|
|
52
|
+
*
|
|
53
|
+
* TS catches cross-type assignments here: `block.payload.labels = { downloadCsv: 'X' }`
|
|
54
|
+
* on a `TableArtifactRecord`-typed block is a type error because `downloadCsv` isn't a
|
|
55
|
+
* `TableArtifactLabels` key.
|
|
45
56
|
*/
|
|
46
|
-
labels?: Partial<
|
|
57
|
+
labels?: Partial<ArtifactLabelsOf<TArtifact>>;
|
|
47
58
|
/**
|
|
48
59
|
* Optional side-effect callbacks for actions on the rendered artifact (e.g. `onDownload`).
|
|
49
|
-
*
|
|
50
|
-
* once to bridge artifact actions to their analytics /
|
|
60
|
+
* Flat slice narrowed by `artifact.type` via `ArtifactCallbacksOf<T>`. NOT a wire field
|
|
61
|
+
* — the consumer wires this once to bridge artifact actions to their analytics /
|
|
62
|
+
* observability layer.
|
|
51
63
|
*/
|
|
52
|
-
callbacks?: Partial<
|
|
64
|
+
callbacks?: Partial<ArtifactCallbacksOf<TArtifact>>;
|
|
53
65
|
};
|
|
54
|
-
}
|
|
66
|
+
} : never : never;
|
|
55
67
|
/** Discriminated union of all supported content blocks. Additive — new types extend this union. */
|
|
56
68
|
type BlockRecord = TextBlockRecord | ArtifactRefBlockRecord;
|
|
57
69
|
/** Props every concrete block component receives from the dispatcher. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ComponentType } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { c as ArtifactRecord, b as ArtifactLabelsOf, A as ArtifactCallbacksOf } from './types-GCkXbyFm.js';
|
|
3
3
|
|
|
4
4
|
/** Block-type discriminator constants. Mirrors the wire shape from io-server / shapes-agent. */
|
|
5
5
|
declare const blockTypes: {
|
|
@@ -25,8 +25,15 @@ interface TextBlockRecord {
|
|
|
25
25
|
* `@/components/artifacts/types` so the artifact layer can be consumed independently of the
|
|
26
26
|
* block layer (e.g. by a future surface that renders an artifact outside chat). The block layer
|
|
27
27
|
* imports them here to wrap an artifact in an `ARTIFACT_REF` block.
|
|
28
|
+
*
|
|
29
|
+
* `ArtifactRefBlockRecord` is a *distributed* union over `ArtifactRecord` branches — TS narrows
|
|
30
|
+
* `labels` and `callbacks` to the slice matching `artifact.type` via `ArtifactLabelsOf<T>` /
|
|
31
|
+
* `ArtifactCallbacksOf<T>`. Without this distribution, `Partial<ChartLabels | TableLabels>`
|
|
32
|
+
* collapses to `Partial<ChartLabels> | Partial<TableLabels>` and TS accepts chart-only keys on
|
|
33
|
+
* a TABLE block's payload (the discriminator becomes load-bearing only at runtime, not in the
|
|
34
|
+
* type system).
|
|
28
35
|
*/
|
|
29
|
-
|
|
36
|
+
type ArtifactRefBlockRecord = ArtifactRecord extends infer TArtifact ? TArtifact extends ArtifactRecord ? {
|
|
30
37
|
/** Block-type discriminator. */
|
|
31
38
|
type: typeof blockTypes.ARTIFACT_REF;
|
|
32
39
|
/** Type-specific data; kept as `payload` to match the wire shape 1:1. */
|
|
@@ -34,24 +41,29 @@ interface ArtifactRefBlockRecord {
|
|
|
34
41
|
/** The artifact's stable identifier, used for keying / future cross-message reuse. */
|
|
35
42
|
artifactId: string;
|
|
36
43
|
/** Inlined artifact metadata — clients fetch the underlying data via `artifact.protectedAsset.presignedUrl`. */
|
|
37
|
-
artifact:
|
|
44
|
+
artifact: TArtifact;
|
|
38
45
|
/**
|
|
39
46
|
* Optional consumer-supplied labels for the rendered artifact's action buttons + status
|
|
40
|
-
* messages
|
|
41
|
-
* their i18n layer when materialising the block-record from the
|
|
42
|
-
* the augmented block to `<Block>`. The dispatcher
|
|
43
|
-
*
|
|
44
|
-
*
|
|
47
|
+
* messages — a flat slice narrowed by `artifact.type`. NOT a wire field; the consumer
|
|
48
|
+
* constructs this from their i18n layer when materialising the block-record from the
|
|
49
|
+
* server payload, then passes the augmented block to `<Block>`. The dispatcher forwards
|
|
50
|
+
* the slice directly to the matching renderer — no per-type key wrapping (the block
|
|
51
|
+
* already carries the discriminator).
|
|
52
|
+
*
|
|
53
|
+
* TS catches cross-type assignments here: `block.payload.labels = { downloadCsv: 'X' }`
|
|
54
|
+
* on a `TableArtifactRecord`-typed block is a type error because `downloadCsv` isn't a
|
|
55
|
+
* `TableArtifactLabels` key.
|
|
45
56
|
*/
|
|
46
|
-
labels?: Partial<
|
|
57
|
+
labels?: Partial<ArtifactLabelsOf<TArtifact>>;
|
|
47
58
|
/**
|
|
48
59
|
* Optional side-effect callbacks for actions on the rendered artifact (e.g. `onDownload`).
|
|
49
|
-
*
|
|
50
|
-
* once to bridge artifact actions to their analytics /
|
|
60
|
+
* Flat slice narrowed by `artifact.type` via `ArtifactCallbacksOf<T>`. NOT a wire field
|
|
61
|
+
* — the consumer wires this once to bridge artifact actions to their analytics /
|
|
62
|
+
* observability layer.
|
|
51
63
|
*/
|
|
52
|
-
callbacks?: Partial<
|
|
64
|
+
callbacks?: Partial<ArtifactCallbacksOf<TArtifact>>;
|
|
53
65
|
};
|
|
54
|
-
}
|
|
66
|
+
} : never : never;
|
|
55
67
|
/** Discriminated union of all supported content blocks. Additive — new types extend this union. */
|
|
56
68
|
type BlockRecord = TextBlockRecord | ArtifactRefBlockRecord;
|
|
57
69
|
/** Props every concrete block component receives from the dispatcher. */
|
|
@@ -120,8 +120,18 @@ type ChartArtifactRecord = ArtifactBase<typeof artifactTypes.CHART, ChartConfig>
|
|
|
120
120
|
* anticipated additions without forcing every consumer to provide them today.
|
|
121
121
|
*/
|
|
122
122
|
interface ChartArtifactLabels {
|
|
123
|
-
/** Tooltip + aria-label on the Download
|
|
123
|
+
/** Tooltip + aria-label on the Download menu's trigger button (icon-only, opens the format
|
|
124
|
+
* picker). The trigger is action-shaped (just "Download"); the menu items spell out the
|
|
125
|
+
* format. */
|
|
124
126
|
download: string;
|
|
127
|
+
/** Label for the "Download CSV" item inside the Download menu. */
|
|
128
|
+
downloadCsv: string;
|
|
129
|
+
/** Label for the "Download PNG" item inside the Download menu. */
|
|
130
|
+
downloadPng: string;
|
|
131
|
+
/** Tooltip + aria-label on the "Copy Image" button in the chart artifact header (idle state).
|
|
132
|
+
* Transient working / success / error tooltips remain in English — they flash for ~1.5s and the
|
|
133
|
+
* cost of translating them is rarely worth it. */
|
|
134
|
+
copyAsImage: string;
|
|
125
135
|
/** Status message shown when no presigned URL is available or the chart config is malformed. */
|
|
126
136
|
unavailable: string;
|
|
127
137
|
/** Status message shown when the fetch / parse fails at runtime. */
|
|
@@ -153,8 +163,15 @@ declare const DEFAULT_CHART_ARTIFACT_LABELS: ChartArtifactLabels;
|
|
|
153
163
|
* prevent the anchor's download navigation) — it's purely for analytics / observability hooks.
|
|
154
164
|
*/
|
|
155
165
|
interface ChartArtifactCallbacks {
|
|
156
|
-
/** Fires when the Download CSV
|
|
166
|
+
/** Fires when the "Download CSV" menu item is selected. Browser-native download still happens. */
|
|
157
167
|
onDownload?: (artifact: ChartArtifactRecord) => void;
|
|
168
|
+
/** Fires when the "Download PNG" menu item is selected. Runs alongside the rasterise — fires
|
|
169
|
+
* regardless of whether the rasterise ultimately succeeds (failures surface via console.warn). */
|
|
170
|
+
onDownloadPng?: (artifact: ChartArtifactRecord) => void;
|
|
171
|
+
/** Fires when the Copy Image button is clicked. Fires regardless of whether the copy ultimately
|
|
172
|
+
* succeeds (the result is reported via the button's own state flash) — use this only for
|
|
173
|
+
* analytics / observability, not for retrying failed copies. */
|
|
174
|
+
onCopyAsImage?: (artifact: ChartArtifactRecord) => void;
|
|
158
175
|
}
|
|
159
176
|
|
|
160
177
|
/**
|
|
@@ -255,32 +272,6 @@ interface TableArtifactCallbacks {
|
|
|
255
272
|
* plan, §6.4 (table contract).
|
|
256
273
|
*/
|
|
257
274
|
|
|
258
|
-
/**
|
|
259
|
-
* Per-artifact-type labels map. Lets a consumer pass labels for every artifact kind in a single
|
|
260
|
-
* bag at the block layer (`<ArtifactRefBlock>` payload); the dispatcher routes the matching slice
|
|
261
|
-
* (`labels[artifact.type]`) to the concrete artifact component.
|
|
262
|
-
*
|
|
263
|
-
* Extension pattern: add a new field here when adding a new artifact type. Keep the field
|
|
264
|
-
* optional so older consumers don't break on upgrade.
|
|
265
|
-
*/
|
|
266
|
-
interface ArtifactLabelsMap {
|
|
267
|
-
TABLE: TableArtifactLabels;
|
|
268
|
-
CHART: ChartArtifactLabels;
|
|
269
|
-
}
|
|
270
|
-
/**
|
|
271
|
-
* Per-artifact-type callbacks map. Sibling to `ArtifactLabelsMap` — consumer passes a single
|
|
272
|
-
* bag at the block layer covering every artifact type's action callbacks (today: `onDownload`).
|
|
273
|
-
* Used for analytics / observability hooks — every callback is optional and fires alongside
|
|
274
|
-
* the default browser behaviour (it does NOT replace it).
|
|
275
|
-
*
|
|
276
|
-
* Each callback receives its artifact-type's `ArtifactBase`-derived record so consumers can
|
|
277
|
-
* derive analytics context (title, config, etc.) from one wiring at the chat-surface level
|
|
278
|
-
* instead of per-block closures.
|
|
279
|
-
*/
|
|
280
|
-
interface ArtifactCallbacksMap {
|
|
281
|
-
TABLE: TableArtifactCallbacks;
|
|
282
|
-
CHART: ChartArtifactCallbacks;
|
|
283
|
-
}
|
|
284
275
|
/**
|
|
285
276
|
* Discriminated union of all supported artifacts. Extension pattern: add the new branch here AND
|
|
286
277
|
* in the `ArtifactServices` map (single source of truth for the type→component mapping). Older
|
|
@@ -288,30 +279,37 @@ interface ArtifactCallbacksMap {
|
|
|
288
279
|
* guard.
|
|
289
280
|
*/
|
|
290
281
|
type ArtifactRecord = TableArtifactRecord | ChartArtifactRecord;
|
|
282
|
+
/**
|
|
283
|
+
* Type-level lookup from an `ArtifactRecord` branch to its labels / callbacks slice. The block
|
|
284
|
+
* layer already carries the discriminator on `artifact.type`, so the renderer-side `labels` and
|
|
285
|
+
* `callbacks` props expose exactly one type's slice — never a union-bag keyed by type. Consumers
|
|
286
|
+
* emit a flat object; the dispatcher narrows it implicitly via `TArtifact`.
|
|
287
|
+
*/
|
|
288
|
+
type ArtifactLabelsOf<TArtifact extends ArtifactRecord> = TArtifact extends ChartArtifactRecord ? ChartArtifactLabels : TArtifact extends TableArtifactRecord ? TableArtifactLabels : never;
|
|
289
|
+
/** Sibling to `ArtifactLabelsOf` — callbacks slice matching the artifact branch. */
|
|
290
|
+
type ArtifactCallbacksOf<TArtifact extends ArtifactRecord> = TArtifact extends ChartArtifactRecord ? ChartArtifactCallbacks : TArtifact extends TableArtifactRecord ? TableArtifactCallbacks : never;
|
|
291
291
|
/**
|
|
292
292
|
* Props every concrete artifact component receives from the dispatcher.
|
|
293
293
|
*
|
|
294
|
-
* `labels`
|
|
295
|
-
*
|
|
296
|
-
*
|
|
297
|
-
*
|
|
294
|
+
* `labels` and `callbacks` are the renderer's OWN flat slice — narrowed by `TArtifact` so a
|
|
295
|
+
* `ChartArtifact` reads `ChartArtifactLabels` directly. The block layer (`ArtifactRefBlockRecord`)
|
|
296
|
+
* is a *distributed* union over `ArtifactRecord` branches, so wrong-shape labels for a given
|
|
297
|
+
* artifact.type are caught at the consumer's construction site — not silently forwarded here.
|
|
298
298
|
*/
|
|
299
299
|
interface ArtifactServiceProps<TArtifact extends ArtifactRecord = ArtifactRecord> {
|
|
300
300
|
/** The artifact metadata (config + presigned URL). */
|
|
301
301
|
artifact: TArtifact;
|
|
302
302
|
/**
|
|
303
|
-
* Optional localized labels
|
|
304
|
-
*
|
|
305
|
-
* default (per-key `Partial` merge against `DEFAULT_*_ARTIFACT_LABELS`).
|
|
303
|
+
* Optional localized labels for this artifact's action buttons + status messages. Per-key
|
|
304
|
+
* `Partial` merge against `DEFAULT_*_ARTIFACT_LABELS` — anything omitted falls back to English.
|
|
306
305
|
*/
|
|
307
|
-
labels?: Partial<
|
|
306
|
+
labels?: Partial<ArtifactLabelsOf<TArtifact>>;
|
|
308
307
|
/**
|
|
309
|
-
* Optional side-effect callbacks
|
|
310
|
-
* (e.g. tracking a download event).
|
|
311
|
-
* (`callbacks?.TABLE`, `callbacks?.CHART`). Callbacks fire alongside the default browser
|
|
308
|
+
* Optional side-effect callbacks for actions on this artifact — for analytics / observability
|
|
309
|
+
* hooks (e.g. tracking a download event). Callbacks fire alongside the default browser
|
|
312
310
|
* behaviour and do not replace it.
|
|
313
311
|
*/
|
|
314
|
-
callbacks?: Partial<
|
|
312
|
+
callbacks?: Partial<ArtifactCallbacksOf<TArtifact>>;
|
|
315
313
|
}
|
|
316
314
|
/** Per-artifact-type service — registry entry that pairs a discriminator with its concrete component. */
|
|
317
315
|
interface ArtifactService<TArtifact extends ArtifactRecord = ArtifactRecord> {
|
|
@@ -329,4 +327,4 @@ interface ArtifactService<TArtifact extends ArtifactRecord = ArtifactRecord> {
|
|
|
329
327
|
toClipboardText: (artifact: TArtifact) => string;
|
|
330
328
|
}
|
|
331
329
|
|
|
332
|
-
export { type
|
|
330
|
+
export { type ArtifactCallbacksOf as A, type BarChartConfig as B, type ChartArtifactLabels as C, DEFAULT_CHART_ARTIFACT_LABELS as D, type LineChartConfig as L, type PieChartConfig as P, type TableArtifactLabels as T, type ArtifactDataRow as a, type ArtifactLabelsOf as b, type ArtifactRecord as c, type ArtifactService as d, type ArtifactServiceProps as e, type ArtifactType as f, type ChartArtifactRecord as g, type ChartConfig as h, type ChartStats as i, DEFAULT_TABLE_ARTIFACT_LABELS as j, type TableArtifactRecord as k, type TableColumn as l, type TableConfig as m, type TableRow as n, type TableStats as o, artifactTypes as p };
|
package/package.json
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shapesos/clay",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"main": "./dist/index.cjs",
|
|
5
5
|
"module": "./dist/index.js",
|
|
6
6
|
"devDependencies": {
|
|
7
7
|
"@changesets/changelog-github": "^0.6.0",
|
|
8
8
|
"@changesets/cli": "^2.30.0",
|
|
9
9
|
"@eslint/js": "^10.0.1",
|
|
10
|
+
"@fontsource-variable/crimson-pro": "^5.2.8",
|
|
11
|
+
"@fontsource-variable/geist": "^5.2.9",
|
|
10
12
|
"@playwright/test": "^1.58.2",
|
|
11
13
|
"@storybook/addon-a11y": "^10.2.19",
|
|
12
14
|
"@storybook/addon-docs": "^10.2.19",
|
|
@@ -117,6 +119,11 @@
|
|
|
117
119
|
"import": "./dist/utils.js",
|
|
118
120
|
"require": "./dist/utils.cjs"
|
|
119
121
|
},
|
|
122
|
+
"./capture": {
|
|
123
|
+
"types": "./dist/capture.d.ts",
|
|
124
|
+
"import": "./dist/capture.js",
|
|
125
|
+
"require": "./dist/capture.cjs"
|
|
126
|
+
},
|
|
120
127
|
"./button": {
|
|
121
128
|
"types": "./dist/button.d.ts",
|
|
122
129
|
"import": "./dist/button.js",
|
|
@@ -141,8 +148,9 @@
|
|
|
141
148
|
"registry": "https://registry.npmjs.org/"
|
|
142
149
|
},
|
|
143
150
|
"scripts": {
|
|
144
|
-
"build": "bun run gen:theme && tsup && bun run build:css",
|
|
151
|
+
"build": "bun run gen:font && bun run gen:theme && tsup && bun run build:css",
|
|
145
152
|
"build:css": "tailwindcss -i src/styles/tailwind.css -o dist/blocks.css --minify",
|
|
153
|
+
"gen:font": "bun run scripts/generate-font-embed.ts",
|
|
146
154
|
"gen:theme": "bun run scripts/generate-theme-tokens.ts",
|
|
147
155
|
"dev": "tsup --watch",
|
|
148
156
|
"storybook": "storybook dev -p 6006",
|
|
@@ -165,8 +173,10 @@
|
|
|
165
173
|
"type": "module",
|
|
166
174
|
"types": "./dist/index.d.ts",
|
|
167
175
|
"dependencies": {
|
|
176
|
+
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
168
177
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
169
178
|
"clsx": "^2.1.1",
|
|
179
|
+
"html-to-image": "^1.11.13",
|
|
170
180
|
"lottie-react": "^2.4.1",
|
|
171
181
|
"papaparse": "^5.5.3",
|
|
172
182
|
"react-markdown": "^8.0.7",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/blocks/types.ts","../src/components/blocks/artifact-ref-block/artifact-ref-block.tsx","../src/components/blocks/block-services/artifact-ref-block-service.ts","../src/components/blocks/text-block/text-block.tsx","../src/components/blocks/scrollable-table/scrollable-table-styles.ts","../src/components/blocks/scrollable-table/scrollable-table.tsx","../src/components/blocks/text-block/sanitize.ts","../src/components/blocks/text-block/text-block-styles.ts","../src/components/blocks/block-services/text-block-service.ts","../src/components/blocks/block-services/index.ts","../src/components/blocks/block/block.tsx"],"sourcesContent":["import type { ComponentType } from \"react\";\n\nimport type { ArtifactCallbacksMap, ArtifactLabelsMap, ArtifactRecord } from \"@/components/artifacts/types\";\n\n/** Block-type discriminator constants. Mirrors the wire shape from io-server / shapes-agent. */\nexport const blockTypes = {\n TEXT: \"TEXT\",\n ARTIFACT_REF: \"ARTIFACT_REF\",\n} as const;\n\n/** Discriminator for content blocks. */\nexport type BlockType = (typeof blockTypes)[keyof typeof blockTypes];\n\n/** Plain-text content block — rendered as Markdown. */\nexport interface TextBlockRecord {\n /** Block-type discriminator. */\n type: typeof blockTypes.TEXT;\n /** Type-specific data; kept as `payload` to match the wire shape 1:1. */\n payload: {\n /** The Markdown source for this text segment. */\n text: string;\n };\n}\n\n/**\n * Reference-to-an-artifact content block — dispatched to the per-type artifact component.\n *\n * The artifact-domain types (`ArtifactRecord`, `TableArtifactRecord`, etc.) live in\n * `@/components/artifacts/types` so the artifact layer can be consumed independently of the\n * block layer (e.g. by a future surface that renders an artifact outside chat). The block layer\n * imports them here to wrap an artifact in an `ARTIFACT_REF` block.\n */\nexport interface ArtifactRefBlockRecord {\n /** Block-type discriminator. */\n type: typeof blockTypes.ARTIFACT_REF;\n /** Type-specific data; kept as `payload` to match the wire shape 1:1. */\n payload: {\n /** The artifact's stable identifier, used for keying / future cross-message reuse. */\n artifactId: string;\n /** Inlined artifact metadata — clients fetch the underlying data via `artifact.protectedAsset.presignedUrl`. */\n artifact: ArtifactRecord;\n /**\n * Optional consumer-supplied labels for the rendered artifact's action buttons + status\n * messages, keyed by artifact type. NOT a wire field — the consumer constructs this from\n * their i18n layer when materialising the block-record from the server payload, then passes\n * the augmented block to `<Block>`. The dispatcher stays generic — it forwards the whole\n * `labels` bag to every artifact component, and each component reads its own slice\n * (`labels.TABLE`, `labels.CHART`) internally.\n */\n labels?: Partial<ArtifactLabelsMap>;\n /**\n * Optional side-effect callbacks for actions on the rendered artifact (e.g. `onDownload`).\n * Keyed by artifact type, mirroring `labels`. NOT a wire field — the consumer wires this\n * once to bridge artifact actions to their analytics / observability layer.\n */\n callbacks?: Partial<ArtifactCallbacksMap>;\n };\n}\n\n/** Discriminated union of all supported content blocks. Additive — new types extend this union. */\nexport type BlockRecord = TextBlockRecord | ArtifactRefBlockRecord;\n\n/** Props every concrete block component receives from the dispatcher. */\nexport interface BlockComponentProps<TBlock extends BlockRecord = BlockRecord> {\n /** The block to render. */\n block: TBlock;\n}\n\n/** Per-block-type service — registry entry that pairs a discriminator with its concrete component. */\nexport interface BlockService<TBlock extends BlockRecord = BlockRecord> {\n /** Discriminator value this service handles. */\n type: BlockType;\n /** React component that renders a block of this type. */\n Component: ComponentType<BlockComponentProps<TBlock>>;\n /**\n * Returns a plain-text or markdown string representation of this block suitable for clipboard\n * copy. Called by `copyMessageText` when the user clicks \"copy message\".\n *\n * - `TextBlockService`: returns `block.payload.text` verbatim (markdown preserved).\n * - `ArtifactRefBlockService`: delegates to `ArtifactServices[artifact.type].toClipboardText`.\n * Falls back to `[Artifact: <title>]` when the artifact type has no registered component.\n *\n * Optional so external `BlockService` implementors don't break on upgrade — when omitted, the\n * aggregator treats the block as contributing the empty string (silently skipped). Implementations\n * must be pure, synchronous functions — no async, no hooks, no side effects.\n */\n toClipboardText?: (block: TBlock) => string;\n}\n","import type { ReactNode } from \"react\";\n\nimport { ArtifactServices } from \"@/components/artifacts/artifact-services\";\nimport type { ArtifactRefBlockRecord, BlockComponentProps } from \"../types\";\n\n/**\n * Renders an `ARTIFACT_REF` block by dispatching the inlined artifact to its per-type component.\n *\n * Generic forward: every artifact component accepts the same `(artifact, labels)` shape — labels\n * is the union `ArtifactLabelsMap` bag, and each component reads its own slice internally.\n * That keeps this dispatcher a one-liner: lookup the service, pass both props through, no\n * switch and no cast at the boundary.\n *\n * Unknown artifact types render as `null` — the map only contains types we know how to render,\n * so an older clay client receiving a future artifact type degrades silently rather than\n * crashing the chat.\n *\n * Localized labels live in `block.payload.labels` (keyed by artifact type). Consumer builds\n * that bag from their i18n layer when materialising the block-record from the server payload.\n */\nexport function ArtifactRefBlock({ block }: BlockComponentProps<ArtifactRefBlockRecord>): ReactNode {\n const { artifact, labels, callbacks } = block.payload;\n const entry = ArtifactServices[artifact.type];\n if (!entry) return null;\n const { Component } = entry;\n return <Component artifact={artifact} labels={labels} callbacks={callbacks} />;\n}\n","import { artifactToClipboardText } from \"@/components/artifacts/artifact-services\";\nimport { ArtifactRefBlock } from \"../artifact-ref-block/artifact-ref-block\";\nimport { blockTypes } from \"../types\";\nimport type { ArtifactRefBlockRecord, BlockService } from \"../types\";\n\nexport const ArtifactRefBlockService: BlockService<ArtifactRefBlockRecord> = {\n type: blockTypes.ARTIFACT_REF,\n Component: ArtifactRefBlock,\n /**\n * Delegates to the registered artifact component's `toClipboardText`. Falls back to\n * `[Artifact: <title>]` via `artifactToClipboardText`'s own fallback when the artifact type\n * has no registered component, so copy never silently produces an empty string.\n */\n toClipboardText: (block) => artifactToClipboardText(block.payload.artifact),\n};\n","import type { ReactNode } from \"react\";\nimport ReactMarkdown from \"react-markdown\";\nimport remarkBreaks from \"remark-breaks\";\nimport remarkGfm from \"remark-gfm\";\n\nimport { ScrollableTable } from \"../scrollable-table/scrollable-table\";\nimport type { BlockComponentProps, TextBlockRecord } from \"../types\";\nimport { sanitize } from \"./sanitize\";\nimport { TextBlockWrapper } from \"./text-block-styles\";\n\nconst markdownComponents = {\n table: ((tableProps: { node?: unknown; children?: ReactNode }) => (\n <ScrollableTable {...tableProps} />\n )) as React.ComponentType<unknown>,\n};\n\n/** Renders a TEXT block as Markdown with GFM (tables, strikethrough) and line breaks. */\nexport function TextBlock({ block }: BlockComponentProps<TextBlockRecord>): ReactNode {\n return (\n <TextBlockWrapper>\n <ReactMarkdown remarkPlugins={[remarkGfm, remarkBreaks]} components={markdownComponents}>\n {sanitize(block.payload.text)}\n </ReactMarkdown>\n </TextBlockWrapper>\n );\n}\n","import styled from \"styled-components\";\n\nexport const TableContainer = styled.div`\n position: relative;\n margin-block: 8px 16px;\n`;\n\nexport const TableScroll = styled.div`\n width: 100%;\n overflow-x: auto;\n overflow-y: hidden;\n`;\n","import { type ReactNode } from \"react\";\n\nimport { TableContainer, TableScroll } from \"./scrollable-table-styles\";\n\n/** Props for the ScrollableTable component. */\ninterface ScrollableTableProps {\n /** Unused node prop from react-markdown. */\n node?: unknown;\n /** Table children elements. */\n children?: ReactNode;\n}\n\n/** Renders a markdown table inside a horizontally scrollable wrapper. Read-only — actions live on artifact-tables. */\nexport function ScrollableTable({ node: _node, ...props }: ScrollableTableProps): ReactNode {\n return (\n <TableContainer>\n <TableScroll>\n <table {...props} />\n </TableScroll>\n </TableContainer>\n );\n}\n","// Strips io-server's `<!-- table-title: ... -->` HTML-comment metadata before rendering.\n// The marker is emitted by the server's CSV-export pipeline so the export button can label\n// the file; it has no place in the visual output. If the server-side format changes\n// (prefix, spacing, closing-tag style), this filter silently stops matching and the\n// raw HTML comment leaks into rendered Markdown — keep this contract aligned with io-server.\nexport function sanitize(text: string): string {\n return text\n .split(\"\\n\")\n .filter((line) => {\n const t = line.trim();\n return !(t.startsWith(\"<!-- table-title:\") && t.endsWith(\"-->\"));\n })\n .join(\"\\n\");\n}\n","import styled from \"styled-components\";\n\nimport { colors } from \"@/tokens/colors\";\nimport { typographyMixin, typographyTypes } from \"@/tokens/typography\";\n\nexport const TextBlockWrapper = styled.div`\n ${typographyMixin(typographyTypes.GEIST_BODY_S_REGULAR)};\n color: ${colors[\"brown-100\"]};\n word-break: break-word;\n\n & h1 {\n ${typographyMixin(typographyTypes.GEIST_HEADING_S_BOLD)};\n margin-block: 20px;\n }\n\n & h2 {\n ${typographyMixin(typographyTypes.GEIST_BODY_L_SEMI_BOLD)};\n margin-block: 12px;\n }\n\n & h3,\n & h4,\n & h5,\n & h6 {\n ${typographyMixin(typographyTypes.GEIST_BODY_M_SEMI_BOLD)};\n margin-block: 8px;\n }\n\n & strong {\n ${typographyMixin(typographyTypes.GEIST_BODY_S_SEMI_BOLD)};\n }\n\n & p {\n margin-block: 0px;\n }\n\n & p + p {\n margin-block: 8px 0px;\n }\n\n & ul,\n & ol {\n margin-block: 16px;\n padding-left: 20px;\n }\n\n & li + li {\n margin-block: 4px;\n }\n\n & ol {\n list-style-type: decimal;\n }\n\n & ol ol {\n list-style-type: lower-alpha;\n }\n\n & ol ol ol {\n list-style-type: lower-roman;\n }\n\n & a {\n color: inherit;\n text-decoration-line: underline;\n text-decoration-style: dotted;\n text-decoration-thickness: auto;\n text-underline-offset: auto;\n text-underline-position: from-font;\n transition: color 75ms ease-in-out;\n\n &:hover {\n color: ${colors[\"blue-600\"]};\n }\n }\n\n & hr {\n border: none;\n border-top: 1px solid ${colors[\"brown-40\"]};\n margin-block: 20px;\n }\n\n & table {\n margin: 0;\n width: 100%;\n border-collapse: collapse;\n }\n\n & th,\n & td {\n border: none;\n border-bottom: 1px solid ${colors[\"brown-40\"]};\n text-align: left;\n }\n\n & th {\n ${typographyMixin(typographyTypes.GEIST_LABEL_CAPTION_MEDIUM)};\n padding: 8px;\n }\n\n & td {\n ${typographyMixin(typographyTypes.GEIST_BODY_XS_MEDIUM)};\n padding: 16px 8px;\n min-width: 150px;\n width: 1%;\n }\n\n & td strong {\n font-weight: inherit;\n font-size: inherit;\n line-height: inherit;\n }\n\n & blockquote {\n margin-block: 4px;\n margin-inline: 0px;\n padding-left: 16px;\n border-left: 4px solid ${colors[\"brown-40\"]};\n color: ${colors[\"brown-80\"]};\n }\n`;\n","import { markdownToPlainText } from \"@/utils/markdown-to-plain-text\";\nimport { TextBlock } from \"../text-block/text-block\";\nimport { blockTypes } from \"../types\";\nimport type { BlockService, TextBlockRecord } from \"../types\";\n\nexport const TextBlockService: BlockService<TextBlockRecord> = {\n type: blockTypes.TEXT,\n Component: TextBlock,\n /**\n * Converts the block's markdown source to plain text so the final clipboard value is clean\n * when pasted into tools that don't render markdown. Each block type owns its own clipboard\n * conversion so `useCopyToClipboard` can write text verbatim without a second pass.\n */\n toClipboardText: (block) => markdownToPlainText(block.payload.text),\n};\n","import { blockTypes, type BlockService, type BlockType } from \"../types\";\nimport { ArtifactRefBlockService } from \"./artifact-ref-block-service\";\nimport { TextBlockService } from \"./text-block-service\";\n\n// `BlockService<TBlock>` is invariant on `TBlock` via React's `ComponentType` (props are\n// contravariant). The concrete services overlap structurally with the base `BlockService` type\n// enough for a direct `as BlockService` cast. The registry dispatches by runtime discriminator —\n// `BlockServices[block.type]` always resolves to the matching concrete service — so the cast is sound.\nexport const BlockServices: Record<BlockType, BlockService> = {\n [blockTypes.TEXT]: TextBlockService as BlockService,\n [blockTypes.ARTIFACT_REF]: ArtifactRefBlockService as BlockService,\n};\n","import type { ReactNode } from \"react\";\n\nimport { BlockServices } from \"../block-services\";\nimport type { BlockRecord } from \"../types\";\n\n/** Props for the Block dispatcher. */\ninterface BlockProps {\n /** The block to render. Dispatched to the registered concrete component for its `type`. */\n block: BlockRecord;\n}\n\n/**\n * Dispatches a single block to its registered concrete component. Unknown types render as a no-op.\n *\n * Generic by design: per-block-type extras (e.g. localized artifact labels for `ARTIFACT_REF`)\n * live on the block's `payload`, not as sibling props here. That keeps the dispatcher's contract\n * shallow — third-party `BlockService` implementors only need to handle `{ block }` — and lets\n * the consumer materialise a fully-decorated block once (from the server payload + their i18n\n * layer) instead of threading sibling props through every dispatch site.\n */\nexport function Block({ block }: BlockProps): ReactNode {\n const service = BlockServices[block.type];\n if (!service) return null;\n const { Component } = service;\n return <Component block={block} />;\n}\n"],"mappings":"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","names":["jsx","styled","styled","jsx","jsx"]}
|
package/dist/chunk-AQEJRMRN.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=chunk-AQEJRMRN.js.map
|