@x-plat/design-system 0.14.19 → 0.15.0

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.
@@ -36,13 +36,13 @@ __export(Select_exports, {
36
36
  module.exports = __toCommonJS(Select_exports);
37
37
 
38
38
  // src/components/Select/Select.tsx
39
- var import_react6 = __toESM(require("react"), 1);
39
+ var import_react7 = __toESM(require("react"), 1);
40
40
 
41
41
  // src/tokens/hooks/Portal.tsx
42
42
  var import_react_dom = __toESM(require("react-dom"), 1);
43
- var Portal = ({ children }) => {
43
+ var Portal = ({ children, container }) => {
44
44
  if (typeof document === "undefined") return null;
45
- return import_react_dom.default.createPortal(children, document.body);
45
+ return import_react_dom.default.createPortal(children, container ?? document.body);
46
46
  };
47
47
  Portal.displayName = "Portal";
48
48
  var Portal_default = Portal;
@@ -148,8 +148,9 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
148
148
  );
149
149
  if (frozenMaxRef.current === void 0) frozenMaxRef.current = suggested;
150
150
  const maxHeight = frozenMaxRef.current;
151
- pop.style.top = `${top + window.scrollY}px`;
152
- pop.style.left = `${left + window.scrollX}px`;
151
+ const hostRect = (pop.offsetParent ?? pop.parentElement)?.getBoundingClientRect();
152
+ pop.style.top = `${top - (hostRect?.top ?? 0)}px`;
153
+ pop.style.left = `${left - (hostRect?.left ?? 0)}px`;
153
154
  pop.style.maxHeight = maxHeight === null ? "" : `${maxHeight}px`;
154
155
  pop.style.clipPath = over.top || over.right || over.bottom || over.left ? `inset(${over.top}px ${over.right}px ${over.bottom}px ${over.left}px)` : "none";
155
156
  directionRef.current = next;
@@ -224,8 +225,34 @@ var useClickOutside = (refs, handler, enabled = true) => {
224
225
  };
225
226
  var useClickOutside_default = useClickOutside;
226
227
 
227
- // src/tokens/hooks/useOverlayKeyboard.ts
228
+ // src/tokens/hooks/useOverlayHost.ts
228
229
  var import_react3 = __toESM(require("react"), 1);
230
+ var useOverlayHost = (triggerRef, enabled) => {
231
+ const [host, setHost] = import_react3.default.useState(null);
232
+ import_react3.default.useLayoutEffect(() => {
233
+ if (!enabled || !triggerRef.current) {
234
+ setHost(null);
235
+ return;
236
+ }
237
+ const el = document.createElement("div");
238
+ el.dataset.xplatOverlayHost = "";
239
+ el.style.position = "relative";
240
+ el.style.width = "0";
241
+ el.style.height = "0";
242
+ const parent = findScrollParent(triggerRef.current) ?? document.body;
243
+ parent.appendChild(el);
244
+ setHost(el);
245
+ return () => {
246
+ el.remove();
247
+ setHost(null);
248
+ };
249
+ }, [enabled, triggerRef]);
250
+ return host;
251
+ };
252
+ var useOverlayHost_default = useOverlayHost;
253
+
254
+ // src/tokens/hooks/useOverlayKeyboard.ts
255
+ var import_react4 = __toESM(require("react"), 1);
229
256
  var FOCUSABLE = [
230
257
  "a[href]",
231
258
  "button:not([disabled])",
@@ -235,7 +262,7 @@ var FOCUSABLE = [
235
262
  "[tabindex]:not([tabindex='-1'])"
236
263
  ].join(",");
237
264
  var useEscapeKey = (enabled, onEscape) => {
238
- import_react3.default.useEffect(() => {
265
+ import_react4.default.useEffect(() => {
239
266
  if (!enabled) return;
240
267
  const onKey = (e) => {
241
268
  if (e.key !== "Escape") return;
@@ -248,9 +275,9 @@ var useEscapeKey = (enabled, onEscape) => {
248
275
  }, [enabled, onEscape]);
249
276
  };
250
277
  var useCloseWhenFocusHidden = (enabled, triggerRef, popRef, onClose) => {
251
- const onCloseRef = import_react3.default.useRef(onClose);
278
+ const onCloseRef = import_react4.default.useRef(onClose);
252
279
  onCloseRef.current = onClose;
253
- import_react3.default.useEffect(() => {
280
+ import_react4.default.useEffect(() => {
254
281
  const trigger = triggerRef.current;
255
282
  if (!enabled || !trigger) return;
256
283
  const observer = new IntersectionObserver(
@@ -1314,16 +1341,16 @@ Field.displayName = "Field";
1314
1341
  var hasError = (validations) => !!validations?.some((v) => v.status === "error");
1315
1342
 
1316
1343
  // src/components/Select/context.ts
1317
- var import_react4 = __toESM(require("react"), 1);
1318
- var SelectContext = import_react4.default.createContext(null);
1344
+ var import_react5 = __toESM(require("react"), 1);
1345
+ var SelectContext = import_react5.default.createContext(null);
1319
1346
  var context_default = SelectContext;
1320
1347
 
1321
1348
  // src/components/Select/SelectItem.tsx
1322
- var import_react5 = __toESM(require("react"), 1);
1349
+ var import_react6 = __toESM(require("react"), 1);
1323
1350
  var import_jsx_runtime296 = require("react/jsx-runtime");
1324
1351
  var SelectItem = (props) => {
1325
1352
  const { children, value, onClick, disabled = false } = props;
1326
- const ctx = import_react5.default.useContext(context_default);
1353
+ const ctx = import_react6.default.useContext(context_default);
1327
1354
  const handleClick = (e) => {
1328
1355
  e.preventDefault();
1329
1356
  e.stopPropagation();
@@ -1373,29 +1400,29 @@ var SelectRoot = (props) => {
1373
1400
  required,
1374
1401
  size = "md"
1375
1402
  } = props;
1376
- const fieldId = import_react6.default.useId();
1377
- const itemChildren = import_react6.default.Children.toArray(children).filter(
1378
- (child) => import_react6.default.isValidElement(child) && child.type === SelectItem_default
1403
+ const fieldId = import_react7.default.useId();
1404
+ const itemChildren = import_react7.default.Children.toArray(children).filter(
1405
+ (child) => import_react7.default.isValidElement(child) && child.type === SelectItem_default
1379
1406
  );
1380
1407
  const isControlled = valueProp !== void 0;
1381
- const [isOpen, setOpen] = import_react6.default.useState(false);
1382
- const [uncontrolledLabel, setUncontrolledLabel] = import_react6.default.useState(null);
1383
- const [uncontrolledValue, setUncontrolledValue] = import_react6.default.useState(void 0);
1384
- const controlledLabel = import_react6.default.useMemo(() => {
1408
+ const [isOpen, setOpen] = import_react7.default.useState(false);
1409
+ const [uncontrolledLabel, setUncontrolledLabel] = import_react7.default.useState(null);
1410
+ const [uncontrolledValue, setUncontrolledValue] = import_react7.default.useState(void 0);
1411
+ const controlledLabel = import_react7.default.useMemo(() => {
1385
1412
  if (!isControlled) return null;
1386
1413
  const match = itemChildren.find((child) => child.props.value === valueProp);
1387
1414
  return match ? match.props.children : null;
1388
1415
  }, [isControlled, valueProp, itemChildren]);
1389
1416
  const selectedLabel = isControlled ? controlledLabel : uncontrolledLabel;
1390
1417
  const selectedValue = isControlled ? valueProp : uncontrolledValue;
1391
- const triggerRef = import_react6.default.useRef(null);
1392
- const contentRef = import_react6.default.useRef(null);
1393
- const [mounted, setMounted] = import_react6.default.useState(false);
1394
- const [visible, setVisible] = import_react6.default.useState(false);
1395
- import_react6.default.useEffect(() => {
1418
+ const triggerRef = import_react7.default.useRef(null);
1419
+ const contentRef = import_react7.default.useRef(null);
1420
+ const [mounted, setMounted] = import_react7.default.useState(false);
1421
+ const [visible, setVisible] = import_react7.default.useState(false);
1422
+ import_react7.default.useEffect(() => {
1396
1423
  if (disabled && isOpen) setOpen(false);
1397
1424
  }, [disabled, isOpen]);
1398
- import_react6.default.useEffect(() => {
1425
+ import_react7.default.useEffect(() => {
1399
1426
  if (isOpen) {
1400
1427
  setMounted(true);
1401
1428
  const t2 = setTimeout(() => setVisible(true), 1);
@@ -1405,33 +1432,34 @@ var SelectRoot = (props) => {
1405
1432
  const t = setTimeout(() => setMounted(false), ANIMATION_DURATION_MS);
1406
1433
  return () => clearTimeout(t);
1407
1434
  }, [isOpen]);
1408
- const [query, setQuery] = import_react6.default.useState("");
1435
+ const [query, setQuery] = import_react7.default.useState("");
1409
1436
  const textOf = (node) => {
1410
1437
  if (node === null || node === void 0 || typeof node === "boolean") return "";
1411
1438
  if (typeof node === "string" || typeof node === "number") return String(node);
1412
1439
  if (Array.isArray(node)) return node.map(textOf).join("");
1413
- if (import_react6.default.isValidElement(node)) return textOf(node.props.children);
1440
+ if (import_react7.default.isValidElement(node)) return textOf(node.props.children);
1414
1441
  return "";
1415
1442
  };
1416
- const visibleItems = import_react6.default.useMemo(() => {
1443
+ const visibleItems = import_react7.default.useMemo(() => {
1417
1444
  if (!searchable || !query.trim()) return itemChildren;
1418
1445
  const q = query.trim().toLowerCase();
1419
1446
  return itemChildren.filter((c) => textOf(c.props.children).toLowerCase().includes(q));
1420
1447
  }, [searchable, query, itemChildren]);
1421
- const open = import_react6.default.useCallback(() => setOpen(true), []);
1422
- const close = import_react6.default.useCallback(() => {
1448
+ const open = import_react7.default.useCallback(() => setOpen(true), []);
1449
+ const close = import_react7.default.useCallback(() => {
1423
1450
  setOpen(false);
1424
1451
  setQuery("");
1425
1452
  }, []);
1426
- const toggle = import_react6.default.useCallback(() => setOpen((prev) => !prev), []);
1453
+ const toggle = import_react7.default.useCallback(() => setOpen((prev) => !prev), []);
1427
1454
  useClickOutside_default([contentRef, triggerRef], close, isOpen);
1428
1455
  useCloseWhenFocusHidden(isOpen, triggerRef, contentRef, close);
1429
1456
  useEscapeKey(isOpen, () => {
1430
1457
  close();
1431
1458
  triggerRef.current?.focus({ preventScroll: true });
1432
1459
  });
1460
+ const host = useOverlayHost_default(triggerRef, mounted);
1433
1461
  useAutoPosition_default(triggerRef, contentRef, mounted);
1434
- const setSelected = import_react6.default.useCallback(
1462
+ const setSelected = import_react7.default.useCallback(
1435
1463
  (label2, itemValue) => {
1436
1464
  if (!isControlled) {
1437
1465
  setUncontrolledLabel(label2);
@@ -1441,7 +1469,7 @@ var SelectRoot = (props) => {
1441
1469
  },
1442
1470
  [isControlled, onChange]
1443
1471
  );
1444
- const ctxValue = import_react6.default.useMemo(
1472
+ const ctxValue = import_react7.default.useMemo(
1445
1473
  () => ({
1446
1474
  isOpen,
1447
1475
  mounted,
@@ -1520,7 +1548,7 @@ var SelectRoot = (props) => {
1520
1548
  ]
1521
1549
  }
1522
1550
  ),
1523
- mounted && /* @__PURE__ */ (0, import_jsx_runtime297.jsx)(Portal_default, { children: /* @__PURE__ */ (0, import_jsx_runtime297.jsxs)(
1551
+ mounted && /* @__PURE__ */ (0, import_jsx_runtime297.jsx)(Portal_default, { container: host, children: /* @__PURE__ */ (0, import_jsx_runtime297.jsxs)(
1524
1552
  "div",
1525
1553
  {
1526
1554
  className: clsx_default("lib-xplat-select-content", size, stateClass),
@@ -1,11 +1,11 @@
1
1
  // src/components/Select/Select.tsx
2
- import React6 from "react";
2
+ import React7 from "react";
3
3
 
4
4
  // src/tokens/hooks/Portal.tsx
5
5
  import ReactDOM from "react-dom";
6
- var Portal = ({ children }) => {
6
+ var Portal = ({ children, container }) => {
7
7
  if (typeof document === "undefined") return null;
8
- return ReactDOM.createPortal(children, document.body);
8
+ return ReactDOM.createPortal(children, container ?? document.body);
9
9
  };
10
10
  Portal.displayName = "Portal";
11
11
  var Portal_default = Portal;
@@ -111,8 +111,9 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
111
111
  );
112
112
  if (frozenMaxRef.current === void 0) frozenMaxRef.current = suggested;
113
113
  const maxHeight = frozenMaxRef.current;
114
- pop.style.top = `${top + window.scrollY}px`;
115
- pop.style.left = `${left + window.scrollX}px`;
114
+ const hostRect = (pop.offsetParent ?? pop.parentElement)?.getBoundingClientRect();
115
+ pop.style.top = `${top - (hostRect?.top ?? 0)}px`;
116
+ pop.style.left = `${left - (hostRect?.left ?? 0)}px`;
116
117
  pop.style.maxHeight = maxHeight === null ? "" : `${maxHeight}px`;
117
118
  pop.style.clipPath = over.top || over.right || over.bottom || over.left ? `inset(${over.top}px ${over.right}px ${over.bottom}px ${over.left}px)` : "none";
118
119
  directionRef.current = next;
@@ -187,8 +188,34 @@ var useClickOutside = (refs, handler, enabled = true) => {
187
188
  };
188
189
  var useClickOutside_default = useClickOutside;
189
190
 
190
- // src/tokens/hooks/useOverlayKeyboard.ts
191
+ // src/tokens/hooks/useOverlayHost.ts
191
192
  import React3 from "react";
193
+ var useOverlayHost = (triggerRef, enabled) => {
194
+ const [host, setHost] = React3.useState(null);
195
+ React3.useLayoutEffect(() => {
196
+ if (!enabled || !triggerRef.current) {
197
+ setHost(null);
198
+ return;
199
+ }
200
+ const el = document.createElement("div");
201
+ el.dataset.xplatOverlayHost = "";
202
+ el.style.position = "relative";
203
+ el.style.width = "0";
204
+ el.style.height = "0";
205
+ const parent = findScrollParent(triggerRef.current) ?? document.body;
206
+ parent.appendChild(el);
207
+ setHost(el);
208
+ return () => {
209
+ el.remove();
210
+ setHost(null);
211
+ };
212
+ }, [enabled, triggerRef]);
213
+ return host;
214
+ };
215
+ var useOverlayHost_default = useOverlayHost;
216
+
217
+ // src/tokens/hooks/useOverlayKeyboard.ts
218
+ import React4 from "react";
192
219
  var FOCUSABLE = [
193
220
  "a[href]",
194
221
  "button:not([disabled])",
@@ -198,7 +225,7 @@ var FOCUSABLE = [
198
225
  "[tabindex]:not([tabindex='-1'])"
199
226
  ].join(",");
200
227
  var useEscapeKey = (enabled, onEscape) => {
201
- React3.useEffect(() => {
228
+ React4.useEffect(() => {
202
229
  if (!enabled) return;
203
230
  const onKey = (e) => {
204
231
  if (e.key !== "Escape") return;
@@ -211,9 +238,9 @@ var useEscapeKey = (enabled, onEscape) => {
211
238
  }, [enabled, onEscape]);
212
239
  };
213
240
  var useCloseWhenFocusHidden = (enabled, triggerRef, popRef, onClose) => {
214
- const onCloseRef = React3.useRef(onClose);
241
+ const onCloseRef = React4.useRef(onClose);
215
242
  onCloseRef.current = onClose;
216
- React3.useEffect(() => {
243
+ React4.useEffect(() => {
217
244
  const trigger = triggerRef.current;
218
245
  if (!enabled || !trigger) return;
219
246
  const observer = new IntersectionObserver(
@@ -1277,16 +1304,16 @@ Field.displayName = "Field";
1277
1304
  var hasError = (validations) => !!validations?.some((v) => v.status === "error");
1278
1305
 
1279
1306
  // src/components/Select/context.ts
1280
- import React4 from "react";
1281
- var SelectContext = React4.createContext(null);
1307
+ import React5 from "react";
1308
+ var SelectContext = React5.createContext(null);
1282
1309
  var context_default = SelectContext;
1283
1310
 
1284
1311
  // src/components/Select/SelectItem.tsx
1285
- import React5 from "react";
1312
+ import React6 from "react";
1286
1313
  import { jsx as jsx296 } from "react/jsx-runtime";
1287
1314
  var SelectItem = (props) => {
1288
1315
  const { children, value, onClick, disabled = false } = props;
1289
- const ctx = React5.useContext(context_default);
1316
+ const ctx = React6.useContext(context_default);
1290
1317
  const handleClick = (e) => {
1291
1318
  e.preventDefault();
1292
1319
  e.stopPropagation();
@@ -1336,29 +1363,29 @@ var SelectRoot = (props) => {
1336
1363
  required,
1337
1364
  size = "md"
1338
1365
  } = props;
1339
- const fieldId = React6.useId();
1340
- const itemChildren = React6.Children.toArray(children).filter(
1341
- (child) => React6.isValidElement(child) && child.type === SelectItem_default
1366
+ const fieldId = React7.useId();
1367
+ const itemChildren = React7.Children.toArray(children).filter(
1368
+ (child) => React7.isValidElement(child) && child.type === SelectItem_default
1342
1369
  );
1343
1370
  const isControlled = valueProp !== void 0;
1344
- const [isOpen, setOpen] = React6.useState(false);
1345
- const [uncontrolledLabel, setUncontrolledLabel] = React6.useState(null);
1346
- const [uncontrolledValue, setUncontrolledValue] = React6.useState(void 0);
1347
- const controlledLabel = React6.useMemo(() => {
1371
+ const [isOpen, setOpen] = React7.useState(false);
1372
+ const [uncontrolledLabel, setUncontrolledLabel] = React7.useState(null);
1373
+ const [uncontrolledValue, setUncontrolledValue] = React7.useState(void 0);
1374
+ const controlledLabel = React7.useMemo(() => {
1348
1375
  if (!isControlled) return null;
1349
1376
  const match = itemChildren.find((child) => child.props.value === valueProp);
1350
1377
  return match ? match.props.children : null;
1351
1378
  }, [isControlled, valueProp, itemChildren]);
1352
1379
  const selectedLabel = isControlled ? controlledLabel : uncontrolledLabel;
1353
1380
  const selectedValue = isControlled ? valueProp : uncontrolledValue;
1354
- const triggerRef = React6.useRef(null);
1355
- const contentRef = React6.useRef(null);
1356
- const [mounted, setMounted] = React6.useState(false);
1357
- const [visible, setVisible] = React6.useState(false);
1358
- React6.useEffect(() => {
1381
+ const triggerRef = React7.useRef(null);
1382
+ const contentRef = React7.useRef(null);
1383
+ const [mounted, setMounted] = React7.useState(false);
1384
+ const [visible, setVisible] = React7.useState(false);
1385
+ React7.useEffect(() => {
1359
1386
  if (disabled && isOpen) setOpen(false);
1360
1387
  }, [disabled, isOpen]);
1361
- React6.useEffect(() => {
1388
+ React7.useEffect(() => {
1362
1389
  if (isOpen) {
1363
1390
  setMounted(true);
1364
1391
  const t2 = setTimeout(() => setVisible(true), 1);
@@ -1368,33 +1395,34 @@ var SelectRoot = (props) => {
1368
1395
  const t = setTimeout(() => setMounted(false), ANIMATION_DURATION_MS);
1369
1396
  return () => clearTimeout(t);
1370
1397
  }, [isOpen]);
1371
- const [query, setQuery] = React6.useState("");
1398
+ const [query, setQuery] = React7.useState("");
1372
1399
  const textOf = (node) => {
1373
1400
  if (node === null || node === void 0 || typeof node === "boolean") return "";
1374
1401
  if (typeof node === "string" || typeof node === "number") return String(node);
1375
1402
  if (Array.isArray(node)) return node.map(textOf).join("");
1376
- if (React6.isValidElement(node)) return textOf(node.props.children);
1403
+ if (React7.isValidElement(node)) return textOf(node.props.children);
1377
1404
  return "";
1378
1405
  };
1379
- const visibleItems = React6.useMemo(() => {
1406
+ const visibleItems = React7.useMemo(() => {
1380
1407
  if (!searchable || !query.trim()) return itemChildren;
1381
1408
  const q = query.trim().toLowerCase();
1382
1409
  return itemChildren.filter((c) => textOf(c.props.children).toLowerCase().includes(q));
1383
1410
  }, [searchable, query, itemChildren]);
1384
- const open = React6.useCallback(() => setOpen(true), []);
1385
- const close = React6.useCallback(() => {
1411
+ const open = React7.useCallback(() => setOpen(true), []);
1412
+ const close = React7.useCallback(() => {
1386
1413
  setOpen(false);
1387
1414
  setQuery("");
1388
1415
  }, []);
1389
- const toggle = React6.useCallback(() => setOpen((prev) => !prev), []);
1416
+ const toggle = React7.useCallback(() => setOpen((prev) => !prev), []);
1390
1417
  useClickOutside_default([contentRef, triggerRef], close, isOpen);
1391
1418
  useCloseWhenFocusHidden(isOpen, triggerRef, contentRef, close);
1392
1419
  useEscapeKey(isOpen, () => {
1393
1420
  close();
1394
1421
  triggerRef.current?.focus({ preventScroll: true });
1395
1422
  });
1423
+ const host = useOverlayHost_default(triggerRef, mounted);
1396
1424
  useAutoPosition_default(triggerRef, contentRef, mounted);
1397
- const setSelected = React6.useCallback(
1425
+ const setSelected = React7.useCallback(
1398
1426
  (label2, itemValue) => {
1399
1427
  if (!isControlled) {
1400
1428
  setUncontrolledLabel(label2);
@@ -1404,7 +1432,7 @@ var SelectRoot = (props) => {
1404
1432
  },
1405
1433
  [isControlled, onChange]
1406
1434
  );
1407
- const ctxValue = React6.useMemo(
1435
+ const ctxValue = React7.useMemo(
1408
1436
  () => ({
1409
1437
  isOpen,
1410
1438
  mounted,
@@ -1483,7 +1511,7 @@ var SelectRoot = (props) => {
1483
1511
  ]
1484
1512
  }
1485
1513
  ),
1486
- mounted && /* @__PURE__ */ jsx297(Portal_default, { children: /* @__PURE__ */ jsxs190(
1514
+ mounted && /* @__PURE__ */ jsx297(Portal_default, { container: host, children: /* @__PURE__ */ jsxs190(
1487
1515
  "div",
1488
1516
  {
1489
1517
  className: clsx_default("lib-xplat-select-content", size, stateClass),
@@ -35,13 +35,13 @@ __export(TimePicker_exports, {
35
35
  module.exports = __toCommonJS(TimePicker_exports);
36
36
 
37
37
  // src/components/TimePicker/TimePicker.tsx
38
- var import_react4 = __toESM(require("react"), 1);
38
+ var import_react5 = __toESM(require("react"), 1);
39
39
 
40
40
  // src/tokens/hooks/Portal.tsx
41
41
  var import_react_dom = __toESM(require("react-dom"), 1);
42
- var Portal = ({ children }) => {
42
+ var Portal = ({ children, container }) => {
43
43
  if (typeof document === "undefined") return null;
44
- return import_react_dom.default.createPortal(children, document.body);
44
+ return import_react_dom.default.createPortal(children, container ?? document.body);
45
45
  };
46
46
  Portal.displayName = "Portal";
47
47
  var Portal_default = Portal;
@@ -147,8 +147,9 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
147
147
  );
148
148
  if (frozenMaxRef.current === void 0) frozenMaxRef.current = suggested;
149
149
  const maxHeight = frozenMaxRef.current;
150
- pop.style.top = `${top + window.scrollY}px`;
151
- pop.style.left = `${left + window.scrollX}px`;
150
+ const hostRect = (pop.offsetParent ?? pop.parentElement)?.getBoundingClientRect();
151
+ pop.style.top = `${top - (hostRect?.top ?? 0)}px`;
152
+ pop.style.left = `${left - (hostRect?.left ?? 0)}px`;
152
153
  pop.style.maxHeight = maxHeight === null ? "" : `${maxHeight}px`;
153
154
  pop.style.clipPath = over.top || over.right || over.bottom || over.left ? `inset(${over.top}px ${over.right}px ${over.bottom}px ${over.left}px)` : "none";
154
155
  directionRef.current = next;
@@ -223,8 +224,34 @@ var useClickOutside = (refs, handler, enabled = true) => {
223
224
  };
224
225
  var useClickOutside_default = useClickOutside;
225
226
 
226
- // src/tokens/hooks/useOverlayKeyboard.ts
227
+ // src/tokens/hooks/useOverlayHost.ts
227
228
  var import_react3 = __toESM(require("react"), 1);
229
+ var useOverlayHost = (triggerRef, enabled) => {
230
+ const [host, setHost] = import_react3.default.useState(null);
231
+ import_react3.default.useLayoutEffect(() => {
232
+ if (!enabled || !triggerRef.current) {
233
+ setHost(null);
234
+ return;
235
+ }
236
+ const el = document.createElement("div");
237
+ el.dataset.xplatOverlayHost = "";
238
+ el.style.position = "relative";
239
+ el.style.width = "0";
240
+ el.style.height = "0";
241
+ const parent = findScrollParent(triggerRef.current) ?? document.body;
242
+ parent.appendChild(el);
243
+ setHost(el);
244
+ return () => {
245
+ el.remove();
246
+ setHost(null);
247
+ };
248
+ }, [enabled, triggerRef]);
249
+ return host;
250
+ };
251
+ var useOverlayHost_default = useOverlayHost;
252
+
253
+ // src/tokens/hooks/useOverlayKeyboard.ts
254
+ var import_react4 = __toESM(require("react"), 1);
228
255
  var FOCUSABLE = [
229
256
  "a[href]",
230
257
  "button:not([disabled])",
@@ -234,7 +261,7 @@ var FOCUSABLE = [
234
261
  "[tabindex]:not([tabindex='-1'])"
235
262
  ].join(",");
236
263
  var useEscapeKey = (enabled, onEscape) => {
237
- import_react3.default.useEffect(() => {
264
+ import_react4.default.useEffect(() => {
238
265
  if (!enabled) return;
239
266
  const onKey = (e) => {
240
267
  if (e.key !== "Escape") return;
@@ -247,9 +274,9 @@ var useEscapeKey = (enabled, onEscape) => {
247
274
  }, [enabled, onEscape]);
248
275
  };
249
276
  var useCloseWhenFocusHidden = (enabled, triggerRef, popRef, onClose) => {
250
- const onCloseRef = import_react3.default.useRef(onClose);
277
+ const onCloseRef = import_react4.default.useRef(onClose);
251
278
  onCloseRef.current = onClose;
252
- import_react3.default.useEffect(() => {
279
+ import_react4.default.useEffect(() => {
253
280
  const trigger = triggerRef.current;
254
281
  if (!enabled || !trigger) return;
255
282
  const observer = new IntersectionObserver(
@@ -459,13 +486,13 @@ var TimePicker = (props) => {
459
486
  required,
460
487
  validations
461
488
  } = props;
462
- const fieldId = import_react4.default.useId();
463
- const triggerRef = import_react4.default.useRef(null);
464
- const contentRef = import_react4.default.useRef(null);
465
- const [isOpen, setOpen] = import_react4.default.useState(false);
466
- const [mounted, setMounted] = import_react4.default.useState(false);
467
- const [visible, setVisible] = import_react4.default.useState(false);
468
- const options = import_react4.default.useMemo(() => {
489
+ const fieldId = import_react5.default.useId();
490
+ const triggerRef = import_react5.default.useRef(null);
491
+ const contentRef = import_react5.default.useRef(null);
492
+ const [isOpen, setOpen] = import_react5.default.useState(false);
493
+ const [mounted, setMounted] = import_react5.default.useState(false);
494
+ const [visible, setVisible] = import_react5.default.useState(false);
495
+ const options = import_react5.default.useMemo(() => {
469
496
  const safeStep = step > 0 && step <= 720 ? step : 30;
470
497
  const lo = toMinutes(min) ?? 0;
471
498
  const hi = toMinutes(max) ?? 24 * 60 - 1;
@@ -473,18 +500,19 @@ var TimePicker = (props) => {
473
500
  for (let t = lo; t <= hi; t += safeStep) out.push(toHHmm(t));
474
501
  return out;
475
502
  }, [step, min, max]);
476
- const close = import_react4.default.useCallback(() => setOpen(false), []);
503
+ const close = import_react5.default.useCallback(() => setOpen(false), []);
477
504
  useClickOutside_default([triggerRef, contentRef], close, isOpen);
478
505
  useCloseWhenFocusHidden(isOpen, triggerRef, contentRef, close);
479
506
  useEscapeKey(isOpen, () => {
480
507
  close();
481
508
  triggerRef.current?.focus({ preventScroll: true });
482
509
  });
510
+ const host = useOverlayHost_default(triggerRef, mounted);
483
511
  useAutoPosition_default(triggerRef, contentRef, mounted);
484
- import_react4.default.useEffect(() => {
512
+ import_react5.default.useEffect(() => {
485
513
  if (disabled && isOpen) setOpen(false);
486
514
  }, [disabled, isOpen]);
487
- import_react4.default.useEffect(() => {
515
+ import_react5.default.useEffect(() => {
488
516
  if (isOpen) {
489
517
  setMounted(true);
490
518
  const t2 = setTimeout(() => setVisible(true), 1);
@@ -522,7 +550,7 @@ var TimePicker = (props) => {
522
550
  children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: clsx_default("time-picker-value", !value && "placeholder"), children: value ? display(value, use12Hours) : placeholder })
523
551
  }
524
552
  ),
525
- mounted && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Portal_default, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
553
+ mounted && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Portal_default, { container: host, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
526
554
  "div",
527
555
  {
528
556
  ref: contentRef,