@x-plat/design-system 0.5.12 → 0.5.14

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.
@@ -80,29 +80,50 @@ var toSmoothPath = (points) => {
80
80
  }
81
81
  return d;
82
82
  };
83
+ var RESIZE_SETTLE_MS = 150;
83
84
  var useChartSize = (ref) => {
84
85
  const [size, setSize] = import_react.default.useState({ width: 0, height: 0 });
86
+ const isResizing = import_react.default.useRef(false);
87
+ const settleTimer = import_react.default.useRef(0);
88
+ const lastSize = import_react.default.useRef({ width: 0, height: 0 });
89
+ const initialRef = import_react.default.useRef(true);
85
90
  import_react.default.useEffect(() => {
86
91
  const el = ref.current;
87
92
  if (!el) return;
88
- let rafId = 0;
89
93
  const observer = new ResizeObserver((entries) => {
90
- cancelAnimationFrame(rafId);
91
- rafId = requestAnimationFrame(() => {
92
- const entry = entries[0];
93
- if (!entry) return;
94
- const { width, height } = entry.contentRect;
95
- const w = Math.floor(width);
96
- const h = Math.floor(height);
97
- setSize((prev) => prev.width === w && prev.height === h ? prev : { width: w, height: h });
98
- });
94
+ const entry = entries[0];
95
+ if (!entry) return;
96
+ const { width, height } = entry.contentRect;
97
+ const w = Math.floor(width);
98
+ const h = Math.floor(height);
99
+ if (w === lastSize.current.width && h === lastSize.current.height) return;
100
+ lastSize.current = { width: w, height: h };
101
+ if (initialRef.current) {
102
+ initialRef.current = false;
103
+ setSize({ width: w, height: h });
104
+ return;
105
+ }
106
+ isResizing.current = true;
107
+ if (el.firstElementChild) {
108
+ const svg = el.firstElementChild;
109
+ svg.style.transformOrigin = "0 0";
110
+ svg.style.transform = `scale(${w / (size.width || w)}, ${h / (size.height || h)})`;
111
+ }
112
+ window.clearTimeout(settleTimer.current);
113
+ settleTimer.current = window.setTimeout(() => {
114
+ isResizing.current = false;
115
+ if (el.firstElementChild) {
116
+ el.firstElementChild.style.transform = "";
117
+ }
118
+ setSize({ width: w, height: h });
119
+ }, RESIZE_SETTLE_MS);
99
120
  });
100
121
  observer.observe(el);
101
122
  return () => {
102
- cancelAnimationFrame(rafId);
123
+ window.clearTimeout(settleTimer.current);
103
124
  observer.disconnect();
104
125
  };
105
- }, [ref]);
126
+ }, [ref, size.width, size.height]);
106
127
  return size;
107
128
  };
108
129
  var useChartTooltip = (enabled) => {
@@ -294,17 +315,19 @@ var BarChart = import_react.default.memo(({ data, labels, width, height, onHover
294
315
  const chartW = width - PADDING.left - PADDING.right;
295
316
  const chartH = height - PADDING.top - PADDING.bottom;
296
317
  const groupW = chartW / count;
297
- const barW = Math.max(1, Math.min(32, groupW * 0.7 / groupCount));
318
+ const barGap = groupCount > 1 ? 2 : 0;
319
+ const barW = Math.max(1, Math.min(32, (groupW * 0.7 - barGap * (groupCount - 1)) / groupCount));
298
320
  const bars = import_react.default.useMemo(
299
321
  () => entries.map(
300
322
  ([, values], di) => values.map((v, i) => {
323
+ const totalBarsW = barW * groupCount + barGap * (groupCount - 1);
301
324
  const h = Math.max(0, v / maxVal * chartH);
302
- const x = PADDING.left + groupW * i + (groupW - barW * groupCount) / 2 + barW * di;
325
+ const x = PADDING.left + groupW * i + (groupW - totalBarsW) / 2 + (barW + barGap) * di;
303
326
  const y = PADDING.top + chartH - h;
304
327
  return { x, y, w: barW, h, v };
305
328
  })
306
329
  ),
307
- [entries, maxVal, chartH, groupW, barW, groupCount]
330
+ [entries, maxVal, chartH, groupW, barW, barGap, groupCount]
308
331
  );
309
332
  const barLabelStep = getLabelStep(count, chartW);
310
333
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: `0 0 ${width} ${height}`, className: "chart-svg", children: [
@@ -316,22 +339,22 @@ var BarChart = import_react.default.memo(({ data, labels, width, height, onHover
316
339
  entries.map(([key], di) => {
317
340
  const palette = getPalette(LINE_BAR_PALETTES, di, key);
318
341
  const color = palette[2];
319
- return bars[di].map((b, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
320
- "rect",
321
- {
322
- x: b.x,
323
- y: b.y,
324
- width: b.w,
325
- height: b.h,
326
- rx: Math.min(4, b.w / 2),
327
- fill: color,
328
- className: "chart-bar",
329
- onMouseEnter: (e) => onHover(e, `${key}: ${labels[i]} \u2014 ${b.v}`),
330
- onMouseMove: onMove,
331
- onMouseLeave: onLeave
332
- },
333
- `${di}-${i}`
334
- ));
342
+ return bars[di].map((b, i) => {
343
+ const r = Math.min(4, b.w / 2);
344
+ const d = b.h <= r ? `M ${b.x} ${b.y + b.h} V ${b.y} H ${b.x + b.w} V ${b.y + b.h} Z` : `M ${b.x} ${b.y + b.h} V ${b.y + r} Q ${b.x} ${b.y} ${b.x + r} ${b.y} H ${b.x + b.w - r} Q ${b.x + b.w} ${b.y} ${b.x + b.w} ${b.y + r} V ${b.y + b.h} Z`;
345
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
346
+ "path",
347
+ {
348
+ d,
349
+ fill: color,
350
+ className: "chart-bar",
351
+ onMouseEnter: (e) => onHover(e, `${key}: ${labels[i]} \u2014 ${b.v}`),
352
+ onMouseMove: onMove,
353
+ onMouseLeave: onLeave
354
+ },
355
+ `${di}-${i}`
356
+ );
357
+ });
335
358
  })
336
359
  ] });
337
360
  });
@@ -418,20 +441,22 @@ var TooltipBubble = ({ x, y, containerWidth, children }) => {
418
441
  }
419
442
  );
420
443
  };
421
- var Chart = (props) => {
444
+ var Chart = import_react.default.memo((props) => {
422
445
  const { type, data, labels, tooltip: showTooltip = true } = props;
423
446
  const { tooltip, show, hide, move, containerRef } = useChartTooltip(showTooltip);
424
447
  const { width, height } = useChartSize(containerRef);
448
+ const stableData = import_react.default.useMemo(() => data, [JSON.stringify(data)]);
449
+ const stableLabels = import_react.default.useMemo(() => labels, [JSON.stringify(labels)]);
425
450
  const ready = width > 0 && height > 0;
426
451
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "lib-xplat-chart", ref: containerRef, children: [
427
- ready && type === "line" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LineChart, { data, labels, width, height, onHover: show, onMove: move, onLeave: hide }),
428
- ready && type === "curve" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CurveChart, { data, labels, width, height, onHover: show, onMove: move, onLeave: hide }),
429
- ready && type === "bar" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BarChart, { data, labels, width, height, onHover: show, onMove: move, onLeave: hide }),
430
- ready && type === "pie" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PieDonutChart, { data, labels, width, height, onHover: show, onMove: move, onLeave: hide }),
431
- ready && type === "doughnut" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PieDonutChart, { data, labels, width, height, isDoughnut: true, onHover: show, onMove: move, onLeave: hide }),
452
+ ready && type === "line" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LineChart, { data: stableData, labels: stableLabels, width, height, onHover: show, onMove: move, onLeave: hide }),
453
+ ready && type === "curve" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CurveChart, { data: stableData, labels: stableLabels, width, height, onHover: show, onMove: move, onLeave: hide }),
454
+ ready && type === "bar" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BarChart, { data: stableData, labels: stableLabels, width, height, onHover: show, onMove: move, onLeave: hide }),
455
+ ready && type === "pie" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, onHover: show, onMove: move, onLeave: hide }),
456
+ ready && type === "doughnut" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, isDoughnut: true, onHover: show, onMove: move, onLeave: hide }),
432
457
  tooltip.visible && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TooltipBubble, { x: tooltip.x, y: tooltip.y, containerWidth: width, children: tooltip.content })
433
458
  ] });
434
- };
459
+ });
435
460
  Chart.displayName = "Chart";
436
461
  var Chart_default = Chart;
437
462
  // Annotate the CommonJS export names for ESM import in node:
@@ -9,6 +9,8 @@
9
9
  display: block;
10
10
  width: 100%;
11
11
  height: 100%;
12
+ will-change: transform;
13
+ contain: layout style paint;
12
14
  }
13
15
  .lib-xplat-chart .chart-grid {
14
16
  stroke: var(--semantic-border-subtle);
@@ -6,6 +6,6 @@ interface ChartProps {
6
6
  labels: string[];
7
7
  tooltip?: boolean;
8
8
  }
9
- declare const Chart: React.FC<ChartProps>;
9
+ declare const Chart: React.NamedExoticComponent<ChartProps>;
10
10
 
11
11
  export { Chart };
@@ -6,6 +6,6 @@ interface ChartProps {
6
6
  labels: string[];
7
7
  tooltip?: boolean;
8
8
  }
9
- declare const Chart: React.FC<ChartProps>;
9
+ declare const Chart: React.NamedExoticComponent<ChartProps>;
10
10
 
11
11
  export { Chart };
@@ -44,29 +44,50 @@ var toSmoothPath = (points) => {
44
44
  }
45
45
  return d;
46
46
  };
47
+ var RESIZE_SETTLE_MS = 150;
47
48
  var useChartSize = (ref) => {
48
49
  const [size, setSize] = React.useState({ width: 0, height: 0 });
50
+ const isResizing = React.useRef(false);
51
+ const settleTimer = React.useRef(0);
52
+ const lastSize = React.useRef({ width: 0, height: 0 });
53
+ const initialRef = React.useRef(true);
49
54
  React.useEffect(() => {
50
55
  const el = ref.current;
51
56
  if (!el) return;
52
- let rafId = 0;
53
57
  const observer = new ResizeObserver((entries) => {
54
- cancelAnimationFrame(rafId);
55
- rafId = requestAnimationFrame(() => {
56
- const entry = entries[0];
57
- if (!entry) return;
58
- const { width, height } = entry.contentRect;
59
- const w = Math.floor(width);
60
- const h = Math.floor(height);
61
- setSize((prev) => prev.width === w && prev.height === h ? prev : { width: w, height: h });
62
- });
58
+ const entry = entries[0];
59
+ if (!entry) return;
60
+ const { width, height } = entry.contentRect;
61
+ const w = Math.floor(width);
62
+ const h = Math.floor(height);
63
+ if (w === lastSize.current.width && h === lastSize.current.height) return;
64
+ lastSize.current = { width: w, height: h };
65
+ if (initialRef.current) {
66
+ initialRef.current = false;
67
+ setSize({ width: w, height: h });
68
+ return;
69
+ }
70
+ isResizing.current = true;
71
+ if (el.firstElementChild) {
72
+ const svg = el.firstElementChild;
73
+ svg.style.transformOrigin = "0 0";
74
+ svg.style.transform = `scale(${w / (size.width || w)}, ${h / (size.height || h)})`;
75
+ }
76
+ window.clearTimeout(settleTimer.current);
77
+ settleTimer.current = window.setTimeout(() => {
78
+ isResizing.current = false;
79
+ if (el.firstElementChild) {
80
+ el.firstElementChild.style.transform = "";
81
+ }
82
+ setSize({ width: w, height: h });
83
+ }, RESIZE_SETTLE_MS);
63
84
  });
64
85
  observer.observe(el);
65
86
  return () => {
66
- cancelAnimationFrame(rafId);
87
+ window.clearTimeout(settleTimer.current);
67
88
  observer.disconnect();
68
89
  };
69
- }, [ref]);
90
+ }, [ref, size.width, size.height]);
70
91
  return size;
71
92
  };
72
93
  var useChartTooltip = (enabled) => {
@@ -258,17 +279,19 @@ var BarChart = React.memo(({ data, labels, width, height, onHover, onMove, onLea
258
279
  const chartW = width - PADDING.left - PADDING.right;
259
280
  const chartH = height - PADDING.top - PADDING.bottom;
260
281
  const groupW = chartW / count;
261
- const barW = Math.max(1, Math.min(32, groupW * 0.7 / groupCount));
282
+ const barGap = groupCount > 1 ? 2 : 0;
283
+ const barW = Math.max(1, Math.min(32, (groupW * 0.7 - barGap * (groupCount - 1)) / groupCount));
262
284
  const bars = React.useMemo(
263
285
  () => entries.map(
264
286
  ([, values], di) => values.map((v, i) => {
287
+ const totalBarsW = barW * groupCount + barGap * (groupCount - 1);
265
288
  const h = Math.max(0, v / maxVal * chartH);
266
- const x = PADDING.left + groupW * i + (groupW - barW * groupCount) / 2 + barW * di;
289
+ const x = PADDING.left + groupW * i + (groupW - totalBarsW) / 2 + (barW + barGap) * di;
267
290
  const y = PADDING.top + chartH - h;
268
291
  return { x, y, w: barW, h, v };
269
292
  })
270
293
  ),
271
- [entries, maxVal, chartH, groupW, barW, groupCount]
294
+ [entries, maxVal, chartH, groupW, barW, barGap, groupCount]
272
295
  );
273
296
  const barLabelStep = getLabelStep(count, chartW);
274
297
  return /* @__PURE__ */ jsxs("svg", { viewBox: `0 0 ${width} ${height}`, className: "chart-svg", children: [
@@ -280,22 +303,22 @@ var BarChart = React.memo(({ data, labels, width, height, onHover, onMove, onLea
280
303
  entries.map(([key], di) => {
281
304
  const palette = getPalette(LINE_BAR_PALETTES, di, key);
282
305
  const color = palette[2];
283
- return bars[di].map((b, i) => /* @__PURE__ */ jsx(
284
- "rect",
285
- {
286
- x: b.x,
287
- y: b.y,
288
- width: b.w,
289
- height: b.h,
290
- rx: Math.min(4, b.w / 2),
291
- fill: color,
292
- className: "chart-bar",
293
- onMouseEnter: (e) => onHover(e, `${key}: ${labels[i]} \u2014 ${b.v}`),
294
- onMouseMove: onMove,
295
- onMouseLeave: onLeave
296
- },
297
- `${di}-${i}`
298
- ));
306
+ return bars[di].map((b, i) => {
307
+ const r = Math.min(4, b.w / 2);
308
+ const d = b.h <= r ? `M ${b.x} ${b.y + b.h} V ${b.y} H ${b.x + b.w} V ${b.y + b.h} Z` : `M ${b.x} ${b.y + b.h} V ${b.y + r} Q ${b.x} ${b.y} ${b.x + r} ${b.y} H ${b.x + b.w - r} Q ${b.x + b.w} ${b.y} ${b.x + b.w} ${b.y + r} V ${b.y + b.h} Z`;
309
+ return /* @__PURE__ */ jsx(
310
+ "path",
311
+ {
312
+ d,
313
+ fill: color,
314
+ className: "chart-bar",
315
+ onMouseEnter: (e) => onHover(e, `${key}: ${labels[i]} \u2014 ${b.v}`),
316
+ onMouseMove: onMove,
317
+ onMouseLeave: onLeave
318
+ },
319
+ `${di}-${i}`
320
+ );
321
+ });
299
322
  })
300
323
  ] });
301
324
  });
@@ -382,20 +405,22 @@ var TooltipBubble = ({ x, y, containerWidth, children }) => {
382
405
  }
383
406
  );
384
407
  };
385
- var Chart = (props) => {
408
+ var Chart = React.memo((props) => {
386
409
  const { type, data, labels, tooltip: showTooltip = true } = props;
387
410
  const { tooltip, show, hide, move, containerRef } = useChartTooltip(showTooltip);
388
411
  const { width, height } = useChartSize(containerRef);
412
+ const stableData = React.useMemo(() => data, [JSON.stringify(data)]);
413
+ const stableLabels = React.useMemo(() => labels, [JSON.stringify(labels)]);
389
414
  const ready = width > 0 && height > 0;
390
415
  return /* @__PURE__ */ jsxs("div", { className: "lib-xplat-chart", ref: containerRef, children: [
391
- ready && type === "line" && /* @__PURE__ */ jsx(LineChart, { data, labels, width, height, onHover: show, onMove: move, onLeave: hide }),
392
- ready && type === "curve" && /* @__PURE__ */ jsx(CurveChart, { data, labels, width, height, onHover: show, onMove: move, onLeave: hide }),
393
- ready && type === "bar" && /* @__PURE__ */ jsx(BarChart, { data, labels, width, height, onHover: show, onMove: move, onLeave: hide }),
394
- ready && type === "pie" && /* @__PURE__ */ jsx(PieDonutChart, { data, labels, width, height, onHover: show, onMove: move, onLeave: hide }),
395
- ready && type === "doughnut" && /* @__PURE__ */ jsx(PieDonutChart, { data, labels, width, height, isDoughnut: true, onHover: show, onMove: move, onLeave: hide }),
416
+ ready && type === "line" && /* @__PURE__ */ jsx(LineChart, { data: stableData, labels: stableLabels, width, height, onHover: show, onMove: move, onLeave: hide }),
417
+ ready && type === "curve" && /* @__PURE__ */ jsx(CurveChart, { data: stableData, labels: stableLabels, width, height, onHover: show, onMove: move, onLeave: hide }),
418
+ ready && type === "bar" && /* @__PURE__ */ jsx(BarChart, { data: stableData, labels: stableLabels, width, height, onHover: show, onMove: move, onLeave: hide }),
419
+ ready && type === "pie" && /* @__PURE__ */ jsx(PieDonutChart, { data: stableData, labels: stableLabels, width, height, onHover: show, onMove: move, onLeave: hide }),
420
+ ready && type === "doughnut" && /* @__PURE__ */ jsx(PieDonutChart, { data: stableData, labels: stableLabels, width, height, isDoughnut: true, onHover: show, onMove: move, onLeave: hide }),
396
421
  tooltip.visible && /* @__PURE__ */ jsx(TooltipBubble, { x: tooltip.x, y: tooltip.y, containerWidth: width, children: tooltip.content })
397
422
  ] });
398
- };
423
+ });
399
424
  Chart.displayName = "Chart";
400
425
  var Chart_default = Chart;
401
426
  export {
@@ -443,12 +443,8 @@ var PortalContainerContext = import_react4.default.createContext(null);
443
443
  var PortalProvider = ({ container, children }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PortalContainerContext.Provider, { value: container, children });
444
444
  var Portal = ({ children }) => {
445
445
  const contextContainer = import_react4.default.useContext(PortalContainerContext);
446
- const [fallback, setFallback] = import_react4.default.useState(null);
447
- import_react4.default.useEffect(() => {
448
- if (!contextContainer) setFallback(document.body);
449
- }, [contextContainer]);
450
- const container = contextContainer ?? fallback;
451
- if (!container) return null;
446
+ if (typeof document === "undefined") return null;
447
+ const container = contextContainer ?? document.body;
452
448
  return import_react_dom.default.createPortal(children, container);
453
449
  };
454
450
  Portal.displayName = "Portal";
@@ -404,12 +404,8 @@ var PortalContainerContext = React3.createContext(null);
404
404
  var PortalProvider = ({ container, children }) => /* @__PURE__ */ jsx10(PortalContainerContext.Provider, { value: container, children });
405
405
  var Portal = ({ children }) => {
406
406
  const contextContainer = React3.useContext(PortalContainerContext);
407
- const [fallback, setFallback] = React3.useState(null);
408
- React3.useEffect(() => {
409
- if (!contextContainer) setFallback(document.body);
410
- }, [contextContainer]);
411
- const container = contextContainer ?? fallback;
412
- if (!container) return null;
407
+ if (typeof document === "undefined") return null;
408
+ const container = contextContainer ?? document.body;
413
409
  return ReactDOM.createPortal(children, container);
414
410
  };
415
411
  Portal.displayName = "Portal";
@@ -68,15 +68,15 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
68
68
  direction
69
69
  });
70
70
  }, [triggerRef, popRef]);
71
+ import_react.default.useLayoutEffect(() => {
72
+ if (!enabled) return;
73
+ calculatePosition();
74
+ }, [calculatePosition, enabled]);
71
75
  import_react.default.useEffect(() => {
72
76
  if (!enabled) return;
73
- const raf = requestAnimationFrame(() => {
74
- calculatePosition();
75
- });
76
77
  window.addEventListener("resize", calculatePosition);
77
78
  window.addEventListener("scroll", calculatePosition, true);
78
79
  return () => {
79
- cancelAnimationFrame(raf);
80
80
  window.removeEventListener("resize", calculatePosition);
81
81
  window.removeEventListener("scroll", calculatePosition, true);
82
82
  };
@@ -117,12 +117,8 @@ var import_jsx_runtime = require("react/jsx-runtime");
117
117
  var PortalContainerContext = import_react3.default.createContext(null);
118
118
  var Portal = ({ children }) => {
119
119
  const contextContainer = import_react3.default.useContext(PortalContainerContext);
120
- const [fallback, setFallback] = import_react3.default.useState(null);
121
- import_react3.default.useEffect(() => {
122
- if (!contextContainer) setFallback(document.body);
123
- }, [contextContainer]);
124
- const container = contextContainer ?? fallback;
125
- if (!container) return null;
120
+ if (typeof document === "undefined") return null;
121
+ const container = contextContainer ?? document.body;
126
122
  return import_react_dom.default.createPortal(children, container);
127
123
  };
128
124
  Portal.displayName = "Portal";
@@ -32,15 +32,15 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
32
32
  direction
33
33
  });
34
34
  }, [triggerRef, popRef]);
35
+ React.useLayoutEffect(() => {
36
+ if (!enabled) return;
37
+ calculatePosition();
38
+ }, [calculatePosition, enabled]);
35
39
  React.useEffect(() => {
36
40
  if (!enabled) return;
37
- const raf = requestAnimationFrame(() => {
38
- calculatePosition();
39
- });
40
41
  window.addEventListener("resize", calculatePosition);
41
42
  window.addEventListener("scroll", calculatePosition, true);
42
43
  return () => {
43
- cancelAnimationFrame(raf);
44
44
  window.removeEventListener("resize", calculatePosition);
45
45
  window.removeEventListener("scroll", calculatePosition, true);
46
46
  };
@@ -81,12 +81,8 @@ import { jsx } from "react/jsx-runtime";
81
81
  var PortalContainerContext = React3.createContext(null);
82
82
  var Portal = ({ children }) => {
83
83
  const contextContainer = React3.useContext(PortalContainerContext);
84
- const [fallback, setFallback] = React3.useState(null);
85
- React3.useEffect(() => {
86
- if (!contextContainer) setFallback(document.body);
87
- }, [contextContainer]);
88
- const container = contextContainer ?? fallback;
89
- if (!container) return null;
84
+ if (typeof document === "undefined") return null;
85
+ const container = contextContainer ?? document.body;
90
86
  return ReactDOM.createPortal(children, container);
91
87
  };
92
88
  Portal.displayName = "Portal";
@@ -46,12 +46,8 @@ var PortalContainerContext = import_react.default.createContext(null);
46
46
  var PortalProvider = ({ container, children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PortalContainerContext.Provider, { value: container, children });
47
47
  var Portal = ({ children }) => {
48
48
  const contextContainer = import_react.default.useContext(PortalContainerContext);
49
- const [fallback, setFallback] = import_react.default.useState(null);
50
- import_react.default.useEffect(() => {
51
- if (!contextContainer) setFallback(document.body);
52
- }, [contextContainer]);
53
- const container = contextContainer ?? fallback;
54
- if (!container) return null;
49
+ if (typeof document === "undefined") return null;
50
+ const container = contextContainer ?? document.body;
55
51
  return import_react_dom.default.createPortal(children, container);
56
52
  };
57
53
  Portal.displayName = "Portal";
@@ -10,12 +10,8 @@ var PortalContainerContext = React.createContext(null);
10
10
  var PortalProvider = ({ container, children }) => /* @__PURE__ */ jsx(PortalContainerContext.Provider, { value: container, children });
11
11
  var Portal = ({ children }) => {
12
12
  const contextContainer = React.useContext(PortalContainerContext);
13
- const [fallback, setFallback] = React.useState(null);
14
- React.useEffect(() => {
15
- if (!contextContainer) setFallback(document.body);
16
- }, [contextContainer]);
17
- const container = contextContainer ?? fallback;
18
- if (!container) return null;
13
+ if (typeof document === "undefined") return null;
14
+ const container = contextContainer ?? document.body;
19
15
  return ReactDOM.createPortal(children, container);
20
16
  };
21
17
  Portal.displayName = "Portal";
@@ -68,15 +68,15 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
68
68
  direction
69
69
  });
70
70
  }, [triggerRef, popRef]);
71
+ import_react.default.useLayoutEffect(() => {
72
+ if (!enabled) return;
73
+ calculatePosition();
74
+ }, [calculatePosition, enabled]);
71
75
  import_react.default.useEffect(() => {
72
76
  if (!enabled) return;
73
- const raf = requestAnimationFrame(() => {
74
- calculatePosition();
75
- });
76
77
  window.addEventListener("resize", calculatePosition);
77
78
  window.addEventListener("scroll", calculatePosition, true);
78
79
  return () => {
79
- cancelAnimationFrame(raf);
80
80
  window.removeEventListener("resize", calculatePosition);
81
81
  window.removeEventListener("scroll", calculatePosition, true);
82
82
  };
@@ -117,12 +117,8 @@ var import_jsx_runtime = require("react/jsx-runtime");
117
117
  var PortalContainerContext = import_react3.default.createContext(null);
118
118
  var Portal = ({ children }) => {
119
119
  const contextContainer = import_react3.default.useContext(PortalContainerContext);
120
- const [fallback, setFallback] = import_react3.default.useState(null);
121
- import_react3.default.useEffect(() => {
122
- if (!contextContainer) setFallback(document.body);
123
- }, [contextContainer]);
124
- const container = contextContainer ?? fallback;
125
- if (!container) return null;
120
+ if (typeof document === "undefined") return null;
121
+ const container = contextContainer ?? document.body;
126
122
  return import_react_dom.default.createPortal(children, container);
127
123
  };
128
124
  Portal.displayName = "Portal";
@@ -32,15 +32,15 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
32
32
  direction
33
33
  });
34
34
  }, [triggerRef, popRef]);
35
+ React.useLayoutEffect(() => {
36
+ if (!enabled) return;
37
+ calculatePosition();
38
+ }, [calculatePosition, enabled]);
35
39
  React.useEffect(() => {
36
40
  if (!enabled) return;
37
- const raf = requestAnimationFrame(() => {
38
- calculatePosition();
39
- });
40
41
  window.addEventListener("resize", calculatePosition);
41
42
  window.addEventListener("scroll", calculatePosition, true);
42
43
  return () => {
43
- cancelAnimationFrame(raf);
44
44
  window.removeEventListener("resize", calculatePosition);
45
45
  window.removeEventListener("scroll", calculatePosition, true);
46
46
  };
@@ -81,12 +81,8 @@ import { jsx } from "react/jsx-runtime";
81
81
  var PortalContainerContext = React3.createContext(null);
82
82
  var Portal = ({ children }) => {
83
83
  const contextContainer = React3.useContext(PortalContainerContext);
84
- const [fallback, setFallback] = React3.useState(null);
85
- React3.useEffect(() => {
86
- if (!contextContainer) setFallback(document.body);
87
- }, [contextContainer]);
88
- const container = contextContainer ?? fallback;
89
- if (!container) return null;
84
+ if (typeof document === "undefined") return null;
85
+ const container = contextContainer ?? document.body;
90
86
  return ReactDOM.createPortal(children, container);
91
87
  };
92
88
  Portal.displayName = "Portal";
@@ -69,15 +69,15 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
69
69
  direction
70
70
  });
71
71
  }, [triggerRef, popRef]);
72
+ import_react.default.useLayoutEffect(() => {
73
+ if (!enabled) return;
74
+ calculatePosition();
75
+ }, [calculatePosition, enabled]);
72
76
  import_react.default.useEffect(() => {
73
77
  if (!enabled) return;
74
- const raf = requestAnimationFrame(() => {
75
- calculatePosition();
76
- });
77
78
  window.addEventListener("resize", calculatePosition);
78
79
  window.addEventListener("scroll", calculatePosition, true);
79
80
  return () => {
80
- cancelAnimationFrame(raf);
81
81
  window.removeEventListener("resize", calculatePosition);
82
82
  window.removeEventListener("scroll", calculatePosition, true);
83
83
  };
@@ -118,12 +118,8 @@ var import_jsx_runtime = require("react/jsx-runtime");
118
118
  var PortalContainerContext = import_react3.default.createContext(null);
119
119
  var Portal = ({ children }) => {
120
120
  const contextContainer = import_react3.default.useContext(PortalContainerContext);
121
- const [fallback, setFallback] = import_react3.default.useState(null);
122
- import_react3.default.useEffect(() => {
123
- if (!contextContainer) setFallback(document.body);
124
- }, [contextContainer]);
125
- const container = contextContainer ?? fallback;
126
- if (!container) return null;
121
+ if (typeof document === "undefined") return null;
122
+ const container = contextContainer ?? document.body;
127
123
  return import_react_dom.default.createPortal(children, container);
128
124
  };
129
125
  Portal.displayName = "Portal";
@@ -32,15 +32,15 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
32
32
  direction
33
33
  });
34
34
  }, [triggerRef, popRef]);
35
+ React.useLayoutEffect(() => {
36
+ if (!enabled) return;
37
+ calculatePosition();
38
+ }, [calculatePosition, enabled]);
35
39
  React.useEffect(() => {
36
40
  if (!enabled) return;
37
- const raf = requestAnimationFrame(() => {
38
- calculatePosition();
39
- });
40
41
  window.addEventListener("resize", calculatePosition);
41
42
  window.addEventListener("scroll", calculatePosition, true);
42
43
  return () => {
43
- cancelAnimationFrame(raf);
44
44
  window.removeEventListener("resize", calculatePosition);
45
45
  window.removeEventListener("scroll", calculatePosition, true);
46
46
  };
@@ -81,12 +81,8 @@ import { jsx } from "react/jsx-runtime";
81
81
  var PortalContainerContext = React3.createContext(null);
82
82
  var Portal = ({ children }) => {
83
83
  const contextContainer = React3.useContext(PortalContainerContext);
84
- const [fallback, setFallback] = React3.useState(null);
85
- React3.useEffect(() => {
86
- if (!contextContainer) setFallback(document.body);
87
- }, [contextContainer]);
88
- const container = contextContainer ?? fallback;
89
- if (!container) return null;
84
+ if (typeof document === "undefined") return null;
85
+ const container = contextContainer ?? document.body;
90
86
  return ReactDOM.createPortal(children, container);
91
87
  };
92
88
  Portal.displayName = "Portal";