@x-plat/design-system 0.5.37 → 0.5.38

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.
@@ -1,46 +1,46 @@
1
1
  /* src/components/Tooltip/tooltip.scss */
2
+ .lib-xplat-tooltip-trigger {
3
+ display: inline-flex;
4
+ }
2
5
  .lib-xplat-tooltip {
3
- width: fit-content;
4
- position: relative;
5
- }
6
- .lib-xplat-tooltip > .tooltip-content {
7
- width: fit-content;
8
- height: fit-content;
9
- }
10
- .lib-xplat-tooltip > .tooltip-wrapper {
11
- position: absolute;
12
- transform: translateX(-50%) scale(0.5);
13
- left: 50%;
14
- box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
15
- white-space: nowrap;
16
- border-radius: var(--spacing-radius-sm);
17
- padding: var(--spacing-space-2) var(--spacing-space-2);
18
- opacity: 0;
6
+ z-index: 1100;
7
+ padding: var(--spacing-space-3);
8
+ border-radius: var(--spacing-radius-md);
9
+ max-width: 240px;
19
10
  pointer-events: none;
20
- bottom: 100%;
21
- transition: opacity 0.12s ease, transform 0.15s cubic-bezier(0.16, 1, 0.3, 1);
11
+ animation: tooltip-show 120ms ease-out;
22
12
  }
23
- .lib-xplat-tooltip > .tooltip-wrapper.primary {
24
- color: var(--semantic-text-inverse);
13
+ .lib-xplat-tooltip .tooltip-title {
14
+ font-size: 13px;
15
+ line-height: 18px;
16
+ font-weight: 400;
17
+ }
18
+ .lib-xplat-tooltip .tooltip-desc {
19
+ font-size: 12px;
20
+ line-height: 18px;
21
+ font-weight: 400;
22
+ }
23
+ .lib-xplat-tooltip.dark {
25
24
  background-color: var(--semantic-surface-neutral-strong);
25
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
26
+ }
27
+ .lib-xplat-tooltip.dark .tooltip-title,
28
+ .lib-xplat-tooltip.dark .tooltip-desc {
29
+ color: var(--semantic-text-inverse);
26
30
  }
27
- .lib-xplat-tooltip > .tooltip-wrapper.secondary {
31
+ .lib-xplat-tooltip.light {
28
32
  background-color: var(--semantic-surface-neutral-default);
29
- color: var(--semantic-text-strong);
30
- }
31
- .lib-xplat-tooltip.tooltip-bottom > .tooltip-wrapper {
32
- top: 100%;
33
- bottom: auto;
34
- transform-origin: top center;
35
- }
36
- .lib-xplat-tooltip.tooltip-top > .tooltip-wrapper {
37
- bottom: 100%;
38
- top: auto;
39
- transform-origin: bottom center;
40
- }
41
- .lib-xplat-tooltip:hover > .tooltip-content + .tooltip-wrapper,
42
- .lib-xplat-tooltip > .tooltip-content:hover + .tooltip-wrapper {
43
- opacity: 1;
44
- pointer-events: auto;
45
- transform: translateX(-50%) scale(1);
33
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
34
+ }
35
+ .lib-xplat-tooltip.light .tooltip-title,
36
+ .lib-xplat-tooltip.light .tooltip-desc {
37
+ color: var(--semantic-text-subtle);
38
+ }
39
+ @keyframes tooltip-show {
40
+ from {
41
+ opacity: 0;
42
+ }
43
+ to {
44
+ opacity: 1;
45
+ }
46
46
  }
@@ -1,14 +1,12 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
1
  import React from 'react';
3
2
 
4
3
  interface TooltipProps {
5
- type?: "primary" | "secondary";
6
- description: React.ReactNode;
7
- children?: React.ReactNode;
4
+ type?: "dark" | "light";
5
+ title?: React.ReactNode;
6
+ description?: React.ReactNode;
7
+ children: React.ReactNode;
8
+ disabled?: boolean;
8
9
  }
9
- declare const Tooltip: {
10
- (props: TooltipProps): react_jsx_runtime.JSX.Element;
11
- displayName: string;
12
- };
10
+ declare const Tooltip: React.FC<TooltipProps>;
13
11
 
14
12
  export { Tooltip };
@@ -1,14 +1,12 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
1
  import React from 'react';
3
2
 
4
3
  interface TooltipProps {
5
- type?: "primary" | "secondary";
6
- description: React.ReactNode;
7
- children?: React.ReactNode;
4
+ type?: "dark" | "light";
5
+ title?: React.ReactNode;
6
+ description?: React.ReactNode;
7
+ children: React.ReactNode;
8
+ disabled?: boolean;
8
9
  }
9
- declare const Tooltip: {
10
- (props: TooltipProps): react_jsx_runtime.JSX.Element;
11
- displayName: string;
12
- };
10
+ declare const Tooltip: React.FC<TooltipProps>;
13
11
 
14
12
  export { Tooltip };
@@ -1,5 +1,19 @@
1
1
  // src/components/Tooltip/Tooltip.tsx
2
+ import React2 from "react";
3
+
4
+ // src/tokens/hooks/Portal.tsx
2
5
  import React from "react";
6
+ import ReactDOM from "react-dom";
7
+ import { jsx } from "react/jsx-runtime";
8
+ var PortalContainerContext = React.createContext(null);
9
+ var Portal = ({ children }) => {
10
+ const contextContainer = React.useContext(PortalContainerContext);
11
+ if (typeof document === "undefined") return null;
12
+ const container = contextContainer ?? document.body;
13
+ return ReactDOM.createPortal(children, container);
14
+ };
15
+ Portal.displayName = "Portal";
16
+ var Portal_default = Portal;
3
17
 
4
18
  // ../../node_modules/clsx/dist/clsx.mjs
5
19
  function r(e) {
@@ -18,18 +32,94 @@ function clsx() {
18
32
  var clsx_default = clsx;
19
33
 
20
34
  // src/components/Tooltip/Tooltip.tsx
21
- import { jsx, jsxs } from "react/jsx-runtime";
35
+ import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
36
+ var OFFSET = 12;
37
+ var SHOW_DELAY = 300;
22
38
  var Tooltip = (props) => {
23
39
  const {
24
- type = "primary",
40
+ type = "dark",
41
+ title,
25
42
  description,
26
- children
43
+ children,
44
+ disabled = false
27
45
  } = props;
28
- const iconRef = React.useRef(null);
29
- return /* @__PURE__ */ jsxs("div", { className: "lib-xplat-tooltip", children: [
30
- /* @__PURE__ */ jsx("div", { className: "tooltip-content", ref: iconRef, children: children || "Tooltip" }),
31
- /* @__PURE__ */ jsx("div", { className: clsx_default("tooltip-wrapper", type), children: description })
32
- ] });
46
+ const triggerRef = React2.useRef(null);
47
+ const tooltipRef = React2.useRef(null);
48
+ const [visible, setVisible] = React2.useState(false);
49
+ const [pos, setPos] = React2.useState({ left: 0, top: 0 });
50
+ const delayTimer = React2.useRef(0);
51
+ const calculatePos = React2.useCallback((clientX, clientY) => {
52
+ const el = tooltipRef.current;
53
+ if (!el) return;
54
+ const w = el.offsetWidth;
55
+ const h = el.offsetHeight;
56
+ const vw = window.innerWidth;
57
+ let left = clientX + OFFSET;
58
+ let top = clientY - h - OFFSET;
59
+ if (left + w > vw - 8) left = clientX - w - OFFSET;
60
+ if (top < 8) top = clientY + OFFSET;
61
+ if (left < 8) left = 8;
62
+ setPos({ left, top });
63
+ }, []);
64
+ const handleMouseEnter = React2.useCallback(() => {
65
+ if (disabled) return;
66
+ delayTimer.current = window.setTimeout(() => {
67
+ setVisible(true);
68
+ }, SHOW_DELAY);
69
+ }, [disabled]);
70
+ const handleMouseMove = React2.useCallback((e) => {
71
+ if (!visible) return;
72
+ calculatePos(e.clientX, e.clientY);
73
+ }, [visible, calculatePos]);
74
+ const handleMouseLeave = React2.useCallback(() => {
75
+ window.clearTimeout(delayTimer.current);
76
+ setVisible(false);
77
+ }, []);
78
+ const handleClick = React2.useCallback(() => {
79
+ window.clearTimeout(delayTimer.current);
80
+ setVisible(false);
81
+ }, []);
82
+ const handleFocus = React2.useCallback(() => {
83
+ if (disabled) return;
84
+ setVisible(true);
85
+ }, [disabled]);
86
+ const handleBlur = React2.useCallback(() => {
87
+ setVisible(false);
88
+ }, []);
89
+ React2.useLayoutEffect(() => {
90
+ if (!visible || !triggerRef.current) return;
91
+ const rect = triggerRef.current.getBoundingClientRect();
92
+ calculatePos(rect.right, rect.top);
93
+ }, [visible, calculatePos]);
94
+ if (!title && !description) return /* @__PURE__ */ jsx2(Fragment, { children });
95
+ return /* @__PURE__ */ jsxs(
96
+ "div",
97
+ {
98
+ ref: triggerRef,
99
+ className: "lib-xplat-tooltip-trigger",
100
+ onMouseEnter: handleMouseEnter,
101
+ onMouseMove: handleMouseMove,
102
+ onMouseLeave: handleMouseLeave,
103
+ onClick: handleClick,
104
+ onFocus: handleFocus,
105
+ onBlur: handleBlur,
106
+ children: [
107
+ children,
108
+ visible && /* @__PURE__ */ jsx2(Portal_default, { children: /* @__PURE__ */ jsxs(
109
+ "div",
110
+ {
111
+ ref: tooltipRef,
112
+ className: clsx_default("lib-xplat-tooltip", type),
113
+ style: { position: "fixed", left: pos.left, top: pos.top },
114
+ children: [
115
+ title && /* @__PURE__ */ jsx2("div", { className: "tooltip-title", children: title }),
116
+ description && /* @__PURE__ */ jsx2("div", { className: "tooltip-desc", children: description })
117
+ ]
118
+ }
119
+ ) })
120
+ ]
121
+ }
122
+ );
33
123
  };
34
124
  Tooltip.displayName = "Tooltip";
35
125
  var Tooltip_default = Tooltip;
@@ -2380,28 +2380,11 @@ var useChartTooltip = (enabled) => {
2380
2380
  if (!rect) return;
2381
2381
  setTooltip({ visible: true, x: e.clientX - rect.left, y: e.clientY - rect.top, content });
2382
2382
  }, [enabled]);
2383
- const showAt = import_react6.default.useCallback((svgX, svgY, content, svgEl) => {
2384
- if (!enabled) return;
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 });
2399
- }, [enabled]);
2400
2383
  const hide = import_react6.default.useCallback(() => {
2401
2384
  cancelAnimationFrame(rafRef.current);
2402
2385
  setTooltip((prev) => ({ ...prev, visible: false }));
2403
2386
  }, []);
2404
- return { tooltip, show, showAt, hide, move, containerRef };
2387
+ return { tooltip, show, hide, move, containerRef };
2405
2388
  };
2406
2389
  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) => {
2407
2390
  const y = PADDING.top + (1 - ratio) * chartH;
@@ -2466,7 +2449,7 @@ var useCrosshair = (seriesPoints, entries, labels, chartH) => {
2466
2449
  }, [entries, seriesPoints]);
2467
2450
  return { activeIndex, handleMouseMove, handleMouseLeave, tooltipContent, getTooltipAt };
2468
2451
  };
2469
- var LineChart = import_react6.default.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
2452
+ var LineChart = import_react6.default.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
2470
2453
  const entries = import_react6.default.useMemo(() => Object.entries(data), [data]);
2471
2454
  const maxVal = import_react6.default.useMemo(() => {
2472
2455
  const allValues = entries.flatMap(([, v]) => v);
@@ -2486,7 +2469,6 @@ var LineChart = import_react6.default.memo(({ data, labels, width, height, anima
2486
2469
  [entries, count, chartW, chartH, maxVal]
2487
2470
  );
2488
2471
  const clipRef = import_react6.default.useRef(null);
2489
- const svgRef = import_react6.default.useRef(null);
2490
2472
  const { activeIndex, handleMouseMove, handleMouseLeave, getTooltipAt } = useCrosshair(seriesPoints, entries, labels, chartH);
2491
2473
  import_react6.default.useEffect(() => {
2492
2474
  if (!animate || !clipRef.current) return;
@@ -2503,14 +2485,12 @@ var LineChart = import_react6.default.memo(({ data, labels, width, height, anima
2503
2485
  return /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)(
2504
2486
  "svg",
2505
2487
  {
2506
- ref: svgRef,
2507
2488
  viewBox: `0 0 ${width} ${height}`,
2508
2489
  className: "chart-svg",
2509
2490
  onMouseMove: (e) => {
2510
2491
  handleMouseMove(e);
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);
2492
+ if (activeIndex !== null) {
2493
+ onHover(e, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
2514
2494
  } else {
2515
2495
  onLeave();
2516
2496
  }
@@ -2578,7 +2558,7 @@ var LineChart = import_react6.default.memo(({ data, labels, width, height, anima
2578
2558
  );
2579
2559
  });
2580
2560
  LineChart.displayName = "LineChart";
2581
- var CurveChart = import_react6.default.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
2561
+ var CurveChart = import_react6.default.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
2582
2562
  const entries = import_react6.default.useMemo(() => Object.entries(data), [data]);
2583
2563
  const maxVal = import_react6.default.useMemo(() => {
2584
2564
  const allValues = entries.flatMap(([, v]) => v);
@@ -2598,7 +2578,6 @@ var CurveChart = import_react6.default.memo(({ data, labels, width, height, anim
2598
2578
  [entries, count, chartW, chartH, maxVal]
2599
2579
  );
2600
2580
  const curveClipRef = import_react6.default.useRef(null);
2601
- const curveSvgRef = import_react6.default.useRef(null);
2602
2581
  const { activeIndex, handleMouseMove, handleMouseLeave, getTooltipAt } = useCrosshair(seriesPoints, entries, labels, chartH);
2603
2582
  import_react6.default.useEffect(() => {
2604
2583
  if (!animate || !curveClipRef.current) return;
@@ -2615,14 +2594,13 @@ var CurveChart = import_react6.default.memo(({ data, labels, width, height, anim
2615
2594
  return /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)(
2616
2595
  "svg",
2617
2596
  {
2618
- ref: curveSvgRef,
2619
2597
  viewBox: `0 0 ${width} ${height}`,
2620
2598
  className: "chart-svg",
2621
2599
  onMouseMove: (e) => {
2622
2600
  handleMouseMove(e);
2623
2601
  if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
2624
2602
  const p = seriesPoints[0][activeIndex];
2625
- onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`, curveSvgRef.current);
2603
+ onHover(e, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
2626
2604
  } else {
2627
2605
  onLeave();
2628
2606
  }
@@ -2690,8 +2668,7 @@ var CurveChart = import_react6.default.memo(({ data, labels, width, height, anim
2690
2668
  );
2691
2669
  });
2692
2670
  CurveChart.displayName = "CurveChart";
2693
- var BarChart = import_react6.default.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
2694
- const barSvgRef = import_react6.default.useRef(null);
2671
+ var BarChart = import_react6.default.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
2695
2672
  const entries = import_react6.default.useMemo(() => Object.entries(data), [data]);
2696
2673
  const maxVal = import_react6.default.useMemo(() => {
2697
2674
  const allValues = entries.flatMap(([, v]) => v);
@@ -2718,7 +2695,7 @@ var BarChart = import_react6.default.memo(({ data, labels, width, height, animat
2718
2695
  [entries, maxVal, chartH, groupW, barW, barGap, groupCount]
2719
2696
  );
2720
2697
  const barLabelStep = getLabelStep(count, chartW);
2721
- return /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)("svg", { ref: barSvgRef, viewBox: `0 0 ${width} ${height}`, className: "chart-svg", children: [
2698
+ return /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)("svg", { viewBox: `0 0 ${width} ${height}`, className: "chart-svg", children: [
2722
2699
  /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(GridLines, { width, height, chartH, maxVal }),
2723
2700
  labels.map((label, i) => {
2724
2701
  if (i % barLabelStep !== 0) return null;
@@ -2741,7 +2718,8 @@ var BarChart = import_react6.default.memo(({ data, labels, width, height, animat
2741
2718
  transformOrigin: `${b.x + b.w / 2}px ${baseline}px`,
2742
2719
  animationDelay: `${delay}ms`
2743
2720
  } : void 0,
2744
- onMouseEnter: () => onShowAt(b.x + b.w / 2, b.y, `${key}: ${labels[i]} \u2014 ${b.v}`, barSvgRef.current),
2721
+ onMouseEnter: (e) => onHover(e, `${key}: ${labels[i]} \u2014 ${b.v}`),
2722
+ onMouseMove: onMove,
2745
2723
  onMouseLeave: onLeave
2746
2724
  },
2747
2725
  `${di}-${i}`
@@ -2829,14 +2807,17 @@ var PieDonutChart = import_react6.default.memo(
2829
2807
  {
2830
2808
  d: s.d,
2831
2809
  fill: PIE_COLORS[(i + colorOffset) % PIE_COLORS.length],
2832
- className: "chart-slice"
2810
+ className: "chart-slice",
2811
+ onMouseEnter: (e) => onHover(e, `${s.label} \u2014 ${s.v.toLocaleString()} (${s.pct}%)`),
2812
+ onMouseMove: onMove,
2813
+ onMouseLeave: onLeave
2833
2814
  }
2834
2815
  ) }, i)) })
2835
2816
  ] });
2836
2817
  }
2837
2818
  );
2838
2819
  PieDonutChart.displayName = "PieDonutChart";
2839
- var ChartTooltip = ({ x, y, containerWidth, containerHeight, children }) => {
2820
+ var ChartTooltip = ({ x, y, containerWidth, containerHeight, tooltipType, children }) => {
2840
2821
  const ref = import_react6.default.useRef(null);
2841
2822
  const [pos, setPos] = import_react6.default.useState({ left: 0, top: 0 });
2842
2823
  import_react6.default.useLayoutEffect(() => {
@@ -2851,13 +2832,20 @@ var ChartTooltip = ({ x, y, containerWidth, containerHeight, children }) => {
2851
2832
  if (left < 0) left = 0;
2852
2833
  setPos({ left, top });
2853
2834
  }, [x, y, containerWidth, containerHeight]);
2854
- return /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(
2835
+ const content = typeof children === "string" ? children : "";
2836
+ const sepIdx = content.indexOf(" \u2014 ");
2837
+ const title = sepIdx >= 0 ? content.slice(0, sepIdx) : content;
2838
+ const desc = sepIdx >= 0 ? content.slice(sepIdx + 3) : "";
2839
+ return /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)(
2855
2840
  "div",
2856
2841
  {
2857
2842
  ref,
2858
- className: "chart-tooltip chart-tooltip-show",
2843
+ className: `chart-tooltip chart-tooltip-show chart-tooltip-${tooltipType}`,
2859
2844
  style: { left: pos.left, top: pos.top },
2860
- children
2845
+ children: [
2846
+ title && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("div", { className: "chart-tooltip-title", children: title }),
2847
+ desc && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)("div", { className: "chart-tooltip-desc", children: desc })
2848
+ ]
2861
2849
  }
2862
2850
  );
2863
2851
  };
@@ -2900,8 +2888,8 @@ var ChartLegend = ({ data, labels, type }) => {
2900
2888
  }) });
2901
2889
  };
2902
2890
  var Chart = import_react6.default.memo((props) => {
2903
- const { type, data, labels, tooltip: showTooltip = true } = props;
2904
- const { tooltip, show, showAt, hide, move, containerRef } = useChartTooltip(showTooltip);
2891
+ const { type, data, labels, tooltip: showTooltip = true, tooltipType = "dark" } = props;
2892
+ const { tooltip, show, hide, move, containerRef } = useChartTooltip(showTooltip);
2905
2893
  const { width, height } = useChartSize(containerRef);
2906
2894
  const stableData = import_react6.default.useMemo(() => data, [JSON.stringify(data)]);
2907
2895
  const stableLabels = import_react6.default.useMemo(() => labels, [JSON.stringify(labels)]);
@@ -2909,13 +2897,13 @@ var Chart = import_react6.default.memo((props) => {
2909
2897
  const animate = useChartAnimation(containerRef, dataKey);
2910
2898
  const ready = width > 0 && height > 0;
2911
2899
  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 }),
2900
+ ready && type === "line" && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(LineChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
2901
+ ready && type === "curve" && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(CurveChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
2902
+ ready && type === "bar" && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(BarChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
2903
+ ready && type === "pie" && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
2904
+ ready && type === "doughnut" && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, isDoughnut: true, onHover: show, onMove: move, onLeave: hide }),
2917
2905
  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 })
2906
+ tooltip.visible && tooltip.content && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(ChartTooltip, { x: tooltip.x, y: tooltip.y, containerWidth: width, containerHeight: height, tooltipType, children: tooltip.content })
2919
2907
  ] });
2920
2908
  });
2921
2909
  Chart.displayName = "Chart";
@@ -5423,17 +5411,93 @@ ToastProvider.displayName = "ToastProvider";
5423
5411
  // src/components/Tooltip/Tooltip.tsx
5424
5412
  var import_react40 = __toESM(require("react"), 1);
5425
5413
  var import_jsx_runtime348 = require("react/jsx-runtime");
5414
+ var OFFSET = 12;
5415
+ var SHOW_DELAY = 300;
5426
5416
  var Tooltip = (props) => {
5427
5417
  const {
5428
- type = "primary",
5418
+ type = "dark",
5419
+ title,
5429
5420
  description,
5430
- children
5421
+ children,
5422
+ disabled = false
5431
5423
  } = props;
5432
- const iconRef = import_react40.default.useRef(null);
5433
- return /* @__PURE__ */ (0, import_jsx_runtime348.jsxs)("div", { className: "lib-xplat-tooltip", children: [
5434
- /* @__PURE__ */ (0, import_jsx_runtime348.jsx)("div", { className: "tooltip-content", ref: iconRef, children: children || "Tooltip" }),
5435
- /* @__PURE__ */ (0, import_jsx_runtime348.jsx)("div", { className: clsx_default("tooltip-wrapper", type), children: description })
5436
- ] });
5424
+ const triggerRef = import_react40.default.useRef(null);
5425
+ const tooltipRef = import_react40.default.useRef(null);
5426
+ const [visible, setVisible] = import_react40.default.useState(false);
5427
+ const [pos, setPos] = import_react40.default.useState({ left: 0, top: 0 });
5428
+ const delayTimer = import_react40.default.useRef(0);
5429
+ const calculatePos = import_react40.default.useCallback((clientX, clientY) => {
5430
+ const el = tooltipRef.current;
5431
+ if (!el) return;
5432
+ const w = el.offsetWidth;
5433
+ const h = el.offsetHeight;
5434
+ const vw = window.innerWidth;
5435
+ let left = clientX + OFFSET;
5436
+ let top = clientY - h - OFFSET;
5437
+ if (left + w > vw - 8) left = clientX - w - OFFSET;
5438
+ if (top < 8) top = clientY + OFFSET;
5439
+ if (left < 8) left = 8;
5440
+ setPos({ left, top });
5441
+ }, []);
5442
+ const handleMouseEnter = import_react40.default.useCallback(() => {
5443
+ if (disabled) return;
5444
+ delayTimer.current = window.setTimeout(() => {
5445
+ setVisible(true);
5446
+ }, SHOW_DELAY);
5447
+ }, [disabled]);
5448
+ const handleMouseMove = import_react40.default.useCallback((e) => {
5449
+ if (!visible) return;
5450
+ calculatePos(e.clientX, e.clientY);
5451
+ }, [visible, calculatePos]);
5452
+ const handleMouseLeave = import_react40.default.useCallback(() => {
5453
+ window.clearTimeout(delayTimer.current);
5454
+ setVisible(false);
5455
+ }, []);
5456
+ const handleClick = import_react40.default.useCallback(() => {
5457
+ window.clearTimeout(delayTimer.current);
5458
+ setVisible(false);
5459
+ }, []);
5460
+ const handleFocus = import_react40.default.useCallback(() => {
5461
+ if (disabled) return;
5462
+ setVisible(true);
5463
+ }, [disabled]);
5464
+ const handleBlur = import_react40.default.useCallback(() => {
5465
+ setVisible(false);
5466
+ }, []);
5467
+ import_react40.default.useLayoutEffect(() => {
5468
+ if (!visible || !triggerRef.current) return;
5469
+ const rect = triggerRef.current.getBoundingClientRect();
5470
+ calculatePos(rect.right, rect.top);
5471
+ }, [visible, calculatePos]);
5472
+ if (!title && !description) return /* @__PURE__ */ (0, import_jsx_runtime348.jsx)(import_jsx_runtime348.Fragment, { children });
5473
+ return /* @__PURE__ */ (0, import_jsx_runtime348.jsxs)(
5474
+ "div",
5475
+ {
5476
+ ref: triggerRef,
5477
+ className: "lib-xplat-tooltip-trigger",
5478
+ onMouseEnter: handleMouseEnter,
5479
+ onMouseMove: handleMouseMove,
5480
+ onMouseLeave: handleMouseLeave,
5481
+ onClick: handleClick,
5482
+ onFocus: handleFocus,
5483
+ onBlur: handleBlur,
5484
+ children: [
5485
+ children,
5486
+ visible && /* @__PURE__ */ (0, import_jsx_runtime348.jsx)(Portal_default, { children: /* @__PURE__ */ (0, import_jsx_runtime348.jsxs)(
5487
+ "div",
5488
+ {
5489
+ ref: tooltipRef,
5490
+ className: clsx_default("lib-xplat-tooltip", type),
5491
+ style: { position: "fixed", left: pos.left, top: pos.top },
5492
+ children: [
5493
+ title && /* @__PURE__ */ (0, import_jsx_runtime348.jsx)("div", { className: "tooltip-title", children: title }),
5494
+ description && /* @__PURE__ */ (0, import_jsx_runtime348.jsx)("div", { className: "tooltip-desc", children: description })
5495
+ ]
5496
+ }
5497
+ ) })
5498
+ ]
5499
+ }
5500
+ );
5437
5501
  };
5438
5502
  Tooltip.displayName = "Tooltip";
5439
5503
  var Tooltip_default = Tooltip;