@skiddph/prui 0.10.2 → 0.12.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/app.js +1 -1
- package/dist/chunks/{auth-shell-BudxZ4__.js → auth-shell-DBKlNZtl.js} +278 -270
- package/dist/core/drawer.js +46 -63
- package/dist/core/input.d.ts +5 -1
- package/dist/core/input.js +61 -37
- package/dist/core/overlay.d.ts +12 -0
- package/dist/core/overlay.js +121 -96
- package/dist/i18n/index.d.ts +2 -0
- package/dist/i18n.js +15 -13
- package/dist/index.js +1 -1
- package/dist/prui-utilities.css +1 -1
- package/dist/prui.css +6 -1
- package/dist/theme/base.css +5 -0
- package/package.json +1 -1
package/dist/core/drawer.js
CHANGED
|
@@ -1,93 +1,76 @@
|
|
|
1
|
-
import { jsx as t, jsxs as
|
|
2
|
-
import * as
|
|
3
|
-
import { X as
|
|
4
|
-
import { cn as
|
|
5
|
-
import {
|
|
6
|
-
import { usePruiI18n as
|
|
7
|
-
const
|
|
1
|
+
import { jsx as t, jsxs as C } from "react/jsx-runtime";
|
|
2
|
+
import * as u from "react";
|
|
3
|
+
import { X as M } from "lucide-react";
|
|
4
|
+
import { cn as R } from "./cn.js";
|
|
5
|
+
import { useMountTransition as T, useOverlay as Y, Portal as k } from "./overlay.js";
|
|
6
|
+
import { usePruiI18n as P } from "../i18n.js";
|
|
7
|
+
const j = {
|
|
8
8
|
left: "left-0 top-0 h-full prui-drawer-panel",
|
|
9
9
|
right: "right-0 top-0 h-full prui-drawer-panel",
|
|
10
10
|
top: "left-0 top-0 w-full prui-drawer-panel",
|
|
11
11
|
bottom: "left-0 bottom-0 w-full prui-drawer-panel"
|
|
12
|
-
},
|
|
12
|
+
}, L = {
|
|
13
13
|
left: "translateX(0)",
|
|
14
14
|
right: "translateX(0)",
|
|
15
15
|
top: "translateY(0)",
|
|
16
16
|
bottom: "translateY(0)"
|
|
17
|
-
},
|
|
17
|
+
}, $ = {
|
|
18
18
|
left: "translateX(-100%)",
|
|
19
19
|
right: "translateX(100%)",
|
|
20
20
|
top: "translateY(-100%)",
|
|
21
21
|
bottom: "translateY(100%)"
|
|
22
|
-
},
|
|
23
|
-
const [
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if (u(!0), f) {
|
|
29
|
-
d(!0);
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
const C = requestAnimationFrame(() => d(!0));
|
|
33
|
-
return () => cancelAnimationFrame(C);
|
|
34
|
-
}
|
|
35
|
-
if (d(!1), f) {
|
|
36
|
-
u(!1);
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
const e = setTimeout(() => u(!1), 300);
|
|
40
|
-
return () => clearTimeout(e);
|
|
41
|
-
}, [l, f]);
|
|
42
|
-
const { ref: T } = A({
|
|
43
|
-
open: l,
|
|
44
|
-
onEscape: () => c(!1)
|
|
22
|
+
}, f = u.forwardRef(function({ open: a, defaultOpen: n = !1, onOpenChange: l, side: e = "right", size: r, children: c, ariaLabel: h, hideClose: b, className: v, style: y }, g) {
|
|
23
|
+
const [w, x] = u.useState(n), p = a !== void 0, d = p ? a : w, { mounted: S, shown: i } = T(d), { t: N } = P(), s = (o) => {
|
|
24
|
+
p || x(o), l == null || l(o);
|
|
25
|
+
}, { ref: D } = Y({
|
|
26
|
+
open: d,
|
|
27
|
+
onEscape: () => s(!1)
|
|
45
28
|
});
|
|
46
|
-
if (!
|
|
29
|
+
if (!S) return null;
|
|
47
30
|
const X = {
|
|
48
|
-
transform:
|
|
31
|
+
transform: i ? L[e] : $[e],
|
|
49
32
|
transition: "transform var(--prui-duration-slow) var(--prui-ease-out)",
|
|
50
|
-
...
|
|
51
|
-
...
|
|
33
|
+
...e === "left" || e === "right" ? { width: typeof r == "number" ? `${r}px` : r ?? "400px" } : { maxHeight: typeof r == "number" ? `${r}px` : r ?? "80vh" },
|
|
34
|
+
...y
|
|
52
35
|
};
|
|
53
|
-
return /* @__PURE__ */ t(
|
|
36
|
+
return /* @__PURE__ */ t(k, { children: /* @__PURE__ */ t("div", { ref: D, children: /* @__PURE__ */ t(
|
|
54
37
|
"div",
|
|
55
38
|
{
|
|
56
39
|
className: "prui-drawer-overlay fixed inset-0 z-[var(--prui-z-modal)]",
|
|
57
40
|
style: {
|
|
58
41
|
backgroundColor: "var(--prui-scrim)",
|
|
59
|
-
opacity:
|
|
42
|
+
opacity: i ? 1 : 0,
|
|
60
43
|
transition: "opacity var(--prui-duration-slow) var(--prui-ease-out)"
|
|
61
44
|
},
|
|
62
|
-
onMouseDown: (
|
|
63
|
-
|
|
45
|
+
onMouseDown: (o) => {
|
|
46
|
+
o.target === o.currentTarget && s(!1);
|
|
64
47
|
},
|
|
65
|
-
children: /* @__PURE__ */
|
|
48
|
+
children: /* @__PURE__ */ C(
|
|
66
49
|
"div",
|
|
67
50
|
{
|
|
68
|
-
ref:
|
|
51
|
+
ref: g,
|
|
69
52
|
role: "dialog",
|
|
70
53
|
"aria-modal": "true",
|
|
71
|
-
"aria-label":
|
|
72
|
-
"data-state":
|
|
73
|
-
className:
|
|
54
|
+
"aria-label": h,
|
|
55
|
+
"data-state": i ? "open" : "closed",
|
|
56
|
+
className: R(
|
|
74
57
|
"absolute flex flex-col overflow-y-auto border border-[var(--prui-line)] bg-[var(--prui-surface)]",
|
|
75
58
|
"text-[var(--prui-fg)] shadow-[var(--prui-shadow-modal)] outline-none",
|
|
76
|
-
|
|
77
|
-
|
|
59
|
+
j[e],
|
|
60
|
+
v
|
|
78
61
|
),
|
|
79
62
|
style: X,
|
|
80
63
|
children: [
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
64
|
+
e === "bottom" ? /* @__PURE__ */ t("div", { "aria-hidden": !0, className: "mx-auto mt-2 mb-1 h-1 w-10 shrink-0 rounded-[var(--prui-radius-full)] bg-[var(--prui-line)]" }) : null,
|
|
65
|
+
c,
|
|
66
|
+
b ? null : /* @__PURE__ */ t(
|
|
84
67
|
"button",
|
|
85
68
|
{
|
|
86
69
|
type: "button",
|
|
87
|
-
"aria-label":
|
|
88
|
-
onClick: () =>
|
|
70
|
+
"aria-label": N.close,
|
|
71
|
+
onClick: () => s(!1),
|
|
89
72
|
className: "absolute right-3 top-3 rounded-[var(--prui-radius-1)] p-1 text-[var(--prui-dim)] transition-colors hover:bg-[var(--prui-raise)] hover:text-[var(--prui-fg)] cursor-pointer",
|
|
90
|
-
children: /* @__PURE__ */ t(
|
|
73
|
+
children: /* @__PURE__ */ t(M, { className: "h-4 w-4", "aria-hidden": !0 })
|
|
91
74
|
}
|
|
92
75
|
)
|
|
93
76
|
]
|
|
@@ -96,12 +79,12 @@ const L = {
|
|
|
96
79
|
}
|
|
97
80
|
) }) });
|
|
98
81
|
});
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
return /* @__PURE__ */ t(
|
|
82
|
+
f.displayName = "Drawer";
|
|
83
|
+
const E = u.forwardRef(function(a, n) {
|
|
84
|
+
return /* @__PURE__ */ t(f, { ref: n, side: "bottom", ...a });
|
|
102
85
|
});
|
|
103
|
-
|
|
104
|
-
const
|
|
86
|
+
E.displayName = "Sheet";
|
|
87
|
+
const A = {
|
|
105
88
|
name: "Drawer",
|
|
106
89
|
props: [
|
|
107
90
|
{ name: "open", type: "boolean", default: "undefined", control: "boolean" },
|
|
@@ -112,7 +95,7 @@ const J = {
|
|
|
112
95
|
{ name: "ariaLabel", type: "string", default: null, control: "text" },
|
|
113
96
|
{ name: "hideClose", type: "boolean", default: "false", control: "boolean" }
|
|
114
97
|
]
|
|
115
|
-
},
|
|
98
|
+
}, B = {
|
|
116
99
|
name: "Sheet",
|
|
117
100
|
props: [
|
|
118
101
|
{ name: "open", type: "boolean", default: "undefined", control: "boolean" },
|
|
@@ -122,8 +105,8 @@ const J = {
|
|
|
122
105
|
]
|
|
123
106
|
};
|
|
124
107
|
export {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
108
|
+
f as Drawer,
|
|
109
|
+
E as Sheet,
|
|
110
|
+
A as drawerPropsMeta,
|
|
111
|
+
B as sheetPropsMeta
|
|
129
112
|
};
|
package/dist/core/input.d.ts
CHANGED
|
@@ -14,8 +14,12 @@ export interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElem
|
|
|
14
14
|
variant?: "default" | "filled";
|
|
15
15
|
/** Icon rendered inside the field's leading edge. */
|
|
16
16
|
icon?: React.ReactNode;
|
|
17
|
-
/** Icon rendered inside the field's trailing edge.
|
|
17
|
+
/** Icon rendered inside the field's trailing edge. A custom trailingIcon
|
|
18
|
+
* takes over the slot and suppresses the password eye toggle. */
|
|
18
19
|
trailingIcon?: React.ReactNode;
|
|
20
|
+
/** With type="password", render an eye show/hide toggle in the trailing
|
|
21
|
+
* slot (the default). Set false to keep a plain masked field. */
|
|
22
|
+
passwordToggle?: boolean;
|
|
19
23
|
}
|
|
20
24
|
export declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
|
|
21
25
|
export declare const inputPropsMeta: PropsMeta;
|
package/dist/core/input.js
CHANGED
|
@@ -1,59 +1,83 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import * as
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
1
|
+
import { jsx as e, jsxs as S } from "react/jsx-runtime";
|
|
2
|
+
import * as u from "react";
|
|
3
|
+
import { EyeOff as T, Eye as k } from "lucide-react";
|
|
4
|
+
import { resolveSurface as z, withSurface as E } from "./surface.js";
|
|
5
|
+
import { cn as h } from "./cn.js";
|
|
6
|
+
import { usePruiI18n as M } from "../i18n.js";
|
|
7
|
+
const v = "prui-f-control prui-input w-full bg-[var(--prui-s-bg,var(--prui-background))] text-[var(--prui-s-fg,var(--prui-fg))] placeholder:text-[var(--prui-dim)] border border-[var(--prui-line)] rounded-[var(--prui-s-radius,var(--prui-radius))] text-sm outline-none transition-colors focus:border-[var(--prui-brand)] focus:ring-2 focus:ring-[var(--prui-brand)]/30 disabled:opacity-50 disabled:cursor-not-allowed", D = {
|
|
6
8
|
sm: "h-8 px-2.5",
|
|
7
9
|
md: "h-9 px-3",
|
|
8
10
|
lg: "h-11 px-4 text-base"
|
|
9
|
-
},
|
|
10
|
-
({ className:
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
t && "pr-9",
|
|
18
|
-
|
|
11
|
+
}, B = u.forwardRef(
|
|
12
|
+
({ className: s, style: l, type: a = "text", size: i = "md", variant: g = "default", icon: r, trailingIcon: t, passwordToggle: y = !0, bg: b, fg: x, radius: w, texture: N, textureColor: R, elevation: P, ...p }, j) => {
|
|
13
|
+
const { t: c } = M(), [n, C] = u.useState(!1), o = a === "password" && y !== !1 && !t, I = z({ bg: b, fg: x, radius: w, texture: N, textureColor: R, elevation: P }), f = E(
|
|
14
|
+
h(
|
|
15
|
+
v,
|
|
16
|
+
D[i],
|
|
17
|
+
g === "filled" && "bg-[var(--prui-s-bg,var(--prui-raise))] border-transparent",
|
|
18
|
+
r && "pl-9",
|
|
19
|
+
(t || o) && "pr-9",
|
|
20
|
+
s
|
|
19
21
|
),
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
),
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
l,
|
|
23
|
+
I
|
|
24
|
+
), m = /* @__PURE__ */ e(
|
|
25
|
+
"input",
|
|
26
|
+
{
|
|
27
|
+
ref: j,
|
|
28
|
+
type: o && n ? "text" : a,
|
|
29
|
+
className: f.className,
|
|
30
|
+
style: f.style,
|
|
31
|
+
...p
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
return !r && !t && !o ? m : /* @__PURE__ */ S("span", { className: "relative inline-flex w-full", children: [
|
|
35
|
+
r ? /* @__PURE__ */ e("span", { "aria-hidden": !0, className: "pointer-events-none absolute left-3 top-1/2 flex -translate-y-1/2 items-center text-[var(--prui-dim)] [&>svg]:h-4 [&>svg]:w-4", children: r }) : null,
|
|
36
|
+
m,
|
|
37
|
+
t ? /* @__PURE__ */ e("span", { "aria-hidden": !0, className: "pointer-events-none absolute right-3 top-1/2 flex -translate-y-1/2 items-center text-[var(--prui-dim)] [&>svg]:h-4 [&>svg]:w-4", children: t }) : o ? /* @__PURE__ */ e(
|
|
38
|
+
"button",
|
|
39
|
+
{
|
|
40
|
+
type: "button",
|
|
41
|
+
"aria-label": n ? c.hidePassword : c.showPassword,
|
|
42
|
+
"aria-pressed": n,
|
|
43
|
+
disabled: p.disabled,
|
|
44
|
+
onMouseDown: (d) => d.preventDefault(),
|
|
45
|
+
onClick: () => C((d) => !d),
|
|
46
|
+
className: "absolute right-1.5 top-1/2 flex h-6 w-6 -translate-y-1/2 cursor-pointer items-center justify-center rounded-[var(--prui-radius-1)] text-[var(--prui-dim)] hover:bg-[var(--prui-raise)] hover:text-[var(--prui-fg)] disabled:cursor-not-allowed disabled:opacity-50",
|
|
47
|
+
children: n ? /* @__PURE__ */ e(T, { className: "h-4 w-4", "aria-hidden": !0 }) : /* @__PURE__ */ e(k, { className: "h-4 w-4", "aria-hidden": !0 })
|
|
48
|
+
}
|
|
49
|
+
) : null
|
|
27
50
|
] });
|
|
28
51
|
}
|
|
29
52
|
);
|
|
30
|
-
|
|
31
|
-
const
|
|
53
|
+
B.displayName = "Input";
|
|
54
|
+
const J = {
|
|
32
55
|
name: "Input",
|
|
33
56
|
props: [
|
|
34
57
|
{ name: "type", type: "string", default: "'text'", control: "select", options: ["text", "password", "email", "number", "search"] },
|
|
35
58
|
{ name: "size", type: "'sm' | 'md' | 'lg'", default: "'md'", control: "select", options: ["sm", "md", "lg"] },
|
|
36
59
|
{ name: "variant", type: "'default' | 'filled'", default: "'default'", control: "select", options: ["default", "filled"] },
|
|
37
60
|
{ name: "icon", type: "ReactNode", default: "undefined", control: "none", description: "Icon inside the leading edge (padding adjusts)." },
|
|
38
|
-
{ name: "trailingIcon", type: "ReactNode", default: "undefined", control: "none", description: "Icon inside the trailing edge." },
|
|
61
|
+
{ name: "trailingIcon", type: "ReactNode", default: "undefined", control: "none", description: "Icon inside the trailing edge; takes over the slot from the password eye." },
|
|
62
|
+
{ name: "passwordToggle", type: "boolean", default: "true", control: "boolean", description: "type=password renders an eye show/hide toggle unless a trailingIcon owns the slot." },
|
|
39
63
|
{ name: "value", type: "string", default: null, control: "text" },
|
|
40
64
|
{ name: "placeholder", type: "string", default: "undefined", control: "text" },
|
|
41
65
|
{ name: "disabled", type: "boolean", default: "false", control: "boolean" },
|
|
42
66
|
{ name: "onChange", type: "(e) => void", default: null, control: "none" }
|
|
43
67
|
]
|
|
44
|
-
},
|
|
45
|
-
({ className:
|
|
68
|
+
}, O = u.forwardRef(
|
|
69
|
+
({ className: s, style: l, ...a }, i) => /* @__PURE__ */ e(
|
|
46
70
|
"textarea",
|
|
47
71
|
{
|
|
48
|
-
ref:
|
|
49
|
-
style:
|
|
50
|
-
className:
|
|
51
|
-
...
|
|
72
|
+
ref: i,
|
|
73
|
+
style: l,
|
|
74
|
+
className: h(v, "h-auto min-h-20 resize-y px-3 py-2", s),
|
|
75
|
+
...a
|
|
52
76
|
}
|
|
53
77
|
)
|
|
54
78
|
);
|
|
55
|
-
|
|
56
|
-
const
|
|
79
|
+
O.displayName = "Textarea";
|
|
80
|
+
const K = {
|
|
57
81
|
name: "Textarea",
|
|
58
82
|
props: [
|
|
59
83
|
{ name: "value", type: "string", default: null, control: "textarea" },
|
|
@@ -63,8 +87,8 @@ const k = {
|
|
|
63
87
|
]
|
|
64
88
|
};
|
|
65
89
|
export {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
90
|
+
B as Input,
|
|
91
|
+
O as Textarea,
|
|
92
|
+
J as inputPropsMeta,
|
|
93
|
+
K as textareaPropsMeta
|
|
70
94
|
};
|
package/dist/core/overlay.d.ts
CHANGED
|
@@ -25,6 +25,18 @@ export declare function Portal({ children, container, }: {
|
|
|
25
25
|
}): React.ReactPortal | null;
|
|
26
26
|
/** True when the user asked the OS for reduced motion. */
|
|
27
27
|
export declare function useReducedMotion(): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Mount/unmount lifecycle for enter/exit animations. Mounts immediately when
|
|
30
|
+
* `open` turns true; flips `shown` a frame later so the enter state (the
|
|
31
|
+
* "from" transform) paints first — a single rAF can merge into that first
|
|
32
|
+
* paint under discrete-event flushes and skip the animation entirely, so this
|
|
33
|
+
* waits two frames. On close, `shown` drops at once and unmounting waits
|
|
34
|
+
* `exitMs` for the exit animation. Reduced motion skips both directions.
|
|
35
|
+
*/
|
|
36
|
+
export declare function useMountTransition(open: boolean, exitMs?: number): {
|
|
37
|
+
mounted: boolean;
|
|
38
|
+
shown: boolean;
|
|
39
|
+
};
|
|
28
40
|
/** All focusable elements inside root, in DOM order. */
|
|
29
41
|
export declare function getFocusable(root: HTMLElement | null): HTMLElement[];
|
|
30
42
|
/** Register an overlay; returns its stack id. */
|
package/dist/core/overlay.js
CHANGED
|
@@ -1,23 +1,47 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as c from "react";
|
|
2
2
|
import { createPortal as E } from "react-dom";
|
|
3
|
-
function
|
|
3
|
+
function x({
|
|
4
4
|
children: t,
|
|
5
5
|
container: e
|
|
6
6
|
}) {
|
|
7
|
-
const [
|
|
8
|
-
return
|
|
9
|
-
|
|
10
|
-
}, [e]),
|
|
11
|
-
}
|
|
12
|
-
function
|
|
13
|
-
const [t, e] =
|
|
14
|
-
return
|
|
7
|
+
const [n, s] = c.useState(null);
|
|
8
|
+
return c.useEffect(() => {
|
|
9
|
+
s(e ?? (typeof document < "u" ? document.body : null));
|
|
10
|
+
}, [e]), n == null ? null : E(t, n);
|
|
11
|
+
}
|
|
12
|
+
function v() {
|
|
13
|
+
const [t, e] = c.useState(() => typeof window > "u" || !window.matchMedia ? !1 : window.matchMedia("(prefers-reduced-motion: reduce)").matches);
|
|
14
|
+
return c.useEffect(() => {
|
|
15
15
|
if (typeof window > "u" || !window.matchMedia) return;
|
|
16
|
-
const
|
|
17
|
-
return
|
|
16
|
+
const n = window.matchMedia("(prefers-reduced-motion: reduce)"), s = () => e(n.matches);
|
|
17
|
+
return n.addEventListener("change", s), () => n.removeEventListener("change", s);
|
|
18
18
|
}, []), t;
|
|
19
19
|
}
|
|
20
|
-
|
|
20
|
+
function I(t, e = 300) {
|
|
21
|
+
const n = v(), [s, o] = c.useState(t), [r, u] = c.useState(!1);
|
|
22
|
+
return c.useEffect(() => {
|
|
23
|
+
if (t) {
|
|
24
|
+
if (o(!0), n) {
|
|
25
|
+
u(!0);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
let f = 0;
|
|
29
|
+
const a = requestAnimationFrame(() => {
|
|
30
|
+
f = requestAnimationFrame(() => u(!0));
|
|
31
|
+
});
|
|
32
|
+
return () => {
|
|
33
|
+
cancelAnimationFrame(a), cancelAnimationFrame(f);
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
if (u(!1), n) {
|
|
37
|
+
o(!1);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const i = setTimeout(() => o(!1), e);
|
|
41
|
+
return () => clearTimeout(i);
|
|
42
|
+
}, [t, n, e]), { mounted: s, shown: r };
|
|
43
|
+
}
|
|
44
|
+
const g = [
|
|
21
45
|
"a[href]",
|
|
22
46
|
"button:not([disabled])",
|
|
23
47
|
"input:not([disabled])",
|
|
@@ -30,138 +54,138 @@ const v = [
|
|
|
30
54
|
"[contenteditable]:not([contenteditable='false'])"
|
|
31
55
|
].join(",");
|
|
32
56
|
function y(t) {
|
|
33
|
-
return t ? Array.from(t.querySelectorAll(
|
|
57
|
+
return t ? Array.from(t.querySelectorAll(g)).filter(
|
|
34
58
|
(e) => !e.closest("[inert], [aria-hidden='true']") && !e.hasAttribute("hidden")
|
|
35
59
|
) : [];
|
|
36
60
|
}
|
|
37
|
-
const
|
|
38
|
-
function
|
|
61
|
+
const l = [];
|
|
62
|
+
function T(t) {
|
|
39
63
|
const e = Symbol("prui-overlay");
|
|
40
|
-
return
|
|
64
|
+
return l.push({ id: e, element: t }), e;
|
|
41
65
|
}
|
|
42
|
-
function
|
|
43
|
-
const e =
|
|
44
|
-
e >= 0 &&
|
|
66
|
+
function w(t) {
|
|
67
|
+
const e = l.findIndex((n) => n.id === t);
|
|
68
|
+
e >= 0 && l.splice(e, 1);
|
|
45
69
|
}
|
|
46
70
|
function k(t) {
|
|
47
|
-
const e =
|
|
71
|
+
const e = l[l.length - 1];
|
|
48
72
|
return e != null && e.id === t;
|
|
49
73
|
}
|
|
50
|
-
function
|
|
51
|
-
return
|
|
74
|
+
function B() {
|
|
75
|
+
return l.length;
|
|
52
76
|
}
|
|
53
|
-
function
|
|
54
|
-
const e =
|
|
55
|
-
|
|
77
|
+
function A(t) {
|
|
78
|
+
const e = c.useRef(null), n = c.useRef(null), [s, o] = c.useReducer((i) => i + 1, 0);
|
|
79
|
+
c.useEffect(() => {
|
|
56
80
|
if (!t) return;
|
|
57
|
-
const i =
|
|
58
|
-
return e.current = i,
|
|
59
|
-
|
|
81
|
+
const i = T(null);
|
|
82
|
+
return e.current = i, n.current = l[l.length - 1] ?? null, o(), () => {
|
|
83
|
+
w(i), e.current === i && (e.current = null, n.current = null);
|
|
60
84
|
};
|
|
61
85
|
}, [t]);
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
}, []), u =
|
|
65
|
-
return { setElement:
|
|
66
|
-
}
|
|
67
|
-
function R(t, e,
|
|
68
|
-
const
|
|
69
|
-
|
|
86
|
+
const r = c.useCallback((i) => {
|
|
87
|
+
n.current && (n.current.element = i);
|
|
88
|
+
}, []), u = c.useCallback(() => e.current != null ? k(e.current) : !1, []);
|
|
89
|
+
return { setElement: r, isTop: u };
|
|
90
|
+
}
|
|
91
|
+
function R(t, e, n) {
|
|
92
|
+
const s = c.useRef(n);
|
|
93
|
+
s.current = n, c.useEffect(() => {
|
|
70
94
|
if (!t) return;
|
|
71
|
-
const o = (
|
|
72
|
-
if (
|
|
73
|
-
|
|
95
|
+
const o = (r) => {
|
|
96
|
+
if (r.key !== "Escape" || !e()) return;
|
|
97
|
+
s.current() === !1 && r.stopPropagation();
|
|
74
98
|
};
|
|
75
99
|
return document.addEventListener("keydown", o, !0), () => document.removeEventListener("keydown", o, !0);
|
|
76
100
|
}, [t, e]);
|
|
77
101
|
}
|
|
78
|
-
let
|
|
79
|
-
function
|
|
80
|
-
typeof document > "u" || (
|
|
102
|
+
let m = 0, h = "", p = "";
|
|
103
|
+
function S() {
|
|
104
|
+
typeof document > "u" || (m++, !(m > 1) && (h = document.body.style.overflow, p = document.body.style.paddingRight, document.body.style.overflow = "hidden", document.body.classList.add("modal-open")));
|
|
81
105
|
}
|
|
82
|
-
function
|
|
83
|
-
typeof document > "u" || (
|
|
106
|
+
function L() {
|
|
107
|
+
typeof document > "u" || (m = Math.max(0, m - 1), !(m > 0) && (document.body.style.overflow = h, document.body.style.paddingRight = p, document.body.classList.remove("modal-open")));
|
|
84
108
|
}
|
|
85
|
-
function
|
|
86
|
-
|
|
109
|
+
function C(t) {
|
|
110
|
+
c.useEffect(() => {
|
|
87
111
|
if (t)
|
|
88
|
-
return
|
|
112
|
+
return S(), L;
|
|
89
113
|
}, [t]);
|
|
90
114
|
}
|
|
91
115
|
const b = typeof HTMLElement < "u" && "inert" in HTMLElement.prototype;
|
|
92
|
-
function
|
|
93
|
-
const
|
|
94
|
-
for (const o of Array.from(
|
|
116
|
+
function M(t, e) {
|
|
117
|
+
const n = t.ownerDocument, s = [];
|
|
118
|
+
for (const o of Array.from(n.body.childNodes)) {
|
|
95
119
|
if (!(o instanceof HTMLElement)) continue;
|
|
96
|
-
const
|
|
97
|
-
|
|
120
|
+
const r = o.tagName;
|
|
121
|
+
r === "SCRIPT" || r === "STYLE" || r === "LINK" || r === "NOSCRIPT" || r === "META" || r === "TITLE" || r === "TEMPLATE" || o === t || o.contains(t) || t.contains(o) || e.has(o) || o.getAttribute("aria-hidden") !== "true" && (s.push({ el: o, ariaHidden: o.getAttribute("aria-hidden") }), o.setAttribute("aria-hidden", "true"), b && o.setAttribute("inert", ""));
|
|
98
122
|
}
|
|
99
123
|
return () => {
|
|
100
|
-
for (const { el: o, ariaHidden:
|
|
101
|
-
|
|
124
|
+
for (const { el: o, ariaHidden: r } of s)
|
|
125
|
+
r === null ? o.removeAttribute("aria-hidden") : o.setAttribute("aria-hidden", r), b && o.removeAttribute("inert");
|
|
102
126
|
};
|
|
103
127
|
}
|
|
104
|
-
function
|
|
105
|
-
|
|
128
|
+
function O(t, e) {
|
|
129
|
+
c.useEffect(() => {
|
|
106
130
|
if (!t || !e || typeof document > "u") return;
|
|
107
|
-
const
|
|
108
|
-
for (const
|
|
109
|
-
|
|
110
|
-
return
|
|
131
|
+
const n = /* @__PURE__ */ new Set();
|
|
132
|
+
for (const s of l)
|
|
133
|
+
s.element && n.add(s.element);
|
|
134
|
+
return M(e, n);
|
|
111
135
|
}, [t, e]);
|
|
112
136
|
}
|
|
113
|
-
function
|
|
114
|
-
const o =
|
|
115
|
-
|
|
137
|
+
function N({ active: t, container: e, initialFocus: n = "first", restoreFocus: s = !0 }) {
|
|
138
|
+
const o = c.useRef(null);
|
|
139
|
+
c.useEffect(() => {
|
|
116
140
|
if (!t) return;
|
|
117
141
|
o.current = document.activeElement ?? null;
|
|
118
|
-
const u = (
|
|
142
|
+
const u = (n === !1 ? null : n === "container" ? e : n === "first" ? y(e)[0] ?? e : n.current ?? null) ?? e;
|
|
119
143
|
u && u.isConnected && !u.contains(document.activeElement) && (!u.hasAttribute("tabindex") && u.tagName !== "INPUT" && u.tagName !== "BUTTON" && u.tagName !== "TEXTAREA" && u.tagName !== "SELECT" && u.tagName !== "A" && !u.isContentEditable && u.setAttribute("tabindex", "-1"), u.focus());
|
|
120
|
-
}, [t, e,
|
|
144
|
+
}, [t, e, n]), c.useEffect(() => {
|
|
121
145
|
if (t) return;
|
|
122
|
-
const
|
|
123
|
-
!
|
|
124
|
-
}, [t,
|
|
146
|
+
const r = o.current;
|
|
147
|
+
!r || !s || (o.current = null, r.isConnected && r.focus());
|
|
148
|
+
}, [t, s]), c.useEffect(
|
|
125
149
|
() => () => {
|
|
126
|
-
const
|
|
127
|
-
|
|
150
|
+
const r = o.current;
|
|
151
|
+
r && s && r.isConnected && r.focus();
|
|
128
152
|
},
|
|
129
|
-
[
|
|
130
|
-
),
|
|
153
|
+
[s]
|
|
154
|
+
), c.useEffect(() => {
|
|
131
155
|
if (!t) return;
|
|
132
|
-
const
|
|
156
|
+
const r = (u) => {
|
|
133
157
|
if (u.key !== "Tab") return;
|
|
134
158
|
const i = y(e);
|
|
135
159
|
if (i.length === 0) {
|
|
136
160
|
e && !e.contains(document.activeElement) && (u.preventDefault(), e.focus());
|
|
137
161
|
return;
|
|
138
162
|
}
|
|
139
|
-
const
|
|
163
|
+
const f = i[0], a = i[i.length - 1], d = document.activeElement;
|
|
140
164
|
if (!d || !(e != null && e.contains(d))) {
|
|
141
|
-
u.preventDefault(),
|
|
165
|
+
u.preventDefault(), f.focus();
|
|
142
166
|
return;
|
|
143
167
|
}
|
|
144
|
-
u.shiftKey && d ===
|
|
168
|
+
u.shiftKey && d === f ? (u.preventDefault(), a.focus()) : !u.shiftKey && d === a && (u.preventDefault(), f.focus());
|
|
145
169
|
};
|
|
146
|
-
return document.addEventListener("keydown",
|
|
170
|
+
return document.addEventListener("keydown", r, !0), () => document.removeEventListener("keydown", r, !0);
|
|
147
171
|
}, [t, e]);
|
|
148
172
|
}
|
|
149
|
-
function
|
|
173
|
+
function D({
|
|
150
174
|
open: t,
|
|
151
175
|
onEscape: e,
|
|
152
|
-
modal:
|
|
153
|
-
initialFocus:
|
|
176
|
+
modal: n = !0,
|
|
177
|
+
initialFocus: s = "first",
|
|
154
178
|
restoreFocus: o = !0
|
|
155
179
|
}) {
|
|
156
|
-
const [
|
|
157
|
-
return R(t,
|
|
180
|
+
const [r, u] = c.useState(null), { setElement: i, isTop: f } = A(t);
|
|
181
|
+
return R(t, f, () => e == null ? void 0 : e()), C(t && n), O(t && n && r != null, r), N({ active: t && n, container: r, initialFocus: s, restoreFocus: o }), { ref: c.useCallback(
|
|
158
182
|
(d) => {
|
|
159
183
|
u(d), i(d);
|
|
160
184
|
},
|
|
161
185
|
[i]
|
|
162
|
-
), element:
|
|
186
|
+
), element: r, top: f };
|
|
163
187
|
}
|
|
164
|
-
const
|
|
188
|
+
const K = {
|
|
165
189
|
name: "useOverlay",
|
|
166
190
|
props: [
|
|
167
191
|
{ name: "open", type: "boolean", default: null, control: "boolean" },
|
|
@@ -172,18 +196,19 @@ const D = {
|
|
|
172
196
|
]
|
|
173
197
|
};
|
|
174
198
|
export {
|
|
175
|
-
|
|
199
|
+
x as Portal,
|
|
176
200
|
y as getFocusable,
|
|
177
201
|
k as isTopOverlay,
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
202
|
+
B as overlayCount,
|
|
203
|
+
K as overlayPropsMeta,
|
|
204
|
+
T as pushOverlay,
|
|
205
|
+
w as removeOverlay,
|
|
182
206
|
R as useEscapeKey,
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
207
|
+
N as useFocusTrap,
|
|
208
|
+
O as useInertBackground,
|
|
209
|
+
I as useMountTransition,
|
|
210
|
+
D as useOverlay,
|
|
211
|
+
A as useOverlayStack,
|
|
212
|
+
v as useReducedMotion,
|
|
213
|
+
C as useScrollLock
|
|
189
214
|
};
|