haze-ui 1.22.0 → 1.24.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/README.md +7 -0
- package/dist/components/BottomSheet/BottomSheet.js +33 -16
- package/dist/components/Collapsible/Collapsible.js +34 -27
- package/dist/components/Combobox/Combobox.js +2 -1
- package/dist/components/ConfirmDialog/ConfirmDialog.js +60 -42
- package/dist/components/ContextMenu/ContextMenu.js +2 -1
- package/dist/components/ContextMenu/ContextMenuContent.js +33 -23
- package/dist/components/Datepicker/DatepickerCore.js +2 -1
- package/dist/components/Dialog/Dialog.js +40 -21
- package/dist/components/Drawer/Drawer.js +37 -18
- package/dist/components/DropdownMenu/DropdownMenu.js +27 -25
- package/dist/components/DropdownMenu/DropdownMenuContent.js +2 -2
- package/dist/components/Menu/Menu.js +43 -35
- package/dist/components/Popover/Popover.js +27 -25
- package/dist/components/Toast/Toast.js +25 -20
- package/dist/components/Toast/ToastContainer.js +31 -24
- package/dist/components/Tooltip/Tooltip.js +37 -34
- package/dist/css/alert.css +1 -1
- package/dist/css/approval-card.css +1 -1
- package/dist/css/async-section.css +1 -1
- package/dist/css/badge.css +1 -1
- package/dist/css/banner.css +1 -1
- package/dist/css/bottom-sheet.css +1 -1
- package/dist/css/chat-message.css +1 -1
- package/dist/css/code-block.css +1 -1
- package/dist/css/collapsible.css +1 -1
- package/dist/css/combobox.css +1 -1
- package/dist/css/confirm-dialog.css +1 -1
- package/dist/css/context-menu.css +2 -2
- package/dist/css/conversation-list.css +1 -1
- package/dist/css/datepicker.css +1 -1
- package/dist/css/dialog.css +1 -1
- package/dist/css/diff-viewer.css +1 -1
- package/dist/css/drawer.css +1 -1
- package/dist/css/dropdown-menu.css +2 -2
- package/dist/css/inline-edit.css +1 -1
- package/dist/css/log-viewer.css +1 -1
- package/dist/css/markdown-renderer.css +1 -1
- package/dist/css/menu.css +1 -1
- package/dist/css/navigation-bar.css +1 -1
- package/dist/css/popover.css +1 -1
- package/dist/css/step-timeline.css +1 -1
- package/dist/css/tag-group.css +1 -1
- package/dist/css/tag-input.css +1 -1
- package/dist/css/tag.css +1 -1
- package/dist/css/toast.css +1 -1
- package/dist/css/token-counter.css +1 -1
- package/dist/css/tokens.css +2 -1
- package/dist/css/tool-call-card.css +1 -1
- package/dist/css/tooltip.css +1 -1
- package/dist/haze-ui.css +36 -35
- package/dist/tokens/index.js +4 -1
- package/dist/tokens/motion.js +6 -0
- package/dist/tokens/oklch.js +117 -0
- package/dist/tokens/palette.js +327 -0
- package/dist/tokens/registry.js +154 -145
- package/dist/types/components/BottomSheet/BottomSheet.d.ts +3 -3
- package/dist/types/components/Collapsible/Collapsible.d.ts +1 -1
- package/dist/types/components/ConfirmDialog/ConfirmDialog.d.ts +3 -3
- package/dist/types/components/DropdownMenu/DropdownMenu.d.ts +7 -1
- package/dist/types/components/Popover/Popover.d.ts +7 -1
- package/dist/types/components/Toast/Toast.d.ts +3 -3
- package/dist/types/components/Tooltip/Tooltip.d.ts +4 -1
- package/dist/types/tokens/index.d.ts +5 -0
- package/dist/types/tokens/motion.d.ts +1 -0
- package/dist/types/tokens/oklch.d.ts +35 -0
- package/dist/types/tokens/palette.d.ts +28 -0
- package/dist/types/utils/collision.d.ts +62 -0
- package/dist/types/utils/floating.d.ts +95 -19
- package/dist/types/utils/focus-scope.d.ts +25 -0
- package/dist/types/utils/focus.d.ts +23 -0
- package/dist/types/utils/presence.d.ts +22 -0
- package/dist/utils/collision.js +73 -0
- package/dist/utils/floating.js +195 -150
- package/dist/utils/focus-scope.js +63 -0
- package/dist/utils/focus.js +34 -0
- package/dist/utils/presence.js +72 -0
- package/package.json +4 -2
package/dist/utils/floating.js
CHANGED
|
@@ -1,203 +1,248 @@
|
|
|
1
1
|
|
|
2
2
|
import { classnames as e } from "./classnames.js";
|
|
3
|
+
import { whenExitSettles as t } from "./presence.js";
|
|
4
|
+
import { computeFloatingPosition as n, resolvePadding as r } from "./collision.js";
|
|
3
5
|
/* empty css */
|
|
4
|
-
import { jsx as
|
|
5
|
-
import { useCallback as
|
|
6
|
+
import { jsx as i } from "react/jsx-runtime";
|
|
7
|
+
import { useCallback as a, useEffect as o, useId as s, useRef as c, useState as l } from "react";
|
|
6
8
|
//#region src/lib/utils/floating.tsx
|
|
7
|
-
var
|
|
8
|
-
function
|
|
9
|
+
var u = 500;
|
|
10
|
+
function d() {
|
|
9
11
|
return typeof HTMLElement < "u" && "popover" in HTMLElement.prototype;
|
|
10
12
|
}
|
|
11
|
-
function
|
|
12
|
-
return
|
|
13
|
+
function f() {
|
|
14
|
+
return d() && typeof CSS < "u" && typeof CSS.supports == "function" && CSS.supports("anchor-name: --haze-floating-probe");
|
|
13
15
|
}
|
|
14
|
-
var
|
|
15
|
-
bottom:
|
|
16
|
-
"bottom-span":
|
|
17
|
-
"bottom-center":
|
|
18
|
-
"bottom-end":
|
|
19
|
-
top:
|
|
20
|
-
left:
|
|
21
|
-
right:
|
|
22
|
-
},
|
|
23
|
-
bottom:
|
|
24
|
-
"bottom-span":
|
|
25
|
-
"bottom-center":
|
|
26
|
-
"bottom-end": w,
|
|
27
|
-
top: T,
|
|
28
|
-
left: E,
|
|
29
|
-
right: D
|
|
30
|
-
}, P = {
|
|
31
|
-
bottom: O,
|
|
32
|
-
"bottom-span": O,
|
|
33
|
-
"bottom-center": O,
|
|
16
|
+
var p = "haze-floating__floatingNative", m = "haze-floating__floatingAnchored", h = "haze-floating__floatingFixed", g = "haze-floating__floatingHidden", _ = "haze-floating__floatingAnimated", v = "haze-floating__anchoredBottom", y = "haze-floating__anchoredBottomSpan", b = "haze-floating__anchoredBottomCenter", x = "haze-floating__anchoredBottomEnd", S = "haze-floating__anchoredTop", C = "haze-floating__anchoredLeft", w = "haze-floating__anchoredRight", T = "haze-floating__fallbackBottom", E = T, D = "haze-floating__fallbackBottomCenter", O = "haze-floating__fallbackBottomEnd", k = "haze-floating__fallbackTop", A = "haze-floating__fallbackLeft", j = "haze-floating__fallbackRight", M = "haze-floating__gapBelow", N = "haze-floating__gapAbove", P = "haze-floating__gapBefore", F = "haze-floating__gapAfter", I = {
|
|
17
|
+
bottom: v,
|
|
18
|
+
"bottom-span": y,
|
|
19
|
+
"bottom-center": b,
|
|
20
|
+
"bottom-end": x,
|
|
21
|
+
top: S,
|
|
22
|
+
left: C,
|
|
23
|
+
right: w
|
|
24
|
+
}, L = {
|
|
25
|
+
bottom: T,
|
|
26
|
+
"bottom-span": E,
|
|
27
|
+
"bottom-center": D,
|
|
34
28
|
"bottom-end": O,
|
|
35
29
|
top: k,
|
|
36
30
|
left: A,
|
|
37
31
|
right: j
|
|
32
|
+
}, R = {
|
|
33
|
+
bottom: M,
|
|
34
|
+
"bottom-span": M,
|
|
35
|
+
"bottom-center": M,
|
|
36
|
+
"bottom-end": M,
|
|
37
|
+
top: N,
|
|
38
|
+
left: P,
|
|
39
|
+
right: F
|
|
38
40
|
};
|
|
39
|
-
function
|
|
40
|
-
let
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
41
|
+
function z({ open: e, setOpen: n, triggerRef: r, panelRef: i, animated: g, collision: _ }) {
|
|
42
|
+
let v = `--haze-floating-${s().replace(/[^a-zA-Z0-9]/g, "")}`, y = d(), b = f(), [x, S] = l(!e);
|
|
43
|
+
o(() => {
|
|
44
|
+
e && S(!1);
|
|
45
|
+
}, [e]);
|
|
46
|
+
let C = c(!1), [w, T] = l(!1), E = c(null), D = c(-Infinity), O = c(-Infinity), k = c(null);
|
|
47
|
+
o(() => {
|
|
48
|
+
let r = i.current;
|
|
49
|
+
if (!r || !y) return;
|
|
50
|
+
r !== E.current && (E.current = r, C.current = !1, T(!1));
|
|
51
|
+
let a = !0, o = () => {
|
|
52
|
+
k.current = { el: r }, r.hidePopover();
|
|
53
|
+
}, s = () => {
|
|
54
|
+
if (!(!C.current || r !== i.current)) {
|
|
55
|
+
if (g) {
|
|
56
|
+
let e = () => {
|
|
57
|
+
!a || !C.current || r !== i.current || o();
|
|
58
|
+
}, n = t(r);
|
|
59
|
+
n ? n.then(e) : e();
|
|
60
|
+
} else o();
|
|
61
|
+
}
|
|
62
|
+
}, c = (t) => {
|
|
63
|
+
let i = t.newState;
|
|
64
|
+
if (C.current = i === "open", T(C.current), i === "closed") {
|
|
65
|
+
g && S(!0);
|
|
66
|
+
let t = k.current?.el === r;
|
|
67
|
+
if (k.current = null, t) {
|
|
68
|
+
e && r.showPopover();
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
e && (performance.now() - D.current < u && (O.current = performance.now()), D.current = -Infinity, n(!1));
|
|
72
|
+
} else e || s();
|
|
73
|
+
};
|
|
74
|
+
return r.addEventListener("toggle", c), e ? C.current || r.showPopover() : s(), () => {
|
|
75
|
+
a = !1, r.removeEventListener("toggle", c);
|
|
48
76
|
};
|
|
49
|
-
return n.addEventListener("toggle", r), e && !y.current ? n.showPopover() : !e && y.current && n.hidePopover(), () => n.removeEventListener("toggle", r);
|
|
50
77
|
}, [
|
|
51
|
-
|
|
78
|
+
y,
|
|
52
79
|
e,
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
80
|
+
n,
|
|
81
|
+
i,
|
|
82
|
+
g
|
|
83
|
+
]), o(() => {
|
|
84
|
+
if (y || !e) return;
|
|
85
|
+
let t = (e) => e instanceof Node && !!(r.current?.contains(e) || i.current?.contains(e)), a = (e) => {
|
|
86
|
+
t(e.target) || n(!1);
|
|
87
|
+
}, o = (e) => {
|
|
88
|
+
e.key === "Escape" && n(!1);
|
|
61
89
|
};
|
|
62
|
-
return document.addEventListener("pointerdown",
|
|
63
|
-
document.removeEventListener("pointerdown",
|
|
90
|
+
return document.addEventListener("pointerdown", a), document.addEventListener("keydown", o), () => {
|
|
91
|
+
document.removeEventListener("pointerdown", a), document.removeEventListener("keydown", o);
|
|
64
92
|
};
|
|
65
93
|
}, [
|
|
66
|
-
|
|
94
|
+
y,
|
|
67
95
|
e,
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
96
|
+
n,
|
|
97
|
+
r,
|
|
98
|
+
i
|
|
99
|
+
]), o(() => {
|
|
100
|
+
if (y || !g || e || x) return;
|
|
101
|
+
let n = !0, r = i.current, a = r ? t(r) : null, o = () => {
|
|
102
|
+
n && S(!0);
|
|
103
|
+
};
|
|
104
|
+
return a ? a.then(o) : o(), () => {
|
|
105
|
+
n = !1;
|
|
106
|
+
};
|
|
107
|
+
}, [
|
|
108
|
+
y,
|
|
109
|
+
g,
|
|
110
|
+
e,
|
|
111
|
+
x,
|
|
112
|
+
i
|
|
71
113
|
]);
|
|
72
|
-
let
|
|
73
|
-
e && (
|
|
74
|
-
}, [e]),
|
|
75
|
-
if (performance.now() -
|
|
76
|
-
|
|
114
|
+
let A = a(() => {
|
|
115
|
+
e && (D.current = performance.now());
|
|
116
|
+
}, [e]), j = a(() => {
|
|
117
|
+
if (performance.now() - O.current < u) {
|
|
118
|
+
O.current = -Infinity;
|
|
77
119
|
return;
|
|
78
120
|
}
|
|
79
|
-
|
|
80
|
-
}, [
|
|
121
|
+
n((e) => !e);
|
|
122
|
+
}, [n]);
|
|
81
123
|
return {
|
|
82
124
|
open: e,
|
|
83
|
-
native:
|
|
84
|
-
anchored:
|
|
85
|
-
shown:
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
125
|
+
native: y,
|
|
126
|
+
anchored: b,
|
|
127
|
+
shown: y ? w : e,
|
|
128
|
+
dataState: g ? e ? "open" : "closed" : void 0,
|
|
129
|
+
exited: g ? x : !e,
|
|
130
|
+
collision: _,
|
|
131
|
+
anchorName: v,
|
|
132
|
+
triggerStyle: b ? { anchorName: v } : void 0,
|
|
133
|
+
onTriggerPointerDown: A,
|
|
134
|
+
onTriggerClick: j,
|
|
90
135
|
panelAttrs: {
|
|
91
|
-
popover:
|
|
92
|
-
style:
|
|
136
|
+
popover: y ? "auto" : void 0,
|
|
137
|
+
style: b ? { "--haze-floating-anchor": v } : void 0
|
|
93
138
|
},
|
|
94
139
|
panelClasses: [
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
!
|
|
140
|
+
y && p,
|
|
141
|
+
y && b && m,
|
|
142
|
+
y && !b && h,
|
|
143
|
+
!y && !e && (!g || x) && "haze-floating__floatingHidden",
|
|
144
|
+
!!g && "haze-floating__floatingAnimated"
|
|
99
145
|
],
|
|
100
|
-
triggerRef:
|
|
101
|
-
panelRef:
|
|
146
|
+
triggerRef: r,
|
|
147
|
+
panelRef: i
|
|
102
148
|
};
|
|
103
149
|
}
|
|
104
|
-
function
|
|
150
|
+
function B(e, t) {
|
|
105
151
|
return t === "point" ? [] : [
|
|
106
|
-
e.native && e.anchored &&
|
|
107
|
-
e.native && !e.anchored &&
|
|
108
|
-
!e.native &&
|
|
152
|
+
e.native && e.anchored && I[t],
|
|
153
|
+
e.native && !e.anchored && R[t],
|
|
154
|
+
!e.native && L[t]
|
|
109
155
|
];
|
|
110
156
|
}
|
|
111
|
-
function
|
|
157
|
+
function V(e, t) {
|
|
112
158
|
return parseFloat(getComputedStyle(e)[t]) || 0;
|
|
113
159
|
}
|
|
114
|
-
function
|
|
115
|
-
|
|
116
|
-
|
|
160
|
+
function H(e, t, n, r, i) {
|
|
161
|
+
let a = r, o = Math.max(a, n - i - t);
|
|
162
|
+
return Math.min(Math.max(e, a), o) - e;
|
|
163
|
+
}
|
|
164
|
+
function U(e, t, i, a) {
|
|
165
|
+
if (i === "point") return;
|
|
166
|
+
let o = t.getBoundingClientRect(), s = e.getBoundingClientRect(), c = {
|
|
117
167
|
width: window.innerWidth,
|
|
118
168
|
height: window.innerHeight
|
|
119
|
-
},
|
|
120
|
-
below:
|
|
121
|
-
above:
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
},
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
},
|
|
135
|
-
"bottom-span": {
|
|
136
|
-
side: "bottom",
|
|
137
|
-
align: "start"
|
|
138
|
-
},
|
|
139
|
-
"bottom-center": {
|
|
140
|
-
side: "bottom",
|
|
141
|
-
align: "center"
|
|
142
|
-
},
|
|
143
|
-
"bottom-end": {
|
|
144
|
-
side: "bottom",
|
|
145
|
-
align: "end"
|
|
146
|
-
},
|
|
147
|
-
top: {
|
|
148
|
-
side: "top",
|
|
149
|
-
align: "center"
|
|
169
|
+
}, l = {
|
|
170
|
+
below: V(e, "marginTop"),
|
|
171
|
+
above: V(e, "marginBottom"),
|
|
172
|
+
before: V(e, "marginRight"),
|
|
173
|
+
after: V(e, "marginLeft")
|
|
174
|
+
}, { top: u, left: d } = n({
|
|
175
|
+
trigger: o,
|
|
176
|
+
panel: s,
|
|
177
|
+
viewport: c,
|
|
178
|
+
placement: i,
|
|
179
|
+
gap: l,
|
|
180
|
+
strategy: {
|
|
181
|
+
flip: a?.flip ?? !0,
|
|
182
|
+
shift: a?.shift ?? !0,
|
|
183
|
+
padding: r(a?.collisionPadding)
|
|
150
184
|
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
let e = n === "right" ? p + i.width > a.width : p < 0, t = n === "right" ? r.left - i.width - c.before >= 0 : r.right + i.width + c.after <= a.width;
|
|
154
|
-
e && t && ({top: f, left: p} = u(n === "right" ? "left" : "right"));
|
|
155
|
-
} else {
|
|
156
|
-
let { side: e, align: t } = d[n], o = e === "bottom" ? f + i.height > a.height : f < 0, s = e === "bottom" ? r.top - i.height - c.above >= 0 : r.bottom + i.height + c.below <= a.height;
|
|
157
|
-
o && s && ({top: f, left: p} = l(e === "bottom" ? "top" : "bottom", t));
|
|
158
|
-
}
|
|
159
|
-
f = Math.min(Math.max(f, 0), Math.max(0, a.height - i.height)), p = Math.min(Math.max(p, 0), Math.max(0, a.width - i.width)), e.style.top = `${f}px`, e.style.left = `${p}px`;
|
|
185
|
+
});
|
|
186
|
+
e.style.top = `${u}px`, e.style.left = `${d}px`;
|
|
160
187
|
}
|
|
161
|
-
function
|
|
162
|
-
let { native:
|
|
163
|
-
|
|
164
|
-
if (!
|
|
165
|
-
let e =
|
|
166
|
-
if (!e
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
188
|
+
function W({ behavior: e, placement: t, collision: n }) {
|
|
189
|
+
let { native: i, anchored: a, shown: s, triggerRef: c, panelRef: l } = e;
|
|
190
|
+
o(() => {
|
|
191
|
+
if (!i || t === "point" || !s) return;
|
|
192
|
+
let e = l.current;
|
|
193
|
+
if (!e) return;
|
|
194
|
+
if (a) {
|
|
195
|
+
let i = n?.shift !== !1, a = r(n?.collisionPadding), o = t === "left" || t === "right", s = () => {
|
|
196
|
+
if (!i) {
|
|
197
|
+
e.style.translate = "";
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
let t = e.getBoundingClientRect(), n = o ? 0 : H(t.left, t.width, window.innerWidth, a.left, a.right), r = o ? H(t.top, t.height, window.innerHeight, a.top, a.bottom) : 0;
|
|
201
|
+
e.style.translate = n === 0 && r === 0 ? "" : `${n}px ${r}px`;
|
|
202
|
+
};
|
|
203
|
+
return s(), window.addEventListener("scroll", s, !0), window.addEventListener("resize", s), () => {
|
|
204
|
+
window.removeEventListener("scroll", s, !0), window.removeEventListener("resize", s), e.style.translate = "";
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
let o = c.current;
|
|
208
|
+
if (!o) return;
|
|
209
|
+
let u = () => U(e, o, t, n);
|
|
210
|
+
return u(), window.addEventListener("scroll", u, !0), window.addEventListener("resize", u), () => {
|
|
211
|
+
window.removeEventListener("scroll", u, !0), window.removeEventListener("resize", u);
|
|
170
212
|
};
|
|
171
213
|
}, [
|
|
172
|
-
n,
|
|
173
214
|
i,
|
|
174
215
|
a,
|
|
216
|
+
s,
|
|
175
217
|
t,
|
|
176
|
-
|
|
177
|
-
|
|
218
|
+
n,
|
|
219
|
+
c,
|
|
220
|
+
l
|
|
178
221
|
]);
|
|
179
222
|
}
|
|
180
|
-
function
|
|
181
|
-
|
|
182
|
-
behavior:
|
|
183
|
-
placement:
|
|
223
|
+
function G({ behavior: t, placement: n, collision: r, visualClass: a, className: o, style: s, children: c, ...l }) {
|
|
224
|
+
W({
|
|
225
|
+
behavior: t,
|
|
226
|
+
placement: n ?? "point",
|
|
227
|
+
collision: r ?? t.collision
|
|
184
228
|
});
|
|
185
|
-
let
|
|
186
|
-
...
|
|
187
|
-
...
|
|
229
|
+
let u = t.panelAttrs.style || s ? {
|
|
230
|
+
...t.panelAttrs.style,
|
|
231
|
+
...s
|
|
188
232
|
} : void 0;
|
|
189
|
-
return /* @__PURE__ */
|
|
190
|
-
...
|
|
191
|
-
...
|
|
192
|
-
|
|
233
|
+
return /* @__PURE__ */ i("div", {
|
|
234
|
+
...t.dataState !== void 0 && { "data-state": t.dataState },
|
|
235
|
+
...l,
|
|
236
|
+
...t.panelAttrs,
|
|
237
|
+
style: u,
|
|
193
238
|
className: e([
|
|
194
|
-
|
|
195
|
-
...
|
|
196
|
-
...
|
|
197
|
-
|
|
239
|
+
a,
|
|
240
|
+
...t.panelClasses,
|
|
241
|
+
...n ? B(t, n) : [],
|
|
242
|
+
o
|
|
198
243
|
]),
|
|
199
|
-
children:
|
|
244
|
+
children: c
|
|
200
245
|
});
|
|
201
246
|
}
|
|
202
247
|
//#endregion
|
|
203
|
-
export {
|
|
248
|
+
export { G as FloatingPanel, _ as floatingAnimated, g as floatingHidden, B as floatingPlacementClasses, U as placeFloatingPanel, f as supportsAnchorPositioning, d as supportsNativePopover, z as useFloating, W as useFloatingPosition };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { focusFirst as e, getTabbables as t } from "./focus.js";
|
|
2
|
+
import { useCallback as n, useEffect as r, useLayoutEffect as i, useRef as a } from "react";
|
|
3
|
+
//#region src/lib/utils/focus-scope.ts
|
|
4
|
+
var o = "hazefocusmount", s = "hazefocusunmount";
|
|
5
|
+
function c() {
|
|
6
|
+
document.body.focus(), document.activeElement !== document.body && document.activeElement instanceof HTMLElement && document.activeElement.blur();
|
|
7
|
+
}
|
|
8
|
+
function l(l) {
|
|
9
|
+
let u = a(l);
|
|
10
|
+
i(() => {
|
|
11
|
+
u.current = l;
|
|
12
|
+
});
|
|
13
|
+
let d = a(null), f = a(null), p = n((e) => {
|
|
14
|
+
d.current = e;
|
|
15
|
+
}, []);
|
|
16
|
+
return r(() => {
|
|
17
|
+
if (!l.enabled) return;
|
|
18
|
+
let n = u.current, r = !1, i = document.activeElement;
|
|
19
|
+
f.current = i instanceof HTMLElement ? i : null;
|
|
20
|
+
let a = new Event(o, {
|
|
21
|
+
bubbles: !1,
|
|
22
|
+
cancelable: !0
|
|
23
|
+
});
|
|
24
|
+
d.current?.dispatchEvent(a), n.onMountAutoFocus?.(a), !a.defaultPrevented && n.autoFocus !== !1 && d.current && e(d.current);
|
|
25
|
+
let p = (e) => {
|
|
26
|
+
if (e.key !== "Tab") return;
|
|
27
|
+
let n = d.current;
|
|
28
|
+
if (!n) return;
|
|
29
|
+
let r = t(n), i = r[0], a = r[r.length - 1];
|
|
30
|
+
if (!i || !a) {
|
|
31
|
+
e.preventDefault();
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
let o = document.activeElement, s = o !== null && n.contains(o);
|
|
35
|
+
e.shiftKey ? (o === i || !s) && (e.preventDefault(), a.focus()) : (o === a || !s) && (e.preventDefault(), i.focus());
|
|
36
|
+
}, m = (t) => {
|
|
37
|
+
let n = d.current;
|
|
38
|
+
if (!n || !(t.target instanceof Node) || !n.contains(t.target)) return;
|
|
39
|
+
let i = t.relatedTarget;
|
|
40
|
+
(i instanceof Node ? !n.contains(i) : document.activeElement === document.body) && queueMicrotask(() => {
|
|
41
|
+
if (r) return;
|
|
42
|
+
let t = d.current;
|
|
43
|
+
if (!t) return;
|
|
44
|
+
let n = document.activeElement;
|
|
45
|
+
n !== null && t.contains(n) || e(t);
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
return n.trapped && (document.addEventListener("keydown", p), document.addEventListener("focusout", m)), () => {
|
|
49
|
+
r = !0, n.trapped && (document.removeEventListener("keydown", p), document.removeEventListener("focusout", m));
|
|
50
|
+
let e = u.current, t = new Event(s, {
|
|
51
|
+
bubbles: !1,
|
|
52
|
+
cancelable: !0
|
|
53
|
+
});
|
|
54
|
+
if (d.current?.dispatchEvent(t), e.onUnmountAutoFocus?.(t), t.defaultPrevented || e.returnFocus === !1) return;
|
|
55
|
+
let i = d.current, a = document.activeElement, o = i !== null && a !== null && i.contains(a);
|
|
56
|
+
if (a !== document.body && a !== null && !o) return;
|
|
57
|
+
let l = f.current;
|
|
58
|
+
l?.isConnected && l.focus(), document.activeElement !== l && c();
|
|
59
|
+
};
|
|
60
|
+
}, [l.enabled]), p;
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
export { l as useFocusScope };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region src/lib/utils/focus.ts
|
|
2
|
+
var e = [
|
|
3
|
+
"a[href]:not([disabled])",
|
|
4
|
+
"button:not([disabled])",
|
|
5
|
+
"input:not([disabled]):not([type=hidden])",
|
|
6
|
+
"select:not([disabled])",
|
|
7
|
+
"textarea:not([disabled])",
|
|
8
|
+
"[tabindex]:not([tabindex=\"-1\"])",
|
|
9
|
+
"[contenteditable=true]",
|
|
10
|
+
"audio[controls]",
|
|
11
|
+
"video[controls]",
|
|
12
|
+
"details > summary:first-of-type"
|
|
13
|
+
].join(", ");
|
|
14
|
+
function t(e) {
|
|
15
|
+
return (e instanceof HTMLButtonElement || e instanceof HTMLInputElement || e instanceof HTMLSelectElement || e instanceof HTMLTextAreaElement || e instanceof HTMLOptionElement) && e.disabled;
|
|
16
|
+
}
|
|
17
|
+
function n(e) {
|
|
18
|
+
return typeof e.checkVisibility != "function" || e.checkVisibility({
|
|
19
|
+
checkOpacity: !0,
|
|
20
|
+
checkVisibilityCSS: !0
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
function r(r) {
|
|
24
|
+
return !r.matches(e) || r.getAttribute("tabindex") === "-1" || r.hasAttribute("hidden") || t(r) ? !1 : n(r);
|
|
25
|
+
}
|
|
26
|
+
function i(t) {
|
|
27
|
+
return t ? Array.from(t.querySelectorAll(e)).filter(r) : [];
|
|
28
|
+
}
|
|
29
|
+
function a(e) {
|
|
30
|
+
let t = i(e)[0] ?? e;
|
|
31
|
+
return t === e && e.getAttribute("tabindex") === null && (e.tabIndex = -1), t.focus(), document.activeElement === t;
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { e as TABBABLE_SELECTOR, a as focusFirst, i as getTabbables, r as isTabbable };
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { cloneElement as e, useEffect as t, useRef as n, useState as r } from "react";
|
|
2
|
+
//#region src/lib/utils/presence.tsx
|
|
3
|
+
var i = /* @__PURE__ */ new WeakMap();
|
|
4
|
+
function a(e) {
|
|
5
|
+
if (typeof requestAnimationFrame == "function") {
|
|
6
|
+
requestAnimationFrame(() => requestAnimationFrame(e));
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
setTimeout(e, 32);
|
|
10
|
+
}
|
|
11
|
+
function o(e) {
|
|
12
|
+
let t = 0;
|
|
13
|
+
for (let n of e.split(",")) {
|
|
14
|
+
let e = n.trim(), r = Number.parseFloat(e);
|
|
15
|
+
if (Number.isNaN(r)) continue;
|
|
16
|
+
let i = e.endsWith("ms") ? r : r * 1e3;
|
|
17
|
+
i > t && (t = i);
|
|
18
|
+
}
|
|
19
|
+
return t;
|
|
20
|
+
}
|
|
21
|
+
function s(e) {
|
|
22
|
+
return new Promise((t) => {
|
|
23
|
+
a(() => {
|
|
24
|
+
let n = getComputedStyle(e), r = o(n.animationDuration) + o(n.animationDelay), i = o(n.transitionDuration) + o(n.transitionDelay);
|
|
25
|
+
if (!(n.animationName !== "none" && r > 0 || n.transitionProperty !== "none" && i > 0)) {
|
|
26
|
+
t();
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
let a = () => {
|
|
30
|
+
e.removeEventListener("animationend", s), e.removeEventListener("transitionend", c), window.clearTimeout(l), t();
|
|
31
|
+
}, s = (t) => {
|
|
32
|
+
t.target === e && a();
|
|
33
|
+
}, c = (t) => {
|
|
34
|
+
t.target === e && a();
|
|
35
|
+
};
|
|
36
|
+
e.addEventListener("animationend", s), e.addEventListener("transitionend", c);
|
|
37
|
+
let l = window.setTimeout(a, Math.max(r, i));
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function c(e) {
|
|
42
|
+
if (!e.isConnected) return null;
|
|
43
|
+
let t = i.get(e);
|
|
44
|
+
if (t) return t;
|
|
45
|
+
let n = s(e);
|
|
46
|
+
return i.set(e, n), n.then(() => i.delete(e)), n;
|
|
47
|
+
}
|
|
48
|
+
function l({ present: i, children: a, onExited: o }) {
|
|
49
|
+
let [s, l] = r(i), [u, d] = r(() => i ? "open" : "closed"), [f, p] = r(i), m = n(null);
|
|
50
|
+
if (i !== f && (p(i), i ? (l(!0), d("open")) : d("closed")), t(() => {
|
|
51
|
+
if (!s || u !== "closed") return;
|
|
52
|
+
let e = !0, t = m.current, n = t ? c(t) : null, r = () => {
|
|
53
|
+
e && (e = !1, l(!1), o?.());
|
|
54
|
+
};
|
|
55
|
+
return n ? n.then(r) : r(), () => {
|
|
56
|
+
e = !1;
|
|
57
|
+
};
|
|
58
|
+
}, [
|
|
59
|
+
s,
|
|
60
|
+
u,
|
|
61
|
+
o
|
|
62
|
+
]), !s) return null;
|
|
63
|
+
let h = a, g = h.props.ref;
|
|
64
|
+
return e(h, {
|
|
65
|
+
...h.props["data-state"] === void 0 ? { "data-state": u } : {},
|
|
66
|
+
ref: (e) => {
|
|
67
|
+
m.current = e, typeof g == "function" ? g(e) : g && (g.current = e);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
//#endregion
|
|
72
|
+
export { l as Presence, c as whenExitSettles };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "haze-ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.24.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A React UI component library powered by react-use-control and Linaria",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"lint": "eslint --fix src *.mjs",
|
|
47
47
|
"deploy": "npm run build:demo && gh-pages -d dist",
|
|
48
48
|
"test": "vitest run",
|
|
49
|
-
"test:e2e": "playwright test --config e2e/playwright.config.ts",
|
|
49
|
+
"test:e2e": "PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS=1 playwright test --config e2e/playwright.config.ts",
|
|
50
50
|
"test:watch": "vitest",
|
|
51
51
|
"typecheck": "tsc --noEmit",
|
|
52
52
|
"prepublishOnly": "npm run build",
|
|
@@ -89,6 +89,7 @@
|
|
|
89
89
|
"@testing-library/jest-dom": "^7.0.1",
|
|
90
90
|
"@testing-library/react": "^16.3.3",
|
|
91
91
|
"@testing-library/user-event": "^14.6.6",
|
|
92
|
+
"@types/culori": "^4.0.1",
|
|
92
93
|
"@types/jest-axe": "^3.5.9",
|
|
93
94
|
"@types/node": "^26.4.0",
|
|
94
95
|
"@types/ramda": "^0.32.0",
|
|
@@ -102,6 +103,7 @@
|
|
|
102
103
|
"babel-plugin-transform-jsx-condition": "^0.1.3",
|
|
103
104
|
"commitizen": "^4.3.2",
|
|
104
105
|
"core-js": "^3.50.0",
|
|
106
|
+
"culori": "^4.0.2",
|
|
105
107
|
"date-fns": "^4.4.0",
|
|
106
108
|
"eslint": "^10.9.1",
|
|
107
109
|
"eslint-plugin-compat": "^7.0.2",
|