@x-plat/design-system 0.5.18 → 0.5.19

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.
@@ -73,6 +73,8 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
73
73
  import_react.default.useLayoutEffect(() => {
74
74
  if (!enabled) return;
75
75
  calculatePosition();
76
+ const raf = requestAnimationFrame(calculatePosition);
77
+ return () => cancelAnimationFrame(raf);
76
78
  }, [calculatePosition, enabled]);
77
79
  import_react.default.useEffect(() => {
78
80
  if (!enabled) return;
@@ -37,6 +37,8 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
37
37
  React.useLayoutEffect(() => {
38
38
  if (!enabled) return;
39
39
  calculatePosition();
40
+ const raf = requestAnimationFrame(calculatePosition);
41
+ return () => cancelAnimationFrame(raf);
40
42
  }, [calculatePosition, enabled]);
41
43
  React.useEffect(() => {
42
44
  if (!enabled) return;
@@ -73,6 +73,8 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
73
73
  import_react.default.useLayoutEffect(() => {
74
74
  if (!enabled) return;
75
75
  calculatePosition();
76
+ const raf = requestAnimationFrame(calculatePosition);
77
+ return () => cancelAnimationFrame(raf);
76
78
  }, [calculatePosition, enabled]);
77
79
  import_react.default.useEffect(() => {
78
80
  if (!enabled) return;
@@ -1,6 +1,8 @@
1
1
  /* src/components/PopOver/popOver.scss */
2
2
  .lib-xplat-pop-over {
3
3
  position: relative;
4
+ width: 100%;
5
+ height: 100%;
4
6
  cursor: pointer;
5
7
  user-select: none;
6
8
  }
@@ -37,6 +37,8 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
37
37
  React.useLayoutEffect(() => {
38
38
  if (!enabled) return;
39
39
  calculatePosition();
40
+ const raf = requestAnimationFrame(calculatePosition);
41
+ return () => cancelAnimationFrame(raf);
40
42
  }, [calculatePosition, enabled]);
41
43
  React.useEffect(() => {
42
44
  if (!enabled) return;
@@ -74,6 +74,8 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
74
74
  import_react.default.useLayoutEffect(() => {
75
75
  if (!enabled) return;
76
76
  calculatePosition();
77
+ const raf = requestAnimationFrame(calculatePosition);
78
+ return () => cancelAnimationFrame(raf);
77
79
  }, [calculatePosition, enabled]);
78
80
  import_react.default.useEffect(() => {
79
81
  if (!enabled) return;
@@ -37,6 +37,8 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
37
37
  React.useLayoutEffect(() => {
38
38
  if (!enabled) return;
39
39
  calculatePosition();
40
+ const raf = requestAnimationFrame(calculatePosition);
41
+ return () => cancelAnimationFrame(raf);
40
42
  }, [calculatePosition, enabled]);
41
43
  React.useEffect(() => {
42
44
  if (!enabled) return;
@@ -2197,6 +2197,37 @@ var useChartSize = (ref) => {
2197
2197
  }, [ref]);
2198
2198
  return size;
2199
2199
  };
2200
+ var prefersReducedMotion = () => typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
2201
+ var useChartAnimation = (containerRef, dataKey) => {
2202
+ const [animate, setAnimate] = import_react5.default.useState(false);
2203
+ const prevDataKey = import_react5.default.useRef(dataKey);
2204
+ const hasAnimated = import_react5.default.useRef(false);
2205
+ import_react5.default.useEffect(() => {
2206
+ if (prefersReducedMotion()) return;
2207
+ const el = containerRef.current;
2208
+ if (!el) return;
2209
+ const observer = new IntersectionObserver(
2210
+ ([entry]) => {
2211
+ if (entry.isIntersecting && !hasAnimated.current) {
2212
+ hasAnimated.current = true;
2213
+ setAnimate(true);
2214
+ }
2215
+ },
2216
+ { threshold: 0.1 }
2217
+ );
2218
+ observer.observe(el);
2219
+ return () => observer.disconnect();
2220
+ }, [containerRef]);
2221
+ import_react5.default.useEffect(() => {
2222
+ if (dataKey !== prevDataKey.current) {
2223
+ prevDataKey.current = dataKey;
2224
+ if (prefersReducedMotion()) return;
2225
+ setAnimate(false);
2226
+ requestAnimationFrame(() => setAnimate(true));
2227
+ }
2228
+ }, [dataKey]);
2229
+ return animate || prefersReducedMotion();
2230
+ };
2200
2231
  var useChartTooltip = (enabled) => {
2201
2232
  const [tooltip, setTooltip] = import_react5.default.useState({
2202
2233
  visible: false,
@@ -2262,7 +2293,7 @@ var AxisLabels = import_react5.default.memo(({ labels, count, chartW, height })
2262
2293
  }) });
2263
2294
  });
2264
2295
  AxisLabels.displayName = "AxisLabels";
2265
- var LineChart = import_react5.default.memo(({ data, labels, width, height, onHover, onMove, onLeave }) => {
2296
+ var LineChart = import_react5.default.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
2266
2297
  const entries = import_react5.default.useMemo(() => Object.entries(data), [data]);
2267
2298
  const maxVal = import_react5.default.useMemo(() => {
2268
2299
  const allValues = entries.flatMap(([, v]) => v);
@@ -2282,18 +2313,52 @@ var LineChart = import_react5.default.memo(({ data, labels, width, height, onHov
2282
2313
  [entries, count, chartW, chartH, maxVal]
2283
2314
  );
2284
2315
  const showPoints = count <= 100;
2316
+ const lineRefs = import_react5.default.useRef([]);
2317
+ import_react5.default.useEffect(() => {
2318
+ if (!animate) return;
2319
+ lineRefs.current.forEach((el) => {
2320
+ if (!el) return;
2321
+ const len = el.getTotalLength();
2322
+ el.style.strokeDasharray = `${len}`;
2323
+ el.style.strokeDashoffset = `${len}`;
2324
+ requestAnimationFrame(() => {
2325
+ el.style.transition = "stroke-dashoffset 1200ms ease-out 200ms";
2326
+ el.style.strokeDashoffset = "0";
2327
+ });
2328
+ });
2329
+ }, [animate, seriesPoints]);
2285
2330
  return /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("svg", { viewBox: `0 0 ${width} ${height}`, className: "chart-svg", children: [
2286
2331
  /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(GridLines, { width, height, chartH, maxVal }),
2287
2332
  /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(AxisLabels, { labels, count, chartW, height }),
2288
2333
  entries.map(([key], di) => {
2289
2334
  const palette = getPalette(LINE_BAR_PALETTES, di, key);
2290
2335
  const color = palette[2];
2336
+ const areaColor = palette[0];
2291
2337
  const points = seriesPoints[di];
2338
+ const gradientId = `line-gradient-${di}`;
2339
+ const polyPoints = points.map((p) => `${p.x},${p.y}`).join(" ");
2340
+ 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`;
2292
2341
  return /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("g", { children: [
2342
+ /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
2343
+ /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("stop", { offset: "0%", stopColor: areaColor, stopOpacity: "0.2" }),
2344
+ /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("stop", { offset: "100%", stopColor: areaColor, stopOpacity: "0" })
2345
+ ] }) }),
2346
+ /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
2347
+ "path",
2348
+ {
2349
+ d: areaD,
2350
+ fill: `url(#${gradientId})`,
2351
+ className: "chart-area",
2352
+ style: animate ? { animationDelay: "600ms" } : { opacity: 1 }
2353
+ }
2354
+ ),
2293
2355
  /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
2294
2356
  "polyline",
2295
2357
  {
2296
- points: points.map((p) => `${p.x},${p.y}`).join(" "),
2358
+ ref: (el) => {
2359
+ lineRefs.current[di] = el;
2360
+ },
2361
+ points: polyPoints,
2297
2362
  fill: "none",
2298
2363
  stroke: color,
2299
2364
  strokeWidth: "2"
@@ -2318,7 +2383,7 @@ var LineChart = import_react5.default.memo(({ data, labels, width, height, onHov
2318
2383
  ] });
2319
2384
  });
2320
2385
  LineChart.displayName = "LineChart";
2321
- var CurveChart = import_react5.default.memo(({ data, labels, width, height, onHover, onMove, onLeave }) => {
2386
+ var CurveChart = import_react5.default.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
2322
2387
  const entries = import_react5.default.useMemo(() => Object.entries(data), [data]);
2323
2388
  const maxVal = import_react5.default.useMemo(() => {
2324
2389
  const allValues = entries.flatMap(([, v]) => v);
@@ -2338,6 +2403,20 @@ var CurveChart = import_react5.default.memo(({ data, labels, width, height, onHo
2338
2403
  [entries, count, chartW, chartH, maxVal]
2339
2404
  );
2340
2405
  const showPoints = count <= 100;
2406
+ const lineRefs = import_react5.default.useRef([]);
2407
+ import_react5.default.useEffect(() => {
2408
+ if (!animate) return;
2409
+ lineRefs.current.forEach((el) => {
2410
+ if (!el) return;
2411
+ const len = el.getTotalLength();
2412
+ el.style.strokeDasharray = `${len}`;
2413
+ el.style.strokeDashoffset = `${len}`;
2414
+ requestAnimationFrame(() => {
2415
+ el.style.transition = "stroke-dashoffset 1200ms ease-out 200ms";
2416
+ el.style.strokeDashoffset = "0";
2417
+ });
2418
+ });
2419
+ }, [animate, seriesPoints]);
2341
2420
  return /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("svg", { viewBox: `0 0 ${width} ${height}`, className: "chart-svg", children: [
2342
2421
  /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(GridLines, { width, height, chartH, maxVal }),
2343
2422
  /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(AxisLabels, { labels, count, chartW, height }),
@@ -2354,8 +2433,27 @@ var CurveChart = import_react5.default.memo(({ data, labels, width, height, onHo
2354
2433
  /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("stop", { offset: "0%", stopColor: areaColor, stopOpacity: "0.4" }),
2355
2434
  /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("stop", { offset: "100%", stopColor: areaColor, stopOpacity: "0.02" })
2356
2435
  ] }) }),
2357
- /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("path", { d: areaPath, fill: `url(#${gradientId})` }),
2358
- /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("path", { d: linePath, fill: "none", stroke: color, strokeWidth: "2" }),
2436
+ /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
2437
+ "path",
2438
+ {
2439
+ d: areaPath,
2440
+ fill: `url(#${gradientId})`,
2441
+ className: "chart-area",
2442
+ style: animate ? { animationDelay: "600ms" } : { opacity: 1 }
2443
+ }
2444
+ ),
2445
+ /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
2446
+ "path",
2447
+ {
2448
+ ref: (el) => {
2449
+ lineRefs.current[di] = el;
2450
+ },
2451
+ d: linePath,
2452
+ fill: "none",
2453
+ stroke: color,
2454
+ strokeWidth: "2"
2455
+ }
2456
+ ),
2359
2457
  showPoints && points.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
2360
2458
  "circle",
2361
2459
  {
@@ -2375,7 +2473,7 @@ var CurveChart = import_react5.default.memo(({ data, labels, width, height, onHo
2375
2473
  ] });
2376
2474
  });
2377
2475
  CurveChart.displayName = "CurveChart";
2378
- var BarChart = import_react5.default.memo(({ data, labels, width, height, onHover, onMove, onLeave }) => {
2476
+ var BarChart = import_react5.default.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
2379
2477
  const entries = import_react5.default.useMemo(() => Object.entries(data), [data]);
2380
2478
  const maxVal = import_react5.default.useMemo(() => {
2381
2479
  const allValues = entries.flatMap(([, v]) => v);
@@ -2388,6 +2486,7 @@ var BarChart = import_react5.default.memo(({ data, labels, width, height, onHove
2388
2486
  const groupW = chartW / count;
2389
2487
  const barGap = groupCount > 1 ? 2 : 0;
2390
2488
  const barW = Math.max(1, Math.min(32, (groupW * 0.7 - barGap * (groupCount - 1)) / groupCount));
2489
+ const baseline = PADDING.top + chartH;
2391
2490
  const bars = import_react5.default.useMemo(
2392
2491
  () => entries.map(
2393
2492
  ([, values], di) => values.map((v, i) => {
@@ -2413,12 +2512,17 @@ var BarChart = import_react5.default.memo(({ data, labels, width, height, onHove
2413
2512
  return bars[di].map((b, i) => {
2414
2513
  const r2 = Math.min(4, b.w / 2);
2415
2514
  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`;
2515
+ const delay = 100 + i * 80;
2416
2516
  return /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
2417
2517
  "path",
2418
2518
  {
2419
2519
  d,
2420
2520
  fill: color,
2421
- className: "chart-bar",
2521
+ className: `chart-bar ${animate ? "chart-bar-animate" : ""}`,
2522
+ style: animate ? {
2523
+ transformOrigin: `${b.x + b.w / 2}px ${baseline}px`,
2524
+ animationDelay: `${delay}ms`
2525
+ } : void 0,
2422
2526
  onMouseEnter: (e) => onHover(e, `${key}: ${labels[i]} \u2014 ${b.v}`),
2423
2527
  onMouseMove: onMove,
2424
2528
  onMouseLeave: onLeave
@@ -2431,7 +2535,7 @@ var BarChart = import_react5.default.memo(({ data, labels, width, height, onHove
2431
2535
  });
2432
2536
  BarChart.displayName = "BarChart";
2433
2537
  var PieDonutChart = import_react5.default.memo(
2434
- ({ data, labels, width, height, isDoughnut, onHover, onMove, onLeave }) => {
2538
+ ({ data, labels, width, height, animate, isDoughnut, onHover, onMove, onLeave }) => {
2435
2539
  const entries = import_react5.default.useMemo(() => Object.entries(data), [data]);
2436
2540
  const values = import_react5.default.useMemo(() => entries.flatMap(([, v]) => v), [entries]);
2437
2541
  const total = import_react5.default.useMemo(() => values.reduce((a, b) => a + b, 0) || 1, [values]);
@@ -2471,20 +2575,34 @@ var PieDonutChart = import_react5.default.memo(
2471
2575
  return { d, lx, ly, v, pct, angle, label: labels[i] || `${i + 1}` };
2472
2576
  });
2473
2577
  }, [values, total, cx, cy, r2, innerR, labels]);
2474
- return /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("svg", { viewBox: `0 0 ${size} ${size}`, className: "chart-svg chart-pie", children: sliceData.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("g", { children: [
2475
- /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
2476
- "path",
2477
- {
2478
- d: s.d,
2479
- fill: PIE_COLORS[(i + colorOffset) % PIE_COLORS.length],
2480
- className: "chart-slice",
2481
- onMouseEnter: (e) => onHover(e, `${s.label}: ${s.v} (${s.pct}%)`),
2482
- onMouseMove: onMove,
2483
- onMouseLeave: onLeave
2484
- }
2485
- ),
2486
- s.angle > 0.2 && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("text", { x: s.lx, y: s.ly, className: "chart-pie-label", textAnchor: "middle", dominantBaseline: "central", children: s.v })
2487
- ] }, i)) });
2578
+ return /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("svg", { viewBox: `0 0 ${size} ${size}`, className: "chart-svg chart-pie", children: sliceData.map((s, i) => {
2579
+ const delay = i * 100;
2580
+ return /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("g", { className: animate ? "chart-slice-group-animate" : "", style: animate ? { animationDelay: `${delay}ms` } : void 0, children: [
2581
+ /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
2582
+ "path",
2583
+ {
2584
+ d: s.d,
2585
+ fill: PIE_COLORS[(i + colorOffset) % PIE_COLORS.length],
2586
+ className: "chart-slice",
2587
+ onMouseEnter: (e) => onHover(e, `${s.label}: ${s.v} (${s.pct}%)`),
2588
+ onMouseMove: onMove,
2589
+ onMouseLeave: onLeave
2590
+ }
2591
+ ),
2592
+ s.angle > 0.2 && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
2593
+ "text",
2594
+ {
2595
+ x: s.lx,
2596
+ y: s.ly,
2597
+ className: `chart-pie-label ${animate ? "chart-pie-label-animate" : ""}`,
2598
+ style: animate ? { animationDelay: `${delay + 150}ms` } : void 0,
2599
+ textAnchor: "middle",
2600
+ dominantBaseline: "central",
2601
+ children: s.v
2602
+ }
2603
+ )
2604
+ ] }, i);
2605
+ }) });
2488
2606
  }
2489
2607
  );
2490
2608
  PieDonutChart.displayName = "PieDonutChart";
@@ -2518,13 +2636,15 @@ var Chart = import_react5.default.memo((props) => {
2518
2636
  const { width, height } = useChartSize(containerRef);
2519
2637
  const stableData = import_react5.default.useMemo(() => data, [JSON.stringify(data)]);
2520
2638
  const stableLabels = import_react5.default.useMemo(() => labels, [JSON.stringify(labels)]);
2639
+ const dataKey = import_react5.default.useMemo(() => JSON.stringify(labels), [labels]);
2640
+ const animate = useChartAnimation(containerRef, dataKey);
2521
2641
  const ready = width > 0 && height > 0;
2522
2642
  return /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("div", { className: "lib-xplat-chart", ref: containerRef, children: [
2523
- ready && type === "line" && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(LineChart, { data: stableData, labels: stableLabels, width, height, onHover: show, onMove: move, onLeave: hide }),
2524
- ready && type === "curve" && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(CurveChart, { data: stableData, labels: stableLabels, width, height, onHover: show, onMove: move, onLeave: hide }),
2525
- ready && type === "bar" && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(BarChart, { data: stableData, labels: stableLabels, width, height, onHover: show, onMove: move, onLeave: hide }),
2526
- ready && type === "pie" && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, onHover: show, onMove: move, onLeave: hide }),
2527
- ready && type === "doughnut" && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, isDoughnut: true, onHover: show, onMove: move, onLeave: hide }),
2643
+ ready && type === "line" && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(LineChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
2644
+ ready && type === "curve" && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(CurveChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
2645
+ ready && type === "bar" && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(BarChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
2646
+ ready && type === "pie" && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
2647
+ ready && type === "doughnut" && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, isDoughnut: true, onHover: show, onMove: move, onLeave: hide }),
2528
2648
  tooltip.visible && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(TooltipBubble, { x: tooltip.x, y: tooltip.y, containerWidth: width, children: tooltip.content })
2529
2649
  ] });
2530
2650
  });
@@ -3421,6 +3541,8 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
3421
3541
  import_react18.default.useLayoutEffect(() => {
3422
3542
  if (!enabled) return;
3423
3543
  calculatePosition();
3544
+ const raf = requestAnimationFrame(calculatePosition);
3545
+ return () => cancelAnimationFrame(raf);
3424
3546
  }, [calculatePosition, enabled]);
3425
3547
  import_react18.default.useEffect(() => {
3426
3548
  if (!enabled) return;
@@ -1826,6 +1826,7 @@
1826
1826
  font-weight: 600;
1827
1827
  fill: var(--semantic-text-inverse);
1828
1828
  pointer-events: none;
1829
+ opacity: 1;
1829
1830
  }
1830
1831
  .lib-xplat-chart .chart-pie {
1831
1832
  max-width: 300px;
@@ -1835,10 +1836,10 @@
1835
1836
  cursor: pointer;
1836
1837
  r: 0;
1837
1838
  opacity: 0;
1838
- transition: r 0.15s, opacity 0.15s;
1839
+ transition: r 0.15s ease-out, opacity 0.15s ease-out;
1839
1840
  }
1840
1841
  .lib-xplat-chart .chart-point:hover {
1841
- r: 5;
1842
+ r: 6;
1842
1843
  opacity: 1;
1843
1844
  }
1844
1845
  .lib-xplat-chart .chart-svg:hover .chart-point {
@@ -1847,7 +1848,7 @@
1847
1848
  }
1848
1849
  .lib-xplat-chart .chart-bar {
1849
1850
  cursor: pointer;
1850
- transition: opacity 0.15s, filter 0.15s;
1851
+ transition: opacity 0.15s ease-out, filter 0.15s ease-out;
1851
1852
  }
1852
1853
  .lib-xplat-chart .chart-bar:hover {
1853
1854
  opacity: 0.85;
@@ -1858,15 +1859,22 @@
1858
1859
  stroke: var(--semantic-surface-neutral-default);
1859
1860
  stroke-width: 2;
1860
1861
  transition:
1861
- opacity 0.15s,
1862
- filter 0.15s,
1863
- transform 0.15s;
1862
+ opacity 0.15s ease-out,
1863
+ filter 0.15s ease-out,
1864
+ transform 0.15s ease-out;
1864
1865
  transform-origin: center;
1865
1866
  }
1867
+ .lib-xplat-chart .chart-svg:hover .chart-slice {
1868
+ opacity: 0.5;
1869
+ }
1866
1870
  .lib-xplat-chart .chart-slice:hover {
1867
- opacity: 0.9;
1871
+ opacity: 1 !important;
1872
+ transform: scale(1.03);
1868
1873
  filter: brightness(1.05) drop-shadow(0 2px 6px rgba(0, 0, 0, 0.2));
1869
1874
  }
1875
+ .lib-xplat-chart .chart-area {
1876
+ opacity: 1;
1877
+ }
1870
1878
  .lib-xplat-chart .chart-tooltip {
1871
1879
  position: absolute;
1872
1880
  transform: translate(-50%, -100%);
@@ -1879,6 +1887,65 @@
1879
1887
  white-space: nowrap;
1880
1888
  pointer-events: none;
1881
1889
  z-index: 10;
1890
+ animation: chart-tooltip-in 150ms ease-out;
1891
+ }
1892
+ .lib-xplat-chart .chart-bar-animate {
1893
+ animation: chart-bar-grow 800ms ease-out both;
1894
+ }
1895
+ .lib-xplat-chart .chart-slice-group-animate {
1896
+ animation: chart-slice-in 1000ms ease-out both;
1897
+ }
1898
+ .lib-xplat-chart .chart-pie-label-animate {
1899
+ animation: chart-fade-in 150ms ease-out both;
1900
+ }
1901
+ .lib-xplat-chart .chart-area[style*=animationDelay] {
1902
+ animation: chart-fade-in 800ms ease-out both;
1903
+ }
1904
+ @keyframes chart-bar-grow {
1905
+ from {
1906
+ transform: scaleY(0);
1907
+ }
1908
+ to {
1909
+ transform: scaleY(1);
1910
+ }
1911
+ }
1912
+ @keyframes chart-slice-in {
1913
+ from {
1914
+ opacity: 0;
1915
+ transform: scale(0.8);
1916
+ }
1917
+ to {
1918
+ opacity: 1;
1919
+ transform: scale(1);
1920
+ }
1921
+ }
1922
+ @keyframes chart-fade-in {
1923
+ from {
1924
+ opacity: 0;
1925
+ }
1926
+ to {
1927
+ opacity: 1;
1928
+ }
1929
+ }
1930
+ @keyframes chart-tooltip-in {
1931
+ from {
1932
+ opacity: 0;
1933
+ transform: translate(-50%, -90%);
1934
+ }
1935
+ to {
1936
+ opacity: 1;
1937
+ transform: translate(-50%, -100%);
1938
+ }
1939
+ }
1940
+ @media (prefers-reduced-motion: reduce) {
1941
+ .lib-xplat-chart .chart-bar-animate,
1942
+ .lib-xplat-chart .chart-slice-group-animate,
1943
+ .lib-xplat-chart .chart-pie-label-animate,
1944
+ .lib-xplat-chart .chart-area {
1945
+ animation: none !important;
1946
+ opacity: 1 !important;
1947
+ transform: none !important;
1948
+ }
1882
1949
  }
1883
1950
 
1884
1951
  /* src/components/CheckBox/checkbox.scss */
@@ -2946,6 +3013,8 @@
2946
3013
  /* src/components/PopOver/popOver.scss */
2947
3014
  .lib-xplat-pop-over {
2948
3015
  position: relative;
3016
+ width: 100%;
3017
+ height: 100%;
2949
3018
  cursor: pointer;
2950
3019
  user-select: none;
2951
3020
  }