@x-plat/design-system 0.5.36 → 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.
@@ -186,15 +186,11 @@ var useChartTooltip = (enabled) => {
186
186
  if (!rect) return;
187
187
  setTooltip({ visible: true, x: e.clientX - rect.left, y: e.clientY - rect.top, content });
188
188
  }, [enabled]);
189
- const showAt = import_react.default.useCallback((x, y, content) => {
190
- if (!enabled) return;
191
- setTooltip({ visible: true, x, y, content });
192
- }, [enabled]);
193
189
  const hide = import_react.default.useCallback(() => {
194
190
  cancelAnimationFrame(rafRef.current);
195
191
  setTooltip((prev) => ({ ...prev, visible: false }));
196
192
  }, []);
197
- return { tooltip, show, showAt, hide, move, containerRef };
193
+ return { tooltip, show, hide, move, containerRef };
198
194
  };
199
195
  var GridLines = import_react.default.memo(({ width, height, chartH, maxVal }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: [0, 0.25, 0.5, 0.75, 1].map((ratio) => {
200
196
  const y = PADDING.top + (1 - ratio) * chartH;
@@ -259,7 +255,7 @@ var useCrosshair = (seriesPoints, entries, labels, chartH) => {
259
255
  }, [entries, seriesPoints]);
260
256
  return { activeIndex, handleMouseMove, handleMouseLeave, tooltipContent, getTooltipAt };
261
257
  };
262
- var LineChart = import_react.default.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
258
+ var LineChart = import_react.default.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
263
259
  const entries = import_react.default.useMemo(() => Object.entries(data), [data]);
264
260
  const maxVal = import_react.default.useMemo(() => {
265
261
  const allValues = entries.flatMap(([, v]) => v);
@@ -299,9 +295,8 @@ var LineChart = import_react.default.memo(({ data, labels, width, height, animat
299
295
  className: "chart-svg",
300
296
  onMouseMove: (e) => {
301
297
  handleMouseMove(e);
302
- if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
303
- const p = seriesPoints[0][activeIndex];
304
- onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
298
+ if (activeIndex !== null) {
299
+ onHover(e, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
305
300
  } else {
306
301
  onLeave();
307
302
  }
@@ -369,7 +364,7 @@ var LineChart = import_react.default.memo(({ data, labels, width, height, animat
369
364
  );
370
365
  });
371
366
  LineChart.displayName = "LineChart";
372
- var CurveChart = import_react.default.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
367
+ var CurveChart = import_react.default.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
373
368
  const entries = import_react.default.useMemo(() => Object.entries(data), [data]);
374
369
  const maxVal = import_react.default.useMemo(() => {
375
370
  const allValues = entries.flatMap(([, v]) => v);
@@ -411,7 +406,7 @@ var CurveChart = import_react.default.memo(({ data, labels, width, height, anima
411
406
  handleMouseMove(e);
412
407
  if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
413
408
  const p = seriesPoints[0][activeIndex];
414
- onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
409
+ onHover(e, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
415
410
  } else {
416
411
  onLeave();
417
412
  }
@@ -479,7 +474,7 @@ var CurveChart = import_react.default.memo(({ data, labels, width, height, anima
479
474
  );
480
475
  });
481
476
  CurveChart.displayName = "CurveChart";
482
- var BarChart = import_react.default.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
477
+ var BarChart = import_react.default.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
483
478
  const entries = import_react.default.useMemo(() => Object.entries(data), [data]);
484
479
  const maxVal = import_react.default.useMemo(() => {
485
480
  const allValues = entries.flatMap(([, v]) => v);
@@ -529,7 +524,8 @@ var BarChart = import_react.default.memo(({ data, labels, width, height, animate
529
524
  transformOrigin: `${b.x + b.w / 2}px ${baseline}px`,
530
525
  animationDelay: `${delay}ms`
531
526
  } : void 0,
532
- onMouseEnter: () => onShowAt(b.x + b.w / 2, b.y, `${key}: ${labels[i]} \u2014 ${b.v}`),
527
+ onMouseEnter: (e) => onHover(e, `${key}: ${labels[i]} \u2014 ${b.v}`),
528
+ onMouseMove: onMove,
533
529
  onMouseLeave: onLeave
534
530
  },
535
531
  `${di}-${i}`
@@ -617,14 +613,17 @@ var PieDonutChart = import_react.default.memo(
617
613
  {
618
614
  d: s.d,
619
615
  fill: PIE_COLORS[(i + colorOffset) % PIE_COLORS.length],
620
- className: "chart-slice"
616
+ className: "chart-slice",
617
+ onMouseEnter: (e) => onHover(e, `${s.label} \u2014 ${s.v.toLocaleString()} (${s.pct}%)`),
618
+ onMouseMove: onMove,
619
+ onMouseLeave: onLeave
621
620
  }
622
621
  ) }, i)) })
623
622
  ] });
624
623
  }
625
624
  );
626
625
  PieDonutChart.displayName = "PieDonutChart";
627
- var ChartTooltip = ({ x, y, containerWidth, containerHeight, children }) => {
626
+ var ChartTooltip = ({ x, y, containerWidth, containerHeight, tooltipType, children }) => {
628
627
  const ref = import_react.default.useRef(null);
629
628
  const [pos, setPos] = import_react.default.useState({ left: 0, top: 0 });
630
629
  import_react.default.useLayoutEffect(() => {
@@ -639,13 +638,20 @@ var ChartTooltip = ({ x, y, containerWidth, containerHeight, children }) => {
639
638
  if (left < 0) left = 0;
640
639
  setPos({ left, top });
641
640
  }, [x, y, containerWidth, containerHeight]);
642
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
641
+ const content = typeof children === "string" ? children : "";
642
+ const sepIdx = content.indexOf(" \u2014 ");
643
+ const title = sepIdx >= 0 ? content.slice(0, sepIdx) : content;
644
+ const desc = sepIdx >= 0 ? content.slice(sepIdx + 3) : "";
645
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
643
646
  "div",
644
647
  {
645
648
  ref,
646
- className: "chart-tooltip chart-tooltip-show",
649
+ className: `chart-tooltip chart-tooltip-show chart-tooltip-${tooltipType}`,
647
650
  style: { left: pos.left, top: pos.top },
648
- children
651
+ children: [
652
+ title && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "chart-tooltip-title", children: title }),
653
+ desc && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "chart-tooltip-desc", children: desc })
654
+ ]
649
655
  }
650
656
  );
651
657
  };
@@ -688,8 +694,8 @@ var ChartLegend = ({ data, labels, type }) => {
688
694
  }) });
689
695
  };
690
696
  var Chart = import_react.default.memo((props) => {
691
- const { type, data, labels, tooltip: showTooltip = true } = props;
692
- const { tooltip, show, showAt, hide, move, containerRef } = useChartTooltip(showTooltip);
697
+ const { type, data, labels, tooltip: showTooltip = true, tooltipType = "dark" } = props;
698
+ const { tooltip, show, hide, move, containerRef } = useChartTooltip(showTooltip);
693
699
  const { width, height } = useChartSize(containerRef);
694
700
  const stableData = import_react.default.useMemo(() => data, [JSON.stringify(data)]);
695
701
  const stableLabels = import_react.default.useMemo(() => labels, [JSON.stringify(labels)]);
@@ -697,13 +703,13 @@ var Chart = import_react.default.memo((props) => {
697
703
  const animate = useChartAnimation(containerRef, dataKey);
698
704
  const ready = width > 0 && height > 0;
699
705
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "lib-xplat-chart", ref: containerRef, children: [
700
- ready && type === "line" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LineChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
701
- ready && type === "curve" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CurveChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
702
- ready && type === "bar" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BarChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
703
- ready && type === "pie" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
704
- ready && type === "doughnut" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, isDoughnut: true, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
705
- ready && (type === "bar" || type === "pie" || type === "doughnut") && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChartLegend, { data: stableData, labels: stableLabels, type }),
706
- tooltip.visible && tooltip.content && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChartTooltip, { x: tooltip.x, y: tooltip.y, containerWidth: width, containerHeight: height, children: tooltip.content })
706
+ ready && type === "line" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LineChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
707
+ ready && type === "curve" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CurveChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
708
+ ready && type === "bar" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BarChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
709
+ ready && type === "pie" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
710
+ ready && type === "doughnut" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, isDoughnut: true, onHover: show, onMove: move, onLeave: hide }),
711
+ ready && (type === "pie" || type === "doughnut") && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChartLegend, { data: stableData, labels: stableLabels, type }),
712
+ tooltip.visible && tooltip.content && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChartTooltip, { x: tooltip.x, y: tooltip.y, containerWidth: width, containerHeight: height, tooltipType, children: tooltip.content })
707
713
  ] });
708
714
  });
709
715
  Chart.displayName = "Chart";
@@ -109,17 +109,37 @@
109
109
  position: absolute;
110
110
  z-index: 10;
111
111
  padding: var(--spacing-space-3);
112
- background-color: var(--semantic-surface-neutral-strong);
113
- color: var(--semantic-text-inverse);
114
- font-size: 12px;
115
- line-height: 18px;
116
- font-weight: 500;
117
112
  border-radius: var(--spacing-radius-md);
118
113
  max-width: 240px;
119
114
  pointer-events: none;
120
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
121
115
  animation: chart-tooltip-in 120ms ease-out;
122
116
  }
117
+ .lib-xplat-chart .chart-tooltip .chart-tooltip-title {
118
+ font-size: 13px;
119
+ line-height: 18px;
120
+ font-weight: 400;
121
+ }
122
+ .lib-xplat-chart .chart-tooltip .chart-tooltip-desc {
123
+ font-size: 12px;
124
+ line-height: 18px;
125
+ font-weight: 400;
126
+ }
127
+ .lib-xplat-chart .chart-tooltip.chart-tooltip-dark {
128
+ background-color: var(--semantic-surface-neutral-strong);
129
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
130
+ }
131
+ .lib-xplat-chart .chart-tooltip.chart-tooltip-dark .chart-tooltip-title,
132
+ .lib-xplat-chart .chart-tooltip.chart-tooltip-dark .chart-tooltip-desc {
133
+ color: var(--semantic-text-inverse);
134
+ }
135
+ .lib-xplat-chart .chart-tooltip.chart-tooltip-light {
136
+ background-color: var(--semantic-surface-neutral-default);
137
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
138
+ }
139
+ .lib-xplat-chart .chart-tooltip.chart-tooltip-light .chart-tooltip-title,
140
+ .lib-xplat-chart .chart-tooltip.chart-tooltip-light .chart-tooltip-desc {
141
+ color: var(--semantic-text-subtle);
142
+ }
123
143
  .lib-xplat-chart .chart-legend {
124
144
  display: flex;
125
145
  flex-wrap: wrap;
@@ -5,6 +5,7 @@ interface ChartProps {
5
5
  data: Record<string, number[]>;
6
6
  labels: string[];
7
7
  tooltip?: boolean;
8
+ tooltipType?: "dark" | "light";
8
9
  }
9
10
  declare const Chart: React.NamedExoticComponent<ChartProps>;
10
11
 
@@ -5,6 +5,7 @@ interface ChartProps {
5
5
  data: Record<string, number[]>;
6
6
  labels: string[];
7
7
  tooltip?: boolean;
8
+ tooltipType?: "dark" | "light";
8
9
  }
9
10
  declare const Chart: React.NamedExoticComponent<ChartProps>;
10
11
 
@@ -150,15 +150,11 @@ var useChartTooltip = (enabled) => {
150
150
  if (!rect) return;
151
151
  setTooltip({ visible: true, x: e.clientX - rect.left, y: e.clientY - rect.top, content });
152
152
  }, [enabled]);
153
- const showAt = React.useCallback((x, y, content) => {
154
- if (!enabled) return;
155
- setTooltip({ visible: true, x, y, content });
156
- }, [enabled]);
157
153
  const hide = React.useCallback(() => {
158
154
  cancelAnimationFrame(rafRef.current);
159
155
  setTooltip((prev) => ({ ...prev, visible: false }));
160
156
  }, []);
161
- return { tooltip, show, showAt, hide, move, containerRef };
157
+ return { tooltip, show, hide, move, containerRef };
162
158
  };
163
159
  var GridLines = React.memo(({ width, height, chartH, maxVal }) => /* @__PURE__ */ jsx(Fragment, { children: [0, 0.25, 0.5, 0.75, 1].map((ratio) => {
164
160
  const y = PADDING.top + (1 - ratio) * chartH;
@@ -223,7 +219,7 @@ var useCrosshair = (seriesPoints, entries, labels, chartH) => {
223
219
  }, [entries, seriesPoints]);
224
220
  return { activeIndex, handleMouseMove, handleMouseLeave, tooltipContent, getTooltipAt };
225
221
  };
226
- var LineChart = React.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
222
+ var LineChart = React.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
227
223
  const entries = React.useMemo(() => Object.entries(data), [data]);
228
224
  const maxVal = React.useMemo(() => {
229
225
  const allValues = entries.flatMap(([, v]) => v);
@@ -263,9 +259,8 @@ var LineChart = React.memo(({ data, labels, width, height, animate, onHover, onS
263
259
  className: "chart-svg",
264
260
  onMouseMove: (e) => {
265
261
  handleMouseMove(e);
266
- if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
267
- const p = seriesPoints[0][activeIndex];
268
- onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
262
+ if (activeIndex !== null) {
263
+ onHover(e, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
269
264
  } else {
270
265
  onLeave();
271
266
  }
@@ -333,7 +328,7 @@ var LineChart = React.memo(({ data, labels, width, height, animate, onHover, onS
333
328
  );
334
329
  });
335
330
  LineChart.displayName = "LineChart";
336
- var CurveChart = React.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
331
+ var CurveChart = React.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
337
332
  const entries = React.useMemo(() => Object.entries(data), [data]);
338
333
  const maxVal = React.useMemo(() => {
339
334
  const allValues = entries.flatMap(([, v]) => v);
@@ -375,7 +370,7 @@ var CurveChart = React.memo(({ data, labels, width, height, animate, onHover, on
375
370
  handleMouseMove(e);
376
371
  if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
377
372
  const p = seriesPoints[0][activeIndex];
378
- onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
373
+ onHover(e, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
379
374
  } else {
380
375
  onLeave();
381
376
  }
@@ -443,7 +438,7 @@ var CurveChart = React.memo(({ data, labels, width, height, animate, onHover, on
443
438
  );
444
439
  });
445
440
  CurveChart.displayName = "CurveChart";
446
- var BarChart = React.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
441
+ var BarChart = React.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
447
442
  const entries = React.useMemo(() => Object.entries(data), [data]);
448
443
  const maxVal = React.useMemo(() => {
449
444
  const allValues = entries.flatMap(([, v]) => v);
@@ -493,7 +488,8 @@ var BarChart = React.memo(({ data, labels, width, height, animate, onHover, onSh
493
488
  transformOrigin: `${b.x + b.w / 2}px ${baseline}px`,
494
489
  animationDelay: `${delay}ms`
495
490
  } : void 0,
496
- onMouseEnter: () => onShowAt(b.x + b.w / 2, b.y, `${key}: ${labels[i]} \u2014 ${b.v}`),
491
+ onMouseEnter: (e) => onHover(e, `${key}: ${labels[i]} \u2014 ${b.v}`),
492
+ onMouseMove: onMove,
497
493
  onMouseLeave: onLeave
498
494
  },
499
495
  `${di}-${i}`
@@ -581,14 +577,17 @@ var PieDonutChart = React.memo(
581
577
  {
582
578
  d: s.d,
583
579
  fill: PIE_COLORS[(i + colorOffset) % PIE_COLORS.length],
584
- className: "chart-slice"
580
+ className: "chart-slice",
581
+ onMouseEnter: (e) => onHover(e, `${s.label} \u2014 ${s.v.toLocaleString()} (${s.pct}%)`),
582
+ onMouseMove: onMove,
583
+ onMouseLeave: onLeave
585
584
  }
586
585
  ) }, i)) })
587
586
  ] });
588
587
  }
589
588
  );
590
589
  PieDonutChart.displayName = "PieDonutChart";
591
- var ChartTooltip = ({ x, y, containerWidth, containerHeight, children }) => {
590
+ var ChartTooltip = ({ x, y, containerWidth, containerHeight, tooltipType, children }) => {
592
591
  const ref = React.useRef(null);
593
592
  const [pos, setPos] = React.useState({ left: 0, top: 0 });
594
593
  React.useLayoutEffect(() => {
@@ -603,13 +602,20 @@ var ChartTooltip = ({ x, y, containerWidth, containerHeight, children }) => {
603
602
  if (left < 0) left = 0;
604
603
  setPos({ left, top });
605
604
  }, [x, y, containerWidth, containerHeight]);
606
- return /* @__PURE__ */ jsx(
605
+ const content = typeof children === "string" ? children : "";
606
+ const sepIdx = content.indexOf(" \u2014 ");
607
+ const title = sepIdx >= 0 ? content.slice(0, sepIdx) : content;
608
+ const desc = sepIdx >= 0 ? content.slice(sepIdx + 3) : "";
609
+ return /* @__PURE__ */ jsxs(
607
610
  "div",
608
611
  {
609
612
  ref,
610
- className: "chart-tooltip chart-tooltip-show",
613
+ className: `chart-tooltip chart-tooltip-show chart-tooltip-${tooltipType}`,
611
614
  style: { left: pos.left, top: pos.top },
612
- children
615
+ children: [
616
+ title && /* @__PURE__ */ jsx("div", { className: "chart-tooltip-title", children: title }),
617
+ desc && /* @__PURE__ */ jsx("div", { className: "chart-tooltip-desc", children: desc })
618
+ ]
613
619
  }
614
620
  );
615
621
  };
@@ -652,8 +658,8 @@ var ChartLegend = ({ data, labels, type }) => {
652
658
  }) });
653
659
  };
654
660
  var Chart = React.memo((props) => {
655
- const { type, data, labels, tooltip: showTooltip = true } = props;
656
- const { tooltip, show, showAt, hide, move, containerRef } = useChartTooltip(showTooltip);
661
+ const { type, data, labels, tooltip: showTooltip = true, tooltipType = "dark" } = props;
662
+ const { tooltip, show, hide, move, containerRef } = useChartTooltip(showTooltip);
657
663
  const { width, height } = useChartSize(containerRef);
658
664
  const stableData = React.useMemo(() => data, [JSON.stringify(data)]);
659
665
  const stableLabels = React.useMemo(() => labels, [JSON.stringify(labels)]);
@@ -661,13 +667,13 @@ var Chart = React.memo((props) => {
661
667
  const animate = useChartAnimation(containerRef, dataKey);
662
668
  const ready = width > 0 && height > 0;
663
669
  return /* @__PURE__ */ jsxs("div", { className: "lib-xplat-chart", ref: containerRef, children: [
664
- ready && type === "line" && /* @__PURE__ */ jsx(LineChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
665
- ready && type === "curve" && /* @__PURE__ */ jsx(CurveChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
666
- ready && type === "bar" && /* @__PURE__ */ jsx(BarChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
667
- ready && type === "pie" && /* @__PURE__ */ jsx(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
668
- ready && type === "doughnut" && /* @__PURE__ */ jsx(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, isDoughnut: true, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
669
- ready && (type === "bar" || type === "pie" || type === "doughnut") && /* @__PURE__ */ jsx(ChartLegend, { data: stableData, labels: stableLabels, type }),
670
- tooltip.visible && tooltip.content && /* @__PURE__ */ jsx(ChartTooltip, { x: tooltip.x, y: tooltip.y, containerWidth: width, containerHeight: height, children: tooltip.content })
670
+ ready && type === "line" && /* @__PURE__ */ jsx(LineChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
671
+ ready && type === "curve" && /* @__PURE__ */ jsx(CurveChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
672
+ ready && type === "bar" && /* @__PURE__ */ jsx(BarChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
673
+ ready && type === "pie" && /* @__PURE__ */ jsx(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
674
+ ready && type === "doughnut" && /* @__PURE__ */ jsx(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, isDoughnut: true, onHover: show, onMove: move, onLeave: hide }),
675
+ ready && (type === "pie" || type === "doughnut") && /* @__PURE__ */ jsx(ChartLegend, { data: stableData, labels: stableLabels, type }),
676
+ tooltip.visible && tooltip.content && /* @__PURE__ */ jsx(ChartTooltip, { x: tooltip.x, y: tooltip.y, containerWidth: width, containerHeight: height, tooltipType, children: tooltip.content })
671
677
  ] });
672
678
  });
673
679
  Chart.displayName = "Chart";
@@ -35,7 +35,21 @@ __export(Tooltip_exports, {
35
35
  module.exports = __toCommonJS(Tooltip_exports);
36
36
 
37
37
  // src/components/Tooltip/Tooltip.tsx
38
+ var import_react2 = __toESM(require("react"), 1);
39
+
40
+ // src/tokens/hooks/Portal.tsx
38
41
  var import_react = __toESM(require("react"), 1);
42
+ var import_react_dom = __toESM(require("react-dom"), 1);
43
+ var import_jsx_runtime = require("react/jsx-runtime");
44
+ var PortalContainerContext = import_react.default.createContext(null);
45
+ var Portal = ({ children }) => {
46
+ const contextContainer = import_react.default.useContext(PortalContainerContext);
47
+ if (typeof document === "undefined") return null;
48
+ const container = contextContainer ?? document.body;
49
+ return import_react_dom.default.createPortal(children, container);
50
+ };
51
+ Portal.displayName = "Portal";
52
+ var Portal_default = Portal;
39
53
 
40
54
  // ../../node_modules/clsx/dist/clsx.mjs
41
55
  function r(e) {
@@ -54,18 +68,94 @@ function clsx() {
54
68
  var clsx_default = clsx;
55
69
 
56
70
  // src/components/Tooltip/Tooltip.tsx
57
- var import_jsx_runtime = require("react/jsx-runtime");
71
+ var import_jsx_runtime2 = require("react/jsx-runtime");
72
+ var OFFSET = 12;
73
+ var SHOW_DELAY = 300;
58
74
  var Tooltip = (props) => {
59
75
  const {
60
- type = "primary",
76
+ type = "dark",
77
+ title,
61
78
  description,
62
- children
79
+ children,
80
+ disabled = false
63
81
  } = props;
64
- const iconRef = import_react.default.useRef(null);
65
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "lib-xplat-tooltip", children: [
66
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "tooltip-content", ref: iconRef, children: children || "Tooltip" }),
67
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: clsx_default("tooltip-wrapper", type), children: description })
68
- ] });
82
+ const triggerRef = import_react2.default.useRef(null);
83
+ const tooltipRef = import_react2.default.useRef(null);
84
+ const [visible, setVisible] = import_react2.default.useState(false);
85
+ const [pos, setPos] = import_react2.default.useState({ left: 0, top: 0 });
86
+ const delayTimer = import_react2.default.useRef(0);
87
+ const calculatePos = import_react2.default.useCallback((clientX, clientY) => {
88
+ const el = tooltipRef.current;
89
+ if (!el) return;
90
+ const w = el.offsetWidth;
91
+ const h = el.offsetHeight;
92
+ const vw = window.innerWidth;
93
+ let left = clientX + OFFSET;
94
+ let top = clientY - h - OFFSET;
95
+ if (left + w > vw - 8) left = clientX - w - OFFSET;
96
+ if (top < 8) top = clientY + OFFSET;
97
+ if (left < 8) left = 8;
98
+ setPos({ left, top });
99
+ }, []);
100
+ const handleMouseEnter = import_react2.default.useCallback(() => {
101
+ if (disabled) return;
102
+ delayTimer.current = window.setTimeout(() => {
103
+ setVisible(true);
104
+ }, SHOW_DELAY);
105
+ }, [disabled]);
106
+ const handleMouseMove = import_react2.default.useCallback((e) => {
107
+ if (!visible) return;
108
+ calculatePos(e.clientX, e.clientY);
109
+ }, [visible, calculatePos]);
110
+ const handleMouseLeave = import_react2.default.useCallback(() => {
111
+ window.clearTimeout(delayTimer.current);
112
+ setVisible(false);
113
+ }, []);
114
+ const handleClick = import_react2.default.useCallback(() => {
115
+ window.clearTimeout(delayTimer.current);
116
+ setVisible(false);
117
+ }, []);
118
+ const handleFocus = import_react2.default.useCallback(() => {
119
+ if (disabled) return;
120
+ setVisible(true);
121
+ }, [disabled]);
122
+ const handleBlur = import_react2.default.useCallback(() => {
123
+ setVisible(false);
124
+ }, []);
125
+ import_react2.default.useLayoutEffect(() => {
126
+ if (!visible || !triggerRef.current) return;
127
+ const rect = triggerRef.current.getBoundingClientRect();
128
+ calculatePos(rect.right, rect.top);
129
+ }, [visible, calculatePos]);
130
+ if (!title && !description) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children });
131
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
132
+ "div",
133
+ {
134
+ ref: triggerRef,
135
+ className: "lib-xplat-tooltip-trigger",
136
+ onMouseEnter: handleMouseEnter,
137
+ onMouseMove: handleMouseMove,
138
+ onMouseLeave: handleMouseLeave,
139
+ onClick: handleClick,
140
+ onFocus: handleFocus,
141
+ onBlur: handleBlur,
142
+ children: [
143
+ children,
144
+ visible && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Portal_default, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
145
+ "div",
146
+ {
147
+ ref: tooltipRef,
148
+ className: clsx_default("lib-xplat-tooltip", type),
149
+ style: { position: "fixed", left: pos.left, top: pos.top },
150
+ children: [
151
+ title && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "tooltip-title", children: title }),
152
+ description && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "tooltip-desc", children: description })
153
+ ]
154
+ }
155
+ ) })
156
+ ]
157
+ }
158
+ );
69
159
  };
70
160
  Tooltip.displayName = "Tooltip";
71
161
  var Tooltip_default = Tooltip;
@@ -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 };