@x-plat/design-system 0.5.19 → 0.5.21

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.
@@ -1864,7 +1864,7 @@
1864
1864
  transform 0.15s ease-out;
1865
1865
  transform-origin: center;
1866
1866
  }
1867
- .lib-xplat-chart .chart-svg:hover .chart-slice {
1867
+ .lib-xplat-chart .chart-pie:has(.chart-slice:hover) .chart-slice {
1868
1868
  opacity: 0.5;
1869
1869
  }
1870
1870
  .lib-xplat-chart .chart-slice:hover {
@@ -1892,10 +1892,8 @@
1892
1892
  .lib-xplat-chart .chart-bar-animate {
1893
1893
  animation: chart-bar-grow 800ms ease-out both;
1894
1894
  }
1895
- .lib-xplat-chart .chart-slice-group-animate {
1896
- animation: chart-slice-in 1000ms ease-out both;
1897
- }
1898
1895
  .lib-xplat-chart .chart-pie-label-animate {
1896
+ opacity: 0;
1899
1897
  animation: chart-fade-in 150ms ease-out both;
1900
1898
  }
1901
1899
  .lib-xplat-chart .chart-area[style*=animationDelay] {
@@ -1909,16 +1907,6 @@
1909
1907
  transform: scaleY(1);
1910
1908
  }
1911
1909
  }
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
1910
  @keyframes chart-fade-in {
1923
1911
  from {
1924
1912
  opacity: 0;
@@ -1939,7 +1927,6 @@
1939
1927
  }
1940
1928
  @media (prefers-reduced-motion: reduce) {
1941
1929
  .lib-xplat-chart .chart-bar-animate,
1942
- .lib-xplat-chart .chart-slice-group-animate,
1943
1930
  .lib-xplat-chart .chart-pie-label-animate,
1944
1931
  .lib-xplat-chart .chart-area {
1945
1932
  animation: none !important;
@@ -2458,8 +2458,22 @@ var PieDonutChart = React5.memo(
2458
2458
  const innerR = isDoughnut ? r2 * 0.5 : 0;
2459
2459
  const firstKey = entries[0]?.[0] ?? "";
2460
2460
  const colorOffset = hashString(firstKey);
2461
+ const maskRef = React5.useRef(null);
2462
+ const maskR = r2 + 10;
2463
+ const maskCircumference = 2 * Math.PI * maskR;
2464
+ React5.useEffect(() => {
2465
+ if (!animate || !maskRef.current) return;
2466
+ const el = maskRef.current;
2467
+ el.style.strokeDasharray = `${maskCircumference}`;
2468
+ el.style.strokeDashoffset = `${maskCircumference}`;
2469
+ requestAnimationFrame(() => {
2470
+ el.style.transition = "stroke-dashoffset 1000ms ease-out";
2471
+ el.style.strokeDashoffset = "0";
2472
+ });
2473
+ }, [animate, maskCircumference]);
2461
2474
  const sliceData = React5.useMemo(() => {
2462
2475
  let angle0 = -Math.PI / 2;
2476
+ let cumulativeAngle = 0;
2463
2477
  return values.map((v, i) => {
2464
2478
  const angle = v / total * Math.PI * 2;
2465
2479
  const endAngle = angle0 + angle;
@@ -2483,38 +2497,53 @@ var PieDonutChart = React5.memo(
2483
2497
  const lx = cx + labelR * Math.cos(midAngle);
2484
2498
  const ly = cy + labelR * Math.sin(midAngle);
2485
2499
  const pct = Math.round(v / total * 100);
2500
+ cumulativeAngle += angle;
2501
+ const sliceEndRatio = cumulativeAngle / (Math.PI * 2);
2502
+ const labelDelay = 1e3 * sliceEndRatio + 150;
2486
2503
  angle0 = endAngle;
2487
- return { d, lx, ly, v, pct, angle, label: labels[i] || `${i + 1}` };
2504
+ return { d, lx, ly, v, pct, angle, label: labels[i] || `${i + 1}`, labelDelay };
2488
2505
  });
2489
2506
  }, [values, total, cx, cy, r2, innerR, labels]);
2490
- return /* @__PURE__ */ jsx305("svg", { viewBox: `0 0 ${size} ${size}`, className: "chart-svg chart-pie", children: sliceData.map((s, i) => {
2491
- const delay = i * 100;
2492
- return /* @__PURE__ */ jsxs196("g", { className: animate ? "chart-slice-group-animate" : "", style: animate ? { animationDelay: `${delay}ms` } : void 0, children: [
2493
- /* @__PURE__ */ jsx305(
2494
- "path",
2495
- {
2496
- d: s.d,
2497
- fill: PIE_COLORS[(i + colorOffset) % PIE_COLORS.length],
2498
- className: "chart-slice",
2499
- onMouseEnter: (e) => onHover(e, `${s.label}: ${s.v} (${s.pct}%)`),
2500
- onMouseMove: onMove,
2501
- onMouseLeave: onLeave
2502
- }
2503
- ),
2504
- s.angle > 0.2 && /* @__PURE__ */ jsx305(
2505
- "text",
2506
- {
2507
- x: s.lx,
2508
- y: s.ly,
2509
- className: `chart-pie-label ${animate ? "chart-pie-label-animate" : ""}`,
2510
- style: animate ? { animationDelay: `${delay + 150}ms` } : void 0,
2511
- textAnchor: "middle",
2512
- dominantBaseline: "central",
2513
- children: s.v
2514
- }
2515
- )
2516
- ] }, i);
2517
- }) });
2507
+ const maskId = `pie-mask-${isDoughnut ? "d" : "p"}`;
2508
+ return /* @__PURE__ */ jsxs196("svg", { viewBox: `0 0 ${size} ${size}`, className: "chart-svg chart-pie", children: [
2509
+ animate && /* @__PURE__ */ jsx305("defs", { children: /* @__PURE__ */ jsx305("mask", { id: maskId, children: /* @__PURE__ */ jsx305(
2510
+ "circle",
2511
+ {
2512
+ ref: maskRef,
2513
+ cx,
2514
+ cy,
2515
+ r: maskR,
2516
+ fill: "none",
2517
+ stroke: "white",
2518
+ strokeWidth: maskR * 2,
2519
+ transform: `rotate(-90 ${cx} ${cy})`
2520
+ }
2521
+ ) }) }),
2522
+ /* @__PURE__ */ jsx305("g", { mask: animate ? `url(#${maskId})` : void 0, children: sliceData.map((s, i) => /* @__PURE__ */ jsx305("g", { children: /* @__PURE__ */ jsx305(
2523
+ "path",
2524
+ {
2525
+ d: s.d,
2526
+ fill: PIE_COLORS[(i + colorOffset) % PIE_COLORS.length],
2527
+ className: "chart-slice",
2528
+ onMouseEnter: (e) => onHover(e, `${s.label}: ${s.v} (${s.pct}%)`),
2529
+ onMouseMove: onMove,
2530
+ onMouseLeave: onLeave
2531
+ }
2532
+ ) }, i)) }),
2533
+ sliceData.map((s, i) => s.angle > 0.2 && /* @__PURE__ */ jsx305(
2534
+ "text",
2535
+ {
2536
+ x: s.lx,
2537
+ y: s.ly,
2538
+ className: `chart-pie-label ${animate ? "chart-pie-label-animate" : ""}`,
2539
+ style: animate ? { animationDelay: `${s.labelDelay}ms` } : void 0,
2540
+ textAnchor: "middle",
2541
+ dominantBaseline: "central",
2542
+ children: s.v
2543
+ },
2544
+ `label-${i}`
2545
+ ))
2546
+ ] });
2518
2547
  }
2519
2548
  );
2520
2549
  PieDonutChart.displayName = "PieDonutChart";
@@ -3431,6 +3460,7 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
3431
3460
  const popH = popRef.current.offsetHeight;
3432
3461
  const viewportHeight = window.innerHeight;
3433
3462
  const viewportWidth = window.innerWidth;
3463
+ if (popH === 0 || popW === 0) return;
3434
3464
  let direction = "bottom";
3435
3465
  let top;
3436
3466
  let left;
@@ -3456,6 +3486,14 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
3456
3486
  const raf = requestAnimationFrame(calculatePosition);
3457
3487
  return () => cancelAnimationFrame(raf);
3458
3488
  }, [calculatePosition, enabled]);
3489
+ React17.useEffect(() => {
3490
+ if (!enabled || !popRef.current) return;
3491
+ const observer = new ResizeObserver(() => {
3492
+ calculatePosition();
3493
+ });
3494
+ observer.observe(popRef.current);
3495
+ return () => observer.disconnect();
3496
+ }, [calculatePosition, enabled, popRef]);
3459
3497
  React17.useEffect(() => {
3460
3498
  if (!enabled) return;
3461
3499
  window.addEventListener("resize", calculatePosition);
@@ -4271,12 +4309,20 @@ var Select_default = Select;
4271
4309
 
4272
4310
  // src/components/Skeleton/Skeleton.tsx
4273
4311
  import { jsx as jsx333 } from "react/jsx-runtime";
4274
- var toSizeVar = (token) => token === "full" ? "100%" : `var(--spacing-size-${token})`;
4312
+ var SIZE_MAP = {
4313
+ xs: "var(--spacing-size-1)",
4314
+ sm: "var(--spacing-size-2)",
4315
+ md: "var(--spacing-size-4)",
4316
+ lg: "var(--spacing-size-8)",
4317
+ xl: "var(--spacing-size-12)",
4318
+ "2xl": "var(--spacing-size-16)",
4319
+ full: "100%"
4320
+ };
4275
4321
  var Skeleton = (props) => {
4276
4322
  const { variant = "text", width, height } = props;
4277
4323
  const style = {
4278
- ...width != null && { width: toSizeVar(width) },
4279
- ...height != null && { height: toSizeVar(height) }
4324
+ ...width != null && { width: SIZE_MAP[width] },
4325
+ ...height != null && { height: SIZE_MAP[height] }
4280
4326
  };
4281
4327
  return /* @__PURE__ */ jsx333(
4282
4328
  "div",
package/dist/index.cjs CHANGED
@@ -6957,8 +6957,22 @@ var PieDonutChart = import_react5.default.memo(
6957
6957
  const innerR = isDoughnut ? r2 * 0.5 : 0;
6958
6958
  const firstKey = entries[0]?.[0] ?? "";
6959
6959
  const colorOffset = hashString(firstKey);
6960
+ const maskRef = import_react5.default.useRef(null);
6961
+ const maskR = r2 + 10;
6962
+ const maskCircumference = 2 * Math.PI * maskR;
6963
+ import_react5.default.useEffect(() => {
6964
+ if (!animate || !maskRef.current) return;
6965
+ const el = maskRef.current;
6966
+ el.style.strokeDasharray = `${maskCircumference}`;
6967
+ el.style.strokeDashoffset = `${maskCircumference}`;
6968
+ requestAnimationFrame(() => {
6969
+ el.style.transition = "stroke-dashoffset 1000ms ease-out";
6970
+ el.style.strokeDashoffset = "0";
6971
+ });
6972
+ }, [animate, maskCircumference]);
6960
6973
  const sliceData = import_react5.default.useMemo(() => {
6961
6974
  let angle0 = -Math.PI / 2;
6975
+ let cumulativeAngle = 0;
6962
6976
  return values.map((v, i) => {
6963
6977
  const angle = v / total * Math.PI * 2;
6964
6978
  const endAngle = angle0 + angle;
@@ -6982,38 +6996,53 @@ var PieDonutChart = import_react5.default.memo(
6982
6996
  const lx = cx + labelR * Math.cos(midAngle);
6983
6997
  const ly = cy + labelR * Math.sin(midAngle);
6984
6998
  const pct = Math.round(v / total * 100);
6999
+ cumulativeAngle += angle;
7000
+ const sliceEndRatio = cumulativeAngle / (Math.PI * 2);
7001
+ const labelDelay = 1e3 * sliceEndRatio + 150;
6985
7002
  angle0 = endAngle;
6986
- return { d, lx, ly, v, pct, angle, label: labels[i] || `${i + 1}` };
7003
+ return { d, lx, ly, v, pct, angle, label: labels[i] || `${i + 1}`, labelDelay };
6987
7004
  });
6988
7005
  }, [values, total, cx, cy, r2, innerR, labels]);
6989
- return /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("svg", { viewBox: `0 0 ${size} ${size}`, className: "chart-svg chart-pie", children: sliceData.map((s, i) => {
6990
- const delay = i * 100;
6991
- return /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("g", { className: animate ? "chart-slice-group-animate" : "", style: animate ? { animationDelay: `${delay}ms` } : void 0, children: [
6992
- /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
6993
- "path",
6994
- {
6995
- d: s.d,
6996
- fill: PIE_COLORS[(i + colorOffset) % PIE_COLORS.length],
6997
- className: "chart-slice",
6998
- onMouseEnter: (e) => onHover(e, `${s.label}: ${s.v} (${s.pct}%)`),
6999
- onMouseMove: onMove,
7000
- onMouseLeave: onLeave
7001
- }
7002
- ),
7003
- s.angle > 0.2 && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
7004
- "text",
7005
- {
7006
- x: s.lx,
7007
- y: s.ly,
7008
- className: `chart-pie-label ${animate ? "chart-pie-label-animate" : ""}`,
7009
- style: animate ? { animationDelay: `${delay + 150}ms` } : void 0,
7010
- textAnchor: "middle",
7011
- dominantBaseline: "central",
7012
- children: s.v
7013
- }
7014
- )
7015
- ] }, i);
7016
- }) });
7006
+ const maskId = `pie-mask-${isDoughnut ? "d" : "p"}`;
7007
+ return /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("svg", { viewBox: `0 0 ${size} ${size}`, className: "chart-svg chart-pie", children: [
7008
+ animate && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("mask", { id: maskId, children: /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
7009
+ "circle",
7010
+ {
7011
+ ref: maskRef,
7012
+ cx,
7013
+ cy,
7014
+ r: maskR,
7015
+ fill: "none",
7016
+ stroke: "white",
7017
+ strokeWidth: maskR * 2,
7018
+ transform: `rotate(-90 ${cx} ${cy})`
7019
+ }
7020
+ ) }) }),
7021
+ /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("g", { mask: animate ? `url(#${maskId})` : void 0, children: sliceData.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("g", { children: /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
7022
+ "path",
7023
+ {
7024
+ d: s.d,
7025
+ fill: PIE_COLORS[(i + colorOffset) % PIE_COLORS.length],
7026
+ className: "chart-slice",
7027
+ onMouseEnter: (e) => onHover(e, `${s.label}: ${s.v} (${s.pct}%)`),
7028
+ onMouseMove: onMove,
7029
+ onMouseLeave: onLeave
7030
+ }
7031
+ ) }, i)) }),
7032
+ sliceData.map((s, i) => s.angle > 0.2 && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
7033
+ "text",
7034
+ {
7035
+ x: s.lx,
7036
+ y: s.ly,
7037
+ className: `chart-pie-label ${animate ? "chart-pie-label-animate" : ""}`,
7038
+ style: animate ? { animationDelay: `${s.labelDelay}ms` } : void 0,
7039
+ textAnchor: "middle",
7040
+ dominantBaseline: "central",
7041
+ children: s.v
7042
+ },
7043
+ `label-${i}`
7044
+ ))
7045
+ ] });
7017
7046
  }
7018
7047
  );
7019
7048
  PieDonutChart.displayName = "PieDonutChart";
@@ -7943,6 +7972,7 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
7943
7972
  const popH = popRef.current.offsetHeight;
7944
7973
  const viewportHeight = window.innerHeight;
7945
7974
  const viewportWidth = window.innerWidth;
7975
+ if (popH === 0 || popW === 0) return;
7946
7976
  let direction = "bottom";
7947
7977
  let top;
7948
7978
  let left;
@@ -7968,6 +7998,14 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
7968
7998
  const raf = requestAnimationFrame(calculatePosition);
7969
7999
  return () => cancelAnimationFrame(raf);
7970
8000
  }, [calculatePosition, enabled]);
8001
+ import_react18.default.useEffect(() => {
8002
+ if (!enabled || !popRef.current) return;
8003
+ const observer = new ResizeObserver(() => {
8004
+ calculatePosition();
8005
+ });
8006
+ observer.observe(popRef.current);
8007
+ return () => observer.disconnect();
8008
+ }, [calculatePosition, enabled, popRef]);
7971
8009
  import_react18.default.useEffect(() => {
7972
8010
  if (!enabled) return;
7973
8011
  window.addEventListener("resize", calculatePosition);
@@ -8783,12 +8821,20 @@ var Select_default = Select;
8783
8821
 
8784
8822
  // src/components/Skeleton/Skeleton.tsx
8785
8823
  var import_jsx_runtime333 = require("react/jsx-runtime");
8786
- var toSizeVar = (token) => token === "full" ? "100%" : `var(--spacing-size-${token})`;
8824
+ var SIZE_MAP = {
8825
+ xs: "var(--spacing-size-1)",
8826
+ sm: "var(--spacing-size-2)",
8827
+ md: "var(--spacing-size-4)",
8828
+ lg: "var(--spacing-size-8)",
8829
+ xl: "var(--spacing-size-12)",
8830
+ "2xl": "var(--spacing-size-16)",
8831
+ full: "100%"
8832
+ };
8787
8833
  var Skeleton = (props) => {
8788
8834
  const { variant = "text", width, height } = props;
8789
8835
  const style = {
8790
- ...width != null && { width: toSizeVar(width) },
8791
- ...height != null && { height: toSizeVar(height) }
8836
+ ...width != null && { width: SIZE_MAP[width] },
8837
+ ...height != null && { height: SIZE_MAP[height] }
8792
8838
  };
8793
8839
  return /* @__PURE__ */ (0, import_jsx_runtime333.jsx)(
8794
8840
  "div",
@@ -9931,9 +9977,18 @@ var Video_default = Video;
9931
9977
 
9932
9978
  // src/layout/Grid/FullGrid/FullGrid.tsx
9933
9979
  var import_jsx_runtime348 = require("react/jsx-runtime");
9980
+ var GAP_MAP = {
9981
+ none: "var(--spacing-space-none)",
9982
+ xs: "var(--spacing-space-1)",
9983
+ sm: "var(--spacing-space-2)",
9984
+ md: "var(--spacing-space-4)",
9985
+ lg: "var(--spacing-space-6)",
9986
+ xl: "var(--spacing-space-8)",
9987
+ "2xl": "var(--spacing-space-12)"
9988
+ };
9934
9989
  var FullGrid = (props) => {
9935
9990
  const { children, gap } = props;
9936
- const style = gap != null ? { gap: `var(--spacing-space-${gap})` } : void 0;
9991
+ const style = gap != null ? { gap: GAP_MAP[gap] } : void 0;
9937
9992
  return /* @__PURE__ */ (0, import_jsx_runtime348.jsx)("div", { className: "lib-xplat-full-grid", style, children });
9938
9993
  };
9939
9994
  FullGrid.displayName = "FullGrid";
@@ -9941,9 +9996,18 @@ var FullGrid_default = FullGrid;
9941
9996
 
9942
9997
  // src/layout/Grid/FullScreen/FullScreen.tsx
9943
9998
  var import_jsx_runtime349 = require("react/jsx-runtime");
9999
+ var GAP_MAP2 = {
10000
+ none: "var(--spacing-space-none)",
10001
+ xs: "var(--spacing-space-1)",
10002
+ sm: "var(--spacing-space-2)",
10003
+ md: "var(--spacing-space-4)",
10004
+ lg: "var(--spacing-space-6)",
10005
+ xl: "var(--spacing-space-8)",
10006
+ "2xl": "var(--spacing-space-12)"
10007
+ };
9944
10008
  var FullScreen = (props) => {
9945
10009
  const { children, gap } = props;
9946
- const style = gap != null ? { gap: `var(--spacing-space-${gap})` } : void 0;
10010
+ const style = gap != null ? { gap: GAP_MAP2[gap] } : void 0;
9947
10011
  return /* @__PURE__ */ (0, import_jsx_runtime349.jsx)("div", { className: "lib-xplat-full-screen", style, children });
9948
10012
  };
9949
10013
  FullScreen.displayName = "FullScreen";
package/dist/index.css CHANGED
@@ -1864,7 +1864,7 @@
1864
1864
  transform 0.15s ease-out;
1865
1865
  transform-origin: center;
1866
1866
  }
1867
- .lib-xplat-chart .chart-svg:hover .chart-slice {
1867
+ .lib-xplat-chart .chart-pie:has(.chart-slice:hover) .chart-slice {
1868
1868
  opacity: 0.5;
1869
1869
  }
1870
1870
  .lib-xplat-chart .chart-slice:hover {
@@ -1892,10 +1892,8 @@
1892
1892
  .lib-xplat-chart .chart-bar-animate {
1893
1893
  animation: chart-bar-grow 800ms ease-out both;
1894
1894
  }
1895
- .lib-xplat-chart .chart-slice-group-animate {
1896
- animation: chart-slice-in 1000ms ease-out both;
1897
- }
1898
1895
  .lib-xplat-chart .chart-pie-label-animate {
1896
+ opacity: 0;
1899
1897
  animation: chart-fade-in 150ms ease-out both;
1900
1898
  }
1901
1899
  .lib-xplat-chart .chart-area[style*=animationDelay] {
@@ -1909,16 +1907,6 @@
1909
1907
  transform: scaleY(1);
1910
1908
  }
1911
1909
  }
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
1910
  @keyframes chart-fade-in {
1923
1911
  from {
1924
1912
  opacity: 0;
@@ -1939,7 +1927,6 @@
1939
1927
  }
1940
1928
  @media (prefers-reduced-motion: reduce) {
1941
1929
  .lib-xplat-chart .chart-bar-animate,
1942
- .lib-xplat-chart .chart-slice-group-animate,
1943
1930
  .lib-xplat-chart .chart-pie-label-animate,
1944
1931
  .lib-xplat-chart .chart-area {
1945
1932
  animation: none !important;
package/dist/index.js CHANGED
@@ -6560,8 +6560,22 @@ var PieDonutChart = React5.memo(
6560
6560
  const innerR = isDoughnut ? r2 * 0.5 : 0;
6561
6561
  const firstKey = entries[0]?.[0] ?? "";
6562
6562
  const colorOffset = hashString(firstKey);
6563
+ const maskRef = React5.useRef(null);
6564
+ const maskR = r2 + 10;
6565
+ const maskCircumference = 2 * Math.PI * maskR;
6566
+ React5.useEffect(() => {
6567
+ if (!animate || !maskRef.current) return;
6568
+ const el = maskRef.current;
6569
+ el.style.strokeDasharray = `${maskCircumference}`;
6570
+ el.style.strokeDashoffset = `${maskCircumference}`;
6571
+ requestAnimationFrame(() => {
6572
+ el.style.transition = "stroke-dashoffset 1000ms ease-out";
6573
+ el.style.strokeDashoffset = "0";
6574
+ });
6575
+ }, [animate, maskCircumference]);
6563
6576
  const sliceData = React5.useMemo(() => {
6564
6577
  let angle0 = -Math.PI / 2;
6578
+ let cumulativeAngle = 0;
6565
6579
  return values.map((v, i) => {
6566
6580
  const angle = v / total * Math.PI * 2;
6567
6581
  const endAngle = angle0 + angle;
@@ -6585,38 +6599,53 @@ var PieDonutChart = React5.memo(
6585
6599
  const lx = cx + labelR * Math.cos(midAngle);
6586
6600
  const ly = cy + labelR * Math.sin(midAngle);
6587
6601
  const pct = Math.round(v / total * 100);
6602
+ cumulativeAngle += angle;
6603
+ const sliceEndRatio = cumulativeAngle / (Math.PI * 2);
6604
+ const labelDelay = 1e3 * sliceEndRatio + 150;
6588
6605
  angle0 = endAngle;
6589
- return { d, lx, ly, v, pct, angle, label: labels[i] || `${i + 1}` };
6606
+ return { d, lx, ly, v, pct, angle, label: labels[i] || `${i + 1}`, labelDelay };
6590
6607
  });
6591
6608
  }, [values, total, cx, cy, r2, innerR, labels]);
6592
- return /* @__PURE__ */ jsx305("svg", { viewBox: `0 0 ${size} ${size}`, className: "chart-svg chart-pie", children: sliceData.map((s, i) => {
6593
- const delay = i * 100;
6594
- return /* @__PURE__ */ jsxs196("g", { className: animate ? "chart-slice-group-animate" : "", style: animate ? { animationDelay: `${delay}ms` } : void 0, children: [
6595
- /* @__PURE__ */ jsx305(
6596
- "path",
6597
- {
6598
- d: s.d,
6599
- fill: PIE_COLORS[(i + colorOffset) % PIE_COLORS.length],
6600
- className: "chart-slice",
6601
- onMouseEnter: (e) => onHover(e, `${s.label}: ${s.v} (${s.pct}%)`),
6602
- onMouseMove: onMove,
6603
- onMouseLeave: onLeave
6604
- }
6605
- ),
6606
- s.angle > 0.2 && /* @__PURE__ */ jsx305(
6607
- "text",
6608
- {
6609
- x: s.lx,
6610
- y: s.ly,
6611
- className: `chart-pie-label ${animate ? "chart-pie-label-animate" : ""}`,
6612
- style: animate ? { animationDelay: `${delay + 150}ms` } : void 0,
6613
- textAnchor: "middle",
6614
- dominantBaseline: "central",
6615
- children: s.v
6616
- }
6617
- )
6618
- ] }, i);
6619
- }) });
6609
+ const maskId = `pie-mask-${isDoughnut ? "d" : "p"}`;
6610
+ return /* @__PURE__ */ jsxs196("svg", { viewBox: `0 0 ${size} ${size}`, className: "chart-svg chart-pie", children: [
6611
+ animate && /* @__PURE__ */ jsx305("defs", { children: /* @__PURE__ */ jsx305("mask", { id: maskId, children: /* @__PURE__ */ jsx305(
6612
+ "circle",
6613
+ {
6614
+ ref: maskRef,
6615
+ cx,
6616
+ cy,
6617
+ r: maskR,
6618
+ fill: "none",
6619
+ stroke: "white",
6620
+ strokeWidth: maskR * 2,
6621
+ transform: `rotate(-90 ${cx} ${cy})`
6622
+ }
6623
+ ) }) }),
6624
+ /* @__PURE__ */ jsx305("g", { mask: animate ? `url(#${maskId})` : void 0, children: sliceData.map((s, i) => /* @__PURE__ */ jsx305("g", { children: /* @__PURE__ */ jsx305(
6625
+ "path",
6626
+ {
6627
+ d: s.d,
6628
+ fill: PIE_COLORS[(i + colorOffset) % PIE_COLORS.length],
6629
+ className: "chart-slice",
6630
+ onMouseEnter: (e) => onHover(e, `${s.label}: ${s.v} (${s.pct}%)`),
6631
+ onMouseMove: onMove,
6632
+ onMouseLeave: onLeave
6633
+ }
6634
+ ) }, i)) }),
6635
+ sliceData.map((s, i) => s.angle > 0.2 && /* @__PURE__ */ jsx305(
6636
+ "text",
6637
+ {
6638
+ x: s.lx,
6639
+ y: s.ly,
6640
+ className: `chart-pie-label ${animate ? "chart-pie-label-animate" : ""}`,
6641
+ style: animate ? { animationDelay: `${s.labelDelay}ms` } : void 0,
6642
+ textAnchor: "middle",
6643
+ dominantBaseline: "central",
6644
+ children: s.v
6645
+ },
6646
+ `label-${i}`
6647
+ ))
6648
+ ] });
6620
6649
  }
6621
6650
  );
6622
6651
  PieDonutChart.displayName = "PieDonutChart";
@@ -7546,6 +7575,7 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
7546
7575
  const popH = popRef.current.offsetHeight;
7547
7576
  const viewportHeight = window.innerHeight;
7548
7577
  const viewportWidth = window.innerWidth;
7578
+ if (popH === 0 || popW === 0) return;
7549
7579
  let direction = "bottom";
7550
7580
  let top;
7551
7581
  let left;
@@ -7571,6 +7601,14 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
7571
7601
  const raf = requestAnimationFrame(calculatePosition);
7572
7602
  return () => cancelAnimationFrame(raf);
7573
7603
  }, [calculatePosition, enabled]);
7604
+ React17.useEffect(() => {
7605
+ if (!enabled || !popRef.current) return;
7606
+ const observer = new ResizeObserver(() => {
7607
+ calculatePosition();
7608
+ });
7609
+ observer.observe(popRef.current);
7610
+ return () => observer.disconnect();
7611
+ }, [calculatePosition, enabled, popRef]);
7574
7612
  React17.useEffect(() => {
7575
7613
  if (!enabled) return;
7576
7614
  window.addEventListener("resize", calculatePosition);
@@ -8386,12 +8424,20 @@ var Select_default = Select;
8386
8424
 
8387
8425
  // src/components/Skeleton/Skeleton.tsx
8388
8426
  import { jsx as jsx333 } from "react/jsx-runtime";
8389
- var toSizeVar = (token) => token === "full" ? "100%" : `var(--spacing-size-${token})`;
8427
+ var SIZE_MAP = {
8428
+ xs: "var(--spacing-size-1)",
8429
+ sm: "var(--spacing-size-2)",
8430
+ md: "var(--spacing-size-4)",
8431
+ lg: "var(--spacing-size-8)",
8432
+ xl: "var(--spacing-size-12)",
8433
+ "2xl": "var(--spacing-size-16)",
8434
+ full: "100%"
8435
+ };
8390
8436
  var Skeleton = (props) => {
8391
8437
  const { variant = "text", width, height } = props;
8392
8438
  const style = {
8393
- ...width != null && { width: toSizeVar(width) },
8394
- ...height != null && { height: toSizeVar(height) }
8439
+ ...width != null && { width: SIZE_MAP[width] },
8440
+ ...height != null && { height: SIZE_MAP[height] }
8395
8441
  };
8396
8442
  return /* @__PURE__ */ jsx333(
8397
8443
  "div",
@@ -9534,9 +9580,18 @@ var Video_default = Video;
9534
9580
 
9535
9581
  // src/layout/Grid/FullGrid/FullGrid.tsx
9536
9582
  import { jsx as jsx348 } from "react/jsx-runtime";
9583
+ var GAP_MAP = {
9584
+ none: "var(--spacing-space-none)",
9585
+ xs: "var(--spacing-space-1)",
9586
+ sm: "var(--spacing-space-2)",
9587
+ md: "var(--spacing-space-4)",
9588
+ lg: "var(--spacing-space-6)",
9589
+ xl: "var(--spacing-space-8)",
9590
+ "2xl": "var(--spacing-space-12)"
9591
+ };
9537
9592
  var FullGrid = (props) => {
9538
9593
  const { children, gap } = props;
9539
- const style = gap != null ? { gap: `var(--spacing-space-${gap})` } : void 0;
9594
+ const style = gap != null ? { gap: GAP_MAP[gap] } : void 0;
9540
9595
  return /* @__PURE__ */ jsx348("div", { className: "lib-xplat-full-grid", style, children });
9541
9596
  };
9542
9597
  FullGrid.displayName = "FullGrid";
@@ -9544,9 +9599,18 @@ var FullGrid_default = FullGrid;
9544
9599
 
9545
9600
  // src/layout/Grid/FullScreen/FullScreen.tsx
9546
9601
  import { jsx as jsx349 } from "react/jsx-runtime";
9602
+ var GAP_MAP2 = {
9603
+ none: "var(--spacing-space-none)",
9604
+ xs: "var(--spacing-space-1)",
9605
+ sm: "var(--spacing-space-2)",
9606
+ md: "var(--spacing-space-4)",
9607
+ lg: "var(--spacing-space-6)",
9608
+ xl: "var(--spacing-space-8)",
9609
+ "2xl": "var(--spacing-space-12)"
9610
+ };
9547
9611
  var FullScreen = (props) => {
9548
9612
  const { children, gap } = props;
9549
- const style = gap != null ? { gap: `var(--spacing-space-${gap})` } : void 0;
9613
+ const style = gap != null ? { gap: GAP_MAP2[gap] } : void 0;
9550
9614
  return /* @__PURE__ */ jsx349("div", { className: "lib-xplat-full-screen", style, children });
9551
9615
  };
9552
9616
  FullScreen.displayName = "FullScreen";
@@ -26,9 +26,18 @@ module.exports = __toCommonJS(FullGrid_exports);
26
26
 
27
27
  // src/layout/Grid/FullGrid/FullGrid.tsx
28
28
  var import_jsx_runtime = require("react/jsx-runtime");
29
+ var GAP_MAP = {
30
+ none: "var(--spacing-space-none)",
31
+ xs: "var(--spacing-space-1)",
32
+ sm: "var(--spacing-space-2)",
33
+ md: "var(--spacing-space-4)",
34
+ lg: "var(--spacing-space-6)",
35
+ xl: "var(--spacing-space-8)",
36
+ "2xl": "var(--spacing-space-12)"
37
+ };
29
38
  var FullGrid = (props) => {
30
39
  const { children, gap } = props;
31
- const style = gap != null ? { gap: `var(--spacing-space-${gap})` } : void 0;
40
+ const style = gap != null ? { gap: GAP_MAP[gap] } : void 0;
32
41
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "lib-xplat-full-grid", style, children });
33
42
  };
34
43
  FullGrid.displayName = "FullGrid";
@@ -1,9 +1,9 @@
1
1
  import React from 'react';
2
2
 
3
- type SpaceToken = "none" | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16;
3
+ type GapToken = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl";
4
4
  interface FullGridProps {
5
5
  children: React.ReactNode;
6
- gap?: SpaceToken;
6
+ gap?: GapToken;
7
7
  }
8
8
  declare const FullGrid: React.FC<FullGridProps>;
9
9