@x-plat/design-system 0.5.35 → 0.5.37

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.
@@ -2229,25 +2229,8 @@ var CardTab = Object.assign(CardTabRoot, {
2229
2229
  var CardTab_default = CardTab;
2230
2230
 
2231
2231
  // src/components/Chart/Chart.tsx
2232
- var import_react7 = __toESM(require("react"), 1);
2233
-
2234
- // src/tokens/hooks/Portal.tsx
2235
2232
  var import_react6 = __toESM(require("react"), 1);
2236
- var import_react_dom = __toESM(require("react-dom"), 1);
2237
2233
  var import_jsx_runtime307 = require("react/jsx-runtime");
2238
- var PortalContainerContext = import_react6.default.createContext(null);
2239
- var PortalProvider = ({ container, children }) => /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(PortalContainerContext.Provider, { value: container, children });
2240
- var Portal = ({ children }) => {
2241
- const contextContainer = import_react6.default.useContext(PortalContainerContext);
2242
- if (typeof document === "undefined") return null;
2243
- const container = contextContainer ?? document.body;
2244
- return import_react_dom.default.createPortal(children, container);
2245
- };
2246
- Portal.displayName = "Portal";
2247
- var Portal_default = Portal;
2248
-
2249
- // src/components/Chart/Chart.tsx
2250
- var import_jsx_runtime308 = require("react/jsx-runtime");
2251
2234
  var CATEGORICAL_COUNT2 = 8;
2252
2235
  var LINE_BAR_PALETTES = Array.from({ length: CATEGORICAL_COUNT2 }, (_, i) => {
2253
2236
  const n = i + 1;
@@ -2293,11 +2276,11 @@ var toSmoothPath = (points) => {
2293
2276
  };
2294
2277
  var RESIZE_SETTLE_MS = 150;
2295
2278
  var useChartSize = (ref) => {
2296
- const [size, setSize] = import_react7.default.useState({ width: 0, height: 0 });
2297
- const settleTimer = import_react7.default.useRef(0);
2298
- const committedSize = import_react7.default.useRef({ width: 0, height: 0 });
2299
- const initialRef = import_react7.default.useRef(true);
2300
- import_react7.default.useEffect(() => {
2279
+ const [size, setSize] = import_react6.default.useState({ width: 0, height: 0 });
2280
+ const settleTimer = import_react6.default.useRef(0);
2281
+ const committedSize = import_react6.default.useRef({ width: 0, height: 0 });
2282
+ const initialRef = import_react6.default.useRef(true);
2283
+ import_react6.default.useEffect(() => {
2301
2284
  const el = ref.current;
2302
2285
  if (!el) return;
2303
2286
  const observer = new ResizeObserver((entries) => {
@@ -2339,10 +2322,10 @@ var useChartSize = (ref) => {
2339
2322
  };
2340
2323
  var prefersReducedMotion = () => typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
2341
2324
  var useChartAnimation = (containerRef, dataKey) => {
2342
- const [animate, setAnimate] = import_react7.default.useState(false);
2343
- const prevDataKey = import_react7.default.useRef(dataKey);
2344
- const hasAnimated = import_react7.default.useRef(false);
2345
- import_react7.default.useEffect(() => {
2325
+ const [animate, setAnimate] = import_react6.default.useState(false);
2326
+ const prevDataKey = import_react6.default.useRef(dataKey);
2327
+ const hasAnimated = import_react6.default.useRef(false);
2328
+ import_react6.default.useEffect(() => {
2346
2329
  if (prefersReducedMotion()) return;
2347
2330
  const el = containerRef.current;
2348
2331
  if (!el) return;
@@ -2358,7 +2341,7 @@ var useChartAnimation = (containerRef, dataKey) => {
2358
2341
  observer.observe(el);
2359
2342
  return () => observer.disconnect();
2360
2343
  }, [containerRef]);
2361
- import_react7.default.useEffect(() => {
2344
+ import_react6.default.useEffect(() => {
2362
2345
  if (dataKey !== prevDataKey.current) {
2363
2346
  prevDataKey.current = dataKey;
2364
2347
  if (prefersReducedMotion()) return;
@@ -2372,39 +2355,60 @@ var useChartAnimation = (containerRef, dataKey) => {
2372
2355
  };
2373
2356
  var TOOLTIP_OFFSET = 12;
2374
2357
  var useChartTooltip = (enabled) => {
2375
- const [tooltip, setTooltip] = import_react7.default.useState({
2358
+ const [tooltip, setTooltip] = import_react6.default.useState({
2376
2359
  visible: false,
2377
- clientX: 0,
2378
- clientY: 0,
2360
+ x: 0,
2361
+ y: 0,
2379
2362
  content: ""
2380
2363
  });
2381
- const containerRef = import_react7.default.useRef(null);
2382
- const rafRef = import_react7.default.useRef(0);
2383
- const move = import_react7.default.useCallback((e) => {
2364
+ const containerRef = import_react6.default.useRef(null);
2365
+ const rafRef = import_react6.default.useRef(0);
2366
+ const move = import_react6.default.useCallback((e) => {
2384
2367
  if (!enabled) return;
2385
2368
  const cx = e.clientX;
2386
2369
  const cy = e.clientY;
2387
2370
  cancelAnimationFrame(rafRef.current);
2388
2371
  rafRef.current = requestAnimationFrame(() => {
2389
- setTooltip((prev) => ({ ...prev, clientX: cx, clientY: cy }));
2372
+ const rect = containerRef.current?.getBoundingClientRect();
2373
+ if (!rect) return;
2374
+ setTooltip((prev) => ({ ...prev, x: cx - rect.left, y: cy - rect.top }));
2390
2375
  });
2391
2376
  }, [enabled]);
2392
- const show = import_react7.default.useCallback((e, content) => {
2377
+ const show = import_react6.default.useCallback((e, content) => {
2378
+ if (!enabled) return;
2379
+ const rect = containerRef.current?.getBoundingClientRect();
2380
+ if (!rect) return;
2381
+ setTooltip({ visible: true, x: e.clientX - rect.left, y: e.clientY - rect.top, content });
2382
+ }, [enabled]);
2383
+ const showAt = import_react6.default.useCallback((svgX, svgY, content, svgEl) => {
2393
2384
  if (!enabled) return;
2394
- setTooltip({ visible: true, clientX: e.clientX, clientY: e.clientY, content });
2385
+ const container = containerRef.current;
2386
+ if (!container) return;
2387
+ let x = svgX;
2388
+ let y = svgY;
2389
+ if (svgEl) {
2390
+ const svgRect = svgEl.getBoundingClientRect();
2391
+ const containerRect = container.getBoundingClientRect();
2392
+ const vb = svgEl.viewBox.baseVal;
2393
+ const scaleX = svgRect.width / (vb.width || 1);
2394
+ const scaleY = svgRect.height / (vb.height || 1);
2395
+ x = svgX * scaleX + (svgRect.left - containerRect.left);
2396
+ y = svgY * scaleY + (svgRect.top - containerRect.top);
2397
+ }
2398
+ setTooltip({ visible: true, x, y, content });
2395
2399
  }, [enabled]);
2396
- const hide = import_react7.default.useCallback(() => {
2400
+ const hide = import_react6.default.useCallback(() => {
2397
2401
  cancelAnimationFrame(rafRef.current);
2398
2402
  setTooltip((prev) => ({ ...prev, visible: false }));
2399
2403
  }, []);
2400
- return { tooltip, show, hide, move, containerRef };
2404
+ return { tooltip, show, showAt, hide, move, containerRef };
2401
2405
  };
2402
- var GridLines = import_react7.default.memo(({ width, height, chartH, maxVal }) => /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(import_jsx_runtime308.Fragment, { children: [0, 0.25, 0.5, 0.75, 1].map((ratio) => {
2406
+ var GridLines = import_react6.default.memo(({ width, height, chartH, maxVal }) => /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(import_jsx_runtime307.Fragment, { children: [0, 0.25, 0.5, 0.75, 1].map((ratio) => {
2403
2407
  const y = PADDING.top + (1 - ratio) * chartH;
2404
2408
  const val = Math.round(maxVal * ratio);
2405
- return /* @__PURE__ */ (0, import_jsx_runtime308.jsxs)("g", { children: [
2406
- /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("line", { x1: PADDING.left, y1: y, x2: width - PADDING.right, y2: y, className: "chart-grid" }),
2407
- /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("text", { x: PADDING.left - 8, y: y + 4, className: "chart-axis-label", textAnchor: "end", children: val })
2409
+ return /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)("g", { children: [
2410
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("line", { x1: PADDING.left, y1: y, x2: width - PADDING.right, y2: y, className: "chart-grid" }),
2411
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("text", { x: PADDING.left - 8, y: y + 4, className: "chart-axis-label", textAnchor: "end", children: val })
2408
2412
  ] }, ratio);
2409
2413
  }) }));
2410
2414
  GridLines.displayName = "GridLines";
@@ -2414,18 +2418,18 @@ var getLabelStep = (count, chartW) => {
2414
2418
  if (count <= maxLabels) return 1;
2415
2419
  return Math.ceil(count / maxLabels);
2416
2420
  };
2417
- var AxisLabels = import_react7.default.memo(({ labels, count, chartW, height }) => {
2421
+ var AxisLabels = import_react6.default.memo(({ labels, count, chartW, height }) => {
2418
2422
  const step = getLabelStep(count, chartW);
2419
- return /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(import_jsx_runtime308.Fragment, { children: labels.map((label, i) => {
2423
+ return /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(import_jsx_runtime307.Fragment, { children: labels.map((label, i) => {
2420
2424
  if (i % step !== 0) return null;
2421
2425
  const x = PADDING.left + i / (count - 1 || 1) * chartW;
2422
- return /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("text", { x, y: height - 8, className: "chart-axis-label", textAnchor: "middle", children: label }, i);
2426
+ return /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("text", { x, y: height - 8, className: "chart-axis-label", textAnchor: "middle", children: label }, i);
2423
2427
  }) });
2424
2428
  });
2425
2429
  AxisLabels.displayName = "AxisLabels";
2426
2430
  var useCrosshair = (seriesPoints, entries, labels, chartH) => {
2427
- const [activeIndex, setActiveIndex] = import_react7.default.useState(null);
2428
- const handleMouseMove = import_react7.default.useCallback((e) => {
2431
+ const [activeIndex, setActiveIndex] = import_react6.default.useState(null);
2432
+ const handleMouseMove = import_react6.default.useCallback((e) => {
2429
2433
  const svg = e.currentTarget;
2430
2434
  const rect = svg.getBoundingClientRect();
2431
2435
  const mx = (e.clientX - rect.left) / rect.width * svg.viewBox.baseVal.width;
@@ -2444,17 +2448,17 @@ var useCrosshair = (seriesPoints, entries, labels, chartH) => {
2444
2448
  }
2445
2449
  setActiveIndex(minDist <= threshold ? closest : null);
2446
2450
  }, [seriesPoints]);
2447
- const handleMouseLeave = import_react7.default.useCallback(() => {
2451
+ const handleMouseLeave = import_react6.default.useCallback(() => {
2448
2452
  setActiveIndex(null);
2449
2453
  }, []);
2450
- const tooltipContent = import_react7.default.useMemo(() => {
2454
+ const tooltipContent = import_react6.default.useMemo(() => {
2451
2455
  if (activeIndex === null) return "";
2452
2456
  return entries.map(([key], di) => {
2453
2457
  const p = seriesPoints[di]?.[activeIndex];
2454
2458
  return p ? `${key}: ${p.v}` : "";
2455
2459
  }).filter(Boolean).join(" / ");
2456
2460
  }, [activeIndex, entries, seriesPoints]);
2457
- const getTooltipAt = import_react7.default.useCallback((idx) => {
2461
+ const getTooltipAt = import_react6.default.useCallback((idx) => {
2458
2462
  return entries.map(([key], di) => {
2459
2463
  const p = seriesPoints[di]?.[idx];
2460
2464
  return p ? `${key}: ${p.v}` : "";
@@ -2462,16 +2466,16 @@ var useCrosshair = (seriesPoints, entries, labels, chartH) => {
2462
2466
  }, [entries, seriesPoints]);
2463
2467
  return { activeIndex, handleMouseMove, handleMouseLeave, tooltipContent, getTooltipAt };
2464
2468
  };
2465
- var LineChart = import_react7.default.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
2466
- const entries = import_react7.default.useMemo(() => Object.entries(data), [data]);
2467
- const maxVal = import_react7.default.useMemo(() => {
2469
+ var LineChart = import_react6.default.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
2470
+ const entries = import_react6.default.useMemo(() => Object.entries(data), [data]);
2471
+ const maxVal = import_react6.default.useMemo(() => {
2468
2472
  const allValues = entries.flatMap(([, v]) => v);
2469
2473
  return Math.max(...allValues) * 1.2 || 1;
2470
2474
  }, [entries]);
2471
2475
  const count = labels.length;
2472
2476
  const chartW = width - PADDING.left - PADDING.right;
2473
2477
  const chartH = height - PADDING.top - PADDING.bottom;
2474
- const seriesPoints = import_react7.default.useMemo(
2478
+ const seriesPoints = import_react6.default.useMemo(
2475
2479
  () => entries.map(
2476
2480
  ([, values]) => values.map((v, i) => ({
2477
2481
  x: PADDING.left + i / (count - 1 || 1) * chartW,
@@ -2481,9 +2485,10 @@ var LineChart = import_react7.default.memo(({ data, labels, width, height, anima
2481
2485
  ),
2482
2486
  [entries, count, chartW, chartH, maxVal]
2483
2487
  );
2484
- const clipRef = import_react7.default.useRef(null);
2488
+ const clipRef = import_react6.default.useRef(null);
2489
+ const svgRef = import_react6.default.useRef(null);
2485
2490
  const { activeIndex, handleMouseMove, handleMouseLeave, getTooltipAt } = useCrosshair(seriesPoints, entries, labels, chartH);
2486
- import_react7.default.useEffect(() => {
2491
+ import_react6.default.useEffect(() => {
2487
2492
  if (!animate || !clipRef.current) return;
2488
2493
  clipRef.current.setAttribute("width", "0");
2489
2494
  requestAnimationFrame(() => {
@@ -2495,30 +2500,17 @@ var LineChart = import_react7.default.memo(({ data, labels, width, height, anima
2495
2500
  }, [animate, width]);
2496
2501
  const activeX = activeIndex !== null ? seriesPoints[0]?.[activeIndex]?.x ?? null : null;
2497
2502
  const lineClipId = "line-area-clip";
2498
- return /* @__PURE__ */ (0, import_jsx_runtime308.jsxs)(
2503
+ return /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)(
2499
2504
  "svg",
2500
2505
  {
2506
+ ref: svgRef,
2501
2507
  viewBox: `0 0 ${width} ${height}`,
2502
2508
  className: "chart-svg",
2503
2509
  onMouseMove: (e) => {
2504
2510
  handleMouseMove(e);
2505
- const svg = e.currentTarget;
2506
- const rect = svg.getBoundingClientRect();
2507
- const mx = (e.clientX - rect.left) / rect.width * svg.viewBox.baseVal.width;
2508
- const points = seriesPoints[0];
2509
- if (!points || points.length === 0) return;
2510
- const step = points.length > 1 ? Math.abs(points[1].x - points[0].x) : 20;
2511
- let closest = 0;
2512
- let minDist = Math.abs(points[0].x - mx);
2513
- for (let i = 1; i < points.length; i++) {
2514
- const dist = Math.abs(points[i].x - mx);
2515
- if (dist < minDist) {
2516
- minDist = dist;
2517
- closest = i;
2518
- }
2519
- }
2520
- if (minDist <= step / 2) {
2521
- onHover(e, `${labels[closest]} \u2014 ${getTooltipAt(closest)}`);
2511
+ if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
2512
+ const p = seriesPoints[0][activeIndex];
2513
+ onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`, svgRef.current);
2522
2514
  } else {
2523
2515
  onLeave();
2524
2516
  }
@@ -2528,9 +2520,9 @@ var LineChart = import_react7.default.memo(({ data, labels, width, height, anima
2528
2520
  onLeave();
2529
2521
  },
2530
2522
  children: [
2531
- animate && /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("clipPath", { id: lineClipId, children: /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("rect", { ref: clipRef, x: "0", y: "0", width: animate ? 0 : width, height }) }) }),
2532
- /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(GridLines, { width, height, chartH, maxVal }),
2533
- /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(AxisLabels, { labels, count, chartW, height }),
2523
+ animate && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("clipPath", { id: lineClipId, children: /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("rect", { ref: clipRef, x: "0", y: "0", width: animate ? 0 : width, height }) }) }),
2524
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(GridLines, { width, height, chartH, maxVal }),
2525
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(AxisLabels, { labels, count, chartW, height }),
2534
2526
  entries.map(([key], di) => {
2535
2527
  const palette = getPalette(LINE_BAR_PALETTES, di, key);
2536
2528
  const color = palette[2];
@@ -2539,16 +2531,16 @@ var LineChart = import_react7.default.memo(({ data, labels, width, height, anima
2539
2531
  const gradientId = `line-gradient-${di}`;
2540
2532
  const polyPoints = points.map((p) => `${p.x},${p.y}`).join(" ");
2541
2533
  const areaD = `M ${points[0].x},${points[0].y} ${points.map((p) => `L ${p.x},${p.y}`).join(" ")} L ${points[points.length - 1].x},${PADDING.top + chartH} L ${points[0].x},${PADDING.top + chartH} Z`;
2542
- return /* @__PURE__ */ (0, import_jsx_runtime308.jsxs)("g", { children: [
2543
- /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime308.jsxs)("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
2544
- /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("stop", { offset: "0%", stopColor: areaColor, stopOpacity: "0.2" }),
2545
- /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("stop", { offset: "100%", stopColor: areaColor, stopOpacity: "0" })
2534
+ return /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)("g", { children: [
2535
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
2536
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("stop", { offset: "0%", stopColor: areaColor, stopOpacity: "0.2" }),
2537
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("stop", { offset: "100%", stopColor: areaColor, stopOpacity: "0" })
2546
2538
  ] }) }),
2547
- /* @__PURE__ */ (0, import_jsx_runtime308.jsxs)("g", { clipPath: animate ? `url(#${lineClipId})` : void 0, children: [
2548
- /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("path", { d: areaD, fill: `url(#${gradientId})` }),
2549
- /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("polyline", { points: polyPoints, fill: "none", stroke: color, strokeWidth: "2" })
2539
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)("g", { clipPath: animate ? `url(#${lineClipId})` : void 0, children: [
2540
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("path", { d: areaD, fill: `url(#${gradientId})` }),
2541
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("polyline", { points: polyPoints, fill: "none", stroke: color, strokeWidth: "2" })
2550
2542
  ] }),
2551
- activeIndex !== null && points[activeIndex] && /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(
2543
+ activeIndex !== null && points[activeIndex] && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(
2552
2544
  "circle",
2553
2545
  {
2554
2546
  cx: points[activeIndex].x,
@@ -2560,7 +2552,7 @@ var LineChart = import_react7.default.memo(({ data, labels, width, height, anima
2560
2552
  )
2561
2553
  ] }, di);
2562
2554
  }),
2563
- activeX !== null && /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(
2555
+ activeX !== null && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(
2564
2556
  "line",
2565
2557
  {
2566
2558
  x1: activeX,
@@ -2570,7 +2562,7 @@ var LineChart = import_react7.default.memo(({ data, labels, width, height, anima
2570
2562
  className: "chart-crosshair"
2571
2563
  }
2572
2564
  ),
2573
- /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(
2565
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(
2574
2566
  "rect",
2575
2567
  {
2576
2568
  x: PADDING.left,
@@ -2586,16 +2578,16 @@ var LineChart = import_react7.default.memo(({ data, labels, width, height, anima
2586
2578
  );
2587
2579
  });
2588
2580
  LineChart.displayName = "LineChart";
2589
- var CurveChart = import_react7.default.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
2590
- const entries = import_react7.default.useMemo(() => Object.entries(data), [data]);
2591
- const maxVal = import_react7.default.useMemo(() => {
2581
+ var CurveChart = import_react6.default.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
2582
+ const entries = import_react6.default.useMemo(() => Object.entries(data), [data]);
2583
+ const maxVal = import_react6.default.useMemo(() => {
2592
2584
  const allValues = entries.flatMap(([, v]) => v);
2593
2585
  return Math.max(...allValues) * 1.2 || 1;
2594
2586
  }, [entries]);
2595
2587
  const count = labels.length;
2596
2588
  const chartW = width - PADDING.left - PADDING.right;
2597
2589
  const chartH = height - PADDING.top - PADDING.bottom;
2598
- const seriesPoints = import_react7.default.useMemo(
2590
+ const seriesPoints = import_react6.default.useMemo(
2599
2591
  () => entries.map(
2600
2592
  ([, values]) => values.map((v, i) => ({
2601
2593
  x: PADDING.left + i / (count - 1 || 1) * chartW,
@@ -2605,9 +2597,10 @@ var CurveChart = import_react7.default.memo(({ data, labels, width, height, anim
2605
2597
  ),
2606
2598
  [entries, count, chartW, chartH, maxVal]
2607
2599
  );
2608
- const curveClipRef = import_react7.default.useRef(null);
2600
+ const curveClipRef = import_react6.default.useRef(null);
2601
+ const curveSvgRef = import_react6.default.useRef(null);
2609
2602
  const { activeIndex, handleMouseMove, handleMouseLeave, getTooltipAt } = useCrosshair(seriesPoints, entries, labels, chartH);
2610
- import_react7.default.useEffect(() => {
2603
+ import_react6.default.useEffect(() => {
2611
2604
  if (!animate || !curveClipRef.current) return;
2612
2605
  curveClipRef.current.setAttribute("width", "0");
2613
2606
  requestAnimationFrame(() => {
@@ -2619,30 +2612,17 @@ var CurveChart = import_react7.default.memo(({ data, labels, width, height, anim
2619
2612
  }, [animate, width]);
2620
2613
  const activeX = activeIndex !== null ? seriesPoints[0]?.[activeIndex]?.x ?? null : null;
2621
2614
  const curveClipId = "curve-area-clip";
2622
- return /* @__PURE__ */ (0, import_jsx_runtime308.jsxs)(
2615
+ return /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)(
2623
2616
  "svg",
2624
2617
  {
2618
+ ref: curveSvgRef,
2625
2619
  viewBox: `0 0 ${width} ${height}`,
2626
2620
  className: "chart-svg",
2627
2621
  onMouseMove: (e) => {
2628
2622
  handleMouseMove(e);
2629
- const svg = e.currentTarget;
2630
- const rect = svg.getBoundingClientRect();
2631
- const mx = (e.clientX - rect.left) / rect.width * svg.viewBox.baseVal.width;
2632
- const points = seriesPoints[0];
2633
- if (!points || points.length === 0) return;
2634
- const step = points.length > 1 ? Math.abs(points[1].x - points[0].x) : 20;
2635
- let closest = 0;
2636
- let minDist = Math.abs(points[0].x - mx);
2637
- for (let i = 1; i < points.length; i++) {
2638
- const dist = Math.abs(points[i].x - mx);
2639
- if (dist < minDist) {
2640
- minDist = dist;
2641
- closest = i;
2642
- }
2643
- }
2644
- if (minDist <= step / 2) {
2645
- onHover(e, `${labels[closest]} \u2014 ${getTooltipAt(closest)}`);
2623
+ if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
2624
+ const p = seriesPoints[0][activeIndex];
2625
+ onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`, curveSvgRef.current);
2646
2626
  } else {
2647
2627
  onLeave();
2648
2628
  }
@@ -2652,9 +2632,9 @@ var CurveChart = import_react7.default.memo(({ data, labels, width, height, anim
2652
2632
  onLeave();
2653
2633
  },
2654
2634
  children: [
2655
- animate && /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("clipPath", { id: curveClipId, children: /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("rect", { ref: curveClipRef, x: "0", y: "0", width: animate ? 0 : width, height }) }) }),
2656
- /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(GridLines, { width, height, chartH, maxVal }),
2657
- /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(AxisLabels, { labels, count, chartW, height }),
2635
+ animate && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("clipPath", { id: curveClipId, children: /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("rect", { ref: curveClipRef, x: "0", y: "0", width: animate ? 0 : width, height }) }) }),
2636
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(GridLines, { width, height, chartH, maxVal }),
2637
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(AxisLabels, { labels, count, chartW, height }),
2658
2638
  entries.map(([key], di) => {
2659
2639
  const palette = getPalette(LINE_BAR_PALETTES, di, key);
2660
2640
  const color = palette[2];
@@ -2663,16 +2643,16 @@ var CurveChart = import_react7.default.memo(({ data, labels, width, height, anim
2663
2643
  const gradientId = `curve-gradient-${di}`;
2664
2644
  const linePath = toSmoothPath(points);
2665
2645
  const areaPath = linePath + ` L ${points[points.length - 1].x} ${PADDING.top + chartH} L ${points[0].x} ${PADDING.top + chartH} Z`;
2666
- return /* @__PURE__ */ (0, import_jsx_runtime308.jsxs)("g", { children: [
2667
- /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime308.jsxs)("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
2668
- /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("stop", { offset: "0%", stopColor: areaColor, stopOpacity: "0.4" }),
2669
- /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("stop", { offset: "100%", stopColor: areaColor, stopOpacity: "0.02" })
2646
+ return /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)("g", { children: [
2647
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
2648
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("stop", { offset: "0%", stopColor: areaColor, stopOpacity: "0.4" }),
2649
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("stop", { offset: "100%", stopColor: areaColor, stopOpacity: "0.02" })
2670
2650
  ] }) }),
2671
- /* @__PURE__ */ (0, import_jsx_runtime308.jsxs)("g", { clipPath: animate ? `url(#${curveClipId})` : void 0, children: [
2672
- /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("path", { d: areaPath, fill: `url(#${gradientId})` }),
2673
- /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("path", { d: linePath, fill: "none", stroke: color, strokeWidth: "2" })
2651
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)("g", { clipPath: animate ? `url(#${curveClipId})` : void 0, children: [
2652
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("path", { d: areaPath, fill: `url(#${gradientId})` }),
2653
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("path", { d: linePath, fill: "none", stroke: color, strokeWidth: "2" })
2674
2654
  ] }),
2675
- activeIndex !== null && points[activeIndex] && /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(
2655
+ activeIndex !== null && points[activeIndex] && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(
2676
2656
  "circle",
2677
2657
  {
2678
2658
  cx: points[activeIndex].x,
@@ -2684,7 +2664,7 @@ var CurveChart = import_react7.default.memo(({ data, labels, width, height, anim
2684
2664
  )
2685
2665
  ] }, di);
2686
2666
  }),
2687
- activeX !== null && /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(
2667
+ activeX !== null && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(
2688
2668
  "line",
2689
2669
  {
2690
2670
  x1: activeX,
@@ -2694,7 +2674,7 @@ var CurveChart = import_react7.default.memo(({ data, labels, width, height, anim
2694
2674
  className: "chart-crosshair"
2695
2675
  }
2696
2676
  ),
2697
- /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(
2677
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(
2698
2678
  "rect",
2699
2679
  {
2700
2680
  x: PADDING.left,
@@ -2710,9 +2690,10 @@ var CurveChart = import_react7.default.memo(({ data, labels, width, height, anim
2710
2690
  );
2711
2691
  });
2712
2692
  CurveChart.displayName = "CurveChart";
2713
- var BarChart = import_react7.default.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
2714
- const entries = import_react7.default.useMemo(() => Object.entries(data), [data]);
2715
- const maxVal = import_react7.default.useMemo(() => {
2693
+ var BarChart = import_react6.default.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
2694
+ const barSvgRef = import_react6.default.useRef(null);
2695
+ const entries = import_react6.default.useMemo(() => Object.entries(data), [data]);
2696
+ const maxVal = import_react6.default.useMemo(() => {
2716
2697
  const allValues = entries.flatMap(([, v]) => v);
2717
2698
  return Math.max(...allValues) * 1.2 || 1;
2718
2699
  }, [entries]);
@@ -2724,7 +2705,7 @@ var BarChart = import_react7.default.memo(({ data, labels, width, height, animat
2724
2705
  const barGap = groupCount > 1 ? 2 : 0;
2725
2706
  const barW = Math.max(1, Math.min(32, (groupW * 0.7 - barGap * (groupCount - 1)) / groupCount));
2726
2707
  const baseline = PADDING.top + chartH;
2727
- const bars = import_react7.default.useMemo(
2708
+ const bars = import_react6.default.useMemo(
2728
2709
  () => entries.map(
2729
2710
  ([, values], di) => values.map((v, i) => {
2730
2711
  const totalBarsW = barW * groupCount + barGap * (groupCount - 1);
@@ -2737,11 +2718,11 @@ var BarChart = import_react7.default.memo(({ data, labels, width, height, animat
2737
2718
  [entries, maxVal, chartH, groupW, barW, barGap, groupCount]
2738
2719
  );
2739
2720
  const barLabelStep = getLabelStep(count, chartW);
2740
- return /* @__PURE__ */ (0, import_jsx_runtime308.jsxs)("svg", { viewBox: `0 0 ${width} ${height}`, className: "chart-svg", children: [
2741
- /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(GridLines, { width, height, chartH, maxVal }),
2721
+ return /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)("svg", { ref: barSvgRef, viewBox: `0 0 ${width} ${height}`, className: "chart-svg", children: [
2722
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(GridLines, { width, height, chartH, maxVal }),
2742
2723
  labels.map((label, i) => {
2743
2724
  if (i % barLabelStep !== 0) return null;
2744
- return /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("text", { x: PADDING.left + groupW * i + groupW / 2, y: height - 8, className: "chart-axis-label", textAnchor: "middle", children: label }, i);
2725
+ return /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("text", { x: PADDING.left + groupW * i + groupW / 2, y: height - 8, className: "chart-axis-label", textAnchor: "middle", children: label }, i);
2745
2726
  }),
2746
2727
  entries.map(([key], di) => {
2747
2728
  const palette = getPalette(LINE_BAR_PALETTES, di, key);
@@ -2750,7 +2731,7 @@ var BarChart = import_react7.default.memo(({ data, labels, width, height, animat
2750
2731
  const r2 = Math.min(4, b.w / 2);
2751
2732
  const d = b.h <= r2 ? `M ${b.x} ${b.y + b.h} V ${b.y} H ${b.x + b.w} V ${b.y + b.h} Z` : `M ${b.x} ${b.y + b.h} V ${b.y + r2} Q ${b.x} ${b.y} ${b.x + r2} ${b.y} H ${b.x + b.w - r2} Q ${b.x + b.w} ${b.y} ${b.x + b.w} ${b.y + r2} V ${b.y + b.h} Z`;
2752
2733
  const delay = 100 + i * 80;
2753
- return /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(
2734
+ return /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(
2754
2735
  "path",
2755
2736
  {
2756
2737
  d,
@@ -2760,8 +2741,7 @@ var BarChart = import_react7.default.memo(({ data, labels, width, height, animat
2760
2741
  transformOrigin: `${b.x + b.w / 2}px ${baseline}px`,
2761
2742
  animationDelay: `${delay}ms`
2762
2743
  } : void 0,
2763
- onMouseEnter: (e) => onHover(e, `${key}: ${labels[i]} \u2014 ${b.v}`),
2764
- onMouseMove: onMove,
2744
+ onMouseEnter: () => onShowAt(b.x + b.w / 2, b.y, `${key}: ${labels[i]} \u2014 ${b.v}`, barSvgRef.current),
2765
2745
  onMouseLeave: onLeave
2766
2746
  },
2767
2747
  `${di}-${i}`
@@ -2771,11 +2751,11 @@ var BarChart = import_react7.default.memo(({ data, labels, width, height, animat
2771
2751
  ] });
2772
2752
  });
2773
2753
  BarChart.displayName = "BarChart";
2774
- var PieDonutChart = import_react7.default.memo(
2754
+ var PieDonutChart = import_react6.default.memo(
2775
2755
  ({ data, labels, width, height, animate, isDoughnut, onHover, onMove, onLeave }) => {
2776
- const entries = import_react7.default.useMemo(() => Object.entries(data), [data]);
2777
- const values = import_react7.default.useMemo(() => entries.flatMap(([, v]) => v), [entries]);
2778
- const total = import_react7.default.useMemo(() => values.reduce((a, b) => a + b, 0) || 1, [values]);
2756
+ const entries = import_react6.default.useMemo(() => Object.entries(data), [data]);
2757
+ const values = import_react6.default.useMemo(() => entries.flatMap(([, v]) => v), [entries]);
2758
+ const total = import_react6.default.useMemo(() => values.reduce((a, b) => a + b, 0) || 1, [values]);
2779
2759
  const size = Math.min(width, height);
2780
2760
  const cx = size / 2;
2781
2761
  const cy = size / 2;
@@ -2783,10 +2763,10 @@ var PieDonutChart = import_react7.default.memo(
2783
2763
  const innerR = isDoughnut ? r2 * 0.5 : 0;
2784
2764
  const firstKey = entries[0]?.[0] ?? "";
2785
2765
  const colorOffset = hashString(firstKey);
2786
- const maskRef = import_react7.default.useRef(null);
2766
+ const maskRef = import_react6.default.useRef(null);
2787
2767
  const maskR = r2 + 10;
2788
2768
  const maskCircumference = 2 * Math.PI * maskR;
2789
- import_react7.default.useEffect(() => {
2769
+ import_react6.default.useEffect(() => {
2790
2770
  if (!animate || !maskRef.current) return;
2791
2771
  const el = maskRef.current;
2792
2772
  el.style.strokeDasharray = `${maskCircumference}`;
@@ -2796,7 +2776,7 @@ var PieDonutChart = import_react7.default.memo(
2796
2776
  el.style.strokeDashoffset = "0";
2797
2777
  });
2798
2778
  }, [animate, maskCircumference]);
2799
- const sliceData = import_react7.default.useMemo(() => {
2779
+ const sliceData = import_react6.default.useMemo(() => {
2800
2780
  let angle0 = -Math.PI / 2;
2801
2781
  let cumulativeAngle = 0;
2802
2782
  return values.map((v, i) => {
@@ -2830,8 +2810,8 @@ var PieDonutChart = import_react7.default.memo(
2830
2810
  });
2831
2811
  }, [values, total, cx, cy, r2, innerR, labels]);
2832
2812
  const maskId = `pie-mask-${isDoughnut ? "d" : "p"}`;
2833
- return /* @__PURE__ */ (0, import_jsx_runtime308.jsxs)("svg", { viewBox: `0 0 ${size} ${size}`, className: "chart-svg chart-pie", children: [
2834
- animate && /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("mask", { id: maskId, children: /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(
2813
+ return /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)("svg", { viewBox: `0 0 ${size} ${size}`, className: "chart-svg chart-pie", children: [
2814
+ animate && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("mask", { id: maskId, children: /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(
2835
2815
  "circle",
2836
2816
  {
2837
2817
  ref: maskRef,
@@ -2844,56 +2824,39 @@ var PieDonutChart = import_react7.default.memo(
2844
2824
  transform: `rotate(-90 ${cx} ${cy})`
2845
2825
  }
2846
2826
  ) }) }),
2847
- /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("g", { mask: animate ? `url(#${maskId})` : void 0, children: sliceData.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("g", { children: /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(
2827
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("g", { mask: animate ? `url(#${maskId})` : void 0, children: sliceData.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("g", { children: /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(
2848
2828
  "path",
2849
2829
  {
2850
2830
  d: s.d,
2851
2831
  fill: PIE_COLORS[(i + colorOffset) % PIE_COLORS.length],
2852
- className: "chart-slice",
2853
- onMouseEnter: (e) => onHover(e, `${s.label}: ${s.v} (${s.pct}%)`),
2854
- onMouseMove: onMove,
2855
- onMouseLeave: onLeave
2832
+ className: "chart-slice"
2856
2833
  }
2857
- ) }, i)) }),
2858
- sliceData.map((s, i) => s.angle > 0.2 && /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(
2859
- "text",
2860
- {
2861
- x: s.lx,
2862
- y: s.ly,
2863
- className: `chart-pie-label ${animate ? "chart-pie-label-animate" : ""}`,
2864
- style: animate ? { animationDelay: `${s.labelDelay}ms` } : void 0,
2865
- textAnchor: "middle",
2866
- dominantBaseline: "central",
2867
- children: s.v
2868
- },
2869
- `label-${i}`
2870
- ))
2834
+ ) }, i)) })
2871
2835
  ] });
2872
2836
  }
2873
2837
  );
2874
2838
  PieDonutChart.displayName = "PieDonutChart";
2875
- var ChartTooltipPortal = ({ clientX, clientY, visible, children }) => {
2876
- const ref = import_react7.default.useRef(null);
2877
- const [pos, setPos] = import_react7.default.useState({ left: 0, top: 0 });
2878
- import_react7.default.useLayoutEffect(() => {
2839
+ var ChartTooltip = ({ x, y, containerWidth, containerHeight, children }) => {
2840
+ const ref = import_react6.default.useRef(null);
2841
+ const [pos, setPos] = import_react6.default.useState({ left: 0, top: 0 });
2842
+ import_react6.default.useLayoutEffect(() => {
2879
2843
  const el = ref.current;
2880
2844
  if (!el) return;
2881
2845
  const w = el.offsetWidth;
2882
2846
  const h = el.offsetHeight;
2883
- const vw = window.innerWidth;
2884
- let left = clientX + TOOLTIP_OFFSET;
2885
- let top = clientY - h - TOOLTIP_OFFSET;
2886
- if (left + w > vw - 8) left = clientX - w - TOOLTIP_OFFSET;
2887
- if (top < 8) top = clientY + TOOLTIP_OFFSET;
2888
- if (left < 8) left = 8;
2847
+ let left = x + TOOLTIP_OFFSET;
2848
+ let top = y - h - TOOLTIP_OFFSET;
2849
+ if (left + w > containerWidth) left = x - w - TOOLTIP_OFFSET;
2850
+ if (top < 0) top = y + TOOLTIP_OFFSET;
2851
+ if (left < 0) left = 0;
2889
2852
  setPos({ left, top });
2890
- }, [clientX, clientY]);
2891
- return /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(
2853
+ }, [x, y, containerWidth, containerHeight]);
2854
+ return /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(
2892
2855
  "div",
2893
2856
  {
2894
2857
  ref,
2895
- className: `chart-tooltip ${visible ? "chart-tooltip-show" : "chart-tooltip-hide"}`,
2896
- style: { position: "fixed", left: pos.left, top: pos.top, zIndex: 1100 },
2858
+ className: "chart-tooltip chart-tooltip-show",
2859
+ style: { left: pos.left, top: pos.top },
2897
2860
  children
2898
2861
  }
2899
2862
  );
@@ -2905,14 +2868,14 @@ var ChartLegend = ({ data, labels, type }) => {
2905
2868
  const total = values.reduce((a, b) => a + b, 0) || 1;
2906
2869
  const firstKey = entries[0]?.[0] ?? "";
2907
2870
  const colorOffset = hashString(firstKey);
2908
- return /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("div", { className: "chart-legend", children: values.map((v, i) => {
2871
+ return /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("div", { className: "chart-legend", children: values.map((v, i) => {
2909
2872
  const pct = Math.round(v / total * 100);
2910
2873
  const color = PIE_COLORS[(i + colorOffset) % PIE_COLORS.length];
2911
- return /* @__PURE__ */ (0, import_jsx_runtime308.jsxs)("div", { className: "chart-legend-item", children: [
2912
- /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("span", { className: "chart-legend-dot", style: { backgroundColor: color } }),
2913
- /* @__PURE__ */ (0, import_jsx_runtime308.jsxs)("div", { className: "chart-legend-text", children: [
2914
- /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("span", { className: "chart-legend-label", children: labels[i] || `${i + 1}` }),
2915
- /* @__PURE__ */ (0, import_jsx_runtime308.jsxs)("span", { className: "chart-legend-value", children: [
2874
+ return /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)("div", { className: "chart-legend-item", children: [
2875
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("span", { className: "chart-legend-dot", style: { backgroundColor: color } }),
2876
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)("div", { className: "chart-legend-text", children: [
2877
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("span", { className: "chart-legend-label", children: labels[i] || `${i + 1}` }),
2878
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)("span", { className: "chart-legend-value", children: [
2916
2879
  v.toLocaleString(),
2917
2880
  "(",
2918
2881
  pct,
@@ -2922,37 +2885,37 @@ var ChartLegend = ({ data, labels, type }) => {
2922
2885
  ] }, i);
2923
2886
  }) });
2924
2887
  }
2925
- return /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("div", { className: "chart-legend", children: entries.map(([key], di) => {
2888
+ return /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("div", { className: "chart-legend", children: entries.map(([key], di) => {
2926
2889
  const palette = getPalette(LINE_BAR_PALETTES, di, key);
2927
2890
  const color = palette[2];
2928
2891
  const values = entries[di][1];
2929
2892
  const sum = values.reduce((a, b) => a + b, 0);
2930
- return /* @__PURE__ */ (0, import_jsx_runtime308.jsxs)("div", { className: "chart-legend-item", children: [
2931
- /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("span", { className: "chart-legend-dot", style: { backgroundColor: color } }),
2932
- /* @__PURE__ */ (0, import_jsx_runtime308.jsxs)("div", { className: "chart-legend-text", children: [
2933
- /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("span", { className: "chart-legend-label", children: key }),
2934
- /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("span", { className: "chart-legend-value", children: sum.toLocaleString() })
2893
+ return /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)("div", { className: "chart-legend-item", children: [
2894
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("span", { className: "chart-legend-dot", style: { backgroundColor: color } }),
2895
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)("div", { className: "chart-legend-text", children: [
2896
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("span", { className: "chart-legend-label", children: key }),
2897
+ /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("span", { className: "chart-legend-value", children: sum.toLocaleString() })
2935
2898
  ] })
2936
2899
  ] }, di);
2937
2900
  }) });
2938
2901
  };
2939
- var Chart = import_react7.default.memo((props) => {
2902
+ var Chart = import_react6.default.memo((props) => {
2940
2903
  const { type, data, labels, tooltip: showTooltip = true } = props;
2941
- const { tooltip, show, hide, move, containerRef } = useChartTooltip(showTooltip);
2904
+ const { tooltip, show, showAt, hide, move, containerRef } = useChartTooltip(showTooltip);
2942
2905
  const { width, height } = useChartSize(containerRef);
2943
- const stableData = import_react7.default.useMemo(() => data, [JSON.stringify(data)]);
2944
- const stableLabels = import_react7.default.useMemo(() => labels, [JSON.stringify(labels)]);
2945
- const dataKey = import_react7.default.useMemo(() => JSON.stringify(labels), [labels]);
2906
+ const stableData = import_react6.default.useMemo(() => data, [JSON.stringify(data)]);
2907
+ const stableLabels = import_react6.default.useMemo(() => labels, [JSON.stringify(labels)]);
2908
+ const dataKey = import_react6.default.useMemo(() => JSON.stringify(labels), [labels]);
2946
2909
  const animate = useChartAnimation(containerRef, dataKey);
2947
2910
  const ready = width > 0 && height > 0;
2948
- return /* @__PURE__ */ (0, import_jsx_runtime308.jsxs)("div", { className: "lib-xplat-chart", ref: containerRef, children: [
2949
- ready && type === "line" && /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(LineChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
2950
- ready && type === "curve" && /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(CurveChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
2951
- ready && type === "bar" && /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(BarChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
2952
- ready && type === "pie" && /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
2953
- ready && type === "doughnut" && /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, isDoughnut: true, onHover: show, onMove: move, onLeave: hide }),
2954
- ready && (type === "bar" || type === "pie" || type === "doughnut") && /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(ChartLegend, { data: stableData, labels: stableLabels, type }),
2955
- tooltip.content && /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(Portal_default, { children: /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(ChartTooltipPortal, { clientX: tooltip.clientX, clientY: tooltip.clientY, visible: tooltip.visible, children: tooltip.content }) })
2911
+ return /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)("div", { className: "lib-xplat-chart", ref: containerRef, children: [
2912
+ ready && type === "line" && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(LineChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
2913
+ ready && type === "curve" && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(CurveChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
2914
+ ready && type === "bar" && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(BarChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
2915
+ ready && type === "pie" && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
2916
+ ready && type === "doughnut" && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, isDoughnut: true, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
2917
+ ready && (type === "pie" || type === "doughnut") && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(ChartLegend, { data: stableData, labels: stableLabels, type }),
2918
+ tooltip.visible && tooltip.content && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(ChartTooltip, { x: tooltip.x, y: tooltip.y, containerWidth: width, containerHeight: height, children: tooltip.content })
2956
2919
  ] });
2957
2920
  });
2958
2921
  Chart.displayName = "Chart";
@@ -2965,7 +2928,7 @@ var import_tokens_core = require("@x-plat/tokens-core");
2965
2928
  var import_tokens_core2 = require("@x-plat/tokens-core");
2966
2929
 
2967
2930
  // src/components/CheckBox/CheckBox.tsx
2968
- var import_jsx_runtime309 = require("react/jsx-runtime");
2931
+ var import_jsx_runtime308 = require("react/jsx-runtime");
2969
2932
  var CheckBox = (props) => {
2970
2933
  const {
2971
2934
  checked,
@@ -2983,8 +2946,8 @@ var CheckBox = (props) => {
2983
2946
  const checkedClasses = `checked`;
2984
2947
  const disabledClasses = "disabled";
2985
2948
  const boxClasses = disabled ? disabledClasses : checked ? checkedClasses : uncheckedClasses;
2986
- return /* @__PURE__ */ (0, import_jsx_runtime309.jsxs)("label", { className: clsx_default("lib-xplat-checkbox", size, type), children: [
2987
- /* @__PURE__ */ (0, import_jsx_runtime309.jsx)(
2949
+ return /* @__PURE__ */ (0, import_jsx_runtime308.jsxs)("label", { className: clsx_default("lib-xplat-checkbox", size, type), children: [
2950
+ /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(
2988
2951
  "input",
2989
2952
  {
2990
2953
  type: "checkbox",
@@ -2994,22 +2957,22 @@ var CheckBox = (props) => {
2994
2957
  ...rest
2995
2958
  }
2996
2959
  ),
2997
- /* @__PURE__ */ (0, import_jsx_runtime309.jsx)("span", { className: clsx_default("checkbox", boxClasses), children: /* @__PURE__ */ (0, import_jsx_runtime309.jsx)("span", { className: clsx_default("check-icon", { visible: checked }), children: /* @__PURE__ */ (0, import_jsx_runtime309.jsx)(CheckIcon_default, {}) }) }),
2998
- label && /* @__PURE__ */ (0, import_jsx_runtime309.jsx)("span", { className: "label", children: label })
2960
+ /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("span", { className: clsx_default("checkbox", boxClasses), children: /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("span", { className: clsx_default("check-icon", { visible: checked }), children: /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(CheckIcon_default, {}) }) }),
2961
+ label && /* @__PURE__ */ (0, import_jsx_runtime308.jsx)("span", { className: "label", children: label })
2999
2962
  ] });
3000
2963
  };
3001
2964
  CheckBox.displayName = "CheckBox";
3002
2965
  var CheckBox_default = CheckBox;
3003
2966
 
3004
2967
  // src/components/Chip/Chip.tsx
3005
- var import_jsx_runtime310 = require("react/jsx-runtime");
2968
+ var import_jsx_runtime309 = require("react/jsx-runtime");
3006
2969
  var Chip = (props) => {
3007
2970
  const {
3008
2971
  children,
3009
2972
  type = "primary",
3010
2973
  size = "md"
3011
2974
  } = props;
3012
- return /* @__PURE__ */ (0, import_jsx_runtime310.jsx)("div", { className: clsx_default("lib-xplat-chip", type, size), children });
2975
+ return /* @__PURE__ */ (0, import_jsx_runtime309.jsx)("div", { className: clsx_default("lib-xplat-chip", type, size), children });
3013
2976
  };
3014
2977
  Chip.displayName = "Chip";
3015
2978
  var Chip_default = Chip;
@@ -3018,20 +2981,20 @@ var Chip_default = Chip;
3018
2981
  var import_react13 = __toESM(require("react"), 1);
3019
2982
 
3020
2983
  // src/components/Input/Input.tsx
3021
- var import_react8 = __toESM(require("react"), 1);
2984
+ var import_react7 = __toESM(require("react"), 1);
3022
2985
 
3023
2986
  // src/components/Input/InputValidations.tsx
3024
- var import_jsx_runtime311 = require("react/jsx-runtime");
2987
+ var import_jsx_runtime310 = require("react/jsx-runtime");
3025
2988
  var InputValidations = (props) => {
3026
2989
  const { message, status = "default" } = props;
3027
- return /* @__PURE__ */ (0, import_jsx_runtime311.jsxs)("div", { className: clsx_default("lib-xplat-input-validation", status), children: [
3028
- /* @__PURE__ */ (0, import_jsx_runtime311.jsxs)("div", { className: "icon", children: [
3029
- status === "default" && /* @__PURE__ */ (0, import_jsx_runtime311.jsx)(InfoIcon_default, {}),
3030
- status === "success" && /* @__PURE__ */ (0, import_jsx_runtime311.jsx)(SuccessIcon_default, {}),
3031
- status === "warning" && /* @__PURE__ */ (0, import_jsx_runtime311.jsx)(InfoIcon_default, {}),
3032
- status === "error" && /* @__PURE__ */ (0, import_jsx_runtime311.jsx)(ErrorIcon_default, {})
2990
+ return /* @__PURE__ */ (0, import_jsx_runtime310.jsxs)("div", { className: clsx_default("lib-xplat-input-validation", status), children: [
2991
+ /* @__PURE__ */ (0, import_jsx_runtime310.jsxs)("div", { className: "icon", children: [
2992
+ status === "default" && /* @__PURE__ */ (0, import_jsx_runtime310.jsx)(InfoIcon_default, {}),
2993
+ status === "success" && /* @__PURE__ */ (0, import_jsx_runtime310.jsx)(SuccessIcon_default, {}),
2994
+ status === "warning" && /* @__PURE__ */ (0, import_jsx_runtime310.jsx)(InfoIcon_default, {}),
2995
+ status === "error" && /* @__PURE__ */ (0, import_jsx_runtime310.jsx)(ErrorIcon_default, {})
3033
2996
  ] }),
3034
- /* @__PURE__ */ (0, import_jsx_runtime311.jsx)("div", { className: "message", children: message })
2997
+ /* @__PURE__ */ (0, import_jsx_runtime310.jsx)("div", { className: "message", children: message })
3035
2998
  ] });
3036
2999
  };
3037
3000
  InputValidations.displayName = "InputValidations";
@@ -3072,8 +3035,8 @@ var handleTelBackspace = (prevValue, currValue) => {
3072
3035
  };
3073
3036
 
3074
3037
  // src/components/Input/Input.tsx
3075
- var import_jsx_runtime312 = require("react/jsx-runtime");
3076
- var import_react9 = require("react");
3038
+ var import_jsx_runtime311 = require("react/jsx-runtime");
3039
+ var import_react8 = require("react");
3077
3040
  var formatValue = (type, value) => {
3078
3041
  if (value === null || value === void 0) return "";
3079
3042
  const strValue = Array.isArray(value) ? String(value[0] ?? "") : String(value);
@@ -3121,7 +3084,7 @@ var parseValue = (type, value) => {
3121
3084
  return value;
3122
3085
  }
3123
3086
  };
3124
- var Input = import_react8.default.forwardRef((props, ref) => {
3087
+ var Input = import_react7.default.forwardRef((props, ref) => {
3125
3088
  const {
3126
3089
  value,
3127
3090
  onChange,
@@ -3147,13 +3110,13 @@ var Input = import_react8.default.forwardRef((props, ref) => {
3147
3110
  onChange(event);
3148
3111
  }
3149
3112
  };
3150
- return /* @__PURE__ */ (0, import_jsx_runtime312.jsxs)("div", { className: "lib-xplat-input-wrap", children: [
3151
- /* @__PURE__ */ (0, import_jsx_runtime312.jsxs)(
3113
+ return /* @__PURE__ */ (0, import_jsx_runtime311.jsxs)("div", { className: "lib-xplat-input-wrap", children: [
3114
+ /* @__PURE__ */ (0, import_jsx_runtime311.jsxs)(
3152
3115
  "div",
3153
3116
  {
3154
3117
  className: clsx_default("lib-xplat-input", size, disabled ? "disabled" : void 0),
3155
3118
  children: [
3156
- /* @__PURE__ */ (0, import_jsx_runtime312.jsx)(
3119
+ /* @__PURE__ */ (0, import_jsx_runtime311.jsx)(
3157
3120
  "input",
3158
3121
  {
3159
3122
  ...inputProps,
@@ -3164,11 +3127,11 @@ var Input = import_react8.default.forwardRef((props, ref) => {
3164
3127
  onChange: handleChange
3165
3128
  }
3166
3129
  ),
3167
- suffix && /* @__PURE__ */ (0, import_jsx_runtime312.jsx)("div", { className: "suffix", children: suffix })
3130
+ suffix && /* @__PURE__ */ (0, import_jsx_runtime311.jsx)("div", { className: "suffix", children: suffix })
3168
3131
  ]
3169
3132
  }
3170
3133
  ),
3171
- validations && /* @__PURE__ */ (0, import_jsx_runtime312.jsx)("div", { className: "lib-xplat-input-validation-wrap", children: validations?.map((validation, idx) => /* @__PURE__ */ (0, import_react9.createElement)(
3134
+ validations && /* @__PURE__ */ (0, import_jsx_runtime311.jsx)("div", { className: "lib-xplat-input-validation-wrap", children: validations?.map((validation, idx) => /* @__PURE__ */ (0, import_react8.createElement)(
3172
3135
  InputValidations_default,
3173
3136
  {
3174
3137
  ...validation,
@@ -3181,20 +3144,20 @@ Input.displayName = "Input";
3181
3144
  var Input_default = Input;
3182
3145
 
3183
3146
  // src/components/Input/PasswordInput/PasswordInput.tsx
3184
- var import_react10 = __toESM(require("react"), 1);
3185
- var import_jsx_runtime313 = require("react/jsx-runtime");
3186
- var PasswordInput = import_react10.default.forwardRef(
3147
+ var import_react9 = __toESM(require("react"), 1);
3148
+ var import_jsx_runtime312 = require("react/jsx-runtime");
3149
+ var PasswordInput = import_react9.default.forwardRef(
3187
3150
  (props, ref) => {
3188
3151
  const { reg: _reg, ...inputProps } = props;
3189
- const [isView, setIsView] = import_react10.default.useState(false);
3152
+ const [isView, setIsView] = import_react9.default.useState(false);
3190
3153
  const handleChangeView = () => {
3191
3154
  setIsView((prev) => !prev);
3192
3155
  };
3193
- return /* @__PURE__ */ (0, import_jsx_runtime313.jsx)(
3156
+ return /* @__PURE__ */ (0, import_jsx_runtime312.jsx)(
3194
3157
  Input_default,
3195
3158
  {
3196
3159
  ...inputProps,
3197
- suffix: /* @__PURE__ */ (0, import_jsx_runtime313.jsx)("div", { className: "wrapper pointer", onClick: handleChangeView, children: isView ? /* @__PURE__ */ (0, import_jsx_runtime313.jsx)(OpenEyeIcon_default, {}) : /* @__PURE__ */ (0, import_jsx_runtime313.jsx)(CloseEyeIcon_default, {}) }),
3160
+ suffix: /* @__PURE__ */ (0, import_jsx_runtime312.jsx)("div", { className: "wrapper pointer", onClick: handleChangeView, children: isView ? /* @__PURE__ */ (0, import_jsx_runtime312.jsx)(OpenEyeIcon_default, {}) : /* @__PURE__ */ (0, import_jsx_runtime312.jsx)(CloseEyeIcon_default, {}) }),
3198
3161
  type: isView ? "text" : "password",
3199
3162
  ref
3200
3163
  }
@@ -3207,6 +3170,23 @@ var PasswordInput_default = PasswordInput;
3207
3170
  // src/components/Modal/Modal.tsx
3208
3171
  var import_react11 = __toESM(require("react"), 1);
3209
3172
  var import_react_dom2 = require("react-dom");
3173
+
3174
+ // src/tokens/hooks/Portal.tsx
3175
+ var import_react10 = __toESM(require("react"), 1);
3176
+ var import_react_dom = __toESM(require("react-dom"), 1);
3177
+ var import_jsx_runtime313 = require("react/jsx-runtime");
3178
+ var PortalContainerContext = import_react10.default.createContext(null);
3179
+ var PortalProvider = ({ container, children }) => /* @__PURE__ */ (0, import_jsx_runtime313.jsx)(PortalContainerContext.Provider, { value: container, children });
3180
+ var Portal = ({ children }) => {
3181
+ const contextContainer = import_react10.default.useContext(PortalContainerContext);
3182
+ if (typeof document === "undefined") return null;
3183
+ const container = contextContainer ?? document.body;
3184
+ return import_react_dom.default.createPortal(children, container);
3185
+ };
3186
+ Portal.displayName = "Portal";
3187
+ var Portal_default = Portal;
3188
+
3189
+ // src/components/Modal/Modal.tsx
3210
3190
  var import_jsx_runtime314 = require("react/jsx-runtime");
3211
3191
  var ANIMATION_DURATION_MS = 200;
3212
3192
  var Modal = (props) => {