@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
|
@@ -35,13 +35,13 @@ __export(Dropdown_exports, {
|
|
|
35
35
|
module.exports = __toCommonJS(Dropdown_exports);
|
|
36
36
|
|
|
37
37
|
// src/components/Dropdown/Dropdown.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(
|
|
@@ -278,11 +314,12 @@ var clsx_default = clsx;
|
|
|
278
314
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
279
315
|
var Dropdown = (props) => {
|
|
280
316
|
const { items, children } = props;
|
|
281
|
-
const [isOpen, setIsOpen] =
|
|
282
|
-
const [mounted, setMounted] =
|
|
283
|
-
const [visible, setVisible] =
|
|
284
|
-
const triggerRef =
|
|
285
|
-
const menuRef =
|
|
317
|
+
const [isOpen, setIsOpen] = import_react5.default.useState(false);
|
|
318
|
+
const [mounted, setMounted] = import_react5.default.useState(false);
|
|
319
|
+
const [visible, setVisible] = import_react5.default.useState(false);
|
|
320
|
+
const triggerRef = import_react5.default.useRef(null);
|
|
321
|
+
const menuRef = import_react5.default.useRef(null);
|
|
322
|
+
const host = useOverlayHost_default(triggerRef, mounted);
|
|
286
323
|
useAutoPosition_default(triggerRef, menuRef, mounted);
|
|
287
324
|
useClickOutside_default([triggerRef, menuRef], () => setIsOpen(false), isOpen);
|
|
288
325
|
useCloseWhenFocusHidden(isOpen, triggerRef, menuRef, () => setIsOpen(false));
|
|
@@ -290,7 +327,7 @@ var Dropdown = (props) => {
|
|
|
290
327
|
setIsOpen(false);
|
|
291
328
|
triggerRef.current?.focus({ preventScroll: true });
|
|
292
329
|
});
|
|
293
|
-
|
|
330
|
+
import_react5.default.useEffect(() => {
|
|
294
331
|
if (isOpen) {
|
|
295
332
|
setMounted(true);
|
|
296
333
|
const t2 = setTimeout(() => setVisible(true), 1);
|
|
@@ -315,7 +352,7 @@ var Dropdown = (props) => {
|
|
|
315
352
|
children
|
|
316
353
|
}
|
|
317
354
|
),
|
|
318
|
-
mounted && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Portal_default, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
355
|
+
mounted && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Portal_default, { container: host, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
319
356
|
"div",
|
|
320
357
|
{
|
|
321
358
|
ref: menuRef,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// src/components/Dropdown/Dropdown.tsx
|
|
2
|
-
import
|
|
2
|
+
import React5 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(
|
|
@@ -242,11 +278,12 @@ var clsx_default = clsx;
|
|
|
242
278
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
243
279
|
var Dropdown = (props) => {
|
|
244
280
|
const { items, children } = props;
|
|
245
|
-
const [isOpen, setIsOpen] =
|
|
246
|
-
const [mounted, setMounted] =
|
|
247
|
-
const [visible, setVisible] =
|
|
248
|
-
const triggerRef =
|
|
249
|
-
const menuRef =
|
|
281
|
+
const [isOpen, setIsOpen] = React5.useState(false);
|
|
282
|
+
const [mounted, setMounted] = React5.useState(false);
|
|
283
|
+
const [visible, setVisible] = React5.useState(false);
|
|
284
|
+
const triggerRef = React5.useRef(null);
|
|
285
|
+
const menuRef = React5.useRef(null);
|
|
286
|
+
const host = useOverlayHost_default(triggerRef, mounted);
|
|
250
287
|
useAutoPosition_default(triggerRef, menuRef, mounted);
|
|
251
288
|
useClickOutside_default([triggerRef, menuRef], () => setIsOpen(false), isOpen);
|
|
252
289
|
useCloseWhenFocusHidden(isOpen, triggerRef, menuRef, () => setIsOpen(false));
|
|
@@ -254,7 +291,7 @@ var Dropdown = (props) => {
|
|
|
254
291
|
setIsOpen(false);
|
|
255
292
|
triggerRef.current?.focus({ preventScroll: true });
|
|
256
293
|
});
|
|
257
|
-
|
|
294
|
+
React5.useEffect(() => {
|
|
258
295
|
if (isOpen) {
|
|
259
296
|
setMounted(true);
|
|
260
297
|
const t2 = setTimeout(() => setVisible(true), 1);
|
|
@@ -279,7 +316,7 @@ var Dropdown = (props) => {
|
|
|
279
316
|
children
|
|
280
317
|
}
|
|
281
318
|
),
|
|
282
|
-
mounted && /* @__PURE__ */ jsx(Portal_default, { children: /* @__PURE__ */ jsx(
|
|
319
|
+
mounted && /* @__PURE__ */ jsx(Portal_default, { container: host, children: /* @__PURE__ */ jsx(
|
|
283
320
|
"div",
|
|
284
321
|
{
|
|
285
322
|
ref: menuRef,
|
|
@@ -35,13 +35,13 @@ __export(PopOver_exports, {
|
|
|
35
35
|
module.exports = __toCommonJS(PopOver_exports);
|
|
36
36
|
|
|
37
37
|
// src/components/PopOver/PopOver.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(
|
|
@@ -278,18 +314,19 @@ var clsx_default = clsx;
|
|
|
278
314
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
279
315
|
var PopOver = (props) => {
|
|
280
316
|
const { children, isOpen, onClose, PopOverEl } = props;
|
|
281
|
-
const popRef =
|
|
282
|
-
const triggerRef =
|
|
283
|
-
const [localOpen, setLocalOpen] =
|
|
284
|
-
const [eventTrigger, setEventTrigger] =
|
|
317
|
+
const popRef = import_react5.default.useRef(null);
|
|
318
|
+
const triggerRef = import_react5.default.useRef(null);
|
|
319
|
+
const [localOpen, setLocalOpen] = import_react5.default.useState(false);
|
|
320
|
+
const [eventTrigger, setEventTrigger] = import_react5.default.useState(false);
|
|
285
321
|
useClickOutside_default([popRef, triggerRef], onClose, isOpen);
|
|
286
322
|
useCloseWhenFocusHidden(isOpen, triggerRef, popRef, onClose);
|
|
287
323
|
useEscapeKey(isOpen, () => {
|
|
288
324
|
onClose();
|
|
289
325
|
triggerRef.current?.focus({ preventScroll: true });
|
|
290
326
|
});
|
|
327
|
+
const host = useOverlayHost_default(triggerRef, localOpen);
|
|
291
328
|
useAutoPosition_default(triggerRef, popRef, localOpen);
|
|
292
|
-
|
|
329
|
+
import_react5.default.useEffect(() => {
|
|
293
330
|
if (isOpen) {
|
|
294
331
|
setLocalOpen(isOpen);
|
|
295
332
|
setTimeout(() => {
|
|
@@ -312,7 +349,7 @@ var PopOver = (props) => {
|
|
|
312
349
|
},
|
|
313
350
|
children: [
|
|
314
351
|
children,
|
|
315
|
-
localOpen && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Portal_default, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
352
|
+
localOpen && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Portal_default, { container: host, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
316
353
|
"div",
|
|
317
354
|
{
|
|
318
355
|
className: clsx_default(
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// src/components/PopOver/PopOver.tsx
|
|
2
|
-
import
|
|
2
|
+
import React5 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(
|
|
@@ -242,18 +278,19 @@ var clsx_default = clsx;
|
|
|
242
278
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
243
279
|
var PopOver = (props) => {
|
|
244
280
|
const { children, isOpen, onClose, PopOverEl } = props;
|
|
245
|
-
const popRef =
|
|
246
|
-
const triggerRef =
|
|
247
|
-
const [localOpen, setLocalOpen] =
|
|
248
|
-
const [eventTrigger, setEventTrigger] =
|
|
281
|
+
const popRef = React5.useRef(null);
|
|
282
|
+
const triggerRef = React5.useRef(null);
|
|
283
|
+
const [localOpen, setLocalOpen] = React5.useState(false);
|
|
284
|
+
const [eventTrigger, setEventTrigger] = React5.useState(false);
|
|
249
285
|
useClickOutside_default([popRef, triggerRef], onClose, isOpen);
|
|
250
286
|
useCloseWhenFocusHidden(isOpen, triggerRef, popRef, onClose);
|
|
251
287
|
useEscapeKey(isOpen, () => {
|
|
252
288
|
onClose();
|
|
253
289
|
triggerRef.current?.focus({ preventScroll: true });
|
|
254
290
|
});
|
|
291
|
+
const host = useOverlayHost_default(triggerRef, localOpen);
|
|
255
292
|
useAutoPosition_default(triggerRef, popRef, localOpen);
|
|
256
|
-
|
|
293
|
+
React5.useEffect(() => {
|
|
257
294
|
if (isOpen) {
|
|
258
295
|
setLocalOpen(isOpen);
|
|
259
296
|
setTimeout(() => {
|
|
@@ -276,7 +313,7 @@ var PopOver = (props) => {
|
|
|
276
313
|
},
|
|
277
314
|
children: [
|
|
278
315
|
children,
|
|
279
|
-
localOpen && /* @__PURE__ */ jsx(Portal_default, { children: /* @__PURE__ */ jsx(
|
|
316
|
+
localOpen && /* @__PURE__ */ jsx(Portal_default, { container: host, children: /* @__PURE__ */ jsx(
|
|
280
317
|
"div",
|
|
281
318
|
{
|
|
282
319
|
className: clsx_default(
|