@heroui/agent 0.2.0-beta.1

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.
@@ -0,0 +1,1391 @@
1
+ "use client";
2
+ import {
3
+ ComponentExportActions,
4
+ TrendChange,
5
+ createComponentSelection,
6
+ formatAxisValue,
7
+ formatNumber,
8
+ paletteChartColor,
9
+ resolveChartColor
10
+ } from "./chunk-DW4AQRM5.js";
11
+ import {
12
+ Card
13
+ } from "./chunk-TOOT6SZ2.js";
14
+ import {
15
+ mergeClassNames
16
+ } from "./chunk-3FG5NRTX.js";
17
+
18
+ // ../agent-ui/src/components/data-visualization/charts/chart-content.tsx
19
+ import { useId, useMemo as useMemo2, useState as useState2 } from "react";
20
+ import {
21
+ Area,
22
+ Bar,
23
+ CartesianGrid,
24
+ Cell,
25
+ Label,
26
+ Line,
27
+ Pie,
28
+ PolarAngleAxis,
29
+ PolarGrid,
30
+ PolarRadiusAxis,
31
+ Radar,
32
+ RadialBar,
33
+ AreaChart as RechartsAreaChart,
34
+ BarChart as RechartsBarChart,
35
+ ComposedChart as RechartsComposedChart,
36
+ LineChart as RechartsLineChart,
37
+ PieChart as RechartsPieChart,
38
+ RadarChart as RechartsRadarChart,
39
+ RadialBarChart as RechartsRadialBarChart,
40
+ ScatterChart as RechartsScatterChart,
41
+ ResponsiveContainer,
42
+ Sankey,
43
+ Scatter,
44
+ Tooltip,
45
+ XAxis,
46
+ YAxis,
47
+ ZAxis
48
+ } from "recharts";
49
+
50
+ // ../agent-ui/src/components/data-visualization/segment/segment.tsx
51
+ import { createContext, useCallback, useContext, useMemo, useState } from "react";
52
+ import { jsx, jsxs } from "react/jsx-runtime";
53
+ var SegmentContext = createContext(null);
54
+ function SegmentRoot({
55
+ children,
56
+ className,
57
+ defaultSelectedKey,
58
+ isDisabled = false,
59
+ onSelectionChange,
60
+ selectedKey,
61
+ size = "md",
62
+ variant = "default",
63
+ ...props
64
+ }) {
65
+ const [uncontrolledKey, setUncontrolledKey] = useState(defaultSelectedKey);
66
+ const activeKey = selectedKey ?? uncontrolledKey;
67
+ const select = useCallback(
68
+ (key) => {
69
+ if (isDisabled || key === activeKey) return;
70
+ if (selectedKey === void 0) setUncontrolledKey(key);
71
+ onSelectionChange?.(key);
72
+ },
73
+ [activeKey, isDisabled, onSelectionChange, selectedKey]
74
+ );
75
+ const context = useMemo(
76
+ () => ({ isDisabled, select, selectedKey: activeKey }),
77
+ [activeKey, isDisabled, select]
78
+ );
79
+ return /* @__PURE__ */ jsx(SegmentContext, { value: context, children: /* @__PURE__ */ jsx(
80
+ "div",
81
+ {
82
+ className: mergeClassNames("aui-segment", className),
83
+ "data-disabled": isDisabled || void 0,
84
+ "data-size": size,
85
+ "data-slot": "agent-ui-segment",
86
+ "data-variant": variant,
87
+ role: "group",
88
+ ...props,
89
+ children
90
+ }
91
+ ) });
92
+ }
93
+ function SegmentItem({
94
+ children,
95
+ className,
96
+ disabled,
97
+ id,
98
+ onClick,
99
+ ...props
100
+ }) {
101
+ const context = useContext(SegmentContext);
102
+ if (!context) throw new Error("Segment.Item must be rendered inside Segment.");
103
+ const isDisabled = context.isDisabled || disabled;
104
+ const isSelected = context.selectedKey === id;
105
+ return /* @__PURE__ */ jsxs(
106
+ "button",
107
+ {
108
+ "aria-pressed": isSelected,
109
+ className: mergeClassNames("aui-segment__item", className),
110
+ "data-selected": isSelected,
111
+ "data-slot": "agent-ui-segment-item",
112
+ disabled: isDisabled,
113
+ type: "button",
114
+ onClick: (event) => {
115
+ onClick?.(event);
116
+ if (!event.defaultPrevented) context.select(id);
117
+ },
118
+ ...props,
119
+ children: [
120
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "aui-segment__indicator" }),
121
+ /* @__PURE__ */ jsx("span", { className: "aui-segment__label", children })
122
+ ]
123
+ }
124
+ );
125
+ }
126
+ function SegmentSeparator({ className, ...props }) {
127
+ return /* @__PURE__ */ jsx(
128
+ "span",
129
+ {
130
+ "aria-hidden": "true",
131
+ className: mergeClassNames("aui-segment__separator", className),
132
+ "data-slot": "agent-ui-segment-separator",
133
+ ...props
134
+ }
135
+ );
136
+ }
137
+
138
+ // ../agent-ui/src/components/data-visualization/segment/index.ts
139
+ var Segment = Object.assign(SegmentRoot, {
140
+ Item: SegmentItem,
141
+ Root: SegmentRoot,
142
+ Separator: SegmentSeparator
143
+ });
144
+
145
+ // ../agent-ui/src/components/data-visualization/charts/bar-radius.ts
146
+ var FULL_RADIUS = [4, 4, 4, 4];
147
+ var LEFT_RADIUS = [4, 0, 0, 4];
148
+ var NO_RADIUS = [0, 0, 0, 0];
149
+ var RIGHT_RADIUS = [0, 4, 4, 0];
150
+ var TOP_RADIUS = [4, 4, 0, 0];
151
+ function getBarRadius({
152
+ dataKey,
153
+ horizontal,
154
+ stacked,
155
+ visibleStackKeys
156
+ }) {
157
+ if (!stacked) return horizontal ? RIGHT_RADIUS : TOP_RADIUS;
158
+ const index = visibleStackKeys.indexOf(dataKey);
159
+ if (index < 0) return NO_RADIUS;
160
+ if (horizontal && visibleStackKeys.length === 1) return FULL_RADIUS;
161
+ if (horizontal && index === 0) return LEFT_RADIUS;
162
+ if (horizontal && index === visibleStackKeys.length - 1) return RIGHT_RADIUS;
163
+ if (!horizontal && index === visibleStackKeys.length - 1) return TOP_RADIUS;
164
+ return NO_RADIUS;
165
+ }
166
+
167
+ // ../agent-ui/src/components/data-visualization/charts/chart-content.tsx
168
+ import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
169
+ function ChartLegend({
170
+ activeKeys,
171
+ ariaLabel,
172
+ items,
173
+ onToggle
174
+ }) {
175
+ const interactive = onToggle != null && items.length > 1;
176
+ const hasValues = items.some((item) => item.value != null);
177
+ return /* @__PURE__ */ jsx2(
178
+ "div",
179
+ {
180
+ "aria-label": ariaLabel,
181
+ className: mergeClassNames("aui-legend", hasValues ? "aui-legend--values" : void 0),
182
+ "data-slot": "agent-ui-chart-legend",
183
+ role: interactive ? "group" : "list",
184
+ children: items.map((item) => {
185
+ const content = /* @__PURE__ */ jsxs2(Fragment, { children: [
186
+ /* @__PURE__ */ jsx2(
187
+ "span",
188
+ {
189
+ className: "aui-legend__dot",
190
+ "data-slot": "agent-ui-chart-legend-indicator",
191
+ style: { backgroundColor: item.color }
192
+ }
193
+ ),
194
+ /* @__PURE__ */ jsx2("span", { className: "aui-legend__label", children: item.label }),
195
+ item.value != null ? /* @__PURE__ */ jsx2("span", { className: "aui-legend__value", children: item.value }) : null
196
+ ] });
197
+ return interactive ? /* @__PURE__ */ jsx2(
198
+ "button",
199
+ {
200
+ "aria-pressed": activeKeys?.has(item.id) ?? true,
201
+ className: "aui-legend__button",
202
+ "data-slot": "agent-ui-chart-legend-item",
203
+ type: "button",
204
+ onClick: () => onToggle(item.id),
205
+ children: content
206
+ },
207
+ item.id
208
+ ) : /* @__PURE__ */ jsx2(
209
+ "span",
210
+ {
211
+ className: "aui-legend__item",
212
+ "data-slot": "agent-ui-chart-legend-item",
213
+ role: "listitem",
214
+ children: content
215
+ },
216
+ item.id
217
+ );
218
+ })
219
+ }
220
+ );
221
+ }
222
+ function ComponentTooltip({
223
+ active,
224
+ label,
225
+ payload,
226
+ series
227
+ }) {
228
+ if (!active || !payload?.length) return null;
229
+ return /* @__PURE__ */ jsxs2("div", { className: "aui-chart-tooltip", "data-slot": "agent-ui-chart-tooltip", children: [
230
+ label !== void 0 && label !== "" ? /* @__PURE__ */ jsx2("div", { className: "aui-chart-tooltip__header", "data-slot": "agent-ui-chart-tooltip-header", children: label }) : null,
231
+ payload.map((entry, index) => {
232
+ const format = series?.find((item) => item.dataKey === entry.dataKey)?.format;
233
+ const indicatorColor = entry.stroke ?? entry.color ?? entry.fill ?? entry.payload?.fill ?? paletteChartColor(index);
234
+ const value = typeof entry.value === "number" ? formatNumber(entry.value, format) : entry.value;
235
+ return /* @__PURE__ */ jsxs2(
236
+ "div",
237
+ {
238
+ className: "aui-chart-tooltip__item",
239
+ "data-slot": "agent-ui-chart-tooltip-item",
240
+ children: [
241
+ /* @__PURE__ */ jsx2(
242
+ "span",
243
+ {
244
+ className: "aui-chart-tooltip__indicator",
245
+ "data-slot": "agent-ui-chart-tooltip-indicator",
246
+ style: { backgroundColor: indicatorColor }
247
+ }
248
+ ),
249
+ /* @__PURE__ */ jsx2("span", { className: "aui-chart-tooltip__label", "data-slot": "agent-ui-chart-tooltip-label", children: entry.name ?? entry.dataKey }),
250
+ /* @__PURE__ */ jsx2("span", { className: "aui-chart-tooltip__value", "data-slot": "agent-ui-chart-tooltip-value", children: value })
251
+ ]
252
+ },
253
+ `${entry.dataKey ?? entry.name ?? "series"}-${index}`
254
+ );
255
+ })
256
+ ] });
257
+ }
258
+ function datumAtActiveIndex(rows, activeIndex) {
259
+ const index = typeof activeIndex === "number" ? Number(activeIndex) : Number(activeIndex ?? NaN);
260
+ return Number.isInteger(index) ? rows[index] : void 0;
261
+ }
262
+ function CartesianChartComponentContent({
263
+ className,
264
+ component,
265
+ exportFormats,
266
+ onAction,
267
+ onSelect,
268
+ type
269
+ }) {
270
+ const gradientPrefix = useId().replaceAll(":", "");
271
+ const [hidden, setHidden] = useState2(() => /* @__PURE__ */ new Set());
272
+ const ranges = component.ranges ?? [];
273
+ const fallbackRangeId = ranges.find((range) => range.id === component.defaultRangeId)?.id ?? ranges.at(-1)?.id;
274
+ const [selectedRangeId, setSelectedRangeId] = useState2(fallbackRangeId);
275
+ const activeRange = ranges.find((range) => range.id === selectedRangeId) ?? ranges.find((range) => range.id === fallbackRangeId);
276
+ const seriesKeys = useMemo2(
277
+ () => new Set(component.series.map((item) => item.dataKey)),
278
+ [component.series]
279
+ );
280
+ const activeHidden = useMemo2(() => {
281
+ const reconciled = new Set([...hidden].filter((dataKey) => seriesKeys.has(dataKey)));
282
+ return reconciled.size < component.series.length ? reconciled : /* @__PURE__ */ new Set();
283
+ }, [component.series.length, hidden, seriesKeys]);
284
+ const normalizedData = useMemo2(
285
+ () => component.data.map(
286
+ (datum) => Object.fromEntries(
287
+ Object.entries(datum).map(([key, value]) => [
288
+ key,
289
+ typeof value === "number" || typeof value === "string" ? value : String(value ?? "")
290
+ ])
291
+ )
292
+ ),
293
+ [component.data]
294
+ );
295
+ const data = activeRange?.maxItems ? normalizedData.slice(-activeRange.maxItems) : normalizedData;
296
+ const primarySeries = component.series[0];
297
+ const summary = (() => {
298
+ if (!component.showSummary || !primarySeries || data.length === 0) return null;
299
+ const first = Number(data[0]?.[primarySeries.dataKey]);
300
+ const latest = Number(data.at(-1)?.[primarySeries.dataKey]);
301
+ if (!Number.isFinite(first) || !Number.isFinite(latest)) return null;
302
+ return {
303
+ change: first === 0 ? void 0 : (latest - first) / Math.abs(first) * 100,
304
+ // The headline value stays exact even when the axis format is compact.
305
+ format: primarySeries.format && primarySeries.format.style !== "percent" ? { ...primarySeries.format, compact: false } : primarySeries.format,
306
+ label: primarySeries.label,
307
+ value: latest
308
+ };
309
+ })();
310
+ const horizontalBars = type === "bar" && component.kind === "bar-chart" && component.layout === "horizontal";
311
+ const isComposed = component.kind === "composed-chart";
312
+ const visibleBarKeys = component.series.filter((item) => !activeHidden.has(item.dataKey)).map((item) => item.dataKey);
313
+ const visibleComposedStackedBarKeys = isComposed ? component.series.filter((item) => item.type === "bar" && item.stacked && !activeHidden.has(item.dataKey)).map((item) => item.dataKey) : [];
314
+ const leftFormat = isComposed ? component.series.find((item) => item.axis !== "right")?.format : component.series[0]?.format;
315
+ const rightFormat = isComposed ? component.series.find((item) => item.axis === "right")?.format : void 0;
316
+ const hasRightAxis = isComposed && component.series.some((item) => item.axis === "right");
317
+ const formatChartAxis = (value, format = leftFormat) => format ? formatNumber(value, format) : formatAxisValue(value);
318
+ const activeSeriesKeys = new Set(
319
+ component.series.filter((item) => !activeHidden.has(item.dataKey)).map((item) => item.dataKey)
320
+ );
321
+ const legend = /* @__PURE__ */ jsx2(
322
+ ChartLegend,
323
+ {
324
+ activeKeys: activeSeriesKeys,
325
+ ariaLabel: "Chart series",
326
+ items: component.series.map((item, index) => ({
327
+ color: resolveChartColor(item.color, index),
328
+ id: item.dataKey,
329
+ label: item.label
330
+ })),
331
+ onToggle: component.series.length > 1 ? (dataKey) => setHidden(() => {
332
+ const next = new Set(activeHidden);
333
+ const visible = component.series.length - next.size;
334
+ if (next.has(dataKey)) next.delete(dataKey);
335
+ else if (visible > 1) next.add(dataKey);
336
+ return next;
337
+ }) : void 0
338
+ }
339
+ );
340
+ const axes = /* @__PURE__ */ jsxs2(Fragment, { children: [
341
+ /* @__PURE__ */ jsx2(CartesianGrid, { vertical: false }),
342
+ horizontalBars ? /* @__PURE__ */ jsxs2(Fragment, { children: [
343
+ /* @__PURE__ */ jsx2(XAxis, { tickFormatter: (value) => formatChartAxis(value), type: "number" }),
344
+ /* @__PURE__ */ jsx2(YAxis, { dataKey: component.xKey, type: "category", width: 88 })
345
+ ] }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
346
+ /* @__PURE__ */ jsx2(
347
+ XAxis,
348
+ {
349
+ dataKey: component.xKey,
350
+ interval: "preserveStartEnd",
351
+ minTickGap: 28,
352
+ tickMargin: 10
353
+ }
354
+ ),
355
+ /* @__PURE__ */ jsx2(
356
+ YAxis,
357
+ {
358
+ domain: type === "line" ? ["auto", "auto"] : void 0,
359
+ tickFormatter: (value) => formatChartAxis(value),
360
+ width: "auto",
361
+ yAxisId: isComposed ? "left" : void 0
362
+ }
363
+ ),
364
+ hasRightAxis ? /* @__PURE__ */ jsx2(
365
+ YAxis,
366
+ {
367
+ orientation: "right",
368
+ tickFormatter: (value) => formatChartAxis(value, rightFormat),
369
+ width: "auto",
370
+ yAxisId: "right"
371
+ }
372
+ ) : null
373
+ ] }),
374
+ /* @__PURE__ */ jsx2(Tooltip, { content: /* @__PURE__ */ jsx2(ComponentTooltip, { series: component.series }), isAnimationActive: false })
375
+ ] });
376
+ const common = {
377
+ data,
378
+ margin: { bottom: 2, left: 8, right: hasRightAxis ? 8 : 12, top: 8 },
379
+ // Taken from the chart rather than each Bar or Line so one handler covers
380
+ // every cartesian type, and so clicking anywhere in a category selects it
381
+ // instead of only the few pixels the mark occupies.
382
+ ...onSelect && {
383
+ onClick: (state) => {
384
+ const datum = datumAtActiveIndex(data, state.activeIndex);
385
+ if (datum) onSelect(createComponentSelection(component, datum));
386
+ }
387
+ }
388
+ };
389
+ return /* @__PURE__ */ jsxs2(
390
+ Card,
391
+ {
392
+ className,
393
+ description: component.description,
394
+ title: component.title,
395
+ actions: exportFormats?.length ? /* @__PURE__ */ jsx2(
396
+ ComponentExportActions,
397
+ {
398
+ component,
399
+ formats: exportFormats,
400
+ onAction
401
+ }
402
+ ) : null,
403
+ children: [
404
+ summary || ranges.length > 0 ? /* @__PURE__ */ jsxs2("div", { className: "aui-chart-toolbar", "data-slot": "agent-ui-chart-toolbar", children: [
405
+ summary ? /* @__PURE__ */ jsxs2("div", { className: "aui-chart-summary", "data-slot": "agent-ui-chart-summary", children: [
406
+ /* @__PURE__ */ jsx2("span", { className: "aui-chart-summary__label", children: summary.label }),
407
+ /* @__PURE__ */ jsxs2("div", { className: "aui-chart-summary__value-row", children: [
408
+ /* @__PURE__ */ jsx2("strong", { className: "aui-chart-summary__value", children: formatNumber(summary.value, summary.format) }),
409
+ summary.change !== void 0 ? /* @__PURE__ */ jsx2(TrendChange, { value: summary.change }) : null,
410
+ activeRange ? /* @__PURE__ */ jsx2(
411
+ "span",
412
+ {
413
+ className: "aui-chart-summary__range",
414
+ "data-slot": "agent-ui-chart-summary-range",
415
+ children: activeRange.label
416
+ }
417
+ ) : null
418
+ ] })
419
+ ] }) : null,
420
+ ranges.length > 0 ? /* @__PURE__ */ jsx2(
421
+ Segment,
422
+ {
423
+ "aria-label": "Chart range",
424
+ className: "aui-chart-ranges",
425
+ selectedKey: activeRange?.id,
426
+ variant: "text",
427
+ onSelectionChange: setSelectedRangeId,
428
+ children: ranges.map((range) => /* @__PURE__ */ jsx2(Segment.Item, { id: range.id, children: range.label }, range.id))
429
+ }
430
+ ) : null
431
+ ] }) : null,
432
+ /* @__PURE__ */ jsx2(
433
+ "div",
434
+ {
435
+ "aria-label": `${component.title} chart`,
436
+ className: `aui-chart aui-chart--${type}`,
437
+ "data-slot": "agent-ui-chart",
438
+ role: "img",
439
+ children: /* @__PURE__ */ jsx2(ResponsiveContainer, { height: 220, width: "100%", children: type === "composed" && component.kind === "composed-chart" ? /* @__PURE__ */ jsxs2(RechartsComposedChart, { accessibilityLayer: true, ...common, children: [
440
+ /* @__PURE__ */ jsx2("defs", { children: component.series.map((item, index) => /* @__PURE__ */ jsxs2(
441
+ "linearGradient",
442
+ {
443
+ id: `${gradientPrefix}-${index}`,
444
+ x1: "0",
445
+ x2: "0",
446
+ y1: "0",
447
+ y2: "1",
448
+ children: [
449
+ /* @__PURE__ */ jsx2(
450
+ "stop",
451
+ {
452
+ offset: "0%",
453
+ stopColor: resolveChartColor(item.color, index),
454
+ stopOpacity: 0.18
455
+ }
456
+ ),
457
+ /* @__PURE__ */ jsx2(
458
+ "stop",
459
+ {
460
+ offset: "100%",
461
+ stopColor: resolveChartColor(item.color, index),
462
+ stopOpacity: 0.02
463
+ }
464
+ )
465
+ ]
466
+ },
467
+ item.dataKey
468
+ )) }),
469
+ axes,
470
+ component.series.map((item, index) => {
471
+ const color = resolveChartColor(item.color, index);
472
+ const yAxisId = item.axis ?? "left";
473
+ if (item.type === "area") {
474
+ return /* @__PURE__ */ jsx2(
475
+ Area,
476
+ {
477
+ dataKey: item.dataKey,
478
+ dot: false,
479
+ fill: `url(#${gradientPrefix}-${index})`,
480
+ hide: activeHidden.has(item.dataKey),
481
+ isAnimationActive: false,
482
+ name: item.label,
483
+ stackId: item.stacked ? "area-stack" : void 0,
484
+ stroke: color,
485
+ strokeWidth: 2,
486
+ type: "monotone",
487
+ yAxisId
488
+ },
489
+ item.dataKey
490
+ );
491
+ }
492
+ if (item.type === "bar") {
493
+ return /* @__PURE__ */ jsx2(
494
+ Bar,
495
+ {
496
+ dataKey: item.dataKey,
497
+ fill: color,
498
+ hide: activeHidden.has(item.dataKey),
499
+ isAnimationActive: false,
500
+ name: item.label,
501
+ stackId: item.stacked ? "bar-stack" : void 0,
502
+ yAxisId,
503
+ radius: getBarRadius({
504
+ dataKey: item.dataKey,
505
+ horizontal: false,
506
+ stacked: Boolean(item.stacked),
507
+ visibleStackKeys: visibleComposedStackedBarKeys
508
+ })
509
+ },
510
+ item.dataKey
511
+ );
512
+ }
513
+ return /* @__PURE__ */ jsx2(
514
+ Line,
515
+ {
516
+ dataKey: item.dataKey,
517
+ dot: false,
518
+ hide: activeHidden.has(item.dataKey),
519
+ isAnimationActive: false,
520
+ name: item.label,
521
+ stroke: color,
522
+ strokeWidth: 2,
523
+ type: "monotone",
524
+ yAxisId
525
+ },
526
+ item.dataKey
527
+ );
528
+ })
529
+ ] }) : type === "line" ? /* @__PURE__ */ jsxs2(RechartsLineChart, { accessibilityLayer: true, ...common, children: [
530
+ axes,
531
+ component.series.map((item, index) => /* @__PURE__ */ jsx2(
532
+ Line,
533
+ {
534
+ dataKey: item.dataKey,
535
+ dot: false,
536
+ hide: activeHidden.has(item.dataKey),
537
+ isAnimationActive: false,
538
+ name: item.label,
539
+ stroke: resolveChartColor(item.color, index),
540
+ strokeWidth: 2,
541
+ type: "monotone"
542
+ },
543
+ item.dataKey
544
+ ))
545
+ ] }) : type === "area" ? /* @__PURE__ */ jsxs2(RechartsAreaChart, { accessibilityLayer: true, ...common, children: [
546
+ /* @__PURE__ */ jsx2("defs", { children: component.series.map((item, index) => /* @__PURE__ */ jsxs2(
547
+ "linearGradient",
548
+ {
549
+ id: `${gradientPrefix}-${index}`,
550
+ x1: "0",
551
+ x2: "0",
552
+ y1: "0",
553
+ y2: "1",
554
+ children: [
555
+ /* @__PURE__ */ jsx2(
556
+ "stop",
557
+ {
558
+ offset: "0%",
559
+ stopColor: resolveChartColor(item.color, index),
560
+ stopOpacity: 0.2
561
+ }
562
+ ),
563
+ /* @__PURE__ */ jsx2(
564
+ "stop",
565
+ {
566
+ offset: "100%",
567
+ stopColor: resolveChartColor(item.color, index),
568
+ stopOpacity: 0.01
569
+ }
570
+ )
571
+ ]
572
+ },
573
+ item.dataKey
574
+ )) }),
575
+ axes,
576
+ component.series.map((item, index) => /* @__PURE__ */ jsx2(
577
+ Area,
578
+ {
579
+ dataKey: item.dataKey,
580
+ dot: false,
581
+ fill: `url(#${gradientPrefix}-${index})`,
582
+ hide: activeHidden.has(item.dataKey),
583
+ isAnimationActive: false,
584
+ name: item.label,
585
+ stroke: resolveChartColor(item.color, index),
586
+ strokeWidth: 2,
587
+ type: "monotone",
588
+ stackId: component.kind === "area-chart" && component.stacked ? "stack" : void 0
589
+ },
590
+ item.dataKey
591
+ ))
592
+ ] }) : /* @__PURE__ */ jsxs2(
593
+ RechartsBarChart,
594
+ {
595
+ accessibilityLayer: true,
596
+ ...common,
597
+ layout: horizontalBars ? "vertical" : "horizontal",
598
+ children: [
599
+ axes,
600
+ component.series.map((item, index) => /* @__PURE__ */ jsx2(
601
+ Bar,
602
+ {
603
+ dataKey: item.dataKey,
604
+ fill: resolveChartColor(item.color, index),
605
+ hide: activeHidden.has(item.dataKey),
606
+ isAnimationActive: false,
607
+ name: item.label,
608
+ radius: getBarRadius({
609
+ dataKey: item.dataKey,
610
+ horizontal: horizontalBars,
611
+ stacked: component.kind === "bar-chart" && Boolean(component.stacked),
612
+ visibleStackKeys: visibleBarKeys
613
+ }),
614
+ stackId: component.kind === "bar-chart" && component.stacked ? "stack" : void 0
615
+ },
616
+ item.dataKey
617
+ ))
618
+ ]
619
+ }
620
+ ) })
621
+ }
622
+ ),
623
+ legend
624
+ ]
625
+ }
626
+ );
627
+ }
628
+ function LineChartComponentContent(props) {
629
+ return /* @__PURE__ */ jsx2(CartesianChartComponentContent, { ...props, type: "line" });
630
+ }
631
+ function AreaChartComponentContent(props) {
632
+ return /* @__PURE__ */ jsx2(CartesianChartComponentContent, { ...props, type: "area" });
633
+ }
634
+ function BarChartComponentContent(props) {
635
+ return /* @__PURE__ */ jsx2(CartesianChartComponentContent, { ...props, type: "bar" });
636
+ }
637
+ function ComposedChartComponentContent(props) {
638
+ return /* @__PURE__ */ jsx2(CartesianChartComponentContent, { ...props, type: "composed" });
639
+ }
640
+ function ProportionalChartComponentContent({
641
+ className,
642
+ component,
643
+ exportFormats,
644
+ onAction,
645
+ onSelect,
646
+ variant
647
+ }) {
648
+ const [hidden, setHidden] = useState2(() => /* @__PURE__ */ new Set());
649
+ const labels = useMemo2(
650
+ () => new Set(component.data.map((datum) => String(datum[component.labelKey] ?? ""))),
651
+ [component.data, component.labelKey]
652
+ );
653
+ const activeHidden = useMemo2(() => {
654
+ const reconciled = new Set([...hidden].filter((label) => labels.has(label)));
655
+ return reconciled.size < component.data.length ? reconciled : /* @__PURE__ */ new Set();
656
+ }, [component.data.length, hidden, labels]);
657
+ const data = component.data.flatMap((datum, index) => {
658
+ const name = String(datum[component.labelKey] ?? "");
659
+ return activeHidden.has(name) ? [] : [
660
+ {
661
+ color: resolveChartColor(component.colors?.[name], index),
662
+ name,
663
+ original: datum,
664
+ value: Number(datum[component.valueKey] ?? 0)
665
+ }
666
+ ];
667
+ });
668
+ const total = data.reduce((sum, datum) => sum + datum.value, 0);
669
+ const activeCategoryKeys = new Set(
670
+ component.data.map((datum) => String(datum[component.labelKey] ?? "")).filter((label) => !activeHidden.has(label))
671
+ );
672
+ const legend = /* @__PURE__ */ jsx2(
673
+ ChartLegend,
674
+ {
675
+ activeKeys: activeCategoryKeys,
676
+ ariaLabel: "Chart categories",
677
+ items: component.data.map((datum, index) => {
678
+ const label = String(datum[component.labelKey] ?? "");
679
+ return {
680
+ color: resolveChartColor(component.colors?.[label], index),
681
+ id: label,
682
+ label,
683
+ value: formatNumber(Number(datum[component.valueKey] ?? 0), component.format)
684
+ };
685
+ }),
686
+ onToggle: (label) => setHidden(() => {
687
+ const next = new Set(activeHidden);
688
+ if (next.has(label)) next.delete(label);
689
+ else if (next.size < component.data.length - 1) next.add(label);
690
+ return next;
691
+ })
692
+ }
693
+ );
694
+ return /* @__PURE__ */ jsxs2(
695
+ Card,
696
+ {
697
+ className,
698
+ description: component.description,
699
+ title: component.title,
700
+ actions: exportFormats?.length ? /* @__PURE__ */ jsx2(
701
+ ComponentExportActions,
702
+ {
703
+ component,
704
+ formats: exportFormats,
705
+ onAction
706
+ }
707
+ ) : null,
708
+ children: [
709
+ /* @__PURE__ */ jsx2(
710
+ "div",
711
+ {
712
+ "aria-label": `${component.title} ${variant} chart`,
713
+ className: "aui-chart aui-chart--pie",
714
+ "data-slot": "agent-ui-chart",
715
+ role: "img",
716
+ children: /* @__PURE__ */ jsx2(ResponsiveContainer, { height: 220, width: "100%", children: /* @__PURE__ */ jsxs2(RechartsPieChart, { accessibilityLayer: true, children: [
717
+ /* @__PURE__ */ jsxs2(
718
+ Pie,
719
+ {
720
+ cx: "50%",
721
+ cy: "50%",
722
+ data,
723
+ dataKey: "value",
724
+ innerRadius: variant === "donut" ? 58 : 0,
725
+ isAnimationActive: false,
726
+ nameKey: "name",
727
+ outerRadius: 88,
728
+ paddingAngle: 0,
729
+ strokeWidth: 0,
730
+ onClick: (_, index) => {
731
+ const datum = data[index]?.original;
732
+ if (datum) onSelect?.(createComponentSelection(component, datum));
733
+ },
734
+ children: [
735
+ data.map((entry) => /* @__PURE__ */ jsx2(Cell, { fill: entry.color }, entry.name)),
736
+ variant === "donut" ? /* @__PURE__ */ jsx2(
737
+ Label,
738
+ {
739
+ className: "aui-donut-total",
740
+ position: "center",
741
+ value: formatNumber(total, component.format)
742
+ }
743
+ ) : null
744
+ ]
745
+ }
746
+ ),
747
+ /* @__PURE__ */ jsx2(
748
+ Tooltip,
749
+ {
750
+ content: /* @__PURE__ */ jsx2(ComponentTooltip, { series: [{ dataKey: "value", format: component.format }] }),
751
+ isAnimationActive: false
752
+ }
753
+ )
754
+ ] }) })
755
+ }
756
+ ),
757
+ legend
758
+ ]
759
+ }
760
+ );
761
+ }
762
+ function PieChartComponentContent(props) {
763
+ return /* @__PURE__ */ jsx2(ProportionalChartComponentContent, { ...props, variant: "pie" });
764
+ }
765
+ function DonutChartComponentContent(props) {
766
+ return /* @__PURE__ */ jsx2(ProportionalChartComponentContent, { ...props, variant: "donut" });
767
+ }
768
+ function RadarChartComponentContent({
769
+ className,
770
+ component,
771
+ exportFormats,
772
+ onAction
773
+ }) {
774
+ const [hidden, setHidden] = useState2(() => /* @__PURE__ */ new Set());
775
+ const seriesKeys = useMemo2(
776
+ () => new Set(component.series.map((item) => item.dataKey)),
777
+ [component.series]
778
+ );
779
+ const activeHidden = useMemo2(() => {
780
+ const reconciled = new Set([...hidden].filter((dataKey) => seriesKeys.has(dataKey)));
781
+ return reconciled.size < component.series.length ? reconciled : /* @__PURE__ */ new Set();
782
+ }, [component.series.length, hidden, seriesKeys]);
783
+ const activeSeriesKeys = new Set(
784
+ component.series.filter((item) => !activeHidden.has(item.dataKey)).map((item) => item.dataKey)
785
+ );
786
+ const legend = /* @__PURE__ */ jsx2(
787
+ ChartLegend,
788
+ {
789
+ activeKeys: activeSeriesKeys,
790
+ ariaLabel: "Chart series",
791
+ items: component.series.map((item, index) => ({
792
+ color: resolveChartColor(item.color, index),
793
+ id: item.dataKey,
794
+ label: item.label
795
+ })),
796
+ onToggle: component.series.length > 1 ? (dataKey) => setHidden(() => {
797
+ const next = new Set(activeHidden);
798
+ const visible = component.series.length - next.size;
799
+ if (next.has(dataKey)) next.delete(dataKey);
800
+ else if (visible > 1) next.add(dataKey);
801
+ return next;
802
+ }) : void 0
803
+ }
804
+ );
805
+ return /* @__PURE__ */ jsxs2(
806
+ Card,
807
+ {
808
+ className,
809
+ description: component.description,
810
+ title: component.title,
811
+ actions: exportFormats?.length ? /* @__PURE__ */ jsx2(
812
+ ComponentExportActions,
813
+ {
814
+ component,
815
+ formats: exportFormats,
816
+ onAction
817
+ }
818
+ ) : null,
819
+ children: [
820
+ /* @__PURE__ */ jsx2(
821
+ "div",
822
+ {
823
+ "aria-label": `${component.title} radar chart`,
824
+ className: "aui-chart aui-chart--radar",
825
+ "data-slot": "agent-ui-chart",
826
+ role: "img",
827
+ children: /* @__PURE__ */ jsx2(ResponsiveContainer, { height: 240, width: "100%", children: /* @__PURE__ */ jsxs2(
828
+ RechartsRadarChart,
829
+ {
830
+ data: component.data,
831
+ margin: { bottom: 8, left: 20, right: 20, top: 8 },
832
+ children: [
833
+ /* @__PURE__ */ jsx2(PolarGrid, {}),
834
+ /* @__PURE__ */ jsx2(PolarAngleAxis, { dataKey: component.angleKey }),
835
+ /* @__PURE__ */ jsx2(PolarRadiusAxis, { axisLine: false, tick: false }),
836
+ component.series.map(
837
+ (item, index) => activeHidden.has(item.dataKey) ? null : /* @__PURE__ */ jsx2(
838
+ Radar,
839
+ {
840
+ dataKey: item.dataKey,
841
+ fill: resolveChartColor(item.color, index),
842
+ fillOpacity: 0.12,
843
+ isAnimationActive: false,
844
+ name: item.label,
845
+ stroke: resolveChartColor(item.color, index),
846
+ strokeWidth: 2
847
+ },
848
+ item.dataKey
849
+ )
850
+ ),
851
+ /* @__PURE__ */ jsx2(
852
+ Tooltip,
853
+ {
854
+ content: /* @__PURE__ */ jsx2(ComponentTooltip, { series: component.series }),
855
+ isAnimationActive: false
856
+ }
857
+ )
858
+ ]
859
+ }
860
+ ) })
861
+ }
862
+ ),
863
+ legend
864
+ ]
865
+ }
866
+ );
867
+ }
868
+ function RadialChartComponentContent({
869
+ className,
870
+ component,
871
+ exportFormats,
872
+ onAction,
873
+ onSelect
874
+ }) {
875
+ const data = component.data.map((datum, index) => ({
876
+ ...datum,
877
+ fill: resolveChartColor(component.colors?.[String(datum[component.labelKey] ?? "")], index)
878
+ }));
879
+ const legend = /* @__PURE__ */ jsx2(
880
+ ChartLegend,
881
+ {
882
+ ariaLabel: "Chart categories",
883
+ items: component.data.map((datum, index) => {
884
+ const label = String(datum[component.labelKey] ?? "");
885
+ return {
886
+ color: resolveChartColor(component.colors?.[label], index),
887
+ id: `${label}-${index}`,
888
+ label,
889
+ value: formatNumber(Number(datum[component.valueKey] ?? 0), component.format)
890
+ };
891
+ })
892
+ }
893
+ );
894
+ return /* @__PURE__ */ jsxs2(
895
+ Card,
896
+ {
897
+ className,
898
+ description: component.description,
899
+ title: component.title,
900
+ actions: exportFormats?.length ? /* @__PURE__ */ jsx2(
901
+ ComponentExportActions,
902
+ {
903
+ component,
904
+ formats: exportFormats,
905
+ onAction
906
+ }
907
+ ) : null,
908
+ children: [
909
+ /* @__PURE__ */ jsx2(
910
+ "div",
911
+ {
912
+ "aria-label": `${component.title} radial chart`,
913
+ className: "aui-chart aui-chart--radial",
914
+ "data-slot": "agent-ui-chart",
915
+ role: "img",
916
+ children: /* @__PURE__ */ jsx2(ResponsiveContainer, { height: 230, width: "100%", children: /* @__PURE__ */ jsxs2(
917
+ RechartsRadialBarChart,
918
+ {
919
+ cx: "50%",
920
+ cy: "50%",
921
+ data,
922
+ endAngle: component.endAngle ?? -270,
923
+ innerRadius: "24%",
924
+ outerRadius: "92%",
925
+ startAngle: component.startAngle ?? 90,
926
+ children: [
927
+ /* @__PURE__ */ jsx2(PolarAngleAxis, { domain: [0, component.maxValue ?? "auto"], tick: false, type: "number" }),
928
+ /* @__PURE__ */ jsx2(
929
+ RadialBar,
930
+ {
931
+ background: true,
932
+ dataKey: component.valueKey,
933
+ isAnimationActive: false,
934
+ name: component.labelKey,
935
+ onClick: (datum) => onSelect?.(createComponentSelection(component, datum))
936
+ }
937
+ ),
938
+ /* @__PURE__ */ jsx2(
939
+ Tooltip,
940
+ {
941
+ isAnimationActive: false,
942
+ content: /* @__PURE__ */ jsx2(
943
+ ComponentTooltip,
944
+ {
945
+ series: [{ dataKey: component.valueKey, format: component.format }]
946
+ }
947
+ )
948
+ }
949
+ )
950
+ ]
951
+ }
952
+ ) })
953
+ }
954
+ ),
955
+ legend
956
+ ]
957
+ }
958
+ );
959
+ }
960
+ function ScatterChartComponentContent({
961
+ className,
962
+ component,
963
+ exportFormats,
964
+ onAction,
965
+ onSelect
966
+ }) {
967
+ const groups = useMemo2(() => {
968
+ const grouped = /* @__PURE__ */ new Map();
969
+ for (const datum of component.data) {
970
+ const label = component.groupKey ? String(datum[component.groupKey] ?? "Other") : component.title;
971
+ const entries = grouped.get(label) ?? [];
972
+ entries.push(datum);
973
+ grouped.set(label, entries);
974
+ }
975
+ return [...grouped.entries()];
976
+ }, [component.data, component.groupKey, component.title]);
977
+ const series = [
978
+ { dataKey: component.xKey, format: component.format },
979
+ { dataKey: component.yKey, format: component.format },
980
+ ...component.sizeKey ? [{ dataKey: component.sizeKey, format: component.format }] : []
981
+ ];
982
+ const legend = /* @__PURE__ */ jsx2(
983
+ ChartLegend,
984
+ {
985
+ ariaLabel: "Chart groups",
986
+ items: groups.map(([label], index) => ({
987
+ color: resolveChartColor(component.colors?.[label], index),
988
+ id: label,
989
+ label
990
+ }))
991
+ }
992
+ );
993
+ return /* @__PURE__ */ jsxs2(
994
+ Card,
995
+ {
996
+ className,
997
+ description: component.description,
998
+ title: component.title,
999
+ actions: exportFormats?.length ? /* @__PURE__ */ jsx2(
1000
+ ComponentExportActions,
1001
+ {
1002
+ component,
1003
+ formats: exportFormats,
1004
+ onAction
1005
+ }
1006
+ ) : null,
1007
+ children: [
1008
+ /* @__PURE__ */ jsx2(
1009
+ "div",
1010
+ {
1011
+ "aria-label": `${component.title} scatter chart`,
1012
+ className: "aui-chart aui-chart--scatter",
1013
+ "data-slot": "agent-ui-chart",
1014
+ role: "img",
1015
+ children: /* @__PURE__ */ jsx2(ResponsiveContainer, { height: 240, width: "100%", children: /* @__PURE__ */ jsxs2(RechartsScatterChart, { accessibilityLayer: true, margin: { bottom: 8, left: 0, right: 8, top: 8 }, children: [
1016
+ /* @__PURE__ */ jsx2(CartesianGrid, {}),
1017
+ /* @__PURE__ */ jsx2(
1018
+ XAxis,
1019
+ {
1020
+ dataKey: component.xKey,
1021
+ name: component.xKey,
1022
+ tickFormatter: (value) => formatAxisValue(value),
1023
+ type: "number"
1024
+ }
1025
+ ),
1026
+ /* @__PURE__ */ jsx2(
1027
+ YAxis,
1028
+ {
1029
+ dataKey: component.yKey,
1030
+ name: component.yKey,
1031
+ tickFormatter: (value) => formatAxisValue(value),
1032
+ type: "number",
1033
+ width: 42
1034
+ }
1035
+ ),
1036
+ component.sizeKey ? /* @__PURE__ */ jsx2(ZAxis, { dataKey: component.sizeKey, range: [48, 320], type: "number" }) : null,
1037
+ /* @__PURE__ */ jsx2(
1038
+ Tooltip,
1039
+ {
1040
+ content: /* @__PURE__ */ jsx2(ComponentTooltip, { series }),
1041
+ cursor: { strokeDasharray: "4 4" },
1042
+ isAnimationActive: false
1043
+ }
1044
+ ),
1045
+ groups.map(([label, data], index) => /* @__PURE__ */ jsx2(
1046
+ Scatter,
1047
+ {
1048
+ data,
1049
+ fill: resolveChartColor(component.colors?.[label], index),
1050
+ isAnimationActive: false,
1051
+ name: label,
1052
+ onClick: (point) => {
1053
+ const datum = "payload" in point ? point.payload : point;
1054
+ onSelect?.(createComponentSelection(component, datum));
1055
+ }
1056
+ },
1057
+ label
1058
+ ))
1059
+ ] }) })
1060
+ }
1061
+ ),
1062
+ legend
1063
+ ]
1064
+ }
1065
+ );
1066
+ }
1067
+ function HeatmapComponentContent({
1068
+ className,
1069
+ component,
1070
+ exportFormats,
1071
+ onAction,
1072
+ onSelect
1073
+ }) {
1074
+ const xValues = [...new Set(component.data.map((datum) => String(datum[component.xKey] ?? "")))];
1075
+ const yValues = [...new Set(component.data.map((datum) => String(datum[component.yKey] ?? "")))];
1076
+ const values = component.data.map((datum) => Number(datum[component.valueKey] ?? 0));
1077
+ const minimum = Math.min(...values);
1078
+ const maximum = Math.max(...values);
1079
+ const range = maximum - minimum || 1;
1080
+ const width = 420;
1081
+ const left = 84;
1082
+ const top = 28;
1083
+ const right = 8;
1084
+ const bottom = 44;
1085
+ const cellWidth = (width - left - right) / Math.max(1, xValues.length);
1086
+ const cellHeight = Math.max(26, Math.min(44, 230 / Math.max(1, yValues.length)));
1087
+ const height = top + yValues.length * cellHeight + bottom;
1088
+ const dataByCoordinate = new Map(
1089
+ component.data.map((datum) => [
1090
+ `${String(datum[component.xKey] ?? "")}\0${String(datum[component.yKey] ?? "")}`,
1091
+ datum
1092
+ ])
1093
+ );
1094
+ const heatmapColor = resolveChartColor(component.color, 0);
1095
+ const legend = /* @__PURE__ */ jsxs2(
1096
+ "div",
1097
+ {
1098
+ "aria-label": "Heatmap intensity",
1099
+ className: "aui-legend aui-legend--scale",
1100
+ "data-slot": "agent-ui-chart-legend",
1101
+ role: "img",
1102
+ children: [
1103
+ /* @__PURE__ */ jsx2("span", { className: "aui-legend__value", children: formatNumber(minimum, component.format) }),
1104
+ /* @__PURE__ */ jsx2(
1105
+ "span",
1106
+ {
1107
+ className: "aui-legend__scale",
1108
+ style: {
1109
+ background: `linear-gradient(90deg, color-mix(in srgb, ${heatmapColor} 8%, transparent), ${heatmapColor})`
1110
+ }
1111
+ }
1112
+ ),
1113
+ /* @__PURE__ */ jsx2("span", { className: "aui-legend__value", children: formatNumber(maximum, component.format) })
1114
+ ]
1115
+ }
1116
+ );
1117
+ return /* @__PURE__ */ jsxs2(
1118
+ Card,
1119
+ {
1120
+ className,
1121
+ description: component.description,
1122
+ title: component.title,
1123
+ actions: exportFormats?.length ? /* @__PURE__ */ jsx2(
1124
+ ComponentExportActions,
1125
+ {
1126
+ component,
1127
+ formats: exportFormats,
1128
+ onAction
1129
+ }
1130
+ ) : null,
1131
+ children: [
1132
+ /* @__PURE__ */ jsx2(
1133
+ "div",
1134
+ {
1135
+ "aria-label": `${component.title} heatmap`,
1136
+ className: "aui-chart aui-chart--heatmap",
1137
+ "data-slot": "agent-ui-chart",
1138
+ role: "img",
1139
+ children: /* @__PURE__ */ jsxs2(
1140
+ "svg",
1141
+ {
1142
+ "aria-hidden": "true",
1143
+ preserveAspectRatio: "xMidYMid meet",
1144
+ viewBox: `0 0 ${width} ${height}`,
1145
+ children: [
1146
+ xValues.map((label, index) => /* @__PURE__ */ jsx2(
1147
+ "text",
1148
+ {
1149
+ className: "aui-heatmap__axis",
1150
+ textAnchor: "middle",
1151
+ x: left + index * cellWidth + cellWidth / 2,
1152
+ y: height - 14,
1153
+ children: label
1154
+ },
1155
+ label
1156
+ )),
1157
+ yValues.map((label, row) => /* @__PURE__ */ jsxs2("g", { children: [
1158
+ /* @__PURE__ */ jsx2(
1159
+ "text",
1160
+ {
1161
+ className: "aui-heatmap__axis",
1162
+ dominantBaseline: "middle",
1163
+ textAnchor: "end",
1164
+ x: left - 8,
1165
+ y: top + row * cellHeight + cellHeight / 2,
1166
+ children: label
1167
+ }
1168
+ ),
1169
+ xValues.map((xLabel, column) => {
1170
+ const datum = dataByCoordinate.get(`${xLabel}\0${label}`);
1171
+ const value = Number(datum?.[component.valueKey] ?? 0);
1172
+ const opacity = datum ? 0.14 + (value - minimum) / range * 0.76 : 0.04;
1173
+ return /* @__PURE__ */ jsxs2(
1174
+ "g",
1175
+ {
1176
+ className: "aui-heatmap__cell",
1177
+ "data-slot": "agent-ui-heatmap-cell",
1178
+ role: datum && onSelect ? "button" : void 0,
1179
+ tabIndex: datum && onSelect ? 0 : void 0,
1180
+ onClick: () => {
1181
+ if (datum) onSelect?.(createComponentSelection(component, datum));
1182
+ },
1183
+ onKeyDown: (event) => {
1184
+ if (!datum || !onSelect || event.key !== "Enter" && event.key !== " ")
1185
+ return;
1186
+ event.preventDefault();
1187
+ onSelect(createComponentSelection(component, datum));
1188
+ },
1189
+ children: [
1190
+ /* @__PURE__ */ jsx2(
1191
+ "rect",
1192
+ {
1193
+ fill: heatmapColor,
1194
+ fillOpacity: opacity,
1195
+ height: Math.max(1, cellHeight - 3),
1196
+ rx: 6,
1197
+ width: Math.max(1, cellWidth - 3),
1198
+ x: left + column * cellWidth + 1.5,
1199
+ y: top + row * cellHeight + 1.5
1200
+ }
1201
+ ),
1202
+ datum ? /* @__PURE__ */ jsx2("title", { children: `${label}, ${xLabel}: ${formatNumber(value, component.format)}` }) : null
1203
+ ]
1204
+ },
1205
+ xLabel
1206
+ );
1207
+ })
1208
+ ] }, label))
1209
+ ]
1210
+ }
1211
+ )
1212
+ }
1213
+ ),
1214
+ legend
1215
+ ]
1216
+ }
1217
+ );
1218
+ }
1219
+ function SankeyNode({ height, index, payload, width, x, y }) {
1220
+ return /* @__PURE__ */ jsxs2("g", { children: [
1221
+ /* @__PURE__ */ jsx2(
1222
+ "rect",
1223
+ {
1224
+ className: "aui-sankey__node",
1225
+ fill: paletteChartColor(index),
1226
+ height,
1227
+ rx: 4,
1228
+ width,
1229
+ x,
1230
+ y
1231
+ }
1232
+ ),
1233
+ /* @__PURE__ */ jsx2(
1234
+ "text",
1235
+ {
1236
+ className: "aui-sankey__label",
1237
+ dominantBaseline: "middle",
1238
+ x: x + width + 7,
1239
+ y: y + height / 2,
1240
+ children: payload.name
1241
+ }
1242
+ )
1243
+ ] });
1244
+ }
1245
+ function SankeyLink({
1246
+ chartId,
1247
+ index,
1248
+ linkWidth,
1249
+ payload,
1250
+ sourceControlX,
1251
+ sourceX,
1252
+ sourceY,
1253
+ targetControlX,
1254
+ targetX,
1255
+ targetY
1256
+ }) {
1257
+ const half = Math.max(1, linkWidth) / 2;
1258
+ const path = `M${sourceX},${sourceY - half} C${sourceControlX},${sourceY - half} ${targetControlX},${targetY - half} ${targetX},${targetY - half} L${targetX},${targetY + half} C${targetControlX},${targetY + half} ${sourceControlX},${sourceY + half} ${sourceX},${sourceY + half} Z`;
1259
+ return /* @__PURE__ */ jsxs2("g", { children: [
1260
+ /* @__PURE__ */ jsxs2("defs", { children: [
1261
+ /* @__PURE__ */ jsxs2("linearGradient", { id: `${chartId}-link-${index}`, x1: "0", x2: "1", children: [
1262
+ /* @__PURE__ */ jsx2("stop", { offset: "0%", stopColor: "var(--chart-3, var(--accent))", stopOpacity: 0.2 }),
1263
+ /* @__PURE__ */ jsx2(
1264
+ "stop",
1265
+ {
1266
+ offset: "50%",
1267
+ stopColor: "var(--chart-4, oklch(from var(--accent) calc(l + 0.12) c h))",
1268
+ stopOpacity: 0.55
1269
+ }
1270
+ ),
1271
+ /* @__PURE__ */ jsx2(
1272
+ "stop",
1273
+ {
1274
+ offset: "100%",
1275
+ stopColor: "var(--chart-1, oklch(from var(--accent) calc(l - 0.24) c h))",
1276
+ stopOpacity: 0.25
1277
+ }
1278
+ )
1279
+ ] }),
1280
+ /* @__PURE__ */ jsx2("filter", { height: "180%", id: `${chartId}-glow-${index}`, width: "180%", x: "-40%", y: "-40%", children: /* @__PURE__ */ jsx2("feGaussianBlur", { stdDeviation: "2.5" }) })
1281
+ ] }),
1282
+ /* @__PURE__ */ jsx2(
1283
+ "path",
1284
+ {
1285
+ d: path,
1286
+ fill: `url(#${chartId}-link-${index})`,
1287
+ filter: `url(#${chartId}-glow-${index})`,
1288
+ opacity: 0.35
1289
+ }
1290
+ ),
1291
+ /* @__PURE__ */ jsx2("path", { d: path, fill: `url(#${chartId}-link-${index})`, opacity: 0.8 }),
1292
+ /* @__PURE__ */ jsx2("title", { children: `${payload.source.name} \u2192 ${payload.target.name}: ${payload.value}` })
1293
+ ] });
1294
+ }
1295
+ function SankeyChartComponentContent({
1296
+ className,
1297
+ component,
1298
+ exportFormats,
1299
+ onAction,
1300
+ onSelect
1301
+ }) {
1302
+ const chartId = useId().replaceAll(":", "");
1303
+ const nodeIndex = new Map(component.nodes.map((node, index) => [node.id, index]));
1304
+ const data = {
1305
+ links: component.links.flatMap((link) => {
1306
+ const source = nodeIndex.get(link.source);
1307
+ const target = nodeIndex.get(link.target);
1308
+ return source === void 0 || target === void 0 ? [] : [{ source, target, value: link.value }];
1309
+ }),
1310
+ nodes: component.nodes.map((node) => ({ name: node.label }))
1311
+ };
1312
+ return /* @__PURE__ */ jsxs2(
1313
+ Card,
1314
+ {
1315
+ className,
1316
+ description: component.description,
1317
+ title: component.title,
1318
+ actions: exportFormats?.length ? /* @__PURE__ */ jsx2(
1319
+ ComponentExportActions,
1320
+ {
1321
+ component,
1322
+ formats: exportFormats,
1323
+ onAction
1324
+ }
1325
+ ) : null,
1326
+ children: [
1327
+ /* @__PURE__ */ jsx2(
1328
+ "div",
1329
+ {
1330
+ "aria-label": `${component.title} sankey chart`,
1331
+ className: "aui-chart aui-chart--sankey aui-sankey",
1332
+ "data-slot": "agent-ui-chart",
1333
+ role: "img",
1334
+ children: /* @__PURE__ */ jsx2(ResponsiveContainer, { height: 260, width: "100%", children: /* @__PURE__ */ jsx2(
1335
+ Sankey,
1336
+ {
1337
+ data,
1338
+ link: (props) => /* @__PURE__ */ jsx2(SankeyLink, { ...props, chartId }),
1339
+ linkCurvature: 0.55,
1340
+ margin: { bottom: 12, left: 8, right: 92, top: 12 },
1341
+ node: (props) => /* @__PURE__ */ jsx2(SankeyNode, { ...props }),
1342
+ nodePadding: 18,
1343
+ nodeWidth: 12,
1344
+ onClick: (item, type) => onSelect?.(
1345
+ createComponentSelection(component, {
1346
+ element: type,
1347
+ index: item.index,
1348
+ value: "payload" in item ? item.payload.value : void 0
1349
+ })
1350
+ ),
1351
+ children: /* @__PURE__ */ jsx2(
1352
+ Tooltip,
1353
+ {
1354
+ content: /* @__PURE__ */ jsx2(ComponentTooltip, { series: [{ dataKey: "value", format: component.format }] }),
1355
+ isAnimationActive: false
1356
+ }
1357
+ )
1358
+ }
1359
+ ) })
1360
+ }
1361
+ ),
1362
+ /* @__PURE__ */ jsx2(
1363
+ "div",
1364
+ {
1365
+ "aria-label": "Chart encoding",
1366
+ className: "aui-legend",
1367
+ "data-slot": "agent-ui-chart-legend",
1368
+ role: "list",
1369
+ children: /* @__PURE__ */ jsxs2("span", { className: "aui-legend__item", "data-slot": "agent-ui-chart-legend-item", role: "listitem", children: [
1370
+ /* @__PURE__ */ jsx2("span", { className: "aui-legend__flow" }),
1371
+ /* @__PURE__ */ jsx2("span", { className: "aui-legend__label", children: "Flow volume" })
1372
+ ] })
1373
+ }
1374
+ )
1375
+ ]
1376
+ }
1377
+ );
1378
+ }
1379
+ export {
1380
+ AreaChartComponentContent,
1381
+ BarChartComponentContent,
1382
+ ComposedChartComponentContent,
1383
+ DonutChartComponentContent,
1384
+ HeatmapComponentContent,
1385
+ LineChartComponentContent,
1386
+ PieChartComponentContent,
1387
+ RadarChartComponentContent,
1388
+ RadialChartComponentContent,
1389
+ SankeyChartComponentContent,
1390
+ ScatterChartComponentContent
1391
+ };