@heroui/agent 0.2.0-beta.8 → 0.2.0-beta.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/dist/chart-content-BBHQVMP4.js +1 -0
- package/dist/chunk-2XBFFSW2.js +1 -0
- package/dist/chunk-64RI74L5.js +1 -0
- package/dist/chunk-6ZJJN322.js +1 -0
- package/dist/chunk-7KCGPNEN.js +1 -0
- package/dist/chunk-BBB5EHDN.js +5 -0
- package/dist/chunk-CR3H7AVI.js +1 -0
- package/dist/chunk-HCLXS4HQ.js +1 -0
- package/dist/chunk-MXLGM4WV.js +1 -0
- package/dist/chunk-OA3TG5CS.js +1 -0
- package/dist/chunk-PZJ4NC3J.js +1 -0
- package/dist/chunk-RNNGE7KM.js +1 -0
- package/dist/chunk-S6OIAJSC.js +1 -0
- package/dist/chunk-SUDHJNTJ.js +2 -0
- package/dist/chunk-WUAFMD7Z.js +2 -0
- package/dist/component-renderer-GG6JVRUG.js +1 -0
- package/dist/composer-draft-NSKK65F3.js +1 -0
- package/dist/composer-image-draft-KAGTNQR7.js +1 -0
- package/dist/contracts.d.ts +1 -1
- package/dist/contracts.js +2 -2445
- package/dist/embed-runtime-GYXK7V6N.js +5 -0
- package/dist/index.js +1 -31
- package/dist/interactive-map-surface-WC2LPCR7.js +1 -0
- package/dist/internal/client-tools.js +1 -0
- package/dist/internal/models.js +1 -0
- package/dist/internal/runtime.js +1 -0
- package/dist/internal/theme.js +1 -0
- package/dist/next.js +1 -25
- package/dist/server.js +1 -136
- package/package.json +4 -4
- package/dist/chart-content-E4NPTUPR.js +0 -2696
- package/dist/chunk-3FG5NRTX.js +0 -9
- package/dist/chunk-CMZDZGUZ.js +0 -1132
- package/dist/chunk-DS4X5K2R.js +0 -56
- package/dist/chunk-FNGGMHVR.js +0 -625
- package/dist/chunk-G6GFNSG4.js +0 -284
- package/dist/chunk-Q7LGTVBL.js +0 -43
- package/dist/chunk-TOOT6SZ2.js +0 -74
- package/dist/chunk-UUPU3MYB.js +0 -42
- package/dist/chunk-VJA52U5P.js +0 -137
- package/dist/chunk-W7SCMB3O.js +0 -1285
- package/dist/component-renderer-MDDQMQTU.js +0 -10629
- package/dist/composer-draft-DTQAEO5K.js +0 -20
- package/dist/composer-image-draft-IVJ352E6.js +0 -174
- package/dist/embed-runtime-VVAGDPYY.js +0 -9422
- package/dist/interactive-map-surface-67KHT3VB.js +0 -362
package/dist/chunk-DS4X5K2R.js
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
// src/embed/composer-draft.ts
|
|
2
|
-
var AGENT_COMPOSER_DRAFT_MARKER = ":composer-draft:";
|
|
3
|
-
function agentComposerDraftStorageKey(conversationStorageKey, conversationId) {
|
|
4
|
-
return `${conversationStorageKey}${AGENT_COMPOSER_DRAFT_MARKER}${conversationId}:v1`;
|
|
5
|
-
}
|
|
6
|
-
async function readAgentComposerImageDraft(key, now = Date.now()) {
|
|
7
|
-
try {
|
|
8
|
-
const drafts = await import("./composer-image-draft-IVJ352E6.js");
|
|
9
|
-
return await drafts.readAgentComposerImageDraft(key, now);
|
|
10
|
-
} catch {
|
|
11
|
-
return [];
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
async function saveAgentComposerImageDraft(key, files, now = Date.now()) {
|
|
15
|
-
try {
|
|
16
|
-
const drafts = await import("./composer-image-draft-IVJ352E6.js");
|
|
17
|
-
await drafts.saveAgentComposerImageDraft(key, files, now);
|
|
18
|
-
} catch {
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
async function clearAgentComposerDraft(key) {
|
|
22
|
-
try {
|
|
23
|
-
localStorage.removeItem(key);
|
|
24
|
-
} catch {
|
|
25
|
-
}
|
|
26
|
-
try {
|
|
27
|
-
const drafts = await import("./composer-image-draft-IVJ352E6.js");
|
|
28
|
-
await drafts.clearAgentComposerImageDraft(key);
|
|
29
|
-
} catch {
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
async function clearAgentComposerDraftsForProject(agentId) {
|
|
33
|
-
const prefix = `heroui-agent:conversation:${agentId}:`;
|
|
34
|
-
try {
|
|
35
|
-
for (let index = localStorage.length - 1; index >= 0; index -= 1) {
|
|
36
|
-
const key = localStorage.key(index);
|
|
37
|
-
if (key?.startsWith(prefix) && key.includes(AGENT_COMPOSER_DRAFT_MARKER)) {
|
|
38
|
-
localStorage.removeItem(key);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
} catch {
|
|
42
|
-
}
|
|
43
|
-
try {
|
|
44
|
-
const drafts = await import("./composer-image-draft-IVJ352E6.js");
|
|
45
|
-
await drafts.clearAgentComposerImageDraftsForProject(prefix);
|
|
46
|
-
} catch {
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export {
|
|
51
|
-
agentComposerDraftStorageKey,
|
|
52
|
-
readAgentComposerImageDraft,
|
|
53
|
-
saveAgentComposerImageDraft,
|
|
54
|
-
clearAgentComposerDraft,
|
|
55
|
-
clearAgentComposerDraftsForProject
|
|
56
|
-
};
|
package/dist/chunk-FNGGMHVR.js
DELETED
|
@@ -1,625 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
resolveOverlayPortalContainer
|
|
3
|
-
} from "./chunk-TOOT6SZ2.js";
|
|
4
|
-
|
|
5
|
-
// ../agent-ui/src/utils/chart-values.ts
|
|
6
|
-
function resolveGaugeBounds(component) {
|
|
7
|
-
return {
|
|
8
|
-
maximum: component.max ?? (component.format?.style === "percent" ? 1 : 100),
|
|
9
|
-
minimum: component.min ?? 0
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// ../agent-ui/src/types.ts
|
|
14
|
-
function componentActionFromSpec(componentId, action) {
|
|
15
|
-
if (action.toolCall) {
|
|
16
|
-
return {
|
|
17
|
-
actionId: action.id,
|
|
18
|
-
args: action.toolCall.arguments,
|
|
19
|
-
componentId,
|
|
20
|
-
label: action.label,
|
|
21
|
-
prompt: action.prompt,
|
|
22
|
-
toolName: action.toolCall.name,
|
|
23
|
-
type: "tool"
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
if (action.prompt) {
|
|
27
|
-
return { componentId, label: action.label, prompt: action.prompt, type: "followup" };
|
|
28
|
-
}
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
function createComponentSelection(component, datum) {
|
|
32
|
-
return { componentId: component.id, componentTitle: component.title, datum };
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// ../agent-ui/src/utils/formatters.ts
|
|
36
|
-
var numberFormatters = /* @__PURE__ */ new Map();
|
|
37
|
-
function supportedLocale(locale) {
|
|
38
|
-
try {
|
|
39
|
-
return Intl.NumberFormat.supportedLocalesOf([locale])[0] ?? "en";
|
|
40
|
-
} catch {
|
|
41
|
-
return "en";
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
function formatNumber(value, format, locale = "en") {
|
|
45
|
-
const resolvedLocale = supportedLocale(locale);
|
|
46
|
-
if (!format) return value.toLocaleString(resolvedLocale);
|
|
47
|
-
const options = {
|
|
48
|
-
...format.style === "currency" ? { currency: format.currency, style: "currency" } : {},
|
|
49
|
-
...format.style === "percent" ? { style: "percent" } : {},
|
|
50
|
-
...format.style === "percent" && format.maximumFractionDigits !== void 0 ? { maximumFractionDigits: format.maximumFractionDigits } : {},
|
|
51
|
-
...format.style !== "percent" && format.compact ? { notation: "compact" } : {}
|
|
52
|
-
};
|
|
53
|
-
const cacheKey = `${resolvedLocale}:${JSON.stringify(options)}`;
|
|
54
|
-
let formatter = numberFormatters.get(cacheKey);
|
|
55
|
-
if (!formatter) {
|
|
56
|
-
formatter = new Intl.NumberFormat(resolvedLocale, options);
|
|
57
|
-
numberFormatters.set(cacheKey, formatter);
|
|
58
|
-
}
|
|
59
|
-
return formatter.format(value);
|
|
60
|
-
}
|
|
61
|
-
function formatAxisValue(value, locale = "en") {
|
|
62
|
-
const resolvedLocale = supportedLocale(locale);
|
|
63
|
-
const absolute = Math.abs(value);
|
|
64
|
-
if (absolute >= 1e6)
|
|
65
|
-
return `${(value / 1e6).toLocaleString(resolvedLocale, { maximumFractionDigits: 1 })}M`;
|
|
66
|
-
if (absolute >= 1e3)
|
|
67
|
-
return `${(value / 1e3).toLocaleString(resolvedLocale, { maximumFractionDigits: 1 })}K`;
|
|
68
|
-
return value.toLocaleString(resolvedLocale, { maximumFractionDigits: 1 });
|
|
69
|
-
}
|
|
70
|
-
function formatDelta(value, options = {}, locale = "en") {
|
|
71
|
-
const formatter = new Intl.NumberFormat(supportedLocale(locale), {
|
|
72
|
-
maximumFractionDigits: options.maximumFractionDigits ?? 2,
|
|
73
|
-
signDisplay: "always",
|
|
74
|
-
style: options.style === "percent" ? "percent" : "decimal"
|
|
75
|
-
});
|
|
76
|
-
return formatter.format(value);
|
|
77
|
-
}
|
|
78
|
-
function formatCell(value, format, locale = "en") {
|
|
79
|
-
return typeof value === "number" ? formatNumber(value, format, locale) : String(value ?? "");
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// ../agent-ui/src/components/component-actions/export-actions.tsx
|
|
83
|
-
import {
|
|
84
|
-
ChartColumn,
|
|
85
|
-
Copy,
|
|
86
|
-
Ellipsis,
|
|
87
|
-
FileCode,
|
|
88
|
-
FileText,
|
|
89
|
-
LayoutCells,
|
|
90
|
-
Picture
|
|
91
|
-
} from "@gravity-ui/icons";
|
|
92
|
-
import { Button, Dropdown, Label } from "@heroui/react";
|
|
93
|
-
import { useCallback, useRef, useState } from "react";
|
|
94
|
-
|
|
95
|
-
// ../agent-ui/src/components/data-visualization/charts/chart-table.ts
|
|
96
|
-
function humanizeKey(key) {
|
|
97
|
-
const label = key.replace(/([a-z\d])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").trim();
|
|
98
|
-
return label ? `${label[0]?.toUpperCase()}${label.slice(1)}` : key;
|
|
99
|
-
}
|
|
100
|
-
function flattenSunburstRows(root) {
|
|
101
|
-
const rows = [];
|
|
102
|
-
const visit = (node, ancestors, depth) => {
|
|
103
|
-
const path = [...ancestors, node.label];
|
|
104
|
-
const childrenValue = node.children?.reduce(
|
|
105
|
-
(total, child) => total + visit(child, path, depth + 1),
|
|
106
|
-
0
|
|
107
|
-
);
|
|
108
|
-
const value = node.children?.length ? childrenValue ?? 0 : node.value ?? 0;
|
|
109
|
-
if (depth > 0) {
|
|
110
|
-
rows.push({ depth, id: node.id, label: node.label, path: path.join(" / "), value });
|
|
111
|
-
}
|
|
112
|
-
return value;
|
|
113
|
-
};
|
|
114
|
-
visit(root, [], 0);
|
|
115
|
-
return rows;
|
|
116
|
-
}
|
|
117
|
-
function chartToDataTable(component) {
|
|
118
|
-
const columns = [];
|
|
119
|
-
const seen = /* @__PURE__ */ new Set();
|
|
120
|
-
const addColumn = (column) => {
|
|
121
|
-
if (seen.has(column.key)) return;
|
|
122
|
-
seen.add(column.key);
|
|
123
|
-
columns.push(column);
|
|
124
|
-
};
|
|
125
|
-
const addKey = (key, format) => addColumn({ format, key, label: humanizeKey(key) });
|
|
126
|
-
switch (component.kind) {
|
|
127
|
-
case "line-chart":
|
|
128
|
-
case "area-chart":
|
|
129
|
-
case "bar-chart":
|
|
130
|
-
case "composed-chart":
|
|
131
|
-
addKey(component.xKey);
|
|
132
|
-
component.series.forEach(
|
|
133
|
-
(series) => addColumn({ format: series.format, key: series.dataKey, label: series.label })
|
|
134
|
-
);
|
|
135
|
-
break;
|
|
136
|
-
case "candlestick-chart":
|
|
137
|
-
addKey(component.xKey);
|
|
138
|
-
addKey(component.openKey, component.format);
|
|
139
|
-
addKey(component.highKey, component.format);
|
|
140
|
-
addKey(component.lowKey, component.format);
|
|
141
|
-
addKey(component.closeKey, component.format);
|
|
142
|
-
break;
|
|
143
|
-
case "funnel-chart":
|
|
144
|
-
addKey(component.labelKey);
|
|
145
|
-
addKey(component.valueKey, component.format);
|
|
146
|
-
break;
|
|
147
|
-
case "gauge-chart":
|
|
148
|
-
addKey("label");
|
|
149
|
-
addKey("value", component.format);
|
|
150
|
-
addKey("min", component.format);
|
|
151
|
-
addKey("max", component.format);
|
|
152
|
-
break;
|
|
153
|
-
case "pie-chart":
|
|
154
|
-
case "donut-chart":
|
|
155
|
-
case "radial-chart":
|
|
156
|
-
addKey(component.labelKey);
|
|
157
|
-
addKey(component.valueKey, component.format);
|
|
158
|
-
break;
|
|
159
|
-
case "radar-chart":
|
|
160
|
-
addKey(component.angleKey);
|
|
161
|
-
component.series.forEach(
|
|
162
|
-
(series) => addColumn({ format: series.format, key: series.dataKey, label: series.label })
|
|
163
|
-
);
|
|
164
|
-
break;
|
|
165
|
-
case "scatter-chart":
|
|
166
|
-
if (component.labelKey) addKey(component.labelKey);
|
|
167
|
-
if (component.groupKey) addKey(component.groupKey);
|
|
168
|
-
addKey(component.xKey, component.format);
|
|
169
|
-
addKey(component.yKey, component.format);
|
|
170
|
-
if (component.sizeKey) addKey(component.sizeKey, component.format);
|
|
171
|
-
break;
|
|
172
|
-
case "heatmap":
|
|
173
|
-
addKey(component.xKey);
|
|
174
|
-
addKey(component.yKey);
|
|
175
|
-
addKey(component.valueKey, component.format);
|
|
176
|
-
break;
|
|
177
|
-
case "sankey-chart":
|
|
178
|
-
addKey("source");
|
|
179
|
-
addKey("target");
|
|
180
|
-
addKey("value", component.format);
|
|
181
|
-
break;
|
|
182
|
-
case "sunburst-chart":
|
|
183
|
-
addKey("id");
|
|
184
|
-
addKey("label");
|
|
185
|
-
addKey("path");
|
|
186
|
-
addKey("depth");
|
|
187
|
-
addKey("value", component.format);
|
|
188
|
-
break;
|
|
189
|
-
}
|
|
190
|
-
let rows;
|
|
191
|
-
if (component.kind === "sankey-chart") {
|
|
192
|
-
const labels = new Map(component.nodes.map((node) => [node.id, node.label]));
|
|
193
|
-
rows = component.links.map((link) => ({
|
|
194
|
-
source: labels.get(link.source) ?? link.source,
|
|
195
|
-
target: labels.get(link.target) ?? link.target,
|
|
196
|
-
value: link.value
|
|
197
|
-
}));
|
|
198
|
-
} else if (component.kind === "gauge-chart") {
|
|
199
|
-
const { maximum, minimum } = resolveGaugeBounds(component);
|
|
200
|
-
rows = [
|
|
201
|
-
{
|
|
202
|
-
label: component.label,
|
|
203
|
-
max: maximum,
|
|
204
|
-
min: minimum,
|
|
205
|
-
value: component.value
|
|
206
|
-
}
|
|
207
|
-
];
|
|
208
|
-
} else if (component.kind === "sunburst-chart") {
|
|
209
|
-
rows = flattenSunburstRows(component.data);
|
|
210
|
-
} else {
|
|
211
|
-
rows = component.data;
|
|
212
|
-
}
|
|
213
|
-
return {
|
|
214
|
-
columns,
|
|
215
|
-
description: component.description,
|
|
216
|
-
id: component.id,
|
|
217
|
-
kind: "data-table",
|
|
218
|
-
rows,
|
|
219
|
-
title: component.title,
|
|
220
|
-
variant: "secondary"
|
|
221
|
-
};
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// ../agent-ui/src/components/component-actions/export-utils.ts
|
|
225
|
-
var TABULAR_CHART_KINDS = /* @__PURE__ */ new Set([
|
|
226
|
-
"area-chart",
|
|
227
|
-
"bar-chart",
|
|
228
|
-
"candlestick-chart",
|
|
229
|
-
"composed-chart",
|
|
230
|
-
"donut-chart",
|
|
231
|
-
"funnel-chart",
|
|
232
|
-
"gauge-chart",
|
|
233
|
-
"heatmap",
|
|
234
|
-
"line-chart",
|
|
235
|
-
"pie-chart",
|
|
236
|
-
"radar-chart",
|
|
237
|
-
"radial-chart",
|
|
238
|
-
"sankey-chart",
|
|
239
|
-
"scatter-chart",
|
|
240
|
-
"sunburst-chart"
|
|
241
|
-
]);
|
|
242
|
-
function isTabularChart(component) {
|
|
243
|
-
return TABULAR_CHART_KINDS.has(component.kind);
|
|
244
|
-
}
|
|
245
|
-
function filename(title, extension) {
|
|
246
|
-
const stem = title.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 80);
|
|
247
|
-
return `${stem || "agent-ui"}.${extension}`;
|
|
248
|
-
}
|
|
249
|
-
function download(data, type, name) {
|
|
250
|
-
if (typeof document === "undefined" || typeof URL.createObjectURL !== "function") return;
|
|
251
|
-
const url = URL.createObjectURL(new Blob([data], { type }));
|
|
252
|
-
const anchor = document.createElement("a");
|
|
253
|
-
anchor.download = name;
|
|
254
|
-
anchor.href = url;
|
|
255
|
-
anchor.click();
|
|
256
|
-
URL.revokeObjectURL(url);
|
|
257
|
-
}
|
|
258
|
-
function csvCell(value) {
|
|
259
|
-
const text = String(value ?? "");
|
|
260
|
-
return /[",\r\n]/.test(text) ? `"${text.replaceAll('"', '""')}"` : text;
|
|
261
|
-
}
|
|
262
|
-
function componentToCsv(component) {
|
|
263
|
-
let rows;
|
|
264
|
-
let keys;
|
|
265
|
-
if (component.kind === "data-table") {
|
|
266
|
-
rows = component.rows;
|
|
267
|
-
keys = component.columns.map((column) => column.key);
|
|
268
|
-
} else if (isTabularChart(component)) {
|
|
269
|
-
const table = chartToDataTable(component);
|
|
270
|
-
rows = table.rows;
|
|
271
|
-
keys = table.columns.map((column) => column.key);
|
|
272
|
-
}
|
|
273
|
-
if (!rows || !keys?.length) return null;
|
|
274
|
-
return [
|
|
275
|
-
keys.map(csvCell).join(","),
|
|
276
|
-
...rows.map((row) => keys.map((key) => csvCell(row[key])).join(","))
|
|
277
|
-
].join("\n");
|
|
278
|
-
}
|
|
279
|
-
function tableTextCell(value) {
|
|
280
|
-
return value.replace(/[\t\r\n]+/g, " ");
|
|
281
|
-
}
|
|
282
|
-
function componentToTableText(component) {
|
|
283
|
-
return [
|
|
284
|
-
component.columns.map((column) => tableTextCell(column.label)).join(" "),
|
|
285
|
-
...component.rows.map(
|
|
286
|
-
(row) => component.columns.map((column) => tableTextCell(formatCell(row[column.key], column.format))).join(" ")
|
|
287
|
-
)
|
|
288
|
-
].join("\n");
|
|
289
|
-
}
|
|
290
|
-
var SVG_STYLE_TOKENS = [
|
|
291
|
-
"--accent",
|
|
292
|
-
"--border",
|
|
293
|
-
"--chart-1",
|
|
294
|
-
"--chart-2",
|
|
295
|
-
"--chart-3",
|
|
296
|
-
"--chart-4",
|
|
297
|
-
"--chart-5",
|
|
298
|
-
"--danger",
|
|
299
|
-
"--default-foreground",
|
|
300
|
-
"--focus",
|
|
301
|
-
"--foreground",
|
|
302
|
-
"--muted",
|
|
303
|
-
"--success",
|
|
304
|
-
"--surface",
|
|
305
|
-
"--surface-secondary",
|
|
306
|
-
"--warning"
|
|
307
|
-
];
|
|
308
|
-
var SVG_PRESENTATION_PROPERTIES = [
|
|
309
|
-
"color",
|
|
310
|
-
"display",
|
|
311
|
-
"dominant-baseline",
|
|
312
|
-
"fill",
|
|
313
|
-
"fill-opacity",
|
|
314
|
-
"font-family",
|
|
315
|
-
"font-size",
|
|
316
|
-
"font-style",
|
|
317
|
-
"font-weight",
|
|
318
|
-
"letter-spacing",
|
|
319
|
-
"opacity",
|
|
320
|
-
"paint-order",
|
|
321
|
-
"shape-rendering",
|
|
322
|
-
"stroke",
|
|
323
|
-
"stroke-dasharray",
|
|
324
|
-
"stroke-dashoffset",
|
|
325
|
-
"stroke-linecap",
|
|
326
|
-
"stroke-linejoin",
|
|
327
|
-
"stroke-miterlimit",
|
|
328
|
-
"stroke-opacity",
|
|
329
|
-
"stroke-width",
|
|
330
|
-
"text-anchor",
|
|
331
|
-
"vector-effect",
|
|
332
|
-
"visibility"
|
|
333
|
-
];
|
|
334
|
-
function absoluteSvgLength(value) {
|
|
335
|
-
if (!value || value.trim().endsWith("%")) return 0;
|
|
336
|
-
const parsed = Number.parseFloat(value);
|
|
337
|
-
return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
|
|
338
|
-
}
|
|
339
|
-
function viewBoxDimensions(svg) {
|
|
340
|
-
const values = svg.getAttribute("viewBox")?.trim().split(/[ ,]+/).map(Number);
|
|
341
|
-
return {
|
|
342
|
-
height: values?.length === 4 && Number.isFinite(values[3]) ? Math.max(0, values[3]) : 0,
|
|
343
|
-
width: values?.length === 4 && Number.isFinite(values[2]) ? Math.max(0, values[2]) : 0
|
|
344
|
-
};
|
|
345
|
-
}
|
|
346
|
-
function inlineSvgPresentationStyles(source, clone) {
|
|
347
|
-
const sourceElements = [source, ...Array.from(source.querySelectorAll("*"))];
|
|
348
|
-
const cloneElements = [clone, ...Array.from(clone.querySelectorAll("*"))];
|
|
349
|
-
sourceElements.forEach((element, index) => {
|
|
350
|
-
const target = cloneElements[index];
|
|
351
|
-
if (!target) return;
|
|
352
|
-
const computed = getComputedStyle(element);
|
|
353
|
-
const declarations = SVG_PRESENTATION_PROPERTIES.flatMap((property) => {
|
|
354
|
-
const value = computed.getPropertyValue(property).trim();
|
|
355
|
-
return value ? [`${property}:${value}`] : [];
|
|
356
|
-
});
|
|
357
|
-
if (declarations.length === 0) return;
|
|
358
|
-
target.setAttribute(
|
|
359
|
-
"style",
|
|
360
|
-
[target.getAttribute("style"), ...declarations].filter(Boolean).join(";")
|
|
361
|
-
);
|
|
362
|
-
});
|
|
363
|
-
}
|
|
364
|
-
function serializeChartSvg(button) {
|
|
365
|
-
const card = button.closest('[data-slot="agent-ui-card"]');
|
|
366
|
-
const svg = card?.querySelector('[data-slot="agent-ui-chart"] svg');
|
|
367
|
-
if (!(card instanceof HTMLElement) || !(svg instanceof SVGElement)) return null;
|
|
368
|
-
const clone = svg.cloneNode(true);
|
|
369
|
-
const chartName = svg.closest('[data-slot="agent-ui-chart"]')?.getAttribute("aria-label")?.trim();
|
|
370
|
-
const bounds = svg.getBoundingClientRect();
|
|
371
|
-
const viewBox = viewBoxDimensions(svg);
|
|
372
|
-
const width = Math.max(
|
|
373
|
-
1,
|
|
374
|
-
Math.round(bounds.width || absoluteSvgLength(svg.getAttribute("width")) || viewBox.width)
|
|
375
|
-
);
|
|
376
|
-
const height = Math.max(
|
|
377
|
-
1,
|
|
378
|
-
Math.round(bounds.height || absoluteSvgLength(svg.getAttribute("height")) || viewBox.height)
|
|
379
|
-
);
|
|
380
|
-
const styles = getComputedStyle(card);
|
|
381
|
-
const variables = SVG_STYLE_TOKENS.flatMap((token) => {
|
|
382
|
-
const value = styles.getPropertyValue(token).trim();
|
|
383
|
-
return value ? [`${token}:${value}`] : [];
|
|
384
|
-
}).join(";");
|
|
385
|
-
inlineSvgPresentationStyles(svg, clone);
|
|
386
|
-
clone.removeAttribute("aria-hidden");
|
|
387
|
-
clone.setAttribute("role", "img");
|
|
388
|
-
if (chartName) {
|
|
389
|
-
const title = document.createElementNS("http://www.w3.org/2000/svg", "title");
|
|
390
|
-
title.textContent = chartName;
|
|
391
|
-
clone.prepend(title);
|
|
392
|
-
clone.setAttribute("aria-label", chartName);
|
|
393
|
-
}
|
|
394
|
-
clone.setAttribute("xmlns", "http://www.w3.org/2000/svg");
|
|
395
|
-
clone.setAttribute("height", String(height));
|
|
396
|
-
clone.setAttribute("width", String(width));
|
|
397
|
-
if (!clone.hasAttribute("viewBox")) clone.setAttribute("viewBox", `0 0 ${width} ${height}`);
|
|
398
|
-
clone.setAttribute("style", [clone.getAttribute("style"), variables].filter(Boolean).join(";"));
|
|
399
|
-
return { height, markup: new XMLSerializer().serializeToString(clone), width };
|
|
400
|
-
}
|
|
401
|
-
async function exportPng(button, title) {
|
|
402
|
-
const serialized = serializeChartSvg(button);
|
|
403
|
-
if (!serialized || typeof Image === "undefined" || typeof URL.createObjectURL !== "function")
|
|
404
|
-
return;
|
|
405
|
-
const source = URL.createObjectURL(
|
|
406
|
-
new Blob([serialized.markup], { type: "image/svg+xml;charset=utf-8" })
|
|
407
|
-
);
|
|
408
|
-
const image = new Image();
|
|
409
|
-
await new Promise((resolve, reject) => {
|
|
410
|
-
image.onload = () => resolve();
|
|
411
|
-
image.onerror = () => {
|
|
412
|
-
URL.revokeObjectURL(source);
|
|
413
|
-
reject(new Error("Unable to render component image"));
|
|
414
|
-
};
|
|
415
|
-
image.src = source;
|
|
416
|
-
});
|
|
417
|
-
URL.revokeObjectURL(source);
|
|
418
|
-
const canvas = document.createElement("canvas");
|
|
419
|
-
const scale = Math.max(1, window.devicePixelRatio || 1);
|
|
420
|
-
canvas.width = serialized.width * scale;
|
|
421
|
-
canvas.height = serialized.height * scale;
|
|
422
|
-
const context = canvas.getContext("2d");
|
|
423
|
-
if (!context) return;
|
|
424
|
-
context.scale(scale, scale);
|
|
425
|
-
context.drawImage(image, 0, 0, serialized.width, serialized.height);
|
|
426
|
-
const blob = await new Promise((resolve) => canvas.toBlob(resolve, "image/png"));
|
|
427
|
-
if (blob) download(blob, "image/png", filename(title, "png"));
|
|
428
|
-
}
|
|
429
|
-
function exportComponent(button, component, format) {
|
|
430
|
-
if (format === "csv") {
|
|
431
|
-
const csv = componentToCsv(component);
|
|
432
|
-
if (csv) download(csv, "text/csv;charset=utf-8", filename(component.title, "csv"));
|
|
433
|
-
} else if (format === "svg") {
|
|
434
|
-
const serialized = serializeChartSvg(button);
|
|
435
|
-
if (serialized)
|
|
436
|
-
download(serialized.markup, "image/svg+xml;charset=utf-8", filename(component.title, "svg"));
|
|
437
|
-
} else {
|
|
438
|
-
void exportPng(button, component.title).catch(() => void 0);
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
async function copyComponent(component, format) {
|
|
442
|
-
const content = format === "json" ? JSON.stringify(component, null, 2) : component.kind === "data-table" ? componentToTableText(component) : component.kind === "record-card" ? [
|
|
443
|
-
component.title,
|
|
444
|
-
component.description,
|
|
445
|
-
component.status?.label,
|
|
446
|
-
...component.fields.map((field) => `${field.label}: ${field.value}`)
|
|
447
|
-
].filter(Boolean).join("\n") : component.kind === "product-card" ? [
|
|
448
|
-
component.title,
|
|
449
|
-
component.description,
|
|
450
|
-
...component.products.flatMap((product) => [
|
|
451
|
-
[product.name, product.meta].filter(Boolean).join(" \xB7 "),
|
|
452
|
-
`${product.price.currency ?? "USD"} ${product.price.amount}`,
|
|
453
|
-
product.rating ? `Rated ${product.rating.value}/5${product.rating.count === void 0 ? "" : ` (${product.rating.count})`}` : void 0
|
|
454
|
-
])
|
|
455
|
-
].filter(Boolean).join("\n") : JSON.stringify(component);
|
|
456
|
-
await navigator.clipboard?.writeText(content);
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
// ../agent-ui/src/components/component-actions/export-actions.tsx
|
|
460
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
461
|
-
var FORMAT_LABELS = {
|
|
462
|
-
csv: "Export as CSV",
|
|
463
|
-
png: "Export as PNG",
|
|
464
|
-
svg: "Export as SVG"
|
|
465
|
-
};
|
|
466
|
-
var FORMAT_ICONS = {
|
|
467
|
-
csv: FileText,
|
|
468
|
-
png: Picture,
|
|
469
|
-
svg: FileCode
|
|
470
|
-
};
|
|
471
|
-
function ComponentExportActions({
|
|
472
|
-
component,
|
|
473
|
-
copyAction,
|
|
474
|
-
formats = [],
|
|
475
|
-
onAction,
|
|
476
|
-
viewAction
|
|
477
|
-
}) {
|
|
478
|
-
const triggerRef = useRef(null);
|
|
479
|
-
const [portalContainer, setPortalContainer] = useState();
|
|
480
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
481
|
-
const pointerOpenAt = useRef(0);
|
|
482
|
-
const handleOpenChange = (nextOpen) => {
|
|
483
|
-
if (!nextOpen && Date.now() - pointerOpenAt.current < 350) return;
|
|
484
|
-
setIsOpen(nextOpen);
|
|
485
|
-
};
|
|
486
|
-
const captureTrigger = useCallback((node) => {
|
|
487
|
-
triggerRef.current = node;
|
|
488
|
-
setPortalContainer(resolveOverlayPortalContainer(node));
|
|
489
|
-
}, []);
|
|
490
|
-
const supported = formats.filter((format) => format !== "csv" || componentToCsv(component));
|
|
491
|
-
const triggerLabel = copyAction ? `Table options for ${component.title}` : viewAction ? `${supported.length > 0 ? "View and export" : "View"} options for ${component.title}` : `Export options for ${component.title}`;
|
|
492
|
-
if (supported.length === 0 && !viewAction && !copyAction) return null;
|
|
493
|
-
return /* @__PURE__ */ jsx("div", { className: "aui-export-actions", "data-slot": "agent-ui-export-actions", children: /* @__PURE__ */ jsxs(Dropdown, { isOpen, onOpenChange: handleOpenChange, children: [
|
|
494
|
-
/* @__PURE__ */ jsx(
|
|
495
|
-
Button,
|
|
496
|
-
{
|
|
497
|
-
ref: captureTrigger,
|
|
498
|
-
isIconOnly: true,
|
|
499
|
-
"aria-label": triggerLabel,
|
|
500
|
-
size: "sm",
|
|
501
|
-
variant: "ghost",
|
|
502
|
-
onPointerDown: () => {
|
|
503
|
-
pointerOpenAt.current = Date.now();
|
|
504
|
-
},
|
|
505
|
-
children: /* @__PURE__ */ jsx(Ellipsis, {})
|
|
506
|
-
}
|
|
507
|
-
),
|
|
508
|
-
/* @__PURE__ */ jsx(Dropdown.Popover, { placement: "bottom end", UNSTABLE_portalContainer: portalContainer, children: /* @__PURE__ */ jsxs(
|
|
509
|
-
Dropdown.Menu,
|
|
510
|
-
{
|
|
511
|
-
onAction: (key) => {
|
|
512
|
-
if (key === "view") {
|
|
513
|
-
viewAction?.onAction();
|
|
514
|
-
setIsOpen(false);
|
|
515
|
-
return;
|
|
516
|
-
}
|
|
517
|
-
if (key === "copy") {
|
|
518
|
-
copyAction?.();
|
|
519
|
-
onAction?.({ componentId: component.id, format: "text", type: "copy" });
|
|
520
|
-
setIsOpen(false);
|
|
521
|
-
return;
|
|
522
|
-
}
|
|
523
|
-
const format = key;
|
|
524
|
-
if (triggerRef.current) exportComponent(triggerRef.current, component, format);
|
|
525
|
-
onAction?.({ componentId: component.id, format, type: "export" });
|
|
526
|
-
setIsOpen(false);
|
|
527
|
-
},
|
|
528
|
-
children: [
|
|
529
|
-
viewAction ? /* @__PURE__ */ jsxs(Dropdown.Item, { id: "view", textValue: viewAction.label, children: [
|
|
530
|
-
viewAction.target === "table" ? /* @__PURE__ */ jsx(LayoutCells, { "aria-hidden": "true", className: "size-4 shrink-0" }) : /* @__PURE__ */ jsx(ChartColumn, { "aria-hidden": "true", className: "size-4 shrink-0" }),
|
|
531
|
-
/* @__PURE__ */ jsx(Label, { children: viewAction.label })
|
|
532
|
-
] }) : null,
|
|
533
|
-
copyAction ? /* @__PURE__ */ jsxs(Dropdown.Item, { id: "copy", textValue: "Copy table", children: [
|
|
534
|
-
/* @__PURE__ */ jsx(Copy, { "aria-hidden": "true", className: "size-4 shrink-0" }),
|
|
535
|
-
/* @__PURE__ */ jsx(Label, { children: "Copy table" })
|
|
536
|
-
] }) : null,
|
|
537
|
-
supported.map((format) => {
|
|
538
|
-
const FormatIcon = FORMAT_ICONS[format];
|
|
539
|
-
return /* @__PURE__ */ jsxs(Dropdown.Item, { id: format, textValue: FORMAT_LABELS[format], children: [
|
|
540
|
-
/* @__PURE__ */ jsx(FormatIcon, { "aria-hidden": "true", className: "size-4 shrink-0" }),
|
|
541
|
-
/* @__PURE__ */ jsx(Label, { children: FORMAT_LABELS[format] })
|
|
542
|
-
] }, format);
|
|
543
|
-
})
|
|
544
|
-
]
|
|
545
|
-
}
|
|
546
|
-
) })
|
|
547
|
-
] }) });
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
// ../agent-ui/src/components/data-visualization/trend-change/trend-change.tsx
|
|
551
|
-
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
552
|
-
function TrendArrow({ direction }) {
|
|
553
|
-
return /* @__PURE__ */ jsx2(
|
|
554
|
-
"svg",
|
|
555
|
-
{
|
|
556
|
-
"aria-hidden": "true",
|
|
557
|
-
className: "aui-change__indicator",
|
|
558
|
-
fill: "none",
|
|
559
|
-
stroke: "currentColor",
|
|
560
|
-
strokeLinecap: "round",
|
|
561
|
-
strokeLinejoin: "round",
|
|
562
|
-
strokeWidth: "2",
|
|
563
|
-
viewBox: "0 0 24 24",
|
|
564
|
-
children: direction === "up" ? /* @__PURE__ */ jsx2("path", { d: "M12 19V5m-5 5 5-5 5 5" }) : /* @__PURE__ */ jsx2("path", { d: "M12 5v14m5-5-5 5-5-5" })
|
|
565
|
-
}
|
|
566
|
-
);
|
|
567
|
-
}
|
|
568
|
-
function TrendChange({ slot, value }) {
|
|
569
|
-
return /* @__PURE__ */ jsxs2(
|
|
570
|
-
"span",
|
|
571
|
-
{
|
|
572
|
-
className: "aui-change",
|
|
573
|
-
"data-slot": slot,
|
|
574
|
-
"data-trend": value > 0 ? "up" : value < 0 ? "down" : "neutral",
|
|
575
|
-
children: [
|
|
576
|
-
value === 0 ? null : /* @__PURE__ */ jsx2(TrendArrow, { direction: value > 0 ? "up" : "down" }),
|
|
577
|
-
formatDelta(value),
|
|
578
|
-
"%"
|
|
579
|
-
]
|
|
580
|
-
}
|
|
581
|
-
);
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
// ../agent-ui/src/components/data-visualization/charts/chart-colors.ts
|
|
585
|
-
var COLORS = [
|
|
586
|
-
"var(--chart-3, var(--accent))",
|
|
587
|
-
"var(--chart-1, oklch(from var(--accent) calc(l - 0.24) c h))",
|
|
588
|
-
"var(--chart-4, oklch(from var(--accent) calc(l + 0.12) c h))",
|
|
589
|
-
"var(--chart-2, oklch(from var(--accent) calc(l - 0.12) c h))",
|
|
590
|
-
"var(--chart-5, oklch(from var(--accent) calc(l + 0.24) c h))"
|
|
591
|
-
];
|
|
592
|
-
var CHART_COLOR_TOKENS = {
|
|
593
|
-
accent: "var(--accent)",
|
|
594
|
-
"chart-1": "var(--chart-1, oklch(from var(--accent) calc(l - 0.24) c h))",
|
|
595
|
-
"chart-2": "var(--chart-2, oklch(from var(--accent) calc(l - 0.12) c h))",
|
|
596
|
-
"chart-3": "var(--chart-3, var(--accent))",
|
|
597
|
-
"chart-4": "var(--chart-4, oklch(from var(--accent) calc(l + 0.12) c h))",
|
|
598
|
-
"chart-5": "var(--chart-5, oklch(from var(--accent) calc(l + 0.24) c h))",
|
|
599
|
-
danger: "var(--danger)",
|
|
600
|
-
default: "var(--default-foreground, var(--foreground))",
|
|
601
|
-
success: "var(--success)",
|
|
602
|
-
warning: "var(--warning)"
|
|
603
|
-
};
|
|
604
|
-
function resolveChartColor(color, index) {
|
|
605
|
-
return color ? CHART_COLOR_TOKENS[color] : COLORS[index % COLORS.length];
|
|
606
|
-
}
|
|
607
|
-
function paletteChartColor(index) {
|
|
608
|
-
return COLORS[index % COLORS.length];
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
export {
|
|
612
|
-
resolveGaugeBounds,
|
|
613
|
-
componentActionFromSpec,
|
|
614
|
-
createComponentSelection,
|
|
615
|
-
formatNumber,
|
|
616
|
-
formatAxisValue,
|
|
617
|
-
formatCell,
|
|
618
|
-
chartToDataTable,
|
|
619
|
-
copyComponent,
|
|
620
|
-
ComponentExportActions,
|
|
621
|
-
TrendChange,
|
|
622
|
-
CHART_COLOR_TOKENS,
|
|
623
|
-
resolveChartColor,
|
|
624
|
-
paletteChartColor
|
|
625
|
-
};
|