@almadar/ui 4.51.13 → 4.51.15

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.
@@ -3603,6 +3603,67 @@ var init_Radio = __esm({
3603
3603
  Radio.displayName = "Radio";
3604
3604
  }
3605
3605
  });
3606
+ var COLOR_VAR, Sparkline;
3607
+ var init_Sparkline = __esm({
3608
+ "components/atoms/Sparkline.tsx"() {
3609
+ init_cn();
3610
+ COLOR_VAR = {
3611
+ primary: "var(--color-primary)",
3612
+ success: "var(--color-success)",
3613
+ warning: "var(--color-warning)",
3614
+ error: "var(--color-error)",
3615
+ info: "var(--color-info)",
3616
+ muted: "var(--color-muted-foreground)"
3617
+ };
3618
+ Sparkline = ({
3619
+ data,
3620
+ color = "auto",
3621
+ width = 80,
3622
+ height = 32,
3623
+ strokeWidth = 2,
3624
+ fill = false,
3625
+ className
3626
+ }) => {
3627
+ if (data.length < 2) return null;
3628
+ const pad = 2;
3629
+ const min = Math.min(...data);
3630
+ const max = Math.max(...data);
3631
+ const range = max - min || 1;
3632
+ const points = data.map((v, i) => {
3633
+ const x = pad + i / (data.length - 1) * (width - pad * 2);
3634
+ const y = pad + (1 - (v - min) / range) * (height - pad * 2);
3635
+ return `${x},${y}`;
3636
+ }).join(" ");
3637
+ const resolvedColor = color === "auto" ? data[data.length - 1] >= data[0] ? COLOR_VAR.success : COLOR_VAR.error : COLOR_VAR[color];
3638
+ const areaPath = fill ? `M ${pad},${height - pad} L ${points.split(" ").join(" L ")} L ${width - pad},${height - pad} Z` : null;
3639
+ return /* @__PURE__ */ jsxs(
3640
+ "svg",
3641
+ {
3642
+ width,
3643
+ height,
3644
+ viewBox: `0 0 ${width} ${height}`,
3645
+ className: cn("flex-shrink-0", className),
3646
+ "aria-hidden": "true",
3647
+ children: [
3648
+ areaPath && /* @__PURE__ */ jsx("path", { d: areaPath, fill: resolvedColor, opacity: 0.15 }),
3649
+ /* @__PURE__ */ jsx(
3650
+ "polyline",
3651
+ {
3652
+ fill: "none",
3653
+ stroke: resolvedColor,
3654
+ strokeWidth,
3655
+ strokeLinecap: "round",
3656
+ strokeLinejoin: "round",
3657
+ points
3658
+ }
3659
+ )
3660
+ ]
3661
+ }
3662
+ );
3663
+ };
3664
+ Sparkline.displayName = "Sparkline";
3665
+ }
3666
+ });
3606
3667
  var Switch;
3607
3668
  var init_Switch = __esm({
3608
3669
  "components/atoms/Switch.tsx"() {
@@ -9276,7 +9337,7 @@ var init_MapView = __esm({
9276
9337
  shadowSize: [41, 41]
9277
9338
  });
9278
9339
  L.Marker.prototype.options.icon = defaultIcon;
9279
- const { useEffect: useEffect67, useRef: useRef65, useCallback: useCallback110, useState: useState95 } = React81__default;
9340
+ const { useEffect: useEffect67, useRef: useRef65, useCallback: useCallback112, useState: useState96 } = React81__default;
9280
9341
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
9281
9342
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
9282
9343
  function MapUpdater({ centerLat, centerLng, zoom }) {
@@ -9321,8 +9382,8 @@ var init_MapView = __esm({
9321
9382
  showAttribution = true
9322
9383
  }) {
9323
9384
  const eventBus = useEventBus2();
9324
- const [clickedPosition, setClickedPosition] = useState95(null);
9325
- const handleMapClick = useCallback110((lat, lng) => {
9385
+ const [clickedPosition, setClickedPosition] = useState96(null);
9386
+ const handleMapClick = useCallback112((lat, lng) => {
9326
9387
  if (showClickedPin) {
9327
9388
  setClickedPosition({ lat, lng });
9328
9389
  }
@@ -9331,7 +9392,7 @@ var init_MapView = __esm({
9331
9392
  eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
9332
9393
  }
9333
9394
  }, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
9334
- const handleMarkerClick = useCallback110((marker) => {
9395
+ const handleMarkerClick = useCallback112((marker) => {
9335
9396
  onMarkerClick?.(marker);
9336
9397
  if (markerClickEvent) {
9337
9398
  eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
@@ -19231,7 +19292,7 @@ var init_CastleTemplate = __esm({
19231
19292
  CastleTemplate.displayName = "CastleTemplate";
19232
19293
  }
19233
19294
  });
19234
- var CHART_COLORS, BarChart, PieChart, LineChart, Chart;
19295
+ var CHART_COLORS, seriesColor, monthFormatter, formatTimeLabel, BarChart, PieChart, LineChart, ScatterChart, Chart;
19235
19296
  var init_Chart = __esm({
19236
19297
  "components/organisms/Chart.tsx"() {
19237
19298
  "use client";
@@ -19251,38 +19312,159 @@ var init_Chart = __esm({
19251
19312
  "var(--color-info)",
19252
19313
  "var(--color-accent)"
19253
19314
  ];
19254
- BarChart = ({ data, height, showValues }) => {
19255
- const maxValue = Math.max(...data.map((d) => d.value), 1);
19256
- return /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "end", className: "w-full", style: { height }, children: data.map((point, idx) => {
19257
- const barHeight = point.value / maxValue * 100;
19258
- const color = point.color || CHART_COLORS[idx % CHART_COLORS.length];
19259
- return /* @__PURE__ */ jsxs(VStack, { gap: "xs", align: "center", flex: true, className: "min-w-0", children: [
19260
- showValues && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", className: "tabular-nums", children: point.value }),
19261
- /* @__PURE__ */ jsx(
19262
- Box,
19263
- {
19264
- className: cn(
19265
- "w-full rounded-t-sm transition-all duration-500 ease-out min-h-[4px]"
19266
- ),
19267
- style: {
19268
- height: `${barHeight}%`,
19269
- backgroundColor: color
19270
- }
19315
+ seriesColor = (series, idx) => series.color ?? CHART_COLORS[idx % CHART_COLORS.length];
19316
+ monthFormatter = new Intl.DateTimeFormat(void 0, {
19317
+ month: "short",
19318
+ year: "2-digit"
19319
+ });
19320
+ formatTimeLabel = (raw) => {
19321
+ const parsed = new Date(raw);
19322
+ if (Number.isNaN(parsed.getTime())) return raw;
19323
+ return monthFormatter.format(parsed);
19324
+ };
19325
+ BarChart = ({ series, height, showValues, stack, timeAxis, histogram = false, onPointClick }) => {
19326
+ const categories = useMemo(() => {
19327
+ const set = [];
19328
+ const seen = /* @__PURE__ */ new Set();
19329
+ for (const s of series) {
19330
+ for (const p2 of s.data) {
19331
+ if (!seen.has(p2.label)) {
19332
+ seen.add(p2.label);
19333
+ set.push(p2.label);
19271
19334
  }
19272
- ),
19273
- /* @__PURE__ */ jsx(
19274
- Typography,
19275
- {
19276
- variant: "caption",
19277
- color: "secondary",
19278
- className: "truncate w-full text-center",
19279
- children: point.label
19335
+ }
19336
+ }
19337
+ return set;
19338
+ }, [series]);
19339
+ const valueAt = useCallback(
19340
+ (s, label) => {
19341
+ const p2 = s.data.find((d) => d.label === label);
19342
+ return p2 ? p2.value : 0;
19343
+ },
19344
+ []
19345
+ );
19346
+ const columnTotals = useMemo(() => {
19347
+ if (stack === "none") return null;
19348
+ return categories.map(
19349
+ (label) => series.reduce((sum, s) => sum + valueAt(s, label), 0)
19350
+ );
19351
+ }, [categories, series, stack, valueAt]);
19352
+ const maxValue = useMemo(() => {
19353
+ if (stack === "normalize") return 100;
19354
+ if (stack === "stack" && columnTotals) {
19355
+ return Math.max(...columnTotals, 1);
19356
+ }
19357
+ let m = 1;
19358
+ for (const s of series) {
19359
+ for (const p2 of s.data) if (p2.value > m) m = p2.value;
19360
+ }
19361
+ return m;
19362
+ }, [series, stack, columnTotals]);
19363
+ return /* @__PURE__ */ jsx(
19364
+ HStack,
19365
+ {
19366
+ gap: histogram ? "none" : "xs",
19367
+ align: "end",
19368
+ className: "w-full",
19369
+ style: { height },
19370
+ children: categories.map((label, catIdx) => {
19371
+ const displayLabel = timeAxis ? formatTimeLabel(label) : label;
19372
+ if (stack === "none") {
19373
+ return /* @__PURE__ */ jsxs(
19374
+ VStack,
19375
+ {
19376
+ gap: "xs",
19377
+ align: "center",
19378
+ flex: true,
19379
+ className: "min-w-0",
19380
+ children: [
19381
+ /* @__PURE__ */ jsx(HStack, { gap: histogram ? "none" : "xs", align: "end", className: "w-full", style: { height: "100%" }, children: series.map((s, sIdx) => {
19382
+ const value = valueAt(s, label);
19383
+ const barHeight = value / maxValue * 100;
19384
+ const color = seriesColor(s, sIdx);
19385
+ return /* @__PURE__ */ jsx(
19386
+ Box,
19387
+ {
19388
+ className: cn(
19389
+ "rounded-t-sm transition-all duration-500 ease-out min-h-[4px] cursor-pointer hover:opacity-80",
19390
+ histogram ? "flex-1 mx-0" : "flex-1"
19391
+ ),
19392
+ style: {
19393
+ height: `${barHeight}%`,
19394
+ backgroundColor: color
19395
+ },
19396
+ onClick: () => onPointClick?.(
19397
+ { label, value, color },
19398
+ s.name
19399
+ ),
19400
+ title: `${s.name}: ${value}`
19401
+ },
19402
+ s.name
19403
+ );
19404
+ }) }),
19405
+ showValues && series.length === 1 && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", className: "tabular-nums", children: valueAt(series[0], label) }),
19406
+ /* @__PURE__ */ jsx(
19407
+ Typography,
19408
+ {
19409
+ variant: "caption",
19410
+ color: "secondary",
19411
+ className: "truncate w-full text-center",
19412
+ children: displayLabel
19413
+ }
19414
+ )
19415
+ ]
19416
+ },
19417
+ label
19418
+ );
19280
19419
  }
19281
- )
19282
- ] }, point.label);
19283
- }) });
19420
+ const total = columnTotals?.[catIdx] ?? 1;
19421
+ return /* @__PURE__ */ jsxs(
19422
+ VStack,
19423
+ {
19424
+ gap: "xs",
19425
+ align: "center",
19426
+ flex: true,
19427
+ className: "min-w-0",
19428
+ children: [
19429
+ /* @__PURE__ */ jsx(VStack, { gap: "none", className: "w-full", style: { height: "100%" }, justify: "end", children: series.map((s, sIdx) => {
19430
+ const value = valueAt(s, label);
19431
+ const ratio = stack === "normalize" ? total === 0 ? 0 : value / total * 100 : value / maxValue * 100;
19432
+ const color = seriesColor(s, sIdx);
19433
+ return /* @__PURE__ */ jsx(
19434
+ Box,
19435
+ {
19436
+ className: "w-full transition-all duration-500 ease-out cursor-pointer hover:opacity-80",
19437
+ style: {
19438
+ height: `${ratio}%`,
19439
+ backgroundColor: color
19440
+ },
19441
+ onClick: () => onPointClick?.(
19442
+ { label, value, color },
19443
+ s.name
19444
+ ),
19445
+ title: `${s.name}: ${value}`
19446
+ },
19447
+ s.name
19448
+ );
19449
+ }) }),
19450
+ /* @__PURE__ */ jsx(
19451
+ Typography,
19452
+ {
19453
+ variant: "caption",
19454
+ color: "secondary",
19455
+ className: "truncate w-full text-center",
19456
+ children: displayLabel
19457
+ }
19458
+ )
19459
+ ]
19460
+ },
19461
+ label
19462
+ );
19463
+ })
19464
+ }
19465
+ );
19284
19466
  };
19285
- PieChart = ({ data, height, showValues, donut = false }) => {
19467
+ PieChart = ({ data, height, showValues, donut = false, onPointClick }) => {
19286
19468
  const total = data.reduce((sum, d) => sum + d.value, 0);
19287
19469
  const size = Math.min(height, 200);
19288
19470
  const radius = size / 2 - 8;
@@ -19328,7 +19510,11 @@ var init_Chart = __esm({
19328
19510
  fill: seg.color,
19329
19511
  stroke: "var(--color-card)",
19330
19512
  strokeWidth: "2",
19331
- className: "transition-opacity duration-200 hover:opacity-80"
19513
+ className: "transition-opacity duration-200 hover:opacity-80 cursor-pointer",
19514
+ onClick: () => onPointClick?.(
19515
+ { label: seg.label, value: seg.value, color: seg.color },
19516
+ "default"
19517
+ )
19332
19518
  },
19333
19519
  idx
19334
19520
  )),
@@ -19363,56 +19549,243 @@ var init_Chart = __esm({
19363
19549
  ] }, idx)) })
19364
19550
  ] });
19365
19551
  };
19366
- LineChart = ({ data, height, showValues, fill = false }) => {
19367
- const maxValue = Math.max(...data.map((d) => d.value), 1);
19552
+ LineChart = ({ series, height, showValues, fill = false, timeAxis, onPointClick }) => {
19368
19553
  const width = 400;
19369
19554
  const padding = { top: 20, right: 20, bottom: 30, left: 40 };
19370
19555
  const chartWidth = width - padding.left - padding.right;
19371
19556
  const chartHeight = height - padding.top - padding.bottom;
19372
- const points = useMemo(() => {
19373
- return data.map((point, idx) => ({
19374
- x: padding.left + idx / Math.max(data.length - 1, 1) * chartWidth,
19375
- y: padding.top + chartHeight - point.value / maxValue * chartHeight,
19376
- ...point
19377
- }));
19378
- }, [data, maxValue, chartWidth, chartHeight, padding]);
19379
- const linePath = points.map((p2, i) => `${i === 0 ? "M" : "L"} ${p2.x} ${p2.y}`).join(" ");
19380
- const areaPath = `${linePath} L ${points[points.length - 1]?.x ?? 0} ${padding.top + chartHeight} L ${padding.left} ${padding.top + chartHeight} Z`;
19381
- return /* @__PURE__ */ jsxs("svg", { width: "100%", height, viewBox: `0 0 ${width} ${height}`, preserveAspectRatio: "xMidYMid meet", children: [
19382
- [0, 0.25, 0.5, 0.75, 1].map((frac) => {
19383
- const y = padding.top + chartHeight * (1 - frac);
19384
- return /* @__PURE__ */ jsx(
19385
- "line",
19386
- {
19387
- x1: padding.left,
19388
- y1: y,
19389
- x2: width - padding.right,
19390
- y2: y,
19391
- stroke: "var(--color-border)",
19392
- strokeDasharray: "4 4",
19393
- opacity: 0.5
19394
- },
19395
- frac
19396
- );
19397
- }),
19398
- fill && /* @__PURE__ */ jsx("path", { d: areaPath, fill: "var(--color-primary)", opacity: 0.1 }),
19399
- /* @__PURE__ */ jsx("path", { d: linePath, fill: "none", stroke: "var(--color-primary)", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }),
19400
- points.map((p2, idx) => /* @__PURE__ */ jsxs("g", { children: [
19401
- /* @__PURE__ */ jsx("circle", { cx: p2.x, cy: p2.y, r: "4", fill: "var(--color-card)", stroke: "var(--color-primary)", strokeWidth: "2" }),
19402
- showValues && /* @__PURE__ */ jsx("text", { x: p2.x, y: p2.y - 10, textAnchor: "middle", fill: "var(--color-foreground)", fontSize: "10", fontWeight: "500", children: p2.value }),
19403
- /* @__PURE__ */ jsx(
19404
- "text",
19405
- {
19406
- x: p2.x,
19407
- y: height - 8,
19408
- textAnchor: "middle",
19409
- fill: "var(--color-muted-foreground)",
19410
- fontSize: "9",
19411
- children: p2.label
19557
+ const labels = useMemo(() => {
19558
+ const seen = /* @__PURE__ */ new Set();
19559
+ const out = [];
19560
+ for (const s of series) {
19561
+ for (const p2 of s.data) {
19562
+ if (!seen.has(p2.label)) {
19563
+ seen.add(p2.label);
19564
+ out.push(p2.label);
19412
19565
  }
19413
- )
19414
- ] }, idx))
19415
- ] });
19566
+ }
19567
+ }
19568
+ return out;
19569
+ }, [series]);
19570
+ const maxValue = useMemo(() => {
19571
+ let m = 1;
19572
+ for (const s of series) {
19573
+ for (const p2 of s.data) if (p2.value > m) m = p2.value;
19574
+ }
19575
+ return m;
19576
+ }, [series]);
19577
+ const xFor = useCallback(
19578
+ (idx) => padding.left + idx / Math.max(labels.length - 1, 1) * chartWidth,
19579
+ [labels.length, chartWidth, padding.left]
19580
+ );
19581
+ const yFor = useCallback(
19582
+ (value) => padding.top + chartHeight - value / maxValue * chartHeight,
19583
+ [maxValue, chartHeight, padding.top]
19584
+ );
19585
+ return /* @__PURE__ */ jsxs(
19586
+ "svg",
19587
+ {
19588
+ width: "100%",
19589
+ height,
19590
+ viewBox: `0 0 ${width} ${height}`,
19591
+ preserveAspectRatio: "xMidYMid meet",
19592
+ children: [
19593
+ [0, 0.25, 0.5, 0.75, 1].map((frac) => {
19594
+ const y = padding.top + chartHeight * (1 - frac);
19595
+ return /* @__PURE__ */ jsx(
19596
+ "line",
19597
+ {
19598
+ x1: padding.left,
19599
+ y1: y,
19600
+ x2: width - padding.right,
19601
+ y2: y,
19602
+ stroke: "var(--color-border)",
19603
+ strokeDasharray: "4 4",
19604
+ opacity: 0.5
19605
+ },
19606
+ frac
19607
+ );
19608
+ }),
19609
+ series.map((s, sIdx) => {
19610
+ const color = seriesColor(s, sIdx);
19611
+ const points = labels.map((label, idx) => {
19612
+ const point = s.data.find((d) => d.label === label);
19613
+ return {
19614
+ x: xFor(idx),
19615
+ y: yFor(point ? point.value : 0),
19616
+ value: point ? point.value : 0,
19617
+ label
19618
+ };
19619
+ });
19620
+ const linePath = points.map((p2, i) => `${i === 0 ? "M" : "L"} ${p2.x} ${p2.y}`).join(" ");
19621
+ const areaPath = `${linePath} L ${points[points.length - 1]?.x ?? 0} ${padding.top + chartHeight} L ${padding.left} ${padding.top + chartHeight} Z`;
19622
+ return /* @__PURE__ */ jsxs("g", { children: [
19623
+ fill && /* @__PURE__ */ jsx(
19624
+ "path",
19625
+ {
19626
+ d: areaPath,
19627
+ fill: color,
19628
+ opacity: series.length > 1 ? 0.08 : 0.1
19629
+ }
19630
+ ),
19631
+ /* @__PURE__ */ jsx(
19632
+ "path",
19633
+ {
19634
+ d: linePath,
19635
+ fill: "none",
19636
+ stroke: color,
19637
+ strokeWidth: "2",
19638
+ strokeLinecap: "round",
19639
+ strokeLinejoin: "round",
19640
+ strokeDasharray: s.dashed ? "6 4" : void 0
19641
+ }
19642
+ ),
19643
+ points.map((p2, idx) => /* @__PURE__ */ jsxs("g", { children: [
19644
+ /* @__PURE__ */ jsx(
19645
+ "circle",
19646
+ {
19647
+ cx: p2.x,
19648
+ cy: p2.y,
19649
+ r: "4",
19650
+ fill: "var(--color-card)",
19651
+ stroke: color,
19652
+ strokeWidth: "2",
19653
+ className: "cursor-pointer",
19654
+ onClick: () => onPointClick?.(
19655
+ { label: p2.label, value: p2.value, color },
19656
+ s.name
19657
+ )
19658
+ }
19659
+ ),
19660
+ showValues && series.length === 1 && /* @__PURE__ */ jsx(
19661
+ "text",
19662
+ {
19663
+ x: p2.x,
19664
+ y: p2.y - 10,
19665
+ textAnchor: "middle",
19666
+ fill: "var(--color-foreground)",
19667
+ fontSize: "10",
19668
+ fontWeight: "500",
19669
+ children: p2.value
19670
+ }
19671
+ )
19672
+ ] }, idx))
19673
+ ] }, s.name);
19674
+ }),
19675
+ labels.map((label, idx) => /* @__PURE__ */ jsx(
19676
+ "text",
19677
+ {
19678
+ x: xFor(idx),
19679
+ y: height - 8,
19680
+ textAnchor: "middle",
19681
+ fill: "var(--color-muted-foreground)",
19682
+ fontSize: "9",
19683
+ children: timeAxis ? formatTimeLabel(label) : label
19684
+ },
19685
+ label
19686
+ ))
19687
+ ]
19688
+ }
19689
+ );
19690
+ };
19691
+ ScatterChart = ({ data, height, onPointClick }) => {
19692
+ const width = 400;
19693
+ const padding = { top: 20, right: 20, bottom: 30, left: 40 };
19694
+ const chartWidth = width - padding.left - padding.right;
19695
+ const chartHeight = height - padding.top - padding.bottom;
19696
+ const { minX, maxX, minY, maxY } = useMemo(() => {
19697
+ if (data.length === 0) {
19698
+ return { minX: 0, maxX: 1, minY: 0, maxY: 1 };
19699
+ }
19700
+ let mnX = data[0].x;
19701
+ let mxX = data[0].x;
19702
+ let mnY = data[0].y;
19703
+ let mxY = data[0].y;
19704
+ for (const p2 of data) {
19705
+ if (p2.x < mnX) mnX = p2.x;
19706
+ if (p2.x > mxX) mxX = p2.x;
19707
+ if (p2.y < mnY) mnY = p2.y;
19708
+ if (p2.y > mxY) mxY = p2.y;
19709
+ }
19710
+ return { minX: mnX, maxX: mxX, minY: mnY, maxY: mxY };
19711
+ }, [data]);
19712
+ const rangeX = maxX - minX || 1;
19713
+ const rangeY = maxY - minY || 1;
19714
+ return /* @__PURE__ */ jsxs(
19715
+ "svg",
19716
+ {
19717
+ width: "100%",
19718
+ height,
19719
+ viewBox: `0 0 ${width} ${height}`,
19720
+ preserveAspectRatio: "xMidYMid meet",
19721
+ children: [
19722
+ [0, 0.25, 0.5, 0.75, 1].map((frac) => {
19723
+ const y = padding.top + chartHeight * (1 - frac);
19724
+ return /* @__PURE__ */ jsx(
19725
+ "line",
19726
+ {
19727
+ x1: padding.left,
19728
+ y1: y,
19729
+ x2: width - padding.right,
19730
+ y2: y,
19731
+ stroke: "var(--color-border)",
19732
+ strokeDasharray: "4 4",
19733
+ opacity: 0.5
19734
+ },
19735
+ frac
19736
+ );
19737
+ }),
19738
+ data.map((p2, idx) => {
19739
+ const cx = padding.left + (p2.x - minX) / rangeX * chartWidth;
19740
+ const cy = padding.top + chartHeight - (p2.y - minY) / rangeY * chartHeight;
19741
+ const r = p2.size ?? 5;
19742
+ const color = p2.color ?? CHART_COLORS[idx % CHART_COLORS.length];
19743
+ return /* @__PURE__ */ jsx(
19744
+ "circle",
19745
+ {
19746
+ cx,
19747
+ cy,
19748
+ r,
19749
+ fill: color,
19750
+ opacity: 0.7,
19751
+ className: "cursor-pointer hover:opacity-100",
19752
+ onClick: () => onPointClick?.(
19753
+ {
19754
+ label: p2.label ?? `(${p2.x}, ${p2.y})`,
19755
+ value: p2.y,
19756
+ color
19757
+ },
19758
+ "default"
19759
+ ),
19760
+ children: /* @__PURE__ */ jsx("title", { children: p2.label ?? `(${p2.x}, ${p2.y})` })
19761
+ },
19762
+ idx
19763
+ );
19764
+ }),
19765
+ /* @__PURE__ */ jsx(
19766
+ "text",
19767
+ {
19768
+ x: padding.left,
19769
+ y: height - 8,
19770
+ fill: "var(--color-muted-foreground)",
19771
+ fontSize: "9",
19772
+ children: minX.toFixed(1)
19773
+ }
19774
+ ),
19775
+ /* @__PURE__ */ jsx(
19776
+ "text",
19777
+ {
19778
+ x: width - padding.right,
19779
+ y: height - 8,
19780
+ textAnchor: "end",
19781
+ fill: "var(--color-muted-foreground)",
19782
+ fontSize: "9",
19783
+ children: maxX.toFixed(1)
19784
+ }
19785
+ )
19786
+ ]
19787
+ }
19788
+ );
19416
19789
  };
19417
19790
  Chart = ({
19418
19791
  title,
@@ -19420,9 +19793,13 @@ var init_Chart = __esm({
19420
19793
  chartType = "bar",
19421
19794
  series,
19422
19795
  data: simpleData,
19796
+ scatterData,
19423
19797
  height = 200,
19424
19798
  showLegend = true,
19425
19799
  showValues = false,
19800
+ stack = "none",
19801
+ timeAxis = false,
19802
+ drillEvent,
19426
19803
  actions,
19427
19804
  entity,
19428
19805
  isLoading = false,
@@ -19439,11 +19816,25 @@ var init_Chart = __esm({
19439
19816
  },
19440
19817
  [eventBus]
19441
19818
  );
19442
- const normalizedData = useMemo(() => {
19443
- if (simpleData) return simpleData;
19444
- if (series && series.length > 0) return series[0].data;
19819
+ const handlePointClick = useCallback(
19820
+ (point, seriesName) => {
19821
+ if (drillEvent) {
19822
+ eventBus.emit(`UI:${drillEvent}`, {
19823
+ label: point.label,
19824
+ value: point.value,
19825
+ seriesLabel: seriesName === "default" ? void 0 : seriesName
19826
+ });
19827
+ }
19828
+ },
19829
+ [drillEvent, eventBus]
19830
+ );
19831
+ const normalizedSeries = useMemo(() => {
19832
+ if (series && series.length > 0) return series;
19833
+ if (simpleData) return [{ name: "default", data: simpleData }];
19445
19834
  return [];
19446
19835
  }, [simpleData, series]);
19836
+ const firstSeriesData = normalizedSeries[0]?.data ?? [];
19837
+ const hasContent = chartType === "scatter" ? (scatterData?.length ?? 0) > 0 : normalizedSeries.some((s) => s.data.length > 0);
19447
19838
  if (isLoading) {
19448
19839
  return /* @__PURE__ */ jsx(LoadingState, { message: "Loading chart...", className });
19449
19840
  }
@@ -19457,7 +19848,7 @@ var init_Chart = __esm({
19457
19848
  }
19458
19849
  );
19459
19850
  }
19460
- if (normalizedData.length === 0) {
19851
+ if (!hasContent) {
19461
19852
  return /* @__PURE__ */ jsx(EmptyState, { title: t("empty.noData"), description: t("empty.noData"), className });
19462
19853
  }
19463
19854
  return /* @__PURE__ */ jsx(Card, { className: cn("p-6", className), children: /* @__PURE__ */ jsxs(VStack, { gap: "md", children: [
@@ -19478,18 +19869,84 @@ var init_Chart = __esm({
19478
19869
  )) })
19479
19870
  ] }),
19480
19871
  /* @__PURE__ */ jsxs(Box, { className: "w-full", children: [
19481
- chartType === "bar" && /* @__PURE__ */ jsx(BarChart, { data: normalizedData, height, showValues }),
19482
- chartType === "line" && /* @__PURE__ */ jsx(LineChart, { data: normalizedData, height, showValues }),
19483
- chartType === "area" && /* @__PURE__ */ jsx(LineChart, { data: normalizedData, height, showValues, fill: true }),
19484
- chartType === "pie" && /* @__PURE__ */ jsx(PieChart, { data: normalizedData, height, showValues: showLegend }),
19485
- chartType === "donut" && /* @__PURE__ */ jsx(PieChart, { data: normalizedData, height, showValues: showLegend, donut: true })
19872
+ chartType === "bar" && /* @__PURE__ */ jsx(
19873
+ BarChart,
19874
+ {
19875
+ series: normalizedSeries,
19876
+ height,
19877
+ showValues,
19878
+ stack,
19879
+ timeAxis,
19880
+ onPointClick: handlePointClick
19881
+ }
19882
+ ),
19883
+ chartType === "histogram" && /* @__PURE__ */ jsx(
19884
+ BarChart,
19885
+ {
19886
+ series: normalizedSeries,
19887
+ height,
19888
+ showValues,
19889
+ stack: "none",
19890
+ timeAxis: false,
19891
+ histogram: true,
19892
+ onPointClick: handlePointClick
19893
+ }
19894
+ ),
19895
+ chartType === "line" && /* @__PURE__ */ jsx(
19896
+ LineChart,
19897
+ {
19898
+ series: normalizedSeries,
19899
+ height,
19900
+ showValues,
19901
+ timeAxis,
19902
+ onPointClick: handlePointClick
19903
+ }
19904
+ ),
19905
+ chartType === "area" && /* @__PURE__ */ jsx(
19906
+ LineChart,
19907
+ {
19908
+ series: normalizedSeries,
19909
+ height,
19910
+ showValues,
19911
+ timeAxis,
19912
+ fill: true,
19913
+ onPointClick: handlePointClick
19914
+ }
19915
+ ),
19916
+ chartType === "pie" && /* @__PURE__ */ jsx(
19917
+ PieChart,
19918
+ {
19919
+ data: firstSeriesData,
19920
+ height,
19921
+ showValues: showLegend,
19922
+ onPointClick: handlePointClick
19923
+ }
19924
+ ),
19925
+ chartType === "donut" && /* @__PURE__ */ jsx(
19926
+ PieChart,
19927
+ {
19928
+ data: firstSeriesData,
19929
+ height,
19930
+ showValues: showLegend,
19931
+ donut: true,
19932
+ onPointClick: handlePointClick
19933
+ }
19934
+ ),
19935
+ chartType === "scatter" && /* @__PURE__ */ jsx(
19936
+ ScatterChart,
19937
+ {
19938
+ data: scatterData ?? [],
19939
+ height,
19940
+ onPointClick: handlePointClick
19941
+ }
19942
+ )
19486
19943
  ] }),
19487
- showLegend && series && series.length > 1 && /* @__PURE__ */ jsx(HStack, { gap: "md", justify: "center", wrap: true, children: series.map((s, idx) => /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
19944
+ showLegend && normalizedSeries.length > 1 && /* @__PURE__ */ jsx(HStack, { gap: "md", justify: "center", wrap: true, children: normalizedSeries.map((s, idx) => /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
19488
19945
  /* @__PURE__ */ jsx(
19489
19946
  Box,
19490
19947
  {
19491
19948
  className: "w-3 h-3 rounded-full flex-shrink-0",
19492
- style: { backgroundColor: s.color || CHART_COLORS[idx % CHART_COLORS.length] }
19949
+ style: { backgroundColor: seriesColor(s, idx) }
19493
19950
  }
19494
19951
  ),
19495
19952
  /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: s.name })
@@ -24405,6 +24862,151 @@ var init_FlipCard = __esm({
24405
24862
  FlipCard.displayName = "FlipCard";
24406
24863
  }
24407
24864
  });
24865
+ function toISODate(d) {
24866
+ return d.toISOString().slice(0, 10);
24867
+ }
24868
+ function startOfMonth(d) {
24869
+ return new Date(d.getFullYear(), d.getMonth(), 1);
24870
+ }
24871
+ function startOfQuarter(d) {
24872
+ return new Date(d.getFullYear(), Math.floor(d.getMonth() / 3) * 3, 1);
24873
+ }
24874
+ function startOfYear(d) {
24875
+ return new Date(d.getFullYear(), 0, 1);
24876
+ }
24877
+ function daysAgo(n) {
24878
+ const d = /* @__PURE__ */ new Date();
24879
+ d.setDate(d.getDate() - n);
24880
+ return d;
24881
+ }
24882
+ var DEFAULT_PRESETS, DateRangePicker;
24883
+ var init_DateRangePicker = __esm({
24884
+ "components/molecules/DateRangePicker.tsx"() {
24885
+ "use client";
24886
+ init_cn();
24887
+ init_Button();
24888
+ init_Input();
24889
+ init_Stack();
24890
+ init_Typography();
24891
+ init_useEventBus();
24892
+ DEFAULT_PRESETS = [
24893
+ {
24894
+ label: "Last 7 days",
24895
+ value: "7d",
24896
+ range: () => ({ from: toISODate(daysAgo(7)), to: toISODate(/* @__PURE__ */ new Date()) })
24897
+ },
24898
+ {
24899
+ label: "Last 30 days",
24900
+ value: "30d",
24901
+ range: () => ({ from: toISODate(daysAgo(30)), to: toISODate(/* @__PURE__ */ new Date()) })
24902
+ },
24903
+ {
24904
+ label: "This Month",
24905
+ value: "month",
24906
+ range: () => ({ from: toISODate(startOfMonth(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) })
24907
+ },
24908
+ {
24909
+ label: "This Quarter",
24910
+ value: "quarter",
24911
+ range: () => ({ from: toISODate(startOfQuarter(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) })
24912
+ },
24913
+ {
24914
+ label: "YTD",
24915
+ value: "ytd",
24916
+ range: () => ({ from: toISODate(startOfYear(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) })
24917
+ }
24918
+ ];
24919
+ DateRangePicker = ({
24920
+ from: fromProp,
24921
+ to: toProp,
24922
+ event,
24923
+ onChange,
24924
+ presets = DEFAULT_PRESETS,
24925
+ fromLabel = "From",
24926
+ toLabel = "To",
24927
+ className
24928
+ }) => {
24929
+ const eventBus = useEventBus();
24930
+ const [from, setFrom] = useState(fromProp ?? "");
24931
+ const [to, setTo] = useState(toProp ?? "");
24932
+ const [activePreset, setActivePreset] = useState(null);
24933
+ const emit = useCallback(
24934
+ (range) => {
24935
+ onChange?.(range);
24936
+ if (event) eventBus.emit(`UI:${event}`, range);
24937
+ },
24938
+ [onChange, event, eventBus]
24939
+ );
24940
+ const handleFromChange = useCallback(
24941
+ (next) => {
24942
+ setFrom(next);
24943
+ setActivePreset(null);
24944
+ emit({ from: next, to });
24945
+ },
24946
+ [to, emit]
24947
+ );
24948
+ const handleToChange = useCallback(
24949
+ (next) => {
24950
+ setTo(next);
24951
+ setActivePreset(null);
24952
+ emit({ from, to: next });
24953
+ },
24954
+ [from, emit]
24955
+ );
24956
+ const handlePreset = useCallback(
24957
+ (preset) => {
24958
+ const range = preset.range();
24959
+ setFrom(range.from);
24960
+ setTo(range.to);
24961
+ setActivePreset(preset.value);
24962
+ emit(range);
24963
+ },
24964
+ [emit]
24965
+ );
24966
+ const presetButtons = useMemo(
24967
+ () => presets.map((preset) => /* @__PURE__ */ jsx(
24968
+ Button,
24969
+ {
24970
+ variant: activePreset === preset.value ? "primary" : "ghost",
24971
+ size: "sm",
24972
+ onClick: () => handlePreset(preset),
24973
+ children: preset.label
24974
+ },
24975
+ preset.value
24976
+ )),
24977
+ [presets, activePreset, handlePreset]
24978
+ );
24979
+ return /* @__PURE__ */ jsxs(VStack, { gap: "sm", className: cn(className), children: [
24980
+ /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "end", children: [
24981
+ /* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
24982
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: fromLabel }),
24983
+ /* @__PURE__ */ jsx(
24984
+ Input,
24985
+ {
24986
+ type: "date",
24987
+ value: from,
24988
+ onChange: (e) => handleFromChange(e.target.value)
24989
+ }
24990
+ )
24991
+ ] }),
24992
+ /* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
24993
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: toLabel }),
24994
+ /* @__PURE__ */ jsx(
24995
+ Input,
24996
+ {
24997
+ type: "date",
24998
+ value: to,
24999
+ onChange: (e) => handleToChange(e.target.value)
25000
+ }
25001
+ )
25002
+ ] })
25003
+ ] }),
25004
+ presets.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", wrap: true, children: presetButtons })
25005
+ ] });
25006
+ };
25007
+ DateRangePicker.displayName = "DateRangePicker";
25008
+ }
25009
+ });
24408
25010
  var DEFAULT_OPTIONS, DateRangeSelector;
24409
25011
  var init_DateRangeSelector = __esm({
24410
25012
  "components/molecules/DateRangeSelector.tsx"() {
@@ -27376,7 +27978,9 @@ var init_StatDisplay = __esm({
27376
27978
  init_Typography();
27377
27979
  init_Box();
27378
27980
  init_Stack();
27981
+ init_Sparkline();
27379
27982
  init_Icon();
27983
+ init_useEventBus();
27380
27984
  variantColor = {
27381
27985
  default: "text-foreground",
27382
27986
  primary: "text-primary",
@@ -27391,6 +27995,10 @@ var init_StatDisplay = __esm({
27391
27995
  max,
27392
27996
  target,
27393
27997
  trend,
27998
+ trendPolarity = "higher-is-better",
27999
+ trendFormat = "absolute",
28000
+ sparklineData,
28001
+ clickEvent,
27394
28002
  prefix,
27395
28003
  suffix,
27396
28004
  icon: iconProp,
@@ -27404,6 +28012,10 @@ var init_StatDisplay = __esm({
27404
28012
  isLoading = false,
27405
28013
  error = null
27406
28014
  }) => {
28015
+ const eventBus = useEventBus();
28016
+ const handleClick = useCallback(() => {
28017
+ if (clickEvent) eventBus.emit(`UI:${clickEvent}`, { metricLabel: label });
28018
+ }, [clickEvent, eventBus, label]);
27407
28019
  const ResolvedIcon = typeof iconProp === "string" ? resolveIcon(iconProp) : null;
27408
28020
  const iconSizes3 = { sm: "h-4 w-4", md: "h-5 w-5", lg: "h-6 w-6" };
27409
28021
  const valueSizes = { sm: "text-lg", md: "text-2xl", lg: "text-3xl" };
@@ -27414,7 +28026,10 @@ var init_StatDisplay = __esm({
27414
28026
  const targetPct = showTarget ? Math.max(0, Math.min(100, numericValue / target * 100)) : 0;
27415
28027
  const showTrend = typeof trend === "number" && trend !== 0 && Number.isFinite(trend);
27416
28028
  const trendUp = showTrend && trend > 0;
27417
- const trendLabel = showTrend ? `${trendUp ? "\u2191" : "\u2193"} ${Math.abs(trend)}` : "";
28029
+ const trendIsGood = trendPolarity === "lower-is-better" ? !trendUp : trendUp;
28030
+ const trendMagnitude = Math.abs(trend);
28031
+ const trendSuffix = trendFormat === "percent" ? "%" : "";
28032
+ const trendLabel = showTrend ? `${trendUp ? "\u2191" : "\u2193"} ${trendMagnitude}${trendSuffix}` : "";
27418
28033
  if (error) {
27419
28034
  return /* @__PURE__ */ jsx(Card, { className: cn(padSizes[size], className), children: /* @__PURE__ */ jsx(Typography, { variant: "small", color: "error", children: error.message }) });
27420
28035
  }
@@ -27425,38 +28040,57 @@ var init_StatDisplay = __esm({
27425
28040
  ] }) });
27426
28041
  }
27427
28042
  if (compact) {
27428
- return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: cn("items-center", className), children: [
27429
- ResolvedIcon && /* @__PURE__ */ jsx(ResolvedIcon, { className: cn(iconSizes3[size], iconColor) }),
27430
- typeof iconProp !== "string" && iconProp,
27431
- /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: label }),
27432
- /* @__PURE__ */ jsx(Typography, { variant: "h4", className: cn("font-bold", valueSizes[size], variantColor[variant]), children: displayValue }),
27433
- showTrend && /* @__PURE__ */ jsx(Typography, { variant: "caption", className: cn("font-semibold", trendUp ? "text-success" : "text-error"), children: trendLabel })
27434
- ] });
28043
+ return /* @__PURE__ */ jsxs(
28044
+ HStack,
28045
+ {
28046
+ gap: "sm",
28047
+ className: cn("items-center", clickEvent && "cursor-pointer hover:opacity-80", className),
28048
+ onClick: clickEvent ? handleClick : void 0,
28049
+ children: [
28050
+ ResolvedIcon && /* @__PURE__ */ jsx(ResolvedIcon, { className: cn(iconSizes3[size], iconColor) }),
28051
+ typeof iconProp !== "string" && iconProp,
28052
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: label }),
28053
+ /* @__PURE__ */ jsx(Typography, { variant: "h4", className: cn("font-bold", valueSizes[size], variantColor[variant]), children: displayValue }),
28054
+ showTrend && /* @__PURE__ */ jsx(Typography, { variant: "caption", className: cn("font-semibold", trendIsGood ? "text-success" : "text-error"), children: trendLabel }),
28055
+ sparklineData && sparklineData.length > 1 && /* @__PURE__ */ jsx(Sparkline, { data: sparklineData, color: "auto", width: 60, height: 20 })
28056
+ ]
28057
+ }
28058
+ );
27435
28059
  }
27436
- return /* @__PURE__ */ jsx(Card, { className: cn(padSizes[size], className), children: /* @__PURE__ */ jsxs(HStack, { align: "start", justify: "between", children: [
27437
- /* @__PURE__ */ jsxs(VStack, { gap: "none", className: "space-y-1 flex-1", children: [
27438
- /* @__PURE__ */ jsx(Typography, { variant: "overline", color: "secondary", children: label }),
27439
- /* @__PURE__ */ jsxs(HStack, { gap: "sm", align: "end", children: [
27440
- /* @__PURE__ */ jsx(Typography, { variant: "h4", className: cn("font-bold", valueSizes[size], variantColor[variant]), children: displayValue }),
27441
- showTrend && /* @__PURE__ */ jsx(
27442
- Typography,
27443
- {
27444
- variant: "caption",
27445
- className: cn("font-semibold pb-1", trendUp ? "text-success" : "text-error"),
27446
- children: trendLabel
27447
- }
27448
- )
27449
- ] }),
27450
- showTarget && /* @__PURE__ */ jsx(Box, { className: "mt-2 h-1.5 w-full bg-muted rounded-full overflow-hidden", children: /* @__PURE__ */ jsx(
27451
- Box,
27452
- {
27453
- className: cn("h-full rounded-full transition-all", `bg-${variant === "default" ? "primary" : variant}`),
27454
- style: { width: `${targetPct}%` }
27455
- }
27456
- ) })
27457
- ] }),
27458
- (ResolvedIcon || typeof iconProp !== "string" && iconProp) && /* @__PURE__ */ jsx(Box, { className: cn("p-3 rounded-md", iconBg), children: ResolvedIcon ? /* @__PURE__ */ jsx(ResolvedIcon, { className: cn(iconSizes3[size], iconColor) }) : iconProp })
27459
- ] }) });
28060
+ return /* @__PURE__ */ jsx(
28061
+ Card,
28062
+ {
28063
+ className: cn(padSizes[size], clickEvent && "cursor-pointer hover:shadow-md transition-shadow", className),
28064
+ onClick: clickEvent ? handleClick : void 0,
28065
+ children: /* @__PURE__ */ jsxs(HStack, { align: "start", justify: "between", children: [
28066
+ /* @__PURE__ */ jsxs(VStack, { gap: "none", className: "space-y-1 flex-1", children: [
28067
+ /* @__PURE__ */ jsx(Typography, { variant: "overline", color: "secondary", children: label }),
28068
+ /* @__PURE__ */ jsxs(HStack, { gap: "sm", align: "end", children: [
28069
+ /* @__PURE__ */ jsx(Typography, { variant: "h4", className: cn("font-bold", valueSizes[size], variantColor[variant]), children: displayValue }),
28070
+ showTrend && /* @__PURE__ */ jsx(
28071
+ Typography,
28072
+ {
28073
+ variant: "caption",
28074
+ className: cn("font-semibold pb-1", trendIsGood ? "text-success" : "text-error"),
28075
+ children: trendLabel
28076
+ }
28077
+ )
28078
+ ] }),
28079
+ showTarget && /* @__PURE__ */ jsx(Box, { className: "mt-2 h-1.5 w-full bg-muted rounded-full overflow-hidden", children: /* @__PURE__ */ jsx(
28080
+ Box,
28081
+ {
28082
+ className: cn("h-full rounded-full transition-all", `bg-${variant === "default" ? "primary" : variant}`),
28083
+ style: { width: `${targetPct}%` }
28084
+ }
28085
+ ) })
28086
+ ] }),
28087
+ /* @__PURE__ */ jsxs(VStack, { gap: "xs", align: "end", children: [
28088
+ (ResolvedIcon || typeof iconProp !== "string" && iconProp) && /* @__PURE__ */ jsx(Box, { className: cn("p-3 rounded-md", iconBg), children: ResolvedIcon ? /* @__PURE__ */ jsx(ResolvedIcon, { className: cn(iconSizes3[size], iconColor) }) : iconProp }),
28089
+ sparklineData && sparklineData.length > 1 && /* @__PURE__ */ jsx(Sparkline, { data: sparklineData, color: "auto" })
28090
+ ] })
28091
+ ] })
28092
+ }
28093
+ );
27460
28094
  };
27461
28095
  StatDisplay.displayName = "StatDisplay";
27462
28096
  }
@@ -41919,6 +42553,7 @@ var init_StatCard = __esm({
41919
42553
  init_Box();
41920
42554
  init_Stack();
41921
42555
  init_Button();
42556
+ init_Sparkline();
41922
42557
  init_useEventBus();
41923
42558
  init_useTranslate();
41924
42559
  init_Icon();
@@ -42088,32 +42723,7 @@ var init_StatCard = __esm({
42088
42723
  ] }),
42089
42724
  /* @__PURE__ */ jsxs(VStack, { gap: "xs", align: "end", children: [
42090
42725
  Icon3 && /* @__PURE__ */ jsx(Box, { className: cn("p-3", iconBg), children: /* @__PURE__ */ jsx(Icon3, { className: cn("h-6 w-6", iconColor) }) }),
42091
- sparklineData && sparklineData.length > 1 && (() => {
42092
- const w = 80;
42093
- const h = 32;
42094
- const pad = 2;
42095
- const min = Math.min(...sparklineData);
42096
- const max = Math.max(...sparklineData);
42097
- const range = max - min || 1;
42098
- const points = sparklineData.map((v, i) => {
42099
- const x = pad + i / (sparklineData.length - 1) * (w - pad * 2);
42100
- const y = pad + (1 - (v - min) / range) * (h - pad * 2);
42101
- return `${x},${y}`;
42102
- }).join(" ");
42103
- const trending = sparklineData[sparklineData.length - 1] >= sparklineData[0];
42104
- const strokeColor = trending ? "var(--color-success)" : "var(--color-error)";
42105
- return /* @__PURE__ */ jsx("svg", { width: w, height: h, viewBox: `0 0 ${w} ${h}`, className: "flex-shrink-0", children: /* @__PURE__ */ jsx(
42106
- "polyline",
42107
- {
42108
- fill: "none",
42109
- stroke: strokeColor,
42110
- strokeWidth: "2",
42111
- strokeLinecap: "round",
42112
- strokeLinejoin: "round",
42113
- points
42114
- }
42115
- ) });
42116
- })()
42726
+ sparklineData && sparklineData.length > 1 && /* @__PURE__ */ jsx(Sparkline, { data: sparklineData, color: "auto" })
42117
42727
  ] })
42118
42728
  ] }),
42119
42729
  action && /* @__PURE__ */ jsxs(
@@ -44011,6 +44621,7 @@ var init_component_registry_generated = __esm({
44011
44621
  init_DataGrid();
44012
44622
  init_DataList();
44013
44623
  init_DataTable();
44624
+ init_DateRangePicker();
44014
44625
  init_DateRangeSelector();
44015
44626
  init_DayCell();
44016
44627
  init_DebuggerBoard();
@@ -44143,6 +44754,7 @@ var init_component_registry_generated = __esm({
44143
44754
  init_Skeleton();
44144
44755
  init_SocialProof();
44145
44756
  init_SortableList();
44757
+ init_Sparkline();
44146
44758
  init_Split();
44147
44759
  init_SplitPane();
44148
44760
  init_SplitSection();
@@ -44291,6 +44903,7 @@ var init_component_registry_generated = __esm({
44291
44903
  "DataGrid": DataGrid,
44292
44904
  "DataList": DataList,
44293
44905
  "DataTable": DataTable,
44906
+ "DateRangePicker": DateRangePicker,
44294
44907
  "DateRangeSelector": DateRangeSelector,
44295
44908
  "DayCell": DayCell,
44296
44909
  "DebuggerBoard": DebuggerBoard,
@@ -44452,6 +45065,7 @@ var init_component_registry_generated = __esm({
44452
45065
  "SortableList": SortableList,
44453
45066
  "Spacer": SpacerPattern,
44454
45067
  "SpacerPattern": SpacerPattern,
45068
+ "Sparkline": Sparkline,
44455
45069
  "Spinner": SpinnerPattern,
44456
45070
  "SpinnerPattern": SpinnerPattern,
44457
45071
  "Split": Split,