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