@x-plat/design-system 0.14.18 → 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.
- package/dist/components/Dropdown/index.cjs +54 -17
- package/dist/components/Dropdown/index.js +54 -17
- package/dist/components/PopOver/index.cjs +53 -16
- package/dist/components/PopOver/index.js +53 -16
- package/dist/components/Select/index.cjs +73 -36
- package/dist/components/Select/index.js +73 -36
- package/dist/components/TimePicker/index.cjs +58 -21
- package/dist/components/TimePicker/index.js +58 -21
- package/dist/components/Tooltip/index.cjs +2 -2
- package/dist/components/Tooltip/index.js +2 -2
- package/dist/components/index.cjs +255 -215
- package/dist/components/index.js +255 -215
- package/dist/index.cjs +260 -220
- package/dist/index.js +260 -220
- package/package.json +1 -1
|
@@ -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
|
|
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;
|
|
@@ -105,10 +105,16 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
|
|
|
105
105
|
const scrollParentRef = import_react.default.useRef(null);
|
|
106
106
|
const placedRef = import_react.default.useRef(false);
|
|
107
107
|
const frozenMaxRef = import_react.default.useRef(void 0);
|
|
108
|
+
const cssCapRef = import_react.default.useRef(void 0);
|
|
108
109
|
const calculatePosition = import_react.default.useCallback((remeasure = false) => {
|
|
109
110
|
const pop = popRef.current;
|
|
110
111
|
if (!triggerRef.current || !pop) return;
|
|
111
112
|
if (remeasure) frozenMaxRef.current = void 0;
|
|
113
|
+
if (cssCapRef.current === void 0) {
|
|
114
|
+
pop.style.maxHeight = "";
|
|
115
|
+
const raw = getComputedStyle(pop).maxHeight;
|
|
116
|
+
cssCapRef.current = raw === "none" ? null : Number.parseFloat(raw) || null;
|
|
117
|
+
}
|
|
112
118
|
if (remeasure || !sizeRef.current) {
|
|
113
119
|
sizeRef.current = {
|
|
114
120
|
w: pop.offsetWidth,
|
|
@@ -130,8 +136,10 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
|
|
|
130
136
|
};
|
|
131
137
|
const first = !placedRef.current;
|
|
132
138
|
if (first) pop.style.transition = "none";
|
|
139
|
+
const cap = cssCapRef.current;
|
|
140
|
+
const desiredH = cap == null ? popH : Math.min(popH, cap);
|
|
133
141
|
const frozen = frozenMaxRef.current;
|
|
134
|
-
const effectiveH = frozen == null ?
|
|
142
|
+
const effectiveH = frozen == null ? desiredH : Math.min(desiredH, frozen);
|
|
135
143
|
const { direction: next, top, left, over, maxHeight: suggested } = computePlacement(
|
|
136
144
|
triggerRect,
|
|
137
145
|
popW,
|
|
@@ -140,8 +148,9 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
|
|
|
140
148
|
);
|
|
141
149
|
if (frozenMaxRef.current === void 0) frozenMaxRef.current = suggested;
|
|
142
150
|
const maxHeight = frozenMaxRef.current;
|
|
143
|
-
|
|
144
|
-
pop.style.
|
|
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`;
|
|
145
154
|
pop.style.maxHeight = maxHeight === null ? "" : `${maxHeight}px`;
|
|
146
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";
|
|
147
156
|
directionRef.current = next;
|
|
@@ -159,6 +168,7 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
|
|
|
159
168
|
scrollParentRef.current = null;
|
|
160
169
|
placedRef.current = false;
|
|
161
170
|
frozenMaxRef.current = void 0;
|
|
171
|
+
cssCapRef.current = void 0;
|
|
162
172
|
return;
|
|
163
173
|
}
|
|
164
174
|
if (triggerRef.current) {
|
|
@@ -215,8 +225,34 @@ var useClickOutside = (refs, handler, enabled = true) => {
|
|
|
215
225
|
};
|
|
216
226
|
var useClickOutside_default = useClickOutside;
|
|
217
227
|
|
|
218
|
-
// src/tokens/hooks/
|
|
228
|
+
// src/tokens/hooks/useOverlayHost.ts
|
|
219
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);
|
|
220
256
|
var FOCUSABLE = [
|
|
221
257
|
"a[href]",
|
|
222
258
|
"button:not([disabled])",
|
|
@@ -226,7 +262,7 @@ var FOCUSABLE = [
|
|
|
226
262
|
"[tabindex]:not([tabindex='-1'])"
|
|
227
263
|
].join(",");
|
|
228
264
|
var useEscapeKey = (enabled, onEscape) => {
|
|
229
|
-
|
|
265
|
+
import_react4.default.useEffect(() => {
|
|
230
266
|
if (!enabled) return;
|
|
231
267
|
const onKey = (e) => {
|
|
232
268
|
if (e.key !== "Escape") return;
|
|
@@ -239,9 +275,9 @@ var useEscapeKey = (enabled, onEscape) => {
|
|
|
239
275
|
}, [enabled, onEscape]);
|
|
240
276
|
};
|
|
241
277
|
var useCloseWhenFocusHidden = (enabled, triggerRef, popRef, onClose) => {
|
|
242
|
-
const onCloseRef =
|
|
278
|
+
const onCloseRef = import_react4.default.useRef(onClose);
|
|
243
279
|
onCloseRef.current = onClose;
|
|
244
|
-
|
|
280
|
+
import_react4.default.useEffect(() => {
|
|
245
281
|
const trigger = triggerRef.current;
|
|
246
282
|
if (!enabled || !trigger) return;
|
|
247
283
|
const observer = new IntersectionObserver(
|
|
@@ -1305,16 +1341,16 @@ Field.displayName = "Field";
|
|
|
1305
1341
|
var hasError = (validations) => !!validations?.some((v) => v.status === "error");
|
|
1306
1342
|
|
|
1307
1343
|
// src/components/Select/context.ts
|
|
1308
|
-
var
|
|
1309
|
-
var SelectContext =
|
|
1344
|
+
var import_react5 = __toESM(require("react"), 1);
|
|
1345
|
+
var SelectContext = import_react5.default.createContext(null);
|
|
1310
1346
|
var context_default = SelectContext;
|
|
1311
1347
|
|
|
1312
1348
|
// src/components/Select/SelectItem.tsx
|
|
1313
|
-
var
|
|
1349
|
+
var import_react6 = __toESM(require("react"), 1);
|
|
1314
1350
|
var import_jsx_runtime296 = require("react/jsx-runtime");
|
|
1315
1351
|
var SelectItem = (props) => {
|
|
1316
1352
|
const { children, value, onClick, disabled = false } = props;
|
|
1317
|
-
const ctx =
|
|
1353
|
+
const ctx = import_react6.default.useContext(context_default);
|
|
1318
1354
|
const handleClick = (e) => {
|
|
1319
1355
|
e.preventDefault();
|
|
1320
1356
|
e.stopPropagation();
|
|
@@ -1364,29 +1400,29 @@ var SelectRoot = (props) => {
|
|
|
1364
1400
|
required,
|
|
1365
1401
|
size = "md"
|
|
1366
1402
|
} = props;
|
|
1367
|
-
const fieldId =
|
|
1368
|
-
const itemChildren =
|
|
1369
|
-
(child) =>
|
|
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
|
|
1370
1406
|
);
|
|
1371
1407
|
const isControlled = valueProp !== void 0;
|
|
1372
|
-
const [isOpen, setOpen] =
|
|
1373
|
-
const [uncontrolledLabel, setUncontrolledLabel] =
|
|
1374
|
-
const [uncontrolledValue, setUncontrolledValue] =
|
|
1375
|
-
const controlledLabel =
|
|
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(() => {
|
|
1376
1412
|
if (!isControlled) return null;
|
|
1377
1413
|
const match = itemChildren.find((child) => child.props.value === valueProp);
|
|
1378
1414
|
return match ? match.props.children : null;
|
|
1379
1415
|
}, [isControlled, valueProp, itemChildren]);
|
|
1380
1416
|
const selectedLabel = isControlled ? controlledLabel : uncontrolledLabel;
|
|
1381
1417
|
const selectedValue = isControlled ? valueProp : uncontrolledValue;
|
|
1382
|
-
const triggerRef =
|
|
1383
|
-
const contentRef =
|
|
1384
|
-
const [mounted, setMounted] =
|
|
1385
|
-
const [visible, setVisible] =
|
|
1386
|
-
|
|
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(() => {
|
|
1387
1423
|
if (disabled && isOpen) setOpen(false);
|
|
1388
1424
|
}, [disabled, isOpen]);
|
|
1389
|
-
|
|
1425
|
+
import_react7.default.useEffect(() => {
|
|
1390
1426
|
if (isOpen) {
|
|
1391
1427
|
setMounted(true);
|
|
1392
1428
|
const t2 = setTimeout(() => setVisible(true), 1);
|
|
@@ -1396,33 +1432,34 @@ var SelectRoot = (props) => {
|
|
|
1396
1432
|
const t = setTimeout(() => setMounted(false), ANIMATION_DURATION_MS);
|
|
1397
1433
|
return () => clearTimeout(t);
|
|
1398
1434
|
}, [isOpen]);
|
|
1399
|
-
const [query, setQuery] =
|
|
1435
|
+
const [query, setQuery] = import_react7.default.useState("");
|
|
1400
1436
|
const textOf = (node) => {
|
|
1401
1437
|
if (node === null || node === void 0 || typeof node === "boolean") return "";
|
|
1402
1438
|
if (typeof node === "string" || typeof node === "number") return String(node);
|
|
1403
1439
|
if (Array.isArray(node)) return node.map(textOf).join("");
|
|
1404
|
-
if (
|
|
1440
|
+
if (import_react7.default.isValidElement(node)) return textOf(node.props.children);
|
|
1405
1441
|
return "";
|
|
1406
1442
|
};
|
|
1407
|
-
const visibleItems =
|
|
1443
|
+
const visibleItems = import_react7.default.useMemo(() => {
|
|
1408
1444
|
if (!searchable || !query.trim()) return itemChildren;
|
|
1409
1445
|
const q = query.trim().toLowerCase();
|
|
1410
1446
|
return itemChildren.filter((c) => textOf(c.props.children).toLowerCase().includes(q));
|
|
1411
1447
|
}, [searchable, query, itemChildren]);
|
|
1412
|
-
const open =
|
|
1413
|
-
const close =
|
|
1448
|
+
const open = import_react7.default.useCallback(() => setOpen(true), []);
|
|
1449
|
+
const close = import_react7.default.useCallback(() => {
|
|
1414
1450
|
setOpen(false);
|
|
1415
1451
|
setQuery("");
|
|
1416
1452
|
}, []);
|
|
1417
|
-
const toggle =
|
|
1453
|
+
const toggle = import_react7.default.useCallback(() => setOpen((prev) => !prev), []);
|
|
1418
1454
|
useClickOutside_default([contentRef, triggerRef], close, isOpen);
|
|
1419
1455
|
useCloseWhenFocusHidden(isOpen, triggerRef, contentRef, close);
|
|
1420
1456
|
useEscapeKey(isOpen, () => {
|
|
1421
1457
|
close();
|
|
1422
1458
|
triggerRef.current?.focus({ preventScroll: true });
|
|
1423
1459
|
});
|
|
1460
|
+
const host = useOverlayHost_default(triggerRef, mounted);
|
|
1424
1461
|
useAutoPosition_default(triggerRef, contentRef, mounted);
|
|
1425
|
-
const setSelected =
|
|
1462
|
+
const setSelected = import_react7.default.useCallback(
|
|
1426
1463
|
(label2, itemValue) => {
|
|
1427
1464
|
if (!isControlled) {
|
|
1428
1465
|
setUncontrolledLabel(label2);
|
|
@@ -1432,7 +1469,7 @@ var SelectRoot = (props) => {
|
|
|
1432
1469
|
},
|
|
1433
1470
|
[isControlled, onChange]
|
|
1434
1471
|
);
|
|
1435
|
-
const ctxValue =
|
|
1472
|
+
const ctxValue = import_react7.default.useMemo(
|
|
1436
1473
|
() => ({
|
|
1437
1474
|
isOpen,
|
|
1438
1475
|
mounted,
|
|
@@ -1511,7 +1548,7 @@ var SelectRoot = (props) => {
|
|
|
1511
1548
|
]
|
|
1512
1549
|
}
|
|
1513
1550
|
),
|
|
1514
|
-
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)(
|
|
1515
1552
|
"div",
|
|
1516
1553
|
{
|
|
1517
1554
|
className: clsx_default("lib-xplat-select-content", size, stateClass),
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// src/components/Select/Select.tsx
|
|
2
|
-
import
|
|
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;
|
|
@@ -68,10 +68,16 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
|
|
|
68
68
|
const scrollParentRef = React.useRef(null);
|
|
69
69
|
const placedRef = React.useRef(false);
|
|
70
70
|
const frozenMaxRef = React.useRef(void 0);
|
|
71
|
+
const cssCapRef = React.useRef(void 0);
|
|
71
72
|
const calculatePosition = React.useCallback((remeasure = false) => {
|
|
72
73
|
const pop = popRef.current;
|
|
73
74
|
if (!triggerRef.current || !pop) return;
|
|
74
75
|
if (remeasure) frozenMaxRef.current = void 0;
|
|
76
|
+
if (cssCapRef.current === void 0) {
|
|
77
|
+
pop.style.maxHeight = "";
|
|
78
|
+
const raw = getComputedStyle(pop).maxHeight;
|
|
79
|
+
cssCapRef.current = raw === "none" ? null : Number.parseFloat(raw) || null;
|
|
80
|
+
}
|
|
75
81
|
if (remeasure || !sizeRef.current) {
|
|
76
82
|
sizeRef.current = {
|
|
77
83
|
w: pop.offsetWidth,
|
|
@@ -93,8 +99,10 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
|
|
|
93
99
|
};
|
|
94
100
|
const first = !placedRef.current;
|
|
95
101
|
if (first) pop.style.transition = "none";
|
|
102
|
+
const cap = cssCapRef.current;
|
|
103
|
+
const desiredH = cap == null ? popH : Math.min(popH, cap);
|
|
96
104
|
const frozen = frozenMaxRef.current;
|
|
97
|
-
const effectiveH = frozen == null ?
|
|
105
|
+
const effectiveH = frozen == null ? desiredH : Math.min(desiredH, frozen);
|
|
98
106
|
const { direction: next, top, left, over, maxHeight: suggested } = computePlacement(
|
|
99
107
|
triggerRect,
|
|
100
108
|
popW,
|
|
@@ -103,8 +111,9 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
|
|
|
103
111
|
);
|
|
104
112
|
if (frozenMaxRef.current === void 0) frozenMaxRef.current = suggested;
|
|
105
113
|
const maxHeight = frozenMaxRef.current;
|
|
106
|
-
|
|
107
|
-
pop.style.
|
|
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`;
|
|
108
117
|
pop.style.maxHeight = maxHeight === null ? "" : `${maxHeight}px`;
|
|
109
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";
|
|
110
119
|
directionRef.current = next;
|
|
@@ -122,6 +131,7 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
|
|
|
122
131
|
scrollParentRef.current = null;
|
|
123
132
|
placedRef.current = false;
|
|
124
133
|
frozenMaxRef.current = void 0;
|
|
134
|
+
cssCapRef.current = void 0;
|
|
125
135
|
return;
|
|
126
136
|
}
|
|
127
137
|
if (triggerRef.current) {
|
|
@@ -178,8 +188,34 @@ var useClickOutside = (refs, handler, enabled = true) => {
|
|
|
178
188
|
};
|
|
179
189
|
var useClickOutside_default = useClickOutside;
|
|
180
190
|
|
|
181
|
-
// src/tokens/hooks/
|
|
191
|
+
// src/tokens/hooks/useOverlayHost.ts
|
|
182
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";
|
|
183
219
|
var FOCUSABLE = [
|
|
184
220
|
"a[href]",
|
|
185
221
|
"button:not([disabled])",
|
|
@@ -189,7 +225,7 @@ var FOCUSABLE = [
|
|
|
189
225
|
"[tabindex]:not([tabindex='-1'])"
|
|
190
226
|
].join(",");
|
|
191
227
|
var useEscapeKey = (enabled, onEscape) => {
|
|
192
|
-
|
|
228
|
+
React4.useEffect(() => {
|
|
193
229
|
if (!enabled) return;
|
|
194
230
|
const onKey = (e) => {
|
|
195
231
|
if (e.key !== "Escape") return;
|
|
@@ -202,9 +238,9 @@ var useEscapeKey = (enabled, onEscape) => {
|
|
|
202
238
|
}, [enabled, onEscape]);
|
|
203
239
|
};
|
|
204
240
|
var useCloseWhenFocusHidden = (enabled, triggerRef, popRef, onClose) => {
|
|
205
|
-
const onCloseRef =
|
|
241
|
+
const onCloseRef = React4.useRef(onClose);
|
|
206
242
|
onCloseRef.current = onClose;
|
|
207
|
-
|
|
243
|
+
React4.useEffect(() => {
|
|
208
244
|
const trigger = triggerRef.current;
|
|
209
245
|
if (!enabled || !trigger) return;
|
|
210
246
|
const observer = new IntersectionObserver(
|
|
@@ -1268,16 +1304,16 @@ Field.displayName = "Field";
|
|
|
1268
1304
|
var hasError = (validations) => !!validations?.some((v) => v.status === "error");
|
|
1269
1305
|
|
|
1270
1306
|
// src/components/Select/context.ts
|
|
1271
|
-
import
|
|
1272
|
-
var SelectContext =
|
|
1307
|
+
import React5 from "react";
|
|
1308
|
+
var SelectContext = React5.createContext(null);
|
|
1273
1309
|
var context_default = SelectContext;
|
|
1274
1310
|
|
|
1275
1311
|
// src/components/Select/SelectItem.tsx
|
|
1276
|
-
import
|
|
1312
|
+
import React6 from "react";
|
|
1277
1313
|
import { jsx as jsx296 } from "react/jsx-runtime";
|
|
1278
1314
|
var SelectItem = (props) => {
|
|
1279
1315
|
const { children, value, onClick, disabled = false } = props;
|
|
1280
|
-
const ctx =
|
|
1316
|
+
const ctx = React6.useContext(context_default);
|
|
1281
1317
|
const handleClick = (e) => {
|
|
1282
1318
|
e.preventDefault();
|
|
1283
1319
|
e.stopPropagation();
|
|
@@ -1327,29 +1363,29 @@ var SelectRoot = (props) => {
|
|
|
1327
1363
|
required,
|
|
1328
1364
|
size = "md"
|
|
1329
1365
|
} = props;
|
|
1330
|
-
const fieldId =
|
|
1331
|
-
const itemChildren =
|
|
1332
|
-
(child) =>
|
|
1366
|
+
const fieldId = React7.useId();
|
|
1367
|
+
const itemChildren = React7.Children.toArray(children).filter(
|
|
1368
|
+
(child) => React7.isValidElement(child) && child.type === SelectItem_default
|
|
1333
1369
|
);
|
|
1334
1370
|
const isControlled = valueProp !== void 0;
|
|
1335
|
-
const [isOpen, setOpen] =
|
|
1336
|
-
const [uncontrolledLabel, setUncontrolledLabel] =
|
|
1337
|
-
const [uncontrolledValue, setUncontrolledValue] =
|
|
1338
|
-
const controlledLabel =
|
|
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(() => {
|
|
1339
1375
|
if (!isControlled) return null;
|
|
1340
1376
|
const match = itemChildren.find((child) => child.props.value === valueProp);
|
|
1341
1377
|
return match ? match.props.children : null;
|
|
1342
1378
|
}, [isControlled, valueProp, itemChildren]);
|
|
1343
1379
|
const selectedLabel = isControlled ? controlledLabel : uncontrolledLabel;
|
|
1344
1380
|
const selectedValue = isControlled ? valueProp : uncontrolledValue;
|
|
1345
|
-
const triggerRef =
|
|
1346
|
-
const contentRef =
|
|
1347
|
-
const [mounted, setMounted] =
|
|
1348
|
-
const [visible, setVisible] =
|
|
1349
|
-
|
|
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(() => {
|
|
1350
1386
|
if (disabled && isOpen) setOpen(false);
|
|
1351
1387
|
}, [disabled, isOpen]);
|
|
1352
|
-
|
|
1388
|
+
React7.useEffect(() => {
|
|
1353
1389
|
if (isOpen) {
|
|
1354
1390
|
setMounted(true);
|
|
1355
1391
|
const t2 = setTimeout(() => setVisible(true), 1);
|
|
@@ -1359,33 +1395,34 @@ var SelectRoot = (props) => {
|
|
|
1359
1395
|
const t = setTimeout(() => setMounted(false), ANIMATION_DURATION_MS);
|
|
1360
1396
|
return () => clearTimeout(t);
|
|
1361
1397
|
}, [isOpen]);
|
|
1362
|
-
const [query, setQuery] =
|
|
1398
|
+
const [query, setQuery] = React7.useState("");
|
|
1363
1399
|
const textOf = (node) => {
|
|
1364
1400
|
if (node === null || node === void 0 || typeof node === "boolean") return "";
|
|
1365
1401
|
if (typeof node === "string" || typeof node === "number") return String(node);
|
|
1366
1402
|
if (Array.isArray(node)) return node.map(textOf).join("");
|
|
1367
|
-
if (
|
|
1403
|
+
if (React7.isValidElement(node)) return textOf(node.props.children);
|
|
1368
1404
|
return "";
|
|
1369
1405
|
};
|
|
1370
|
-
const visibleItems =
|
|
1406
|
+
const visibleItems = React7.useMemo(() => {
|
|
1371
1407
|
if (!searchable || !query.trim()) return itemChildren;
|
|
1372
1408
|
const q = query.trim().toLowerCase();
|
|
1373
1409
|
return itemChildren.filter((c) => textOf(c.props.children).toLowerCase().includes(q));
|
|
1374
1410
|
}, [searchable, query, itemChildren]);
|
|
1375
|
-
const open =
|
|
1376
|
-
const close =
|
|
1411
|
+
const open = React7.useCallback(() => setOpen(true), []);
|
|
1412
|
+
const close = React7.useCallback(() => {
|
|
1377
1413
|
setOpen(false);
|
|
1378
1414
|
setQuery("");
|
|
1379
1415
|
}, []);
|
|
1380
|
-
const toggle =
|
|
1416
|
+
const toggle = React7.useCallback(() => setOpen((prev) => !prev), []);
|
|
1381
1417
|
useClickOutside_default([contentRef, triggerRef], close, isOpen);
|
|
1382
1418
|
useCloseWhenFocusHidden(isOpen, triggerRef, contentRef, close);
|
|
1383
1419
|
useEscapeKey(isOpen, () => {
|
|
1384
1420
|
close();
|
|
1385
1421
|
triggerRef.current?.focus({ preventScroll: true });
|
|
1386
1422
|
});
|
|
1423
|
+
const host = useOverlayHost_default(triggerRef, mounted);
|
|
1387
1424
|
useAutoPosition_default(triggerRef, contentRef, mounted);
|
|
1388
|
-
const setSelected =
|
|
1425
|
+
const setSelected = React7.useCallback(
|
|
1389
1426
|
(label2, itemValue) => {
|
|
1390
1427
|
if (!isControlled) {
|
|
1391
1428
|
setUncontrolledLabel(label2);
|
|
@@ -1395,7 +1432,7 @@ var SelectRoot = (props) => {
|
|
|
1395
1432
|
},
|
|
1396
1433
|
[isControlled, onChange]
|
|
1397
1434
|
);
|
|
1398
|
-
const ctxValue =
|
|
1435
|
+
const ctxValue = React7.useMemo(
|
|
1399
1436
|
() => ({
|
|
1400
1437
|
isOpen,
|
|
1401
1438
|
mounted,
|
|
@@ -1474,7 +1511,7 @@ var SelectRoot = (props) => {
|
|
|
1474
1511
|
]
|
|
1475
1512
|
}
|
|
1476
1513
|
),
|
|
1477
|
-
mounted && /* @__PURE__ */ jsx297(Portal_default, { children: /* @__PURE__ */ jsxs190(
|
|
1514
|
+
mounted && /* @__PURE__ */ jsx297(Portal_default, { container: host, children: /* @__PURE__ */ jsxs190(
|
|
1478
1515
|
"div",
|
|
1479
1516
|
{
|
|
1480
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
|
|
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;
|
|
@@ -104,10 +104,16 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
|
|
|
104
104
|
const scrollParentRef = import_react.default.useRef(null);
|
|
105
105
|
const placedRef = import_react.default.useRef(false);
|
|
106
106
|
const frozenMaxRef = import_react.default.useRef(void 0);
|
|
107
|
+
const cssCapRef = import_react.default.useRef(void 0);
|
|
107
108
|
const calculatePosition = import_react.default.useCallback((remeasure = false) => {
|
|
108
109
|
const pop = popRef.current;
|
|
109
110
|
if (!triggerRef.current || !pop) return;
|
|
110
111
|
if (remeasure) frozenMaxRef.current = void 0;
|
|
112
|
+
if (cssCapRef.current === void 0) {
|
|
113
|
+
pop.style.maxHeight = "";
|
|
114
|
+
const raw = getComputedStyle(pop).maxHeight;
|
|
115
|
+
cssCapRef.current = raw === "none" ? null : Number.parseFloat(raw) || null;
|
|
116
|
+
}
|
|
111
117
|
if (remeasure || !sizeRef.current) {
|
|
112
118
|
sizeRef.current = {
|
|
113
119
|
w: pop.offsetWidth,
|
|
@@ -129,8 +135,10 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
|
|
|
129
135
|
};
|
|
130
136
|
const first = !placedRef.current;
|
|
131
137
|
if (first) pop.style.transition = "none";
|
|
138
|
+
const cap = cssCapRef.current;
|
|
139
|
+
const desiredH = cap == null ? popH : Math.min(popH, cap);
|
|
132
140
|
const frozen = frozenMaxRef.current;
|
|
133
|
-
const effectiveH = frozen == null ?
|
|
141
|
+
const effectiveH = frozen == null ? desiredH : Math.min(desiredH, frozen);
|
|
134
142
|
const { direction: next, top, left, over, maxHeight: suggested } = computePlacement(
|
|
135
143
|
triggerRect,
|
|
136
144
|
popW,
|
|
@@ -139,8 +147,9 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
|
|
|
139
147
|
);
|
|
140
148
|
if (frozenMaxRef.current === void 0) frozenMaxRef.current = suggested;
|
|
141
149
|
const maxHeight = frozenMaxRef.current;
|
|
142
|
-
|
|
143
|
-
pop.style.
|
|
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`;
|
|
144
153
|
pop.style.maxHeight = maxHeight === null ? "" : `${maxHeight}px`;
|
|
145
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";
|
|
146
155
|
directionRef.current = next;
|
|
@@ -158,6 +167,7 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
|
|
|
158
167
|
scrollParentRef.current = null;
|
|
159
168
|
placedRef.current = false;
|
|
160
169
|
frozenMaxRef.current = void 0;
|
|
170
|
+
cssCapRef.current = void 0;
|
|
161
171
|
return;
|
|
162
172
|
}
|
|
163
173
|
if (triggerRef.current) {
|
|
@@ -214,8 +224,34 @@ var useClickOutside = (refs, handler, enabled = true) => {
|
|
|
214
224
|
};
|
|
215
225
|
var useClickOutside_default = useClickOutside;
|
|
216
226
|
|
|
217
|
-
// src/tokens/hooks/
|
|
227
|
+
// src/tokens/hooks/useOverlayHost.ts
|
|
218
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);
|
|
219
255
|
var FOCUSABLE = [
|
|
220
256
|
"a[href]",
|
|
221
257
|
"button:not([disabled])",
|
|
@@ -225,7 +261,7 @@ var FOCUSABLE = [
|
|
|
225
261
|
"[tabindex]:not([tabindex='-1'])"
|
|
226
262
|
].join(",");
|
|
227
263
|
var useEscapeKey = (enabled, onEscape) => {
|
|
228
|
-
|
|
264
|
+
import_react4.default.useEffect(() => {
|
|
229
265
|
if (!enabled) return;
|
|
230
266
|
const onKey = (e) => {
|
|
231
267
|
if (e.key !== "Escape") return;
|
|
@@ -238,9 +274,9 @@ var useEscapeKey = (enabled, onEscape) => {
|
|
|
238
274
|
}, [enabled, onEscape]);
|
|
239
275
|
};
|
|
240
276
|
var useCloseWhenFocusHidden = (enabled, triggerRef, popRef, onClose) => {
|
|
241
|
-
const onCloseRef =
|
|
277
|
+
const onCloseRef = import_react4.default.useRef(onClose);
|
|
242
278
|
onCloseRef.current = onClose;
|
|
243
|
-
|
|
279
|
+
import_react4.default.useEffect(() => {
|
|
244
280
|
const trigger = triggerRef.current;
|
|
245
281
|
if (!enabled || !trigger) return;
|
|
246
282
|
const observer = new IntersectionObserver(
|
|
@@ -450,13 +486,13 @@ var TimePicker = (props) => {
|
|
|
450
486
|
required,
|
|
451
487
|
validations
|
|
452
488
|
} = props;
|
|
453
|
-
const fieldId =
|
|
454
|
-
const triggerRef =
|
|
455
|
-
const contentRef =
|
|
456
|
-
const [isOpen, setOpen] =
|
|
457
|
-
const [mounted, setMounted] =
|
|
458
|
-
const [visible, setVisible] =
|
|
459
|
-
const options =
|
|
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(() => {
|
|
460
496
|
const safeStep = step > 0 && step <= 720 ? step : 30;
|
|
461
497
|
const lo = toMinutes(min) ?? 0;
|
|
462
498
|
const hi = toMinutes(max) ?? 24 * 60 - 1;
|
|
@@ -464,18 +500,19 @@ var TimePicker = (props) => {
|
|
|
464
500
|
for (let t = lo; t <= hi; t += safeStep) out.push(toHHmm(t));
|
|
465
501
|
return out;
|
|
466
502
|
}, [step, min, max]);
|
|
467
|
-
const close =
|
|
503
|
+
const close = import_react5.default.useCallback(() => setOpen(false), []);
|
|
468
504
|
useClickOutside_default([triggerRef, contentRef], close, isOpen);
|
|
469
505
|
useCloseWhenFocusHidden(isOpen, triggerRef, contentRef, close);
|
|
470
506
|
useEscapeKey(isOpen, () => {
|
|
471
507
|
close();
|
|
472
508
|
triggerRef.current?.focus({ preventScroll: true });
|
|
473
509
|
});
|
|
510
|
+
const host = useOverlayHost_default(triggerRef, mounted);
|
|
474
511
|
useAutoPosition_default(triggerRef, contentRef, mounted);
|
|
475
|
-
|
|
512
|
+
import_react5.default.useEffect(() => {
|
|
476
513
|
if (disabled && isOpen) setOpen(false);
|
|
477
514
|
}, [disabled, isOpen]);
|
|
478
|
-
|
|
515
|
+
import_react5.default.useEffect(() => {
|
|
479
516
|
if (isOpen) {
|
|
480
517
|
setMounted(true);
|
|
481
518
|
const t2 = setTimeout(() => setVisible(true), 1);
|
|
@@ -513,7 +550,7 @@ var TimePicker = (props) => {
|
|
|
513
550
|
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: clsx_default("time-picker-value", !value && "placeholder"), children: value ? display(value, use12Hours) : placeholder })
|
|
514
551
|
}
|
|
515
552
|
),
|
|
516
|
-
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)(
|
|
517
554
|
"div",
|
|
518
555
|
{
|
|
519
556
|
ref: contentRef,
|