@x-plat/design-system 0.5.35 → 0.5.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -35,24 +35,8 @@ __export(Chart_exports, {
35
35
  module.exports = __toCommonJS(Chart_exports);
36
36
 
37
37
  // src/components/Chart/Chart.tsx
38
- var import_react2 = __toESM(require("react"), 1);
39
-
40
- // src/tokens/hooks/Portal.tsx
41
38
  var import_react = __toESM(require("react"), 1);
42
- var import_react_dom = __toESM(require("react-dom"), 1);
43
39
  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;
53
-
54
- // src/components/Chart/Chart.tsx
55
- var import_jsx_runtime2 = require("react/jsx-runtime");
56
40
  var CATEGORICAL_COUNT = 8;
57
41
  var LINE_BAR_PALETTES = Array.from({ length: CATEGORICAL_COUNT }, (_, i) => {
58
42
  const n = i + 1;
@@ -98,11 +82,11 @@ var toSmoothPath = (points) => {
98
82
  };
99
83
  var RESIZE_SETTLE_MS = 150;
100
84
  var useChartSize = (ref) => {
101
- const [size, setSize] = import_react2.default.useState({ width: 0, height: 0 });
102
- const settleTimer = import_react2.default.useRef(0);
103
- const committedSize = import_react2.default.useRef({ width: 0, height: 0 });
104
- const initialRef = import_react2.default.useRef(true);
105
- import_react2.default.useEffect(() => {
85
+ const [size, setSize] = import_react.default.useState({ width: 0, height: 0 });
86
+ const settleTimer = import_react.default.useRef(0);
87
+ const committedSize = import_react.default.useRef({ width: 0, height: 0 });
88
+ const initialRef = import_react.default.useRef(true);
89
+ import_react.default.useEffect(() => {
106
90
  const el = ref.current;
107
91
  if (!el) return;
108
92
  const observer = new ResizeObserver((entries) => {
@@ -144,10 +128,10 @@ var useChartSize = (ref) => {
144
128
  };
145
129
  var prefersReducedMotion = () => typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
146
130
  var useChartAnimation = (containerRef, dataKey) => {
147
- const [animate, setAnimate] = import_react2.default.useState(false);
148
- const prevDataKey = import_react2.default.useRef(dataKey);
149
- const hasAnimated = import_react2.default.useRef(false);
150
- import_react2.default.useEffect(() => {
131
+ const [animate, setAnimate] = import_react.default.useState(false);
132
+ const prevDataKey = import_react.default.useRef(dataKey);
133
+ const hasAnimated = import_react.default.useRef(false);
134
+ import_react.default.useEffect(() => {
151
135
  if (prefersReducedMotion()) return;
152
136
  const el = containerRef.current;
153
137
  if (!el) return;
@@ -163,7 +147,7 @@ var useChartAnimation = (containerRef, dataKey) => {
163
147
  observer.observe(el);
164
148
  return () => observer.disconnect();
165
149
  }, [containerRef]);
166
- import_react2.default.useEffect(() => {
150
+ import_react.default.useEffect(() => {
167
151
  if (dataKey !== prevDataKey.current) {
168
152
  prevDataKey.current = dataKey;
169
153
  if (prefersReducedMotion()) return;
@@ -177,39 +161,60 @@ var useChartAnimation = (containerRef, dataKey) => {
177
161
  };
178
162
  var TOOLTIP_OFFSET = 12;
179
163
  var useChartTooltip = (enabled) => {
180
- const [tooltip, setTooltip] = import_react2.default.useState({
164
+ const [tooltip, setTooltip] = import_react.default.useState({
181
165
  visible: false,
182
- clientX: 0,
183
- clientY: 0,
166
+ x: 0,
167
+ y: 0,
184
168
  content: ""
185
169
  });
186
- const containerRef = import_react2.default.useRef(null);
187
- const rafRef = import_react2.default.useRef(0);
188
- const move = import_react2.default.useCallback((e) => {
170
+ const containerRef = import_react.default.useRef(null);
171
+ const rafRef = import_react.default.useRef(0);
172
+ const move = import_react.default.useCallback((e) => {
189
173
  if (!enabled) return;
190
174
  const cx = e.clientX;
191
175
  const cy = e.clientY;
192
176
  cancelAnimationFrame(rafRef.current);
193
177
  rafRef.current = requestAnimationFrame(() => {
194
- setTooltip((prev) => ({ ...prev, clientX: cx, clientY: cy }));
178
+ const rect = containerRef.current?.getBoundingClientRect();
179
+ if (!rect) return;
180
+ setTooltip((prev) => ({ ...prev, x: cx - rect.left, y: cy - rect.top }));
195
181
  });
196
182
  }, [enabled]);
197
- const show = import_react2.default.useCallback((e, content) => {
183
+ const show = import_react.default.useCallback((e, content) => {
184
+ if (!enabled) return;
185
+ const rect = containerRef.current?.getBoundingClientRect();
186
+ if (!rect) return;
187
+ setTooltip({ visible: true, x: e.clientX - rect.left, y: e.clientY - rect.top, content });
188
+ }, [enabled]);
189
+ const showAt = import_react.default.useCallback((svgX, svgY, content, svgEl) => {
198
190
  if (!enabled) return;
199
- setTooltip({ visible: true, clientX: e.clientX, clientY: e.clientY, content });
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
+ }
204
+ setTooltip({ visible: true, x, y, content });
200
205
  }, [enabled]);
201
- const hide = import_react2.default.useCallback(() => {
206
+ const hide = import_react.default.useCallback(() => {
202
207
  cancelAnimationFrame(rafRef.current);
203
208
  setTooltip((prev) => ({ ...prev, visible: false }));
204
209
  }, []);
205
- return { tooltip, show, hide, move, containerRef };
210
+ return { tooltip, show, showAt, hide, move, containerRef };
206
211
  };
207
- var GridLines = import_react2.default.memo(({ width, height, chartH, maxVal }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: [0, 0.25, 0.5, 0.75, 1].map((ratio) => {
212
+ 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) => {
208
213
  const y = PADDING.top + (1 - ratio) * chartH;
209
214
  const val = Math.round(maxVal * ratio);
210
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("g", { children: [
211
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: PADDING.left, y1: y, x2: width - PADDING.right, y2: y, className: "chart-grid" }),
212
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("text", { x: PADDING.left - 8, y: y + 4, className: "chart-axis-label", textAnchor: "end", children: val })
215
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", { children: [
216
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: PADDING.left, y1: y, x2: width - PADDING.right, y2: y, className: "chart-grid" }),
217
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { x: PADDING.left - 8, y: y + 4, className: "chart-axis-label", textAnchor: "end", children: val })
213
218
  ] }, ratio);
214
219
  }) }));
215
220
  GridLines.displayName = "GridLines";
@@ -219,18 +224,18 @@ var getLabelStep = (count, chartW) => {
219
224
  if (count <= maxLabels) return 1;
220
225
  return Math.ceil(count / maxLabels);
221
226
  };
222
- var AxisLabels = import_react2.default.memo(({ labels, count, chartW, height }) => {
227
+ var AxisLabels = import_react.default.memo(({ labels, count, chartW, height }) => {
223
228
  const step = getLabelStep(count, chartW);
224
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: labels.map((label, i) => {
229
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: labels.map((label, i) => {
225
230
  if (i % step !== 0) return null;
226
231
  const x = PADDING.left + i / (count - 1 || 1) * chartW;
227
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("text", { x, y: height - 8, className: "chart-axis-label", textAnchor: "middle", children: label }, i);
232
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { x, y: height - 8, className: "chart-axis-label", textAnchor: "middle", children: label }, i);
228
233
  }) });
229
234
  });
230
235
  AxisLabels.displayName = "AxisLabels";
231
236
  var useCrosshair = (seriesPoints, entries, labels, chartH) => {
232
- const [activeIndex, setActiveIndex] = import_react2.default.useState(null);
233
- const handleMouseMove = import_react2.default.useCallback((e) => {
237
+ const [activeIndex, setActiveIndex] = import_react.default.useState(null);
238
+ const handleMouseMove = import_react.default.useCallback((e) => {
234
239
  const svg = e.currentTarget;
235
240
  const rect = svg.getBoundingClientRect();
236
241
  const mx = (e.clientX - rect.left) / rect.width * svg.viewBox.baseVal.width;
@@ -249,17 +254,17 @@ var useCrosshair = (seriesPoints, entries, labels, chartH) => {
249
254
  }
250
255
  setActiveIndex(minDist <= threshold ? closest : null);
251
256
  }, [seriesPoints]);
252
- const handleMouseLeave = import_react2.default.useCallback(() => {
257
+ const handleMouseLeave = import_react.default.useCallback(() => {
253
258
  setActiveIndex(null);
254
259
  }, []);
255
- const tooltipContent = import_react2.default.useMemo(() => {
260
+ const tooltipContent = import_react.default.useMemo(() => {
256
261
  if (activeIndex === null) return "";
257
262
  return entries.map(([key], di) => {
258
263
  const p = seriesPoints[di]?.[activeIndex];
259
264
  return p ? `${key}: ${p.v}` : "";
260
265
  }).filter(Boolean).join(" / ");
261
266
  }, [activeIndex, entries, seriesPoints]);
262
- const getTooltipAt = import_react2.default.useCallback((idx) => {
267
+ const getTooltipAt = import_react.default.useCallback((idx) => {
263
268
  return entries.map(([key], di) => {
264
269
  const p = seriesPoints[di]?.[idx];
265
270
  return p ? `${key}: ${p.v}` : "";
@@ -267,16 +272,16 @@ var useCrosshair = (seriesPoints, entries, labels, chartH) => {
267
272
  }, [entries, seriesPoints]);
268
273
  return { activeIndex, handleMouseMove, handleMouseLeave, tooltipContent, getTooltipAt };
269
274
  };
270
- var LineChart = import_react2.default.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
271
- const entries = import_react2.default.useMemo(() => Object.entries(data), [data]);
272
- const maxVal = import_react2.default.useMemo(() => {
275
+ var LineChart = import_react.default.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
276
+ const entries = import_react.default.useMemo(() => Object.entries(data), [data]);
277
+ const maxVal = import_react.default.useMemo(() => {
273
278
  const allValues = entries.flatMap(([, v]) => v);
274
279
  return Math.max(...allValues) * 1.2 || 1;
275
280
  }, [entries]);
276
281
  const count = labels.length;
277
282
  const chartW = width - PADDING.left - PADDING.right;
278
283
  const chartH = height - PADDING.top - PADDING.bottom;
279
- const seriesPoints = import_react2.default.useMemo(
284
+ const seriesPoints = import_react.default.useMemo(
280
285
  () => entries.map(
281
286
  ([, values]) => values.map((v, i) => ({
282
287
  x: PADDING.left + i / (count - 1 || 1) * chartW,
@@ -286,9 +291,10 @@ var LineChart = import_react2.default.memo(({ data, labels, width, height, anima
286
291
  ),
287
292
  [entries, count, chartW, chartH, maxVal]
288
293
  );
289
- const clipRef = import_react2.default.useRef(null);
294
+ const clipRef = import_react.default.useRef(null);
295
+ const svgRef = import_react.default.useRef(null);
290
296
  const { activeIndex, handleMouseMove, handleMouseLeave, getTooltipAt } = useCrosshair(seriesPoints, entries, labels, chartH);
291
- import_react2.default.useEffect(() => {
297
+ import_react.default.useEffect(() => {
292
298
  if (!animate || !clipRef.current) return;
293
299
  clipRef.current.setAttribute("width", "0");
294
300
  requestAnimationFrame(() => {
@@ -300,30 +306,17 @@ var LineChart = import_react2.default.memo(({ data, labels, width, height, anima
300
306
  }, [animate, width]);
301
307
  const activeX = activeIndex !== null ? seriesPoints[0]?.[activeIndex]?.x ?? null : null;
302
308
  const lineClipId = "line-area-clip";
303
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
309
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
304
310
  "svg",
305
311
  {
312
+ ref: svgRef,
306
313
  viewBox: `0 0 ${width} ${height}`,
307
314
  className: "chart-svg",
308
315
  onMouseMove: (e) => {
309
316
  handleMouseMove(e);
310
- const svg = e.currentTarget;
311
- const rect = svg.getBoundingClientRect();
312
- const mx = (e.clientX - rect.left) / rect.width * svg.viewBox.baseVal.width;
313
- const points = seriesPoints[0];
314
- if (!points || points.length === 0) return;
315
- const step = points.length > 1 ? Math.abs(points[1].x - points[0].x) : 20;
316
- let closest = 0;
317
- let minDist = Math.abs(points[0].x - mx);
318
- for (let i = 1; i < points.length; i++) {
319
- const dist = Math.abs(points[i].x - mx);
320
- if (dist < minDist) {
321
- minDist = dist;
322
- closest = i;
323
- }
324
- }
325
- if (minDist <= step / 2) {
326
- onHover(e, `${labels[closest]} \u2014 ${getTooltipAt(closest)}`);
317
+ if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
318
+ const p = seriesPoints[0][activeIndex];
319
+ onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`, svgRef.current);
327
320
  } else {
328
321
  onLeave();
329
322
  }
@@ -333,9 +326,9 @@ var LineChart = import_react2.default.memo(({ data, labels, width, height, anima
333
326
  onLeave();
334
327
  },
335
328
  children: [
336
- animate && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("clipPath", { id: lineClipId, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { ref: clipRef, x: "0", y: "0", width: animate ? 0 : width, height }) }) }),
337
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GridLines, { width, height, chartH, maxVal }),
338
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AxisLabels, { labels, count, chartW, height }),
329
+ animate && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("clipPath", { id: lineClipId, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { ref: clipRef, x: "0", y: "0", width: animate ? 0 : width, height }) }) }),
330
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GridLines, { width, height, chartH, maxVal }),
331
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AxisLabels, { labels, count, chartW, height }),
339
332
  entries.map(([key], di) => {
340
333
  const palette = getPalette(LINE_BAR_PALETTES, di, key);
341
334
  const color = palette[2];
@@ -344,16 +337,16 @@ var LineChart = import_react2.default.memo(({ data, labels, width, height, anima
344
337
  const gradientId = `line-gradient-${di}`;
345
338
  const polyPoints = points.map((p) => `${p.x},${p.y}`).join(" ");
346
339
  const areaD = `M ${points[0].x},${points[0].y} ${points.map((p) => `L ${p.x},${p.y}`).join(" ")} L ${points[points.length - 1].x},${PADDING.top + chartH} L ${points[0].x},${PADDING.top + chartH} Z`;
347
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("g", { children: [
348
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
349
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("stop", { offset: "0%", stopColor: areaColor, stopOpacity: "0.2" }),
350
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("stop", { offset: "100%", stopColor: areaColor, stopOpacity: "0" })
340
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", { children: [
341
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
342
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("stop", { offset: "0%", stopColor: areaColor, stopOpacity: "0.2" }),
343
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("stop", { offset: "100%", stopColor: areaColor, stopOpacity: "0" })
351
344
  ] }) }),
352
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("g", { clipPath: animate ? `url(#${lineClipId})` : void 0, children: [
353
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: areaD, fill: `url(#${gradientId})` }),
354
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polyline", { points: polyPoints, fill: "none", stroke: color, strokeWidth: "2" })
345
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", { clipPath: animate ? `url(#${lineClipId})` : void 0, children: [
346
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: areaD, fill: `url(#${gradientId})` }),
347
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: polyPoints, fill: "none", stroke: color, strokeWidth: "2" })
355
348
  ] }),
356
- activeIndex !== null && points[activeIndex] && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
349
+ activeIndex !== null && points[activeIndex] && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
357
350
  "circle",
358
351
  {
359
352
  cx: points[activeIndex].x,
@@ -365,7 +358,7 @@ var LineChart = import_react2.default.memo(({ data, labels, width, height, anima
365
358
  )
366
359
  ] }, di);
367
360
  }),
368
- activeX !== null && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
361
+ activeX !== null && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
369
362
  "line",
370
363
  {
371
364
  x1: activeX,
@@ -375,7 +368,7 @@ var LineChart = import_react2.default.memo(({ data, labels, width, height, anima
375
368
  className: "chart-crosshair"
376
369
  }
377
370
  ),
378
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
371
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
379
372
  "rect",
380
373
  {
381
374
  x: PADDING.left,
@@ -391,16 +384,16 @@ var LineChart = import_react2.default.memo(({ data, labels, width, height, anima
391
384
  );
392
385
  });
393
386
  LineChart.displayName = "LineChart";
394
- var CurveChart = import_react2.default.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
395
- const entries = import_react2.default.useMemo(() => Object.entries(data), [data]);
396
- const maxVal = import_react2.default.useMemo(() => {
387
+ var CurveChart = import_react.default.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
388
+ const entries = import_react.default.useMemo(() => Object.entries(data), [data]);
389
+ const maxVal = import_react.default.useMemo(() => {
397
390
  const allValues = entries.flatMap(([, v]) => v);
398
391
  return Math.max(...allValues) * 1.2 || 1;
399
392
  }, [entries]);
400
393
  const count = labels.length;
401
394
  const chartW = width - PADDING.left - PADDING.right;
402
395
  const chartH = height - PADDING.top - PADDING.bottom;
403
- const seriesPoints = import_react2.default.useMemo(
396
+ const seriesPoints = import_react.default.useMemo(
404
397
  () => entries.map(
405
398
  ([, values]) => values.map((v, i) => ({
406
399
  x: PADDING.left + i / (count - 1 || 1) * chartW,
@@ -410,9 +403,10 @@ var CurveChart = import_react2.default.memo(({ data, labels, width, height, anim
410
403
  ),
411
404
  [entries, count, chartW, chartH, maxVal]
412
405
  );
413
- const curveClipRef = import_react2.default.useRef(null);
406
+ const curveClipRef = import_react.default.useRef(null);
407
+ const curveSvgRef = import_react.default.useRef(null);
414
408
  const { activeIndex, handleMouseMove, handleMouseLeave, getTooltipAt } = useCrosshair(seriesPoints, entries, labels, chartH);
415
- import_react2.default.useEffect(() => {
409
+ import_react.default.useEffect(() => {
416
410
  if (!animate || !curveClipRef.current) return;
417
411
  curveClipRef.current.setAttribute("width", "0");
418
412
  requestAnimationFrame(() => {
@@ -424,30 +418,17 @@ var CurveChart = import_react2.default.memo(({ data, labels, width, height, anim
424
418
  }, [animate, width]);
425
419
  const activeX = activeIndex !== null ? seriesPoints[0]?.[activeIndex]?.x ?? null : null;
426
420
  const curveClipId = "curve-area-clip";
427
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
421
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
428
422
  "svg",
429
423
  {
424
+ ref: curveSvgRef,
430
425
  viewBox: `0 0 ${width} ${height}`,
431
426
  className: "chart-svg",
432
427
  onMouseMove: (e) => {
433
428
  handleMouseMove(e);
434
- const svg = e.currentTarget;
435
- const rect = svg.getBoundingClientRect();
436
- const mx = (e.clientX - rect.left) / rect.width * svg.viewBox.baseVal.width;
437
- const points = seriesPoints[0];
438
- if (!points || points.length === 0) return;
439
- const step = points.length > 1 ? Math.abs(points[1].x - points[0].x) : 20;
440
- let closest = 0;
441
- let minDist = Math.abs(points[0].x - mx);
442
- for (let i = 1; i < points.length; i++) {
443
- const dist = Math.abs(points[i].x - mx);
444
- if (dist < minDist) {
445
- minDist = dist;
446
- closest = i;
447
- }
448
- }
449
- if (minDist <= step / 2) {
450
- onHover(e, `${labels[closest]} \u2014 ${getTooltipAt(closest)}`);
429
+ if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
430
+ const p = seriesPoints[0][activeIndex];
431
+ onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`, curveSvgRef.current);
451
432
  } else {
452
433
  onLeave();
453
434
  }
@@ -457,9 +438,9 @@ var CurveChart = import_react2.default.memo(({ data, labels, width, height, anim
457
438
  onLeave();
458
439
  },
459
440
  children: [
460
- animate && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("clipPath", { id: curveClipId, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { ref: curveClipRef, x: "0", y: "0", width: animate ? 0 : width, height }) }) }),
461
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GridLines, { width, height, chartH, maxVal }),
462
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AxisLabels, { labels, count, chartW, height }),
441
+ animate && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("clipPath", { id: curveClipId, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { ref: curveClipRef, x: "0", y: "0", width: animate ? 0 : width, height }) }) }),
442
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GridLines, { width, height, chartH, maxVal }),
443
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AxisLabels, { labels, count, chartW, height }),
463
444
  entries.map(([key], di) => {
464
445
  const palette = getPalette(LINE_BAR_PALETTES, di, key);
465
446
  const color = palette[2];
@@ -468,16 +449,16 @@ var CurveChart = import_react2.default.memo(({ data, labels, width, height, anim
468
449
  const gradientId = `curve-gradient-${di}`;
469
450
  const linePath = toSmoothPath(points);
470
451
  const areaPath = linePath + ` L ${points[points.length - 1].x} ${PADDING.top + chartH} L ${points[0].x} ${PADDING.top + chartH} Z`;
471
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("g", { children: [
472
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
473
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("stop", { offset: "0%", stopColor: areaColor, stopOpacity: "0.4" }),
474
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("stop", { offset: "100%", stopColor: areaColor, stopOpacity: "0.02" })
452
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", { children: [
453
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
454
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("stop", { offset: "0%", stopColor: areaColor, stopOpacity: "0.4" }),
455
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("stop", { offset: "100%", stopColor: areaColor, stopOpacity: "0.02" })
475
456
  ] }) }),
476
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("g", { clipPath: animate ? `url(#${curveClipId})` : void 0, children: [
477
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: areaPath, fill: `url(#${gradientId})` }),
478
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: linePath, fill: "none", stroke: color, strokeWidth: "2" })
457
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", { clipPath: animate ? `url(#${curveClipId})` : void 0, children: [
458
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: areaPath, fill: `url(#${gradientId})` }),
459
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: linePath, fill: "none", stroke: color, strokeWidth: "2" })
479
460
  ] }),
480
- activeIndex !== null && points[activeIndex] && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
461
+ activeIndex !== null && points[activeIndex] && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
481
462
  "circle",
482
463
  {
483
464
  cx: points[activeIndex].x,
@@ -489,7 +470,7 @@ var CurveChart = import_react2.default.memo(({ data, labels, width, height, anim
489
470
  )
490
471
  ] }, di);
491
472
  }),
492
- activeX !== null && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
473
+ activeX !== null && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
493
474
  "line",
494
475
  {
495
476
  x1: activeX,
@@ -499,7 +480,7 @@ var CurveChart = import_react2.default.memo(({ data, labels, width, height, anim
499
480
  className: "chart-crosshair"
500
481
  }
501
482
  ),
502
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
483
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
503
484
  "rect",
504
485
  {
505
486
  x: PADDING.left,
@@ -515,9 +496,10 @@ var CurveChart = import_react2.default.memo(({ data, labels, width, height, anim
515
496
  );
516
497
  });
517
498
  CurveChart.displayName = "CurveChart";
518
- var BarChart = import_react2.default.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
519
- const entries = import_react2.default.useMemo(() => Object.entries(data), [data]);
520
- const maxVal = import_react2.default.useMemo(() => {
499
+ var BarChart = import_react.default.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
500
+ const barSvgRef = import_react.default.useRef(null);
501
+ const entries = import_react.default.useMemo(() => Object.entries(data), [data]);
502
+ const maxVal = import_react.default.useMemo(() => {
521
503
  const allValues = entries.flatMap(([, v]) => v);
522
504
  return Math.max(...allValues) * 1.2 || 1;
523
505
  }, [entries]);
@@ -529,7 +511,7 @@ var BarChart = import_react2.default.memo(({ data, labels, width, height, animat
529
511
  const barGap = groupCount > 1 ? 2 : 0;
530
512
  const barW = Math.max(1, Math.min(32, (groupW * 0.7 - barGap * (groupCount - 1)) / groupCount));
531
513
  const baseline = PADDING.top + chartH;
532
- const bars = import_react2.default.useMemo(
514
+ const bars = import_react.default.useMemo(
533
515
  () => entries.map(
534
516
  ([, values], di) => values.map((v, i) => {
535
517
  const totalBarsW = barW * groupCount + barGap * (groupCount - 1);
@@ -542,11 +524,11 @@ var BarChart = import_react2.default.memo(({ data, labels, width, height, animat
542
524
  [entries, maxVal, chartH, groupW, barW, barGap, groupCount]
543
525
  );
544
526
  const barLabelStep = getLabelStep(count, chartW);
545
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { viewBox: `0 0 ${width} ${height}`, className: "chart-svg", children: [
546
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GridLines, { width, height, chartH, maxVal }),
527
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ref: barSvgRef, viewBox: `0 0 ${width} ${height}`, className: "chart-svg", children: [
528
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GridLines, { width, height, chartH, maxVal }),
547
529
  labels.map((label, i) => {
548
530
  if (i % barLabelStep !== 0) return null;
549
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("text", { x: PADDING.left + groupW * i + groupW / 2, y: height - 8, className: "chart-axis-label", textAnchor: "middle", children: label }, i);
531
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { x: PADDING.left + groupW * i + groupW / 2, y: height - 8, className: "chart-axis-label", textAnchor: "middle", children: label }, i);
550
532
  }),
551
533
  entries.map(([key], di) => {
552
534
  const palette = getPalette(LINE_BAR_PALETTES, di, key);
@@ -555,7 +537,7 @@ var BarChart = import_react2.default.memo(({ data, labels, width, height, animat
555
537
  const r = Math.min(4, b.w / 2);
556
538
  const d = b.h <= r ? `M ${b.x} ${b.y + b.h} V ${b.y} H ${b.x + b.w} V ${b.y + b.h} Z` : `M ${b.x} ${b.y + b.h} V ${b.y + r} Q ${b.x} ${b.y} ${b.x + r} ${b.y} H ${b.x + b.w - r} Q ${b.x + b.w} ${b.y} ${b.x + b.w} ${b.y + r} V ${b.y + b.h} Z`;
557
539
  const delay = 100 + i * 80;
558
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
540
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
559
541
  "path",
560
542
  {
561
543
  d,
@@ -565,8 +547,7 @@ var BarChart = import_react2.default.memo(({ data, labels, width, height, animat
565
547
  transformOrigin: `${b.x + b.w / 2}px ${baseline}px`,
566
548
  animationDelay: `${delay}ms`
567
549
  } : void 0,
568
- onMouseEnter: (e) => onHover(e, `${key}: ${labels[i]} \u2014 ${b.v}`),
569
- onMouseMove: onMove,
550
+ onMouseEnter: () => onShowAt(b.x + b.w / 2, b.y, `${key}: ${labels[i]} \u2014 ${b.v}`, barSvgRef.current),
570
551
  onMouseLeave: onLeave
571
552
  },
572
553
  `${di}-${i}`
@@ -576,11 +557,11 @@ var BarChart = import_react2.default.memo(({ data, labels, width, height, animat
576
557
  ] });
577
558
  });
578
559
  BarChart.displayName = "BarChart";
579
- var PieDonutChart = import_react2.default.memo(
560
+ var PieDonutChart = import_react.default.memo(
580
561
  ({ data, labels, width, height, animate, isDoughnut, onHover, onMove, onLeave }) => {
581
- const entries = import_react2.default.useMemo(() => Object.entries(data), [data]);
582
- const values = import_react2.default.useMemo(() => entries.flatMap(([, v]) => v), [entries]);
583
- const total = import_react2.default.useMemo(() => values.reduce((a, b) => a + b, 0) || 1, [values]);
562
+ const entries = import_react.default.useMemo(() => Object.entries(data), [data]);
563
+ const values = import_react.default.useMemo(() => entries.flatMap(([, v]) => v), [entries]);
564
+ const total = import_react.default.useMemo(() => values.reduce((a, b) => a + b, 0) || 1, [values]);
584
565
  const size = Math.min(width, height);
585
566
  const cx = size / 2;
586
567
  const cy = size / 2;
@@ -588,10 +569,10 @@ var PieDonutChart = import_react2.default.memo(
588
569
  const innerR = isDoughnut ? r * 0.5 : 0;
589
570
  const firstKey = entries[0]?.[0] ?? "";
590
571
  const colorOffset = hashString(firstKey);
591
- const maskRef = import_react2.default.useRef(null);
572
+ const maskRef = import_react.default.useRef(null);
592
573
  const maskR = r + 10;
593
574
  const maskCircumference = 2 * Math.PI * maskR;
594
- import_react2.default.useEffect(() => {
575
+ import_react.default.useEffect(() => {
595
576
  if (!animate || !maskRef.current) return;
596
577
  const el = maskRef.current;
597
578
  el.style.strokeDasharray = `${maskCircumference}`;
@@ -601,7 +582,7 @@ var PieDonutChart = import_react2.default.memo(
601
582
  el.style.strokeDashoffset = "0";
602
583
  });
603
584
  }, [animate, maskCircumference]);
604
- const sliceData = import_react2.default.useMemo(() => {
585
+ const sliceData = import_react.default.useMemo(() => {
605
586
  let angle0 = -Math.PI / 2;
606
587
  let cumulativeAngle = 0;
607
588
  return values.map((v, i) => {
@@ -635,8 +616,8 @@ var PieDonutChart = import_react2.default.memo(
635
616
  });
636
617
  }, [values, total, cx, cy, r, innerR, labels]);
637
618
  const maskId = `pie-mask-${isDoughnut ? "d" : "p"}`;
638
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { viewBox: `0 0 ${size} ${size}`, className: "chart-svg chart-pie", children: [
639
- animate && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("mask", { id: maskId, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
619
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: `0 0 ${size} ${size}`, className: "chart-svg chart-pie", children: [
620
+ animate && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("mask", { id: maskId, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
640
621
  "circle",
641
622
  {
642
623
  ref: maskRef,
@@ -649,56 +630,39 @@ var PieDonutChart = import_react2.default.memo(
649
630
  transform: `rotate(-90 ${cx} ${cy})`
650
631
  }
651
632
  ) }) }),
652
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("g", { mask: animate ? `url(#${maskId})` : void 0, children: sliceData.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("g", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
633
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { mask: animate ? `url(#${maskId})` : void 0, children: sliceData.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
653
634
  "path",
654
635
  {
655
636
  d: s.d,
656
637
  fill: PIE_COLORS[(i + colorOffset) % PIE_COLORS.length],
657
- className: "chart-slice",
658
- onMouseEnter: (e) => onHover(e, `${s.label}: ${s.v} (${s.pct}%)`),
659
- onMouseMove: onMove,
660
- onMouseLeave: onLeave
638
+ className: "chart-slice"
661
639
  }
662
- ) }, i)) }),
663
- sliceData.map((s, i) => s.angle > 0.2 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
664
- "text",
665
- {
666
- x: s.lx,
667
- y: s.ly,
668
- className: `chart-pie-label ${animate ? "chart-pie-label-animate" : ""}`,
669
- style: animate ? { animationDelay: `${s.labelDelay}ms` } : void 0,
670
- textAnchor: "middle",
671
- dominantBaseline: "central",
672
- children: s.v
673
- },
674
- `label-${i}`
675
- ))
640
+ ) }, i)) })
676
641
  ] });
677
642
  }
678
643
  );
679
644
  PieDonutChart.displayName = "PieDonutChart";
680
- var ChartTooltipPortal = ({ clientX, clientY, visible, children }) => {
681
- const ref = import_react2.default.useRef(null);
682
- const [pos, setPos] = import_react2.default.useState({ left: 0, top: 0 });
683
- import_react2.default.useLayoutEffect(() => {
645
+ var ChartTooltip = ({ x, y, containerWidth, containerHeight, children }) => {
646
+ const ref = import_react.default.useRef(null);
647
+ const [pos, setPos] = import_react.default.useState({ left: 0, top: 0 });
648
+ import_react.default.useLayoutEffect(() => {
684
649
  const el = ref.current;
685
650
  if (!el) return;
686
651
  const w = el.offsetWidth;
687
652
  const h = el.offsetHeight;
688
- const vw = window.innerWidth;
689
- let left = clientX + TOOLTIP_OFFSET;
690
- let top = clientY - h - TOOLTIP_OFFSET;
691
- if (left + w > vw - 8) left = clientX - w - TOOLTIP_OFFSET;
692
- if (top < 8) top = clientY + TOOLTIP_OFFSET;
693
- if (left < 8) left = 8;
653
+ let left = x + TOOLTIP_OFFSET;
654
+ let top = y - h - TOOLTIP_OFFSET;
655
+ if (left + w > containerWidth) left = x - w - TOOLTIP_OFFSET;
656
+ if (top < 0) top = y + TOOLTIP_OFFSET;
657
+ if (left < 0) left = 0;
694
658
  setPos({ left, top });
695
- }, [clientX, clientY]);
696
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
659
+ }, [x, y, containerWidth, containerHeight]);
660
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
697
661
  "div",
698
662
  {
699
663
  ref,
700
- className: `chart-tooltip ${visible ? "chart-tooltip-show" : "chart-tooltip-hide"}`,
701
- style: { position: "fixed", left: pos.left, top: pos.top, zIndex: 1100 },
664
+ className: "chart-tooltip chart-tooltip-show",
665
+ style: { left: pos.left, top: pos.top },
702
666
  children
703
667
  }
704
668
  );
@@ -710,14 +674,14 @@ var ChartLegend = ({ data, labels, type }) => {
710
674
  const total = values.reduce((a, b) => a + b, 0) || 1;
711
675
  const firstKey = entries[0]?.[0] ?? "";
712
676
  const colorOffset = hashString(firstKey);
713
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "chart-legend", children: values.map((v, i) => {
677
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "chart-legend", children: values.map((v, i) => {
714
678
  const pct = Math.round(v / total * 100);
715
679
  const color = PIE_COLORS[(i + colorOffset) % PIE_COLORS.length];
716
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "chart-legend-item", children: [
717
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "chart-legend-dot", style: { backgroundColor: color } }),
718
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "chart-legend-text", children: [
719
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "chart-legend-label", children: labels[i] || `${i + 1}` }),
720
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "chart-legend-value", children: [
680
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "chart-legend-item", children: [
681
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "chart-legend-dot", style: { backgroundColor: color } }),
682
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "chart-legend-text", children: [
683
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "chart-legend-label", children: labels[i] || `${i + 1}` }),
684
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "chart-legend-value", children: [
721
685
  v.toLocaleString(),
722
686
  "(",
723
687
  pct,
@@ -727,37 +691,37 @@ var ChartLegend = ({ data, labels, type }) => {
727
691
  ] }, i);
728
692
  }) });
729
693
  }
730
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "chart-legend", children: entries.map(([key], di) => {
694
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "chart-legend", children: entries.map(([key], di) => {
731
695
  const palette = getPalette(LINE_BAR_PALETTES, di, key);
732
696
  const color = palette[2];
733
697
  const values = entries[di][1];
734
698
  const sum = values.reduce((a, b) => a + b, 0);
735
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "chart-legend-item", children: [
736
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "chart-legend-dot", style: { backgroundColor: color } }),
737
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "chart-legend-text", children: [
738
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "chart-legend-label", children: key }),
739
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "chart-legend-value", children: sum.toLocaleString() })
699
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "chart-legend-item", children: [
700
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "chart-legend-dot", style: { backgroundColor: color } }),
701
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "chart-legend-text", children: [
702
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "chart-legend-label", children: key }),
703
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "chart-legend-value", children: sum.toLocaleString() })
740
704
  ] })
741
705
  ] }, di);
742
706
  }) });
743
707
  };
744
- var Chart = import_react2.default.memo((props) => {
708
+ var Chart = import_react.default.memo((props) => {
745
709
  const { type, data, labels, tooltip: showTooltip = true } = props;
746
- const { tooltip, show, hide, move, containerRef } = useChartTooltip(showTooltip);
710
+ const { tooltip, show, showAt, hide, move, containerRef } = useChartTooltip(showTooltip);
747
711
  const { width, height } = useChartSize(containerRef);
748
- const stableData = import_react2.default.useMemo(() => data, [JSON.stringify(data)]);
749
- const stableLabels = import_react2.default.useMemo(() => labels, [JSON.stringify(labels)]);
750
- const dataKey = import_react2.default.useMemo(() => JSON.stringify(labels), [labels]);
712
+ const stableData = import_react.default.useMemo(() => data, [JSON.stringify(data)]);
713
+ const stableLabels = import_react.default.useMemo(() => labels, [JSON.stringify(labels)]);
714
+ const dataKey = import_react.default.useMemo(() => JSON.stringify(labels), [labels]);
751
715
  const animate = useChartAnimation(containerRef, dataKey);
752
716
  const ready = width > 0 && height > 0;
753
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "lib-xplat-chart", ref: containerRef, children: [
754
- ready && type === "line" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(LineChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
755
- ready && type === "curve" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CurveChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
756
- ready && type === "bar" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BarChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
757
- ready && type === "pie" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
758
- ready && type === "doughnut" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, isDoughnut: true, onHover: show, onMove: move, onLeave: hide }),
759
- ready && (type === "bar" || type === "pie" || type === "doughnut") && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegend, { data: stableData, labels: stableLabels, type }),
760
- tooltip.content && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Portal_default, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTooltipPortal, { clientX: tooltip.clientX, clientY: tooltip.clientY, visible: tooltip.visible, children: tooltip.content }) })
717
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "lib-xplat-chart", ref: containerRef, children: [
718
+ 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 }),
719
+ 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 }),
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 }),
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 }),
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 }),
723
+ ready && (type === "pie" || type === "doughnut") && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChartLegend, { data: stableData, labels: stableLabels, type }),
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 })
761
725
  ] });
762
726
  });
763
727
  Chart.displayName = "Chart";