@squadbase/vantage 0.6.2-dev1.5aae04e → 0.6.2-dev1.83509f7

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.
Files changed (40) hide show
  1. package/dist/{chunk-XPQSTZUU.js → chunk-7S52M2SL.js} +4 -3
  2. package/dist/chunk-7S52M2SL.js.map +1 -0
  3. package/dist/{chunk-HKSVYMYJ.js → chunk-MYHFZYS4.js} +168 -82
  4. package/dist/chunk-MYHFZYS4.js.map +1 -0
  5. package/dist/components/index.js +2 -2
  6. package/dist/table/index.js +2 -2
  7. package/dist/ui/index.d.ts +4 -1
  8. package/dist/ui/index.js +3 -3
  9. package/dist/ui/index.js.map +1 -1
  10. package/package.json +2 -2
  11. package/registry/ui/area-chart.tsx +45 -19
  12. package/registry/ui/bar-chart.tsx +45 -19
  13. package/registry/ui/bar-list.tsx +44 -17
  14. package/registry/ui/box-plot-chart.tsx +45 -19
  15. package/registry/ui/category-bar.tsx +44 -17
  16. package/registry/ui/chart-frame.tsx +44 -17
  17. package/registry/ui/delta.tsx +4 -4
  18. package/registry/ui/donut-chart.tsx +46 -19
  19. package/registry/ui/echart.tsx +171 -54
  20. package/registry/ui/heatmap.tsx +45 -19
  21. package/registry/ui/histogram-chart.tsx +45 -19
  22. package/registry/ui/legend.tsx +44 -17
  23. package/registry/ui/line-chart.tsx +45 -19
  24. package/registry/ui/page-shell.tsx +7 -7
  25. package/registry/ui/paired-chart.tsx +45 -19
  26. package/registry/ui/sample-data.tsx +1 -1
  27. package/registry/ui/scatter-chart.tsx +45 -19
  28. package/registry/ui/slider.tsx +1 -1
  29. package/registry/ui/status-badge.tsx +8 -8
  30. package/registry/ui/tooltip.tsx +6 -2
  31. package/registry/ui/tracker.tsx +9 -3
  32. package/registry/ui/trend-indicator.tsx +2 -2
  33. package/registry/ui/waterfall-chart.tsx +45 -19
  34. package/skills/vantage-design/SKILL.md +27 -25
  35. package/skills/vantage-design/references/extract.md +16 -14
  36. package/skills/vantage-design/references/format.md +6 -5
  37. package/skills/vantage-design/references/presets.md +60 -110
  38. package/theme.css +13 -12
  39. package/dist/chunk-HKSVYMYJ.js.map +0 -1
  40. package/dist/chunk-XPQSTZUU.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { Tooltip, TooltipTrigger, TooltipContent, Badge, SidebarProvider, Sidebar, SidebarContent, SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarFooter, SidebarRail, SidebarInset, SidebarTrigger, Separator, Input, Table, TableHeader, TableRow, TableHead, TableBody, TableCell, Skeleton, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuCheckboxItem, useIsMobile, Popover, PopoverTrigger, PopoverContent, Calendar, ToggleGroup, ToggleGroupItem, SelectGroup, SelectLabel, Collapsible, CollapsibleTrigger, SidebarMenuButton, SidebarMenuBadge, CollapsibleContent, SidebarMenuSub, SidebarMenuSubItem, SidebarMenuSubButton, SidebarMenuItem, Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, Checkbox, Card, CardHeader, CardDescription, CardTitle, CardAction, CardFooter } from './chunk-XPQSTZUU.js';
1
+ import { Tooltip, TooltipTrigger, TooltipContent, Badge, SidebarProvider, Sidebar, SidebarContent, SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarFooter, SidebarRail, SidebarInset, SidebarTrigger, Separator, Input, Table, TableHeader, TableRow, TableHead, TableBody, TableCell, Skeleton, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuCheckboxItem, useIsMobile, Popover, PopoverTrigger, PopoverContent, Calendar, ToggleGroup, ToggleGroupItem, SelectGroup, SelectLabel, Collapsible, CollapsibleTrigger, SidebarMenuButton, SidebarMenuBadge, CollapsibleContent, SidebarMenuSub, SidebarMenuSubItem, SidebarMenuSubButton, SidebarMenuItem, Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, Checkbox, Card, CardHeader, CardDescription, CardTitle, CardAction, CardFooter } from './chunk-7S52M2SL.js';
2
2
  import { Button } from './chunk-PDOBHMUQ.js';
3
3
  import { cn } from './chunk-U736PVHY.js';
4
4
  import { forwardRef, useState, useEffect, createContext, useId, useRef, useMemo, useCallback, useContext, Fragment as Fragment$1 } from 'react';
@@ -288,11 +288,11 @@ var PageShellHeader = forwardRef(
288
288
  children,
289
289
  updatedAt !== void 0 && updatedAt !== null ? /* @__PURE__ */ jsx("div", { "data-slot": "page-shell-updated-at", className: "ml-auto max-w-full shrink-0 text-right", children: /* @__PURE__ */ jsx(UpdatedAt, { at: updatedAt, variant: updatedAtVariant, timeZone }) }) : null,
290
290
  hasChips ? /* @__PURE__ */ jsxs("div", { "data-slot": "page-shell-chips", className: "order-1 flex basis-full flex-wrap gap-1.5", children: [
291
- source ? /* @__PURE__ */ jsxs(Badge, { variant: "outline", className: "h-auto max-w-full whitespace-normal", children: [
291
+ source ? /* @__PURE__ */ jsxs(Badge, { variant: "outline", className: "h-auto max-w-full whitespace-normal text-muted-foreground", children: [
292
292
  "\u51FA\u5178\uFF1A",
293
293
  source
294
294
  ] }) : null,
295
- periodText && periodText !== EMPTY_VALUE ? /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "tabular-nums", children: periodText }) : null
295
+ periodText && periodText !== EMPTY_VALUE ? /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "tabular-nums text-muted-foreground", children: periodText }) : null
296
296
  ] }) : null,
297
297
  hasStatus ? /* @__PURE__ */ jsx("div", { "data-slot": "page-shell-status", className: "order-2 min-w-0 basis-full", children: status }) : null
298
298
  ]
@@ -389,11 +389,11 @@ var PageShellSummary = forwardRef(
389
389
  );
390
390
  PageShellSummary.displayName = "PageShellSummary";
391
391
  var summaryCardTones = {
392
- positive: "border-positive/30 bg-positive-subtle [&>svg]:text-positive",
393
- negative: "border-negative/30 bg-negative-subtle [&>svg]:text-negative",
394
- warning: "border-warning/30 bg-warning-subtle [&>svg]:text-warning",
395
- info: "border-info/30 bg-info-subtle [&>svg]:text-info",
396
- neutral: "border-neutral/30 bg-neutral-subtle [&>svg]:text-neutral",
392
+ positive: "border-positive/20 dark:border-positive/25 bg-positive-subtle [&>svg]:text-positive",
393
+ negative: "border-negative/20 dark:border-negative/25 bg-negative-subtle [&>svg]:text-negative",
394
+ warning: "border-warning/20 dark:border-warning/25 bg-warning-subtle [&>svg]:text-warning",
395
+ info: "border-info/20 dark:border-info/25 bg-info-subtle [&>svg]:text-info",
396
+ neutral: "border-neutral/20 dark:border-neutral/25 bg-neutral-subtle [&>svg]:text-neutral",
397
397
  violet: "border-chart-4/30 bg-chart-4/5 [&>svg]:text-chart-4",
398
398
  pink: "border-chart-5/30 bg-chart-5/5 [&>svg]:text-chart-5"
399
399
  };
@@ -667,7 +667,7 @@ function SampleBadge({ label: label2 = DEFAULT_SAMPLE_LABEL, className, ...props
667
667
  {
668
668
  "data-slot": "sample-badge",
669
669
  title: SAMPLE_TITLE,
670
- className: cn("border-warning/30 bg-warning-subtle text-warning align-middle", className),
670
+ className: cn("border-warning/20 dark:border-warning/25 bg-warning-subtle text-warning align-middle", className),
671
671
  ...props,
672
672
  children: label2
673
673
  }
@@ -810,6 +810,15 @@ function DashboardCardPreset({
810
810
  var CHART_OTHER_COLOR = "color-mix(in oklab, var(--neutral) 50%, var(--background))";
811
811
  var ChartFrameContext = createContext(false);
812
812
  var SERIES_TOKENS = ["--chart-1", "--chart-2", "--chart-3", "--chart-4", "--chart-5"];
813
+ var tokenScopes = /* @__PURE__ */ new WeakMap();
814
+ var OPTION_COLOR_TOKENS = [
815
+ "--background",
816
+ "--card",
817
+ "--muted",
818
+ "--primary",
819
+ "--destructive",
820
+ ...["positive", "negative", "warning", "neutral", "info"].flatMap((tone) => ["", "-fill", "-subtle"].map((suffix) => `--${tone}${suffix}`))
821
+ ];
813
822
  var normalizeContext;
814
823
  var ZRENDER_COLOR_RE = /^(?:#[0-9a-f]{6}|rgba?\()/i;
815
824
  function toCanvasColor(value) {
@@ -837,7 +846,7 @@ function toCanvasColor(value) {
837
846
  }
838
847
  function readChartTokens(el) {
839
848
  if (typeof document === "undefined") return null;
840
- const target = document.documentElement;
849
+ const target = el ?? document.documentElement;
841
850
  if (!target) return null;
842
851
  const styles = getComputedStyle(target);
843
852
  const read = (name) => toCanvasColor(styles.getPropertyValue(name));
@@ -846,8 +855,10 @@ function readChartTokens(el) {
846
855
  const color = read(token);
847
856
  if (color) series.push(color);
848
857
  }
849
- return {
858
+ const tokens = {
850
859
  series,
860
+ colors: Object.fromEntries(OPTION_COLOR_TOKENS.map((name) => [name, styles.getPropertyValue(name).trim()])),
861
+ surface: readChartSurface(target),
851
862
  ...styles.fontFamily ? { fontFamily: styles.fontFamily } : {},
852
863
  foreground: read("--foreground"),
853
864
  mutedForeground: read("--muted-foreground"),
@@ -855,13 +866,15 @@ function readChartTokens(el) {
855
866
  popover: read("--popover"),
856
867
  popoverForeground: read("--popover-foreground")
857
868
  };
869
+ tokenScopes.set(tokens, target);
870
+ return tokens;
858
871
  }
859
872
  function sameChartTokens(a, b) {
860
873
  if (a === b) return true;
861
874
  if (!a || !b) return false;
862
- return a.series.length === b.series.length && a.series.every((color, i) => color === b.series[i]) && a.fontFamily === b.fontFamily && a.foreground === b.foreground && a.mutedForeground === b.mutedForeground && a.border === b.border && a.popover === b.popover && a.popoverForeground === b.popoverForeground;
875
+ return tokenScopes.get(a) === tokenScopes.get(b) && a.surface === b.surface && Object.keys(a.colors ?? {}).length === Object.keys(b.colors ?? {}).length && Object.entries(a.colors ?? {}).every(([name, value]) => b.colors?.[name] === value) && a.series.length === b.series.length && a.series.every((color, i) => color === b.series[i]) && a.fontFamily === b.fontFamily && a.foreground === b.foreground && a.mutedForeground === b.mutedForeground && a.border === b.border && a.popover === b.popover && a.popoverForeground === b.popoverForeground;
863
876
  }
864
- function watchChartTokens(onChange) {
877
+ function watchChartTokens(onChange, scope) {
865
878
  if (typeof document === "undefined") return () => {
866
879
  };
867
880
  let frame = 0;
@@ -874,8 +887,9 @@ function watchChartTokens(onChange) {
874
887
  };
875
888
  const themeObserver = new MutationObserver(schedule);
876
889
  const attributeFilter = ["class", "style", "data-theme"];
877
- themeObserver.observe(document.documentElement, { attributes: true, attributeFilter });
878
- if (document.body) themeObserver.observe(document.body, { attributes: true, attributeFilter });
890
+ for (let node = scope ?? document.body ?? document.documentElement; node; node = node.parentElement) {
891
+ themeObserver.observe(node, { attributes: true, attributeFilter });
892
+ }
879
893
  const styleObserver = new MutationObserver(schedule);
880
894
  if (document.head) {
881
895
  styleObserver.observe(document.head, {
@@ -944,19 +958,20 @@ function buildChartTheme(tokens) {
944
958
  }
945
959
  };
946
960
  }
947
- function useChartTokens() {
961
+ function useChartTokens(scope) {
948
962
  const [tokens, setTokens] = useState(() => readChartTokens());
949
963
  const tokensRef = useRef(tokens);
950
964
  useEffect(() => {
965
+ const target = scope && "current" in scope ? scope.current : scope;
951
966
  const sync = () => {
952
- const next = readChartTokens();
967
+ const next = readChartTokens(target);
953
968
  if (sameChartTokens(tokensRef.current, next)) return;
954
969
  tokensRef.current = next;
955
970
  setTokens(next);
956
971
  };
957
972
  sync();
958
- return watchChartTokens(sync);
959
- }, []);
973
+ return watchChartTokens(sync, target);
974
+ }, [scope]);
960
975
  return tokens;
961
976
  }
962
977
  var SERIES_TOKEN_NAME_RE = /^chart-([1-5])$/;
@@ -969,12 +984,13 @@ function resolveChartColors(colors, tokens) {
969
984
  if (token) return tokens?.series[Number(token[1]) - 1] ?? "";
970
985
  if (TONE_NAME_RE.test(color.trim())) {
971
986
  if (typeof document === "undefined") return "";
972
- return toCanvasColor(getComputedStyle(document.documentElement).getPropertyValue(`--${color.trim()}`)) ?? "";
987
+ const target = (tokens && tokenScopes.get(tokens)) ?? document.documentElement;
988
+ return toCanvasColor(getComputedStyle(target).getPropertyValue(`--${color.trim()}`)) ?? "";
973
989
  }
974
990
  if (typeof document === "undefined") return color;
975
991
  let value = color.trim();
976
992
  const cssVar = CSS_VAR_RE.exec(value);
977
- const styles = getComputedStyle(document.documentElement);
993
+ const styles = getComputedStyle((tokens && tokenScopes.get(tokens)) ?? document.documentElement);
978
994
  if (cssVar) {
979
995
  value = styles.getPropertyValue(cssVar[1]).trim() || (cssVar[2] ?? "").trim();
980
996
  } else if (value.includes("var(")) {
@@ -1000,11 +1016,12 @@ function readChartSurface(el) {
1000
1016
  if (color) return color;
1001
1017
  }
1002
1018
  }
1003
- return toCanvasColor(getComputedStyle(document.documentElement).getPropertyValue("--background"));
1019
+ return toCanvasColor(getComputedStyle(el ?? document.documentElement).getPropertyValue("--background"));
1004
1020
  }
1005
1021
  var WIDTH_BUCKET = 40;
1006
1022
  function useChartSurface(forwarded, tokens) {
1007
1023
  const [node, setNode] = useState(null);
1024
+ const scopedTokens = useChartTokens(node);
1008
1025
  const [surface, setSurface] = useState(void 0);
1009
1026
  const [width, setWidth] = useState(void 0);
1010
1027
  const ref = useCallback(
@@ -1018,7 +1035,7 @@ function useChartSurface(forwarded, tokens) {
1018
1035
  useEffect(() => {
1019
1036
  if (!node) return;
1020
1037
  setSurface(readChartSurface(node) ?? void 0);
1021
- }, [node, tokens]);
1038
+ }, [node, tokens, scopedTokens]);
1022
1039
  useEffect(() => {
1023
1040
  if (!node || typeof ResizeObserver === "undefined") return;
1024
1041
  const update = (w) => setWidth(Math.floor(w / WIDTH_BUCKET) * WIDTH_BUCKET);
@@ -1027,7 +1044,7 @@ function useChartSurface(forwarded, tokens) {
1027
1044
  observer.observe(node);
1028
1045
  return () => observer.disconnect();
1029
1046
  }, [node]);
1030
- return { ref, surface, width };
1047
+ return { ref, surface, width, tokens: scopedTokens };
1031
1048
  }
1032
1049
  var DEFAULT_CHART_HEIGHT = 288;
1033
1050
  var DEFAULT_EMPTY_TITLE = "\u8868\u793A\u3067\u304D\u308B\u30C7\u30FC\u30BF\u304C\u3042\u308A\u307E\u305B\u3093";
@@ -1242,6 +1259,88 @@ function echartSetOptionOpts(prev, next) {
1242
1259
  for (const key of [...Object.keys(prev), ...Object.keys(next)]) if (COMPONENT_MAIN_TYPES.has(key)) types.add(key);
1243
1260
  return { notMerge: false, replaceMerge: [...types], lazyUpdate: true };
1244
1261
  }
1262
+ var ID_TYPES = [
1263
+ "title",
1264
+ "legend",
1265
+ "grid",
1266
+ "xAxis",
1267
+ "yAxis",
1268
+ "polar",
1269
+ "radiusAxis",
1270
+ "angleAxis",
1271
+ "radar",
1272
+ "dataZoom",
1273
+ "visualMap",
1274
+ "geo",
1275
+ "singleAxis",
1276
+ "calendar"
1277
+ ];
1278
+ var createStableIdState = () => ({ ids: /* @__PURE__ */ new Map(), order: /* @__PURE__ */ new Map() });
1279
+ function shapeOf(v) {
1280
+ if (Array.isArray(v)) return "[]";
1281
+ if (!v || typeof v !== "object" || Object.getPrototypeOf(v) !== Object.prototype) return ".";
1282
+ const o = v;
1283
+ return `{${Object.keys(o).filter((k) => o[k] !== void 0).sort().map((k) => k === "type" || k === "id" ? `${k}=${String(o[k])}` : `${k}:${shapeOf(o[k])}`).join(",")}}`;
1284
+ }
1285
+ function withStableIds(option, state = createStableIdState()) {
1286
+ const out = { ...option };
1287
+ const taken = /* @__PURE__ */ new Set();
1288
+ const list = (v) => Array.isArray(v) ? v : v && typeof v === "object" ? [v] : null;
1289
+ const give = (key, pick) => {
1290
+ const items = list(out[key]);
1291
+ if (!items) return;
1292
+ const used = new Set(items.flatMap((c) => c && c.id != null ? [String(c.id)] : []));
1293
+ const bases = items.map((c, i) => {
1294
+ if (!c || typeof c !== "object" || c.id != null) return null;
1295
+ let base = pick(c, i);
1296
+ for (let n = 2; used.has(base) || taken.has(`${key}\0${base}`); n++) base = `${pick(c, i)}#${n}`;
1297
+ used.add(base);
1298
+ taken.add(`${key}\0${base}`);
1299
+ return base;
1300
+ });
1301
+ const prevOrder = state.order.get(key) ?? [];
1302
+ const cur = bases.filter((b) => b !== null);
1303
+ const inOrder = cur.length === prevOrder.length && cur.every((b, i) => b === prevOrder[i]);
1304
+ state.order.set(key, cur);
1305
+ out[key] = items.map((c, i) => {
1306
+ const base = bases[i];
1307
+ if (base == null) return c;
1308
+ const shape = shapeOf(c);
1309
+ const prev = state.ids.get(base);
1310
+ const version = !prev ? 0 : prev.shape === shape && inOrder ? prev.version : prev.version + 1;
1311
+ state.ids.set(base, { shape, version });
1312
+ return { ...c, id: version ? `${base}~v${version}` : base };
1313
+ });
1314
+ };
1315
+ give("series", (c, i) => `series:${typeof c.name === "string" && c.name ? c.name : i}`);
1316
+ for (const key of ID_TYPES) give(key, (_c, i) => `${key}:${i}`);
1317
+ return out;
1318
+ }
1319
+ function snapshotOption(v) {
1320
+ if (Array.isArray(v)) return v.map(snapshotOption);
1321
+ if (v && typeof v === "object") {
1322
+ const proto = Object.getPrototypeOf(v);
1323
+ if (proto === Object.prototype || proto === null) {
1324
+ return Object.fromEntries(Object.entries(v).map(([k, x]) => [k, snapshotOption(x)]));
1325
+ }
1326
+ }
1327
+ return v;
1328
+ }
1329
+ function optionEquals(a, b) {
1330
+ if (Object.is(a, b)) return true;
1331
+ if (typeof a !== "object" || typeof b !== "object" || !a || !b) return false;
1332
+ if (Array.isArray(a) !== Array.isArray(b)) return false;
1333
+ if (Array.isArray(a)) {
1334
+ const bb = b;
1335
+ return a.length === bb.length && a.every((v, i) => optionEquals(v, bb[i]));
1336
+ }
1337
+ if (a instanceof Date || b instanceof Date) return a instanceof Date && b instanceof Date && a.getTime() === b.getTime();
1338
+ const pa = Object.getPrototypeOf(a);
1339
+ if (pa !== Object.prototype && pa !== null || Object.getPrototypeOf(b) !== pa) return false;
1340
+ const ka = Object.keys(a);
1341
+ const kb = Object.keys(b);
1342
+ return ka.length === kb.length && ka.every((k) => Object.hasOwn(b, k) && optionEquals(a[k], b[k]));
1343
+ }
1245
1344
  function withGraphicFont(option, fontFamily) {
1246
1345
  const graphic = option.graphic;
1247
1346
  if (!fontFamily || !Array.isArray(graphic)) return option;
@@ -1285,31 +1384,11 @@ var EChart = forwardRef(function EChart2({
1285
1384
  const containerRef = useRef(null);
1286
1385
  const [instance, setInstance] = useState(null);
1287
1386
  const [copied, setCopied] = useState(false);
1288
- const [tokens, setTokens] = useState(() => readChartTokens());
1387
+ const tokens = useChartTokens(containerRef);
1289
1388
  const reducedMotion = usePrefersReducedMotion();
1290
1389
  const appliedRef = useRef(null);
1291
- const tokensRef = useRef(tokens);
1292
- useEffect(() => {
1293
- if (theme !== void 0) return;
1294
- const sync = () => {
1295
- const base = readChartTokens();
1296
- const font = containerRef.current ? getComputedStyle(containerRef.current).fontFamily : "";
1297
- const next = base && font ? { ...base, fontFamily: font } : base;
1298
- if (sameChartTokens(tokensRef.current, next)) return;
1299
- tokensRef.current = next;
1300
- setTokens(next);
1301
- };
1302
- sync();
1303
- const stop = watchChartTokens(sync);
1304
- const ancestors = new MutationObserver(sync);
1305
- for (let node = containerRef.current?.parentElement; node; node = node.parentElement) {
1306
- ancestors.observe(node, { attributes: true, attributeFilter: ["class", "style"] });
1307
- }
1308
- return () => {
1309
- stop();
1310
- ancestors.disconnect();
1311
- };
1312
- }, [theme]);
1390
+ const snapshotRef = useRef(null);
1391
+ const idStateRef = useRef(createStableIdState());
1313
1392
  const autoTheme = useMemo(() => tokens ? buildChartTheme(tokens) : void 0, [tokens]);
1314
1393
  const resolvedTheme = theme ?? autoTheme;
1315
1394
  useEffect(() => {
@@ -1317,6 +1396,7 @@ var EChart = forwardRef(function EChart2({
1317
1396
  if (!container) return;
1318
1397
  const inst = init(container, resolvedTheme, { renderer: "canvas" });
1319
1398
  appliedRef.current = null;
1399
+ snapshotRef.current = null;
1320
1400
  container.dataset.rendering = "";
1321
1401
  inst.on("finished", () => {
1322
1402
  delete container.dataset.rendering;
@@ -1337,19 +1417,25 @@ var EChart = forwardRef(function EChart2({
1337
1417
  };
1338
1418
  }, [resolvedTheme]);
1339
1419
  useEffect(() => {
1340
- if (!instance) return;
1420
+ if (!instance || instance.isDisposed()) return;
1421
+ const prepared = withGraphicFont(
1422
+ withMotionPreference(option, reducedMotion),
1423
+ theme === void 0 ? tokens?.fontFamily : void 0
1424
+ );
1425
+ if (snapshotRef.current && optionEquals(snapshotRef.current, prepared)) return;
1341
1426
  if (containerRef.current) containerRef.current.dataset.rendering = "";
1342
- const next = withGraphicFont(withMotionPreference(option, reducedMotion), theme === void 0 ? tokens?.fontFamily : void 0);
1427
+ const next = withStableIds(prepared, idStateRef.current);
1343
1428
  instance.setOption(next, echartSetOptionOpts(appliedRef.current, next));
1344
1429
  appliedRef.current = next;
1430
+ snapshotRef.current = snapshotOption(prepared);
1345
1431
  }, [instance, option, reducedMotion, theme, tokens?.fontFamily]);
1346
1432
  useEffect(() => {
1347
- if (!instance) return;
1433
+ if (!instance || instance.isDisposed()) return;
1348
1434
  if (loading) instance.showLoading();
1349
1435
  else instance.hideLoading();
1350
1436
  }, [instance, loading]);
1351
1437
  useEffect(() => {
1352
- if (!instance || !onEvents) return;
1438
+ if (!instance || instance.isDisposed() || !onEvents) return;
1353
1439
  const entries = Object.entries(onEvents);
1354
1440
  for (const [event, handler] of entries) {
1355
1441
  instance.on(event, handler);
@@ -3252,8 +3338,7 @@ function AreaChartImpl({
3252
3338
  className,
3253
3339
  ...rest
3254
3340
  }, ref) {
3255
- const tokens = useChartTokens();
3256
- const { ref: frameRef, surface, width: plotWidth } = useChartSurface(ref, tokens);
3341
+ const { ref: frameRef, surface, width: plotWidth, tokens } = useChartSurface(ref);
3257
3342
  const tooltipFormatter = useMemo(() => resolveValueFormatter(valueFormatter, format2), [valueFormatter, format2]);
3258
3343
  const axisFormatter = useMemo(() => resolveAxisFormatter(valueFormatter, format2), [valueFormatter, format2]);
3259
3344
  const axisTicks = useMemo(() => resolveAxisTickFormatter(valueFormatter, format2), [valueFormatter, format2]);
@@ -3435,8 +3520,7 @@ function BarChartImpl({
3435
3520
  className,
3436
3521
  ...rest
3437
3522
  }, ref) {
3438
- const tokens = useChartTokens();
3439
- const { ref: frameRef, surface, width: plotWidth } = useChartSurface(ref, tokens);
3523
+ const { ref: frameRef, surface, width: plotWidth, tokens } = useChartSurface(ref);
3440
3524
  const tooltipFormatter = useMemo(() => resolveValueFormatter(valueFormatter, format2), [valueFormatter, format2]);
3441
3525
  const axisFormatter = useMemo(() => resolveAxisFormatter(valueFormatter, format2), [valueFormatter, format2]);
3442
3526
  const axisTicks = useMemo(() => resolveAxisTickFormatter(valueFormatter, format2), [valueFormatter, format2]);
@@ -3620,8 +3704,7 @@ function LineChartImpl({
3620
3704
  className,
3621
3705
  ...rest
3622
3706
  }, ref) {
3623
- const tokens = useChartTokens();
3624
- const { ref: frameRef, surface, width: plotWidth } = useChartSurface(ref, tokens);
3707
+ const { ref: frameRef, surface, width: plotWidth, tokens } = useChartSurface(ref);
3625
3708
  const tooltipFormatter = useMemo(() => resolveValueFormatter(valueFormatter, format2), [valueFormatter, format2]);
3626
3709
  const axisFormatter = useMemo(() => resolveAxisFormatter(valueFormatter, format2), [valueFormatter, format2]);
3627
3710
  const axisTicks = useMemo(() => resolveAxisTickFormatter(valueFormatter, format2), [valueFormatter, format2]);
@@ -3809,7 +3892,7 @@ function DonutChartImpl({
3809
3892
  const maxSlices = donutOptions?.maxSlices;
3810
3893
  const showLegend = donutOptions?.showLegend ?? true;
3811
3894
  const valueFormatter = useMemo(() => resolveValueFormatter(valueFormatterProp, format2), [valueFormatterProp, format2]);
3812
- const tokens = useChartTokens();
3895
+ const { ref: frameRef, tokens } = useChartSurface(ref);
3813
3896
  const slices = useMemo(
3814
3897
  () => donutSlices(data, { index: labelKey, value: valueKey, colors, maxSlices, otherColor: CHART_OTHER_COLOR }),
3815
3898
  [data, labelKey, valueKey, colors, maxSlices]
@@ -3875,7 +3958,7 @@ function DonutChartImpl({
3875
3958
  ChartFrame,
3876
3959
  {
3877
3960
  ...chartRootProps(rest),
3878
- ref,
3961
+ ref: frameRef,
3879
3962
  title,
3880
3963
  summary: resolvedSummary,
3881
3964
  isLoading: isLoading ?? loading ?? false,
@@ -4191,8 +4274,14 @@ function blockColorToCss(color) {
4191
4274
  }
4192
4275
  var NO_ROWS7 = [];
4193
4276
  var Tracker = forwardRef(function Tracker2({ data = NO_ROWS7, defaultColor, hoverEffect = true, className, ...props }, ref) {
4277
+ const containerRef = useRef(null);
4278
+ const setRef = useCallback((node) => {
4279
+ containerRef.current = node;
4280
+ if (typeof ref === "function") return ref(node);
4281
+ if (ref) ref.current = node;
4282
+ }, [ref]);
4194
4283
  const fallback = defaultColor ? blockColorToCss(defaultColor) : DEFAULT_BLOCK_COLOR;
4195
- return /* @__PURE__ */ jsx("div", { ref, "data-slot": "tracker", className: cn("flex h-6 w-full gap-0.5", className), ...props, children: data.map((block, i) => {
4284
+ return /* @__PURE__ */ jsx("div", { ref: setRef, "data-slot": "tracker", className: cn("flex h-6 w-full gap-0.5", className), ...props, children: data.map((block, i) => {
4196
4285
  const blockClass = cn(
4197
4286
  "h-full min-w-0 flex-1 rounded-[2px]",
4198
4287
  hoverEffect && "transition-opacity hover:opacity-60 motion-reduce:transition-none"
@@ -4206,7 +4295,7 @@ var Tracker = forwardRef(function Tracker2({ data = NO_ROWS7, defaultColor, hove
4206
4295
  render: /* @__PURE__ */ jsx("div", { "data-slot": "tracker-block", role: "img", tabIndex: 0, "aria-label": block.tooltip, className: blockClass, style })
4207
4296
  }
4208
4297
  ),
4209
- /* @__PURE__ */ jsx(TooltipContent, { children: block.tooltip })
4298
+ /* @__PURE__ */ jsx(TooltipContent, { container: containerRef, children: block.tooltip })
4210
4299
  ] }, block.key ?? i) : /* @__PURE__ */ jsx("div", { "data-slot": "tracker-block", className: blockClass, style }, block.key ?? i);
4211
4300
  }) });
4212
4301
  });
@@ -4583,8 +4672,7 @@ function WaterfallChartImpl({
4583
4672
  ...rest
4584
4673
  }, ref) {
4585
4674
  const valueKey = categories[0] ?? "";
4586
- const tokens = useChartTokens();
4587
- const { ref: frameRef, width: plotWidth } = useChartSurface(ref, tokens);
4675
+ const { ref: frameRef, width: plotWidth, tokens } = useChartSurface(ref);
4588
4676
  const valueFormatter = useMemo(() => resolveValueFormatter(valueFormatterProp, format2), [valueFormatterProp, format2]);
4589
4677
  const axisFormatter = useMemo(() => resolveAxisFormatter(valueFormatterProp, format2), [valueFormatterProp, format2]);
4590
4678
  const steps = useMemo(() => waterfallSteps(data, { index, value: valueKey, totals, mode }), [data, index, valueKey, totals, mode]);
@@ -4983,8 +5071,7 @@ function ScatterChartImpl({
4983
5071
  className,
4984
5072
  ...rest
4985
5073
  }, ref) {
4986
- const tokens = useChartTokens();
4987
- const { ref: frameRef, width: plotWidth } = useChartSurface(ref, tokens);
5074
+ const { ref: frameRef, width: plotWidth, tokens } = useChartSurface(ref);
4988
5075
  const formatters = useMemo(
4989
5076
  () => ({
4990
5077
  x: resolveValueFormatter(valueFormatter, xFormat ?? format2),
@@ -5688,8 +5775,7 @@ function HeatmapImpl({
5688
5775
  ariaLabel,
5689
5776
  ...rest
5690
5777
  }, ref) {
5691
- const tokens = useChartTokens();
5692
- const { ref: frameRef, surface, width: plotWidth } = useChartSurface(ref, tokens);
5778
+ const { ref: frameRef, surface, width: plotWidth, tokens } = useChartSurface(ref);
5693
5779
  const formatter = useMemo(() => resolveValueFormatter(valueFormatter, format2 ?? "number"), [valueFormatter, format2]);
5694
5780
  const model = useMemo(
5695
5781
  () => buildHeatmapModel({ data, x, y, value, xLabels, yLabels, flag, scale, minValue, maxValue }),
@@ -7404,7 +7490,7 @@ var deltaVariants = cva(
7404
7490
  {
7405
7491
  variants: {
7406
7492
  variant: {
7407
- badge: "h-5 rounded-4xl px-2 py-0.5 text-xs font-semibold [&>svg]:size-3",
7493
+ badge: "h-5 rounded-md border px-2 py-0.5 text-xs font-medium [&>svg]:size-3",
7408
7494
  inline: "text-sm [&>svg]:size-3.5"
7409
7495
  },
7410
7496
  sentiment: {
@@ -7414,9 +7500,9 @@ var deltaVariants = cva(
7414
7500
  }
7415
7501
  },
7416
7502
  compoundVariants: [
7417
- { variant: "badge", sentiment: "positive", className: "bg-positive-subtle" },
7418
- { variant: "badge", sentiment: "negative", className: "bg-negative-subtle" },
7419
- { variant: "badge", sentiment: "neutral", className: "bg-neutral-subtle" }
7503
+ { variant: "badge", sentiment: "positive", className: "border-positive/20 bg-positive-subtle dark:border-positive/25" },
7504
+ { variant: "badge", sentiment: "negative", className: "border-negative/20 bg-negative-subtle dark:border-negative/25" },
7505
+ { variant: "badge", sentiment: "neutral", className: "border-neutral/20 bg-neutral-subtle dark:border-neutral/25" }
7420
7506
  ],
7421
7507
  defaultVariants: {
7422
7508
  variant: "badge",
@@ -7809,8 +7895,8 @@ function updatedAtText(updatedAt, display, locale, now, timeZone) {
7809
7895
  var trendIndicatorVariants = cva("inline-flex items-center gap-0.5 text-sm font-medium", {
7810
7896
  variants: {
7811
7897
  sentiment: {
7812
- positive: "text-chart-1",
7813
- negative: "text-primary",
7898
+ positive: "text-positive",
7899
+ negative: "text-negative",
7814
7900
  neutral: "text-muted-foreground"
7815
7901
  }
7816
7902
  },
@@ -7870,11 +7956,11 @@ var legacyColorTones = {
7870
7956
  blue: "info"
7871
7957
  };
7872
7958
  var toneStyles = {
7873
- positive: { dot: "bg-positive", bg: "bg-positive-subtle", text: "text-positive" },
7874
- negative: { dot: "bg-negative", bg: "bg-negative-subtle", text: "text-negative" },
7875
- warning: { dot: "bg-warning", bg: "bg-warning-subtle", text: "text-warning" },
7876
- info: { dot: "bg-info", bg: "bg-info-subtle", text: "text-info" },
7877
- neutral: { dot: "bg-neutral", bg: "bg-neutral-subtle", text: "text-neutral" }
7959
+ positive: { dot: "bg-positive", bg: "bg-positive-subtle", text: "text-positive", border: "border-positive/20 dark:border-positive/25" },
7960
+ negative: { dot: "bg-negative", bg: "bg-negative-subtle", text: "text-negative", border: "border-negative/20 dark:border-negative/25" },
7961
+ warning: { dot: "bg-warning", bg: "bg-warning-subtle", text: "text-warning", border: "border-warning/20 dark:border-warning/25" },
7962
+ info: { dot: "bg-info", bg: "bg-info-subtle", text: "text-info", border: "border-info/20 dark:border-info/25" },
7963
+ neutral: { dot: "bg-neutral", bg: "bg-neutral-subtle", text: "text-neutral", border: "border-neutral/20 dark:border-neutral/25" }
7878
7964
  };
7879
7965
  var resolveTone = (color) => {
7880
7966
  if (color === void 0) return "neutral";
@@ -7891,10 +7977,10 @@ var StatusBadge = forwardRef(function StatusBadge2({ status, label: label2, colo
7891
7977
  ref,
7892
7978
  "data-slot": "status-badge",
7893
7979
  variant: "outline",
7894
- className: cn("gap-1.5 border-transparent", style.bg, style.text, className),
7980
+ className: cn("gap-1.5 rounded-md", style.border, style.bg, style.text, className),
7895
7981
  "aria-label": displayLabel,
7896
7982
  children: [
7897
- /* @__PURE__ */ jsx("span", { className: cn("inline-block size-2 rounded-full", style.dot), "aria-hidden": "true" }),
7983
+ /* @__PURE__ */ jsx("span", { className: cn("inline-block size-1.5 rounded-full", style.dot), "aria-hidden": "true" }),
7898
7984
  displayLabel
7899
7985
  ]
7900
7986
  }
@@ -7915,5 +8001,5 @@ var Placeholder = forwardRef(function Placeholder2({ className, ...props }, ref)
7915
8001
  Placeholder.displayName = "Placeholder";
7916
8002
 
7917
8003
  export { AppShell, AreaChart, BarChart2 as BarChart, BarList, COMPARISON_LABELS, CategoryBar, ChartFrame, DEFAULT_LOCALE, DEFAULT_SAMPLE_LABEL, DELTA_NOT_COMPARABLE, DashboardCard, DashboardCardAction, DashboardCardContent, DashboardCardDescription, DashboardCardFooter, DashboardCardHeader, DashboardCardPreset, DashboardCardSkeleton, DashboardCardTitle, DataTable, DataTableColumnVisibility, DataTableContent, DataTableExport, DataTablePagination, DataTablePreset, DataTableToolbar, DateRangePicker, Delta, DonutChart, EChart, EMPTY_VALUE, FilterBar, FilterBarActiveChips, FilterBarClearButton, FilterBarMultiSelect, FilterBarPreset, FilterBarSelect, FunnelSteps, Heatmap, KpiCard, Legend, LineChart2 as LineChart, MINUS_SIGN, MetricUnit, MetricValue, MultiSelect, PageShell, PageShellActions, PageShellContent, PageShellDescription, PageShellHeader, PageShellHeaderEnd, PageShellHeading, PageShellMeta, PageShellSummary, PageShellSummaryCard, PageShellTitle, Placeholder, ProgressCircle, RECORD_MIN_POINTS, SampleBadge, SampleClaim, SampleData, ScatterChart, SearchableSelect, SectionHeader, SegmentedControl, Sparkline, StatusBadge, Tracker, TrendIndicator, UpdatedAt, WaterfallChart, comparisonBaseline, comparisonLabel, computeComparison, computeTargetProgress, defaultChangeDisplay, defaultPresets, deltaVariants, detectRecord, fillKpiTemplate, flattenOptions, formatChange, formatChangeAmount, formatDate, formatDateRange, formatDatesInText, formatDelta, formatKind, formatPoints, formatRelativeTime, formatValue, funnelStepsVariants, inferPeriodGrain, isGroupedOptions, metricValueVariants, pageShellSummaryCardVariants, tableToCsv, toCsv, toValueFormatter, toneForValue, useDataTable, useResolvedChartColors, useSampleMark };
7918
- //# sourceMappingURL=chunk-HKSVYMYJ.js.map
7919
- //# sourceMappingURL=chunk-HKSVYMYJ.js.map
8004
+ //# sourceMappingURL=chunk-MYHFZYS4.js.map
8005
+ //# sourceMappingURL=chunk-MYHFZYS4.js.map