@x-plat/design-system 0.5.36 → 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.
@@ -186,8 +186,21 @@ 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) => {
189
+ const showAt = import_react.default.useCallback((svgX, svgY, content, svgEl) => {
190
190
  if (!enabled) return;
191
+ const container = containerRef.current;
192
+ if (!container) return;
193
+ let x = svgX;
194
+ let y = svgY;
195
+ if (svgEl) {
196
+ const svgRect = svgEl.getBoundingClientRect();
197
+ const containerRect = container.getBoundingClientRect();
198
+ const vb = svgEl.viewBox.baseVal;
199
+ const scaleX = svgRect.width / (vb.width || 1);
200
+ const scaleY = svgRect.height / (vb.height || 1);
201
+ x = svgX * scaleX + (svgRect.left - containerRect.left);
202
+ y = svgY * scaleY + (svgRect.top - containerRect.top);
203
+ }
191
204
  setTooltip({ visible: true, x, y, content });
192
205
  }, [enabled]);
193
206
  const hide = import_react.default.useCallback(() => {
@@ -279,6 +292,7 @@ var LineChart = import_react.default.memo(({ data, labels, width, height, animat
279
292
  [entries, count, chartW, chartH, maxVal]
280
293
  );
281
294
  const clipRef = import_react.default.useRef(null);
295
+ const svgRef = import_react.default.useRef(null);
282
296
  const { activeIndex, handleMouseMove, handleMouseLeave, getTooltipAt } = useCrosshair(seriesPoints, entries, labels, chartH);
283
297
  import_react.default.useEffect(() => {
284
298
  if (!animate || !clipRef.current) return;
@@ -295,13 +309,14 @@ var LineChart = import_react.default.memo(({ data, labels, width, height, animat
295
309
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
296
310
  "svg",
297
311
  {
312
+ ref: svgRef,
298
313
  viewBox: `0 0 ${width} ${height}`,
299
314
  className: "chart-svg",
300
315
  onMouseMove: (e) => {
301
316
  handleMouseMove(e);
302
317
  if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
303
318
  const p = seriesPoints[0][activeIndex];
304
- onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
319
+ onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`, svgRef.current);
305
320
  } else {
306
321
  onLeave();
307
322
  }
@@ -389,6 +404,7 @@ var CurveChart = import_react.default.memo(({ data, labels, width, height, anima
389
404
  [entries, count, chartW, chartH, maxVal]
390
405
  );
391
406
  const curveClipRef = import_react.default.useRef(null);
407
+ const curveSvgRef = import_react.default.useRef(null);
392
408
  const { activeIndex, handleMouseMove, handleMouseLeave, getTooltipAt } = useCrosshair(seriesPoints, entries, labels, chartH);
393
409
  import_react.default.useEffect(() => {
394
410
  if (!animate || !curveClipRef.current) return;
@@ -405,13 +421,14 @@ var CurveChart = import_react.default.memo(({ data, labels, width, height, anima
405
421
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
406
422
  "svg",
407
423
  {
424
+ ref: curveSvgRef,
408
425
  viewBox: `0 0 ${width} ${height}`,
409
426
  className: "chart-svg",
410
427
  onMouseMove: (e) => {
411
428
  handleMouseMove(e);
412
429
  if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
413
430
  const p = seriesPoints[0][activeIndex];
414
- onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
431
+ onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`, curveSvgRef.current);
415
432
  } else {
416
433
  onLeave();
417
434
  }
@@ -480,6 +497,7 @@ var CurveChart = import_react.default.memo(({ data, labels, width, height, anima
480
497
  });
481
498
  CurveChart.displayName = "CurveChart";
482
499
  var BarChart = import_react.default.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
500
+ const barSvgRef = import_react.default.useRef(null);
483
501
  const entries = import_react.default.useMemo(() => Object.entries(data), [data]);
484
502
  const maxVal = import_react.default.useMemo(() => {
485
503
  const allValues = entries.flatMap(([, v]) => v);
@@ -506,7 +524,7 @@ var BarChart = import_react.default.memo(({ data, labels, width, height, animate
506
524
  [entries, maxVal, chartH, groupW, barW, barGap, groupCount]
507
525
  );
508
526
  const barLabelStep = getLabelStep(count, chartW);
509
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: `0 0 ${width} ${height}`, className: "chart-svg", children: [
527
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ref: barSvgRef, viewBox: `0 0 ${width} ${height}`, className: "chart-svg", children: [
510
528
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GridLines, { width, height, chartH, maxVal }),
511
529
  labels.map((label, i) => {
512
530
  if (i % barLabelStep !== 0) return null;
@@ -529,7 +547,7 @@ var BarChart = import_react.default.memo(({ data, labels, width, height, animate
529
547
  transformOrigin: `${b.x + b.w / 2}px ${baseline}px`,
530
548
  animationDelay: `${delay}ms`
531
549
  } : void 0,
532
- onMouseEnter: () => onShowAt(b.x + b.w / 2, b.y, `${key}: ${labels[i]} \u2014 ${b.v}`),
550
+ onMouseEnter: () => onShowAt(b.x + b.w / 2, b.y, `${key}: ${labels[i]} \u2014 ${b.v}`, barSvgRef.current),
533
551
  onMouseLeave: onLeave
534
552
  },
535
553
  `${di}-${i}`
@@ -702,7 +720,7 @@ var Chart = import_react.default.memo((props) => {
702
720
  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
721
  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
722
  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 }),
723
+ ready && (type === "pie" || type === "doughnut") && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChartLegend, { data: stableData, labels: stableLabels, type }),
706
724
  tooltip.visible && tooltip.content && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChartTooltip, { x: tooltip.x, y: tooltip.y, containerWidth: width, containerHeight: height, children: tooltip.content })
707
725
  ] });
708
726
  });
@@ -150,8 +150,21 @@ 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) => {
153
+ const showAt = React.useCallback((svgX, svgY, content, svgEl) => {
154
154
  if (!enabled) return;
155
+ const container = containerRef.current;
156
+ if (!container) return;
157
+ let x = svgX;
158
+ let y = svgY;
159
+ if (svgEl) {
160
+ const svgRect = svgEl.getBoundingClientRect();
161
+ const containerRect = container.getBoundingClientRect();
162
+ const vb = svgEl.viewBox.baseVal;
163
+ const scaleX = svgRect.width / (vb.width || 1);
164
+ const scaleY = svgRect.height / (vb.height || 1);
165
+ x = svgX * scaleX + (svgRect.left - containerRect.left);
166
+ y = svgY * scaleY + (svgRect.top - containerRect.top);
167
+ }
155
168
  setTooltip({ visible: true, x, y, content });
156
169
  }, [enabled]);
157
170
  const hide = React.useCallback(() => {
@@ -243,6 +256,7 @@ var LineChart = React.memo(({ data, labels, width, height, animate, onHover, onS
243
256
  [entries, count, chartW, chartH, maxVal]
244
257
  );
245
258
  const clipRef = React.useRef(null);
259
+ const svgRef = React.useRef(null);
246
260
  const { activeIndex, handleMouseMove, handleMouseLeave, getTooltipAt } = useCrosshair(seriesPoints, entries, labels, chartH);
247
261
  React.useEffect(() => {
248
262
  if (!animate || !clipRef.current) return;
@@ -259,13 +273,14 @@ var LineChart = React.memo(({ data, labels, width, height, animate, onHover, onS
259
273
  return /* @__PURE__ */ jsxs(
260
274
  "svg",
261
275
  {
276
+ ref: svgRef,
262
277
  viewBox: `0 0 ${width} ${height}`,
263
278
  className: "chart-svg",
264
279
  onMouseMove: (e) => {
265
280
  handleMouseMove(e);
266
281
  if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
267
282
  const p = seriesPoints[0][activeIndex];
268
- onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
283
+ onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`, svgRef.current);
269
284
  } else {
270
285
  onLeave();
271
286
  }
@@ -353,6 +368,7 @@ var CurveChart = React.memo(({ data, labels, width, height, animate, onHover, on
353
368
  [entries, count, chartW, chartH, maxVal]
354
369
  );
355
370
  const curveClipRef = React.useRef(null);
371
+ const curveSvgRef = React.useRef(null);
356
372
  const { activeIndex, handleMouseMove, handleMouseLeave, getTooltipAt } = useCrosshair(seriesPoints, entries, labels, chartH);
357
373
  React.useEffect(() => {
358
374
  if (!animate || !curveClipRef.current) return;
@@ -369,13 +385,14 @@ var CurveChart = React.memo(({ data, labels, width, height, animate, onHover, on
369
385
  return /* @__PURE__ */ jsxs(
370
386
  "svg",
371
387
  {
388
+ ref: curveSvgRef,
372
389
  viewBox: `0 0 ${width} ${height}`,
373
390
  className: "chart-svg",
374
391
  onMouseMove: (e) => {
375
392
  handleMouseMove(e);
376
393
  if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
377
394
  const p = seriesPoints[0][activeIndex];
378
- onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
395
+ onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`, curveSvgRef.current);
379
396
  } else {
380
397
  onLeave();
381
398
  }
@@ -444,6 +461,7 @@ var CurveChart = React.memo(({ data, labels, width, height, animate, onHover, on
444
461
  });
445
462
  CurveChart.displayName = "CurveChart";
446
463
  var BarChart = React.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
464
+ const barSvgRef = React.useRef(null);
447
465
  const entries = React.useMemo(() => Object.entries(data), [data]);
448
466
  const maxVal = React.useMemo(() => {
449
467
  const allValues = entries.flatMap(([, v]) => v);
@@ -470,7 +488,7 @@ var BarChart = React.memo(({ data, labels, width, height, animate, onHover, onSh
470
488
  [entries, maxVal, chartH, groupW, barW, barGap, groupCount]
471
489
  );
472
490
  const barLabelStep = getLabelStep(count, chartW);
473
- return /* @__PURE__ */ jsxs("svg", { viewBox: `0 0 ${width} ${height}`, className: "chart-svg", children: [
491
+ return /* @__PURE__ */ jsxs("svg", { ref: barSvgRef, viewBox: `0 0 ${width} ${height}`, className: "chart-svg", children: [
474
492
  /* @__PURE__ */ jsx(GridLines, { width, height, chartH, maxVal }),
475
493
  labels.map((label, i) => {
476
494
  if (i % barLabelStep !== 0) return null;
@@ -493,7 +511,7 @@ var BarChart = React.memo(({ data, labels, width, height, animate, onHover, onSh
493
511
  transformOrigin: `${b.x + b.w / 2}px ${baseline}px`,
494
512
  animationDelay: `${delay}ms`
495
513
  } : void 0,
496
- onMouseEnter: () => onShowAt(b.x + b.w / 2, b.y, `${key}: ${labels[i]} \u2014 ${b.v}`),
514
+ onMouseEnter: () => onShowAt(b.x + b.w / 2, b.y, `${key}: ${labels[i]} \u2014 ${b.v}`, barSvgRef.current),
497
515
  onMouseLeave: onLeave
498
516
  },
499
517
  `${di}-${i}`
@@ -666,7 +684,7 @@ var Chart = React.memo((props) => {
666
684
  ready && type === "bar" && /* @__PURE__ */ jsx(BarChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
667
685
  ready && type === "pie" && /* @__PURE__ */ jsx(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
668
686
  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 }),
687
+ ready && (type === "pie" || type === "doughnut") && /* @__PURE__ */ jsx(ChartLegend, { data: stableData, labels: stableLabels, type }),
670
688
  tooltip.visible && tooltip.content && /* @__PURE__ */ jsx(ChartTooltip, { x: tooltip.x, y: tooltip.y, containerWidth: width, containerHeight: height, children: tooltip.content })
671
689
  ] });
672
690
  });
@@ -2380,8 +2380,21 @@ 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((x, y, content) => {
2383
+ const showAt = import_react6.default.useCallback((svgX, svgY, content, svgEl) => {
2384
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
+ }
2385
2398
  setTooltip({ visible: true, x, y, content });
2386
2399
  }, [enabled]);
2387
2400
  const hide = import_react6.default.useCallback(() => {
@@ -2473,6 +2486,7 @@ var LineChart = import_react6.default.memo(({ data, labels, width, height, anima
2473
2486
  [entries, count, chartW, chartH, maxVal]
2474
2487
  );
2475
2488
  const clipRef = import_react6.default.useRef(null);
2489
+ const svgRef = import_react6.default.useRef(null);
2476
2490
  const { activeIndex, handleMouseMove, handleMouseLeave, getTooltipAt } = useCrosshair(seriesPoints, entries, labels, chartH);
2477
2491
  import_react6.default.useEffect(() => {
2478
2492
  if (!animate || !clipRef.current) return;
@@ -2489,13 +2503,14 @@ var LineChart = import_react6.default.memo(({ data, labels, width, height, anima
2489
2503
  return /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)(
2490
2504
  "svg",
2491
2505
  {
2506
+ ref: svgRef,
2492
2507
  viewBox: `0 0 ${width} ${height}`,
2493
2508
  className: "chart-svg",
2494
2509
  onMouseMove: (e) => {
2495
2510
  handleMouseMove(e);
2496
2511
  if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
2497
2512
  const p = seriesPoints[0][activeIndex];
2498
- onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
2513
+ onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`, svgRef.current);
2499
2514
  } else {
2500
2515
  onLeave();
2501
2516
  }
@@ -2583,6 +2598,7 @@ var CurveChart = import_react6.default.memo(({ data, labels, width, height, anim
2583
2598
  [entries, count, chartW, chartH, maxVal]
2584
2599
  );
2585
2600
  const curveClipRef = import_react6.default.useRef(null);
2601
+ const curveSvgRef = import_react6.default.useRef(null);
2586
2602
  const { activeIndex, handleMouseMove, handleMouseLeave, getTooltipAt } = useCrosshair(seriesPoints, entries, labels, chartH);
2587
2603
  import_react6.default.useEffect(() => {
2588
2604
  if (!animate || !curveClipRef.current) return;
@@ -2599,13 +2615,14 @@ var CurveChart = import_react6.default.memo(({ data, labels, width, height, anim
2599
2615
  return /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)(
2600
2616
  "svg",
2601
2617
  {
2618
+ ref: curveSvgRef,
2602
2619
  viewBox: `0 0 ${width} ${height}`,
2603
2620
  className: "chart-svg",
2604
2621
  onMouseMove: (e) => {
2605
2622
  handleMouseMove(e);
2606
2623
  if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
2607
2624
  const p = seriesPoints[0][activeIndex];
2608
- onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
2625
+ onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`, curveSvgRef.current);
2609
2626
  } else {
2610
2627
  onLeave();
2611
2628
  }
@@ -2674,6 +2691,7 @@ var CurveChart = import_react6.default.memo(({ data, labels, width, height, anim
2674
2691
  });
2675
2692
  CurveChart.displayName = "CurveChart";
2676
2693
  var BarChart = import_react6.default.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
2694
+ const barSvgRef = import_react6.default.useRef(null);
2677
2695
  const entries = import_react6.default.useMemo(() => Object.entries(data), [data]);
2678
2696
  const maxVal = import_react6.default.useMemo(() => {
2679
2697
  const allValues = entries.flatMap(([, v]) => v);
@@ -2700,7 +2718,7 @@ var BarChart = import_react6.default.memo(({ data, labels, width, height, animat
2700
2718
  [entries, maxVal, chartH, groupW, barW, barGap, groupCount]
2701
2719
  );
2702
2720
  const barLabelStep = getLabelStep(count, chartW);
2703
- return /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)("svg", { viewBox: `0 0 ${width} ${height}`, className: "chart-svg", children: [
2721
+ return /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)("svg", { ref: barSvgRef, viewBox: `0 0 ${width} ${height}`, className: "chart-svg", children: [
2704
2722
  /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(GridLines, { width, height, chartH, maxVal }),
2705
2723
  labels.map((label, i) => {
2706
2724
  if (i % barLabelStep !== 0) return null;
@@ -2723,7 +2741,7 @@ var BarChart = import_react6.default.memo(({ data, labels, width, height, animat
2723
2741
  transformOrigin: `${b.x + b.w / 2}px ${baseline}px`,
2724
2742
  animationDelay: `${delay}ms`
2725
2743
  } : void 0,
2726
- onMouseEnter: () => onShowAt(b.x + b.w / 2, b.y, `${key}: ${labels[i]} \u2014 ${b.v}`),
2744
+ onMouseEnter: () => onShowAt(b.x + b.w / 2, b.y, `${key}: ${labels[i]} \u2014 ${b.v}`, barSvgRef.current),
2727
2745
  onMouseLeave: onLeave
2728
2746
  },
2729
2747
  `${di}-${i}`
@@ -2896,7 +2914,7 @@ var Chart = import_react6.default.memo((props) => {
2896
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 }),
2897
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 }),
2898
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 }),
2899
- ready && (type === "bar" || type === "pie" || type === "doughnut") && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(ChartLegend, { data: stableData, labels: stableLabels, type }),
2917
+ ready && (type === "pie" || type === "doughnut") && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(ChartLegend, { data: stableData, labels: stableLabels, type }),
2900
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 })
2901
2919
  ] });
2902
2920
  });
@@ -2290,8 +2290,21 @@ var useChartTooltip = (enabled) => {
2290
2290
  if (!rect) return;
2291
2291
  setTooltip({ visible: true, x: e.clientX - rect.left, y: e.clientY - rect.top, content });
2292
2292
  }, [enabled]);
2293
- const showAt = React6.useCallback((x, y, content) => {
2293
+ const showAt = React6.useCallback((svgX, svgY, content, svgEl) => {
2294
2294
  if (!enabled) return;
2295
+ const container = containerRef.current;
2296
+ if (!container) return;
2297
+ let x = svgX;
2298
+ let y = svgY;
2299
+ if (svgEl) {
2300
+ const svgRect = svgEl.getBoundingClientRect();
2301
+ const containerRect = container.getBoundingClientRect();
2302
+ const vb = svgEl.viewBox.baseVal;
2303
+ const scaleX = svgRect.width / (vb.width || 1);
2304
+ const scaleY = svgRect.height / (vb.height || 1);
2305
+ x = svgX * scaleX + (svgRect.left - containerRect.left);
2306
+ y = svgY * scaleY + (svgRect.top - containerRect.top);
2307
+ }
2295
2308
  setTooltip({ visible: true, x, y, content });
2296
2309
  }, [enabled]);
2297
2310
  const hide = React6.useCallback(() => {
@@ -2383,6 +2396,7 @@ var LineChart = React6.memo(({ data, labels, width, height, animate, onHover, on
2383
2396
  [entries, count, chartW, chartH, maxVal]
2384
2397
  );
2385
2398
  const clipRef = React6.useRef(null);
2399
+ const svgRef = React6.useRef(null);
2386
2400
  const { activeIndex, handleMouseMove, handleMouseLeave, getTooltipAt } = useCrosshair(seriesPoints, entries, labels, chartH);
2387
2401
  React6.useEffect(() => {
2388
2402
  if (!animate || !clipRef.current) return;
@@ -2399,13 +2413,14 @@ var LineChart = React6.memo(({ data, labels, width, height, animate, onHover, on
2399
2413
  return /* @__PURE__ */ jsxs197(
2400
2414
  "svg",
2401
2415
  {
2416
+ ref: svgRef,
2402
2417
  viewBox: `0 0 ${width} ${height}`,
2403
2418
  className: "chart-svg",
2404
2419
  onMouseMove: (e) => {
2405
2420
  handleMouseMove(e);
2406
2421
  if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
2407
2422
  const p = seriesPoints[0][activeIndex];
2408
- onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
2423
+ onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`, svgRef.current);
2409
2424
  } else {
2410
2425
  onLeave();
2411
2426
  }
@@ -2493,6 +2508,7 @@ var CurveChart = React6.memo(({ data, labels, width, height, animate, onHover, o
2493
2508
  [entries, count, chartW, chartH, maxVal]
2494
2509
  );
2495
2510
  const curveClipRef = React6.useRef(null);
2511
+ const curveSvgRef = React6.useRef(null);
2496
2512
  const { activeIndex, handleMouseMove, handleMouseLeave, getTooltipAt } = useCrosshair(seriesPoints, entries, labels, chartH);
2497
2513
  React6.useEffect(() => {
2498
2514
  if (!animate || !curveClipRef.current) return;
@@ -2509,13 +2525,14 @@ var CurveChart = React6.memo(({ data, labels, width, height, animate, onHover, o
2509
2525
  return /* @__PURE__ */ jsxs197(
2510
2526
  "svg",
2511
2527
  {
2528
+ ref: curveSvgRef,
2512
2529
  viewBox: `0 0 ${width} ${height}`,
2513
2530
  className: "chart-svg",
2514
2531
  onMouseMove: (e) => {
2515
2532
  handleMouseMove(e);
2516
2533
  if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
2517
2534
  const p = seriesPoints[0][activeIndex];
2518
- onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
2535
+ onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`, curveSvgRef.current);
2519
2536
  } else {
2520
2537
  onLeave();
2521
2538
  }
@@ -2584,6 +2601,7 @@ var CurveChart = React6.memo(({ data, labels, width, height, animate, onHover, o
2584
2601
  });
2585
2602
  CurveChart.displayName = "CurveChart";
2586
2603
  var BarChart = React6.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
2604
+ const barSvgRef = React6.useRef(null);
2587
2605
  const entries = React6.useMemo(() => Object.entries(data), [data]);
2588
2606
  const maxVal = React6.useMemo(() => {
2589
2607
  const allValues = entries.flatMap(([, v]) => v);
@@ -2610,7 +2628,7 @@ var BarChart = React6.memo(({ data, labels, width, height, animate, onHover, onS
2610
2628
  [entries, maxVal, chartH, groupW, barW, barGap, groupCount]
2611
2629
  );
2612
2630
  const barLabelStep = getLabelStep(count, chartW);
2613
- return /* @__PURE__ */ jsxs197("svg", { viewBox: `0 0 ${width} ${height}`, className: "chart-svg", children: [
2631
+ return /* @__PURE__ */ jsxs197("svg", { ref: barSvgRef, viewBox: `0 0 ${width} ${height}`, className: "chart-svg", children: [
2614
2632
  /* @__PURE__ */ jsx307(GridLines, { width, height, chartH, maxVal }),
2615
2633
  labels.map((label, i) => {
2616
2634
  if (i % barLabelStep !== 0) return null;
@@ -2633,7 +2651,7 @@ var BarChart = React6.memo(({ data, labels, width, height, animate, onHover, onS
2633
2651
  transformOrigin: `${b.x + b.w / 2}px ${baseline}px`,
2634
2652
  animationDelay: `${delay}ms`
2635
2653
  } : void 0,
2636
- onMouseEnter: () => onShowAt(b.x + b.w / 2, b.y, `${key}: ${labels[i]} \u2014 ${b.v}`),
2654
+ onMouseEnter: () => onShowAt(b.x + b.w / 2, b.y, `${key}: ${labels[i]} \u2014 ${b.v}`, barSvgRef.current),
2637
2655
  onMouseLeave: onLeave
2638
2656
  },
2639
2657
  `${di}-${i}`
@@ -2806,7 +2824,7 @@ var Chart = React6.memo((props) => {
2806
2824
  ready && type === "bar" && /* @__PURE__ */ jsx307(BarChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
2807
2825
  ready && type === "pie" && /* @__PURE__ */ jsx307(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
2808
2826
  ready && type === "doughnut" && /* @__PURE__ */ jsx307(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, isDoughnut: true, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
2809
- ready && (type === "bar" || type === "pie" || type === "doughnut") && /* @__PURE__ */ jsx307(ChartLegend, { data: stableData, labels: stableLabels, type }),
2827
+ ready && (type === "pie" || type === "doughnut") && /* @__PURE__ */ jsx307(ChartLegend, { data: stableData, labels: stableLabels, type }),
2810
2828
  tooltip.visible && tooltip.content && /* @__PURE__ */ jsx307(ChartTooltip, { x: tooltip.x, y: tooltip.y, containerWidth: width, containerHeight: height, children: tooltip.content })
2811
2829
  ] });
2812
2830
  });
package/dist/index.cjs CHANGED
@@ -6779,8 +6779,21 @@ var useChartTooltip = (enabled) => {
6779
6779
  if (!rect) return;
6780
6780
  setTooltip({ visible: true, x: e.clientX - rect.left, y: e.clientY - rect.top, content });
6781
6781
  }, [enabled]);
6782
- const showAt = import_react6.default.useCallback((x, y, content) => {
6782
+ const showAt = import_react6.default.useCallback((svgX, svgY, content, svgEl) => {
6783
6783
  if (!enabled) return;
6784
+ const container = containerRef.current;
6785
+ if (!container) return;
6786
+ let x = svgX;
6787
+ let y = svgY;
6788
+ if (svgEl) {
6789
+ const svgRect = svgEl.getBoundingClientRect();
6790
+ const containerRect = container.getBoundingClientRect();
6791
+ const vb = svgEl.viewBox.baseVal;
6792
+ const scaleX = svgRect.width / (vb.width || 1);
6793
+ const scaleY = svgRect.height / (vb.height || 1);
6794
+ x = svgX * scaleX + (svgRect.left - containerRect.left);
6795
+ y = svgY * scaleY + (svgRect.top - containerRect.top);
6796
+ }
6784
6797
  setTooltip({ visible: true, x, y, content });
6785
6798
  }, [enabled]);
6786
6799
  const hide = import_react6.default.useCallback(() => {
@@ -6872,6 +6885,7 @@ var LineChart = import_react6.default.memo(({ data, labels, width, height, anima
6872
6885
  [entries, count, chartW, chartH, maxVal]
6873
6886
  );
6874
6887
  const clipRef = import_react6.default.useRef(null);
6888
+ const svgRef = import_react6.default.useRef(null);
6875
6889
  const { activeIndex, handleMouseMove, handleMouseLeave, getTooltipAt } = useCrosshair(seriesPoints, entries, labels, chartH);
6876
6890
  import_react6.default.useEffect(() => {
6877
6891
  if (!animate || !clipRef.current) return;
@@ -6888,13 +6902,14 @@ var LineChart = import_react6.default.memo(({ data, labels, width, height, anima
6888
6902
  return /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)(
6889
6903
  "svg",
6890
6904
  {
6905
+ ref: svgRef,
6891
6906
  viewBox: `0 0 ${width} ${height}`,
6892
6907
  className: "chart-svg",
6893
6908
  onMouseMove: (e) => {
6894
6909
  handleMouseMove(e);
6895
6910
  if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
6896
6911
  const p = seriesPoints[0][activeIndex];
6897
- onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
6912
+ onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`, svgRef.current);
6898
6913
  } else {
6899
6914
  onLeave();
6900
6915
  }
@@ -6982,6 +6997,7 @@ var CurveChart = import_react6.default.memo(({ data, labels, width, height, anim
6982
6997
  [entries, count, chartW, chartH, maxVal]
6983
6998
  );
6984
6999
  const curveClipRef = import_react6.default.useRef(null);
7000
+ const curveSvgRef = import_react6.default.useRef(null);
6985
7001
  const { activeIndex, handleMouseMove, handleMouseLeave, getTooltipAt } = useCrosshair(seriesPoints, entries, labels, chartH);
6986
7002
  import_react6.default.useEffect(() => {
6987
7003
  if (!animate || !curveClipRef.current) return;
@@ -6998,13 +7014,14 @@ var CurveChart = import_react6.default.memo(({ data, labels, width, height, anim
6998
7014
  return /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)(
6999
7015
  "svg",
7000
7016
  {
7017
+ ref: curveSvgRef,
7001
7018
  viewBox: `0 0 ${width} ${height}`,
7002
7019
  className: "chart-svg",
7003
7020
  onMouseMove: (e) => {
7004
7021
  handleMouseMove(e);
7005
7022
  if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
7006
7023
  const p = seriesPoints[0][activeIndex];
7007
- onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
7024
+ onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`, curveSvgRef.current);
7008
7025
  } else {
7009
7026
  onLeave();
7010
7027
  }
@@ -7073,6 +7090,7 @@ var CurveChart = import_react6.default.memo(({ data, labels, width, height, anim
7073
7090
  });
7074
7091
  CurveChart.displayName = "CurveChart";
7075
7092
  var BarChart = import_react6.default.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
7093
+ const barSvgRef = import_react6.default.useRef(null);
7076
7094
  const entries = import_react6.default.useMemo(() => Object.entries(data), [data]);
7077
7095
  const maxVal = import_react6.default.useMemo(() => {
7078
7096
  const allValues = entries.flatMap(([, v]) => v);
@@ -7099,7 +7117,7 @@ var BarChart = import_react6.default.memo(({ data, labels, width, height, animat
7099
7117
  [entries, maxVal, chartH, groupW, barW, barGap, groupCount]
7100
7118
  );
7101
7119
  const barLabelStep = getLabelStep(count, chartW);
7102
- return /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)("svg", { viewBox: `0 0 ${width} ${height}`, className: "chart-svg", children: [
7120
+ return /* @__PURE__ */ (0, import_jsx_runtime307.jsxs)("svg", { ref: barSvgRef, viewBox: `0 0 ${width} ${height}`, className: "chart-svg", children: [
7103
7121
  /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(GridLines, { width, height, chartH, maxVal }),
7104
7122
  labels.map((label, i) => {
7105
7123
  if (i % barLabelStep !== 0) return null;
@@ -7122,7 +7140,7 @@ var BarChart = import_react6.default.memo(({ data, labels, width, height, animat
7122
7140
  transformOrigin: `${b.x + b.w / 2}px ${baseline}px`,
7123
7141
  animationDelay: `${delay}ms`
7124
7142
  } : void 0,
7125
- onMouseEnter: () => onShowAt(b.x + b.w / 2, b.y, `${key}: ${labels[i]} \u2014 ${b.v}`),
7143
+ onMouseEnter: () => onShowAt(b.x + b.w / 2, b.y, `${key}: ${labels[i]} \u2014 ${b.v}`, barSvgRef.current),
7126
7144
  onMouseLeave: onLeave
7127
7145
  },
7128
7146
  `${di}-${i}`
@@ -7295,7 +7313,7 @@ var Chart = import_react6.default.memo((props) => {
7295
7313
  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 }),
7296
7314
  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 }),
7297
7315
  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 }),
7298
- ready && (type === "bar" || type === "pie" || type === "doughnut") && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(ChartLegend, { data: stableData, labels: stableLabels, type }),
7316
+ ready && (type === "pie" || type === "doughnut") && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(ChartLegend, { data: stableData, labels: stableLabels, type }),
7299
7317
  tooltip.visible && tooltip.content && /* @__PURE__ */ (0, import_jsx_runtime307.jsx)(ChartTooltip, { x: tooltip.x, y: tooltip.y, containerWidth: width, containerHeight: height, children: tooltip.content })
7300
7318
  ] });
7301
7319
  });
package/dist/index.js CHANGED
@@ -6380,8 +6380,21 @@ var useChartTooltip = (enabled) => {
6380
6380
  if (!rect) return;
6381
6381
  setTooltip({ visible: true, x: e.clientX - rect.left, y: e.clientY - rect.top, content });
6382
6382
  }, [enabled]);
6383
- const showAt = React6.useCallback((x, y, content) => {
6383
+ const showAt = React6.useCallback((svgX, svgY, content, svgEl) => {
6384
6384
  if (!enabled) return;
6385
+ const container = containerRef.current;
6386
+ if (!container) return;
6387
+ let x = svgX;
6388
+ let y = svgY;
6389
+ if (svgEl) {
6390
+ const svgRect = svgEl.getBoundingClientRect();
6391
+ const containerRect = container.getBoundingClientRect();
6392
+ const vb = svgEl.viewBox.baseVal;
6393
+ const scaleX = svgRect.width / (vb.width || 1);
6394
+ const scaleY = svgRect.height / (vb.height || 1);
6395
+ x = svgX * scaleX + (svgRect.left - containerRect.left);
6396
+ y = svgY * scaleY + (svgRect.top - containerRect.top);
6397
+ }
6385
6398
  setTooltip({ visible: true, x, y, content });
6386
6399
  }, [enabled]);
6387
6400
  const hide = React6.useCallback(() => {
@@ -6473,6 +6486,7 @@ var LineChart = React6.memo(({ data, labels, width, height, animate, onHover, on
6473
6486
  [entries, count, chartW, chartH, maxVal]
6474
6487
  );
6475
6488
  const clipRef = React6.useRef(null);
6489
+ const svgRef = React6.useRef(null);
6476
6490
  const { activeIndex, handleMouseMove, handleMouseLeave, getTooltipAt } = useCrosshair(seriesPoints, entries, labels, chartH);
6477
6491
  React6.useEffect(() => {
6478
6492
  if (!animate || !clipRef.current) return;
@@ -6489,13 +6503,14 @@ var LineChart = React6.memo(({ data, labels, width, height, animate, onHover, on
6489
6503
  return /* @__PURE__ */ jsxs197(
6490
6504
  "svg",
6491
6505
  {
6506
+ ref: svgRef,
6492
6507
  viewBox: `0 0 ${width} ${height}`,
6493
6508
  className: "chart-svg",
6494
6509
  onMouseMove: (e) => {
6495
6510
  handleMouseMove(e);
6496
6511
  if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
6497
6512
  const p = seriesPoints[0][activeIndex];
6498
- onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
6513
+ onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`, svgRef.current);
6499
6514
  } else {
6500
6515
  onLeave();
6501
6516
  }
@@ -6583,6 +6598,7 @@ var CurveChart = React6.memo(({ data, labels, width, height, animate, onHover, o
6583
6598
  [entries, count, chartW, chartH, maxVal]
6584
6599
  );
6585
6600
  const curveClipRef = React6.useRef(null);
6601
+ const curveSvgRef = React6.useRef(null);
6586
6602
  const { activeIndex, handleMouseMove, handleMouseLeave, getTooltipAt } = useCrosshair(seriesPoints, entries, labels, chartH);
6587
6603
  React6.useEffect(() => {
6588
6604
  if (!animate || !curveClipRef.current) return;
@@ -6599,13 +6615,14 @@ var CurveChart = React6.memo(({ data, labels, width, height, animate, onHover, o
6599
6615
  return /* @__PURE__ */ jsxs197(
6600
6616
  "svg",
6601
6617
  {
6618
+ ref: curveSvgRef,
6602
6619
  viewBox: `0 0 ${width} ${height}`,
6603
6620
  className: "chart-svg",
6604
6621
  onMouseMove: (e) => {
6605
6622
  handleMouseMove(e);
6606
6623
  if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
6607
6624
  const p = seriesPoints[0][activeIndex];
6608
- onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
6625
+ onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`, curveSvgRef.current);
6609
6626
  } else {
6610
6627
  onLeave();
6611
6628
  }
@@ -6674,6 +6691,7 @@ var CurveChart = React6.memo(({ data, labels, width, height, animate, onHover, o
6674
6691
  });
6675
6692
  CurveChart.displayName = "CurveChart";
6676
6693
  var BarChart = React6.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
6694
+ const barSvgRef = React6.useRef(null);
6677
6695
  const entries = React6.useMemo(() => Object.entries(data), [data]);
6678
6696
  const maxVal = React6.useMemo(() => {
6679
6697
  const allValues = entries.flatMap(([, v]) => v);
@@ -6700,7 +6718,7 @@ var BarChart = React6.memo(({ data, labels, width, height, animate, onHover, onS
6700
6718
  [entries, maxVal, chartH, groupW, barW, barGap, groupCount]
6701
6719
  );
6702
6720
  const barLabelStep = getLabelStep(count, chartW);
6703
- return /* @__PURE__ */ jsxs197("svg", { viewBox: `0 0 ${width} ${height}`, className: "chart-svg", children: [
6721
+ return /* @__PURE__ */ jsxs197("svg", { ref: barSvgRef, viewBox: `0 0 ${width} ${height}`, className: "chart-svg", children: [
6704
6722
  /* @__PURE__ */ jsx307(GridLines, { width, height, chartH, maxVal }),
6705
6723
  labels.map((label, i) => {
6706
6724
  if (i % barLabelStep !== 0) return null;
@@ -6723,7 +6741,7 @@ var BarChart = React6.memo(({ data, labels, width, height, animate, onHover, onS
6723
6741
  transformOrigin: `${b.x + b.w / 2}px ${baseline}px`,
6724
6742
  animationDelay: `${delay}ms`
6725
6743
  } : void 0,
6726
- onMouseEnter: () => onShowAt(b.x + b.w / 2, b.y, `${key}: ${labels[i]} \u2014 ${b.v}`),
6744
+ onMouseEnter: () => onShowAt(b.x + b.w / 2, b.y, `${key}: ${labels[i]} \u2014 ${b.v}`, barSvgRef.current),
6727
6745
  onMouseLeave: onLeave
6728
6746
  },
6729
6747
  `${di}-${i}`
@@ -6896,7 +6914,7 @@ var Chart = React6.memo((props) => {
6896
6914
  ready && type === "bar" && /* @__PURE__ */ jsx307(BarChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
6897
6915
  ready && type === "pie" && /* @__PURE__ */ jsx307(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
6898
6916
  ready && type === "doughnut" && /* @__PURE__ */ jsx307(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, isDoughnut: true, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
6899
- ready && (type === "bar" || type === "pie" || type === "doughnut") && /* @__PURE__ */ jsx307(ChartLegend, { data: stableData, labels: stableLabels, type }),
6917
+ ready && (type === "pie" || type === "doughnut") && /* @__PURE__ */ jsx307(ChartLegend, { data: stableData, labels: stableLabels, type }),
6900
6918
  tooltip.visible && tooltip.content && /* @__PURE__ */ jsx307(ChartTooltip, { x: tooltip.x, y: tooltip.y, containerWidth: width, containerHeight: height, children: tooltip.content })
6901
6919
  ] });
6902
6920
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@x-plat/design-system",
3
- "version": "0.5.36",
3
+ "version": "0.5.37",
4
4
  "description": "XPLAT UI Design System",
5
5
  "author": "XPLAT WOONG",
6
6
  "main": "dist/index.cjs",