@prokodo/ui 0.0.51 → 0.0.52
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/drawer/Drawer.base.module.scss.js +0 -24
- package/dist/components/drawer/Drawer.client.js +78 -46
- package/dist/components/drawer/Drawer.effects.client.js +73 -7
- package/dist/components/drawer/Drawer.server.js +1 -0
- package/dist/components/drawer/Drawer.view.js +13 -2
- package/dist/constants/project.js +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types/components/drawer/Drawer.effects.client.d.ts +6 -2
- package/dist/ui.css +16 -245
- package/package.json +1 -1
- package/dist/components/drawer/Drawer.effects.module.scss.js +0 -29
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
const DrawerSlideInLeft = "DrawerSlideInLeft";
|
|
2
|
-
const DrawerSlideOutLeft = "DrawerSlideOutLeft";
|
|
3
|
-
const DrawerSlideInRight = "DrawerSlideInRight";
|
|
4
|
-
const DrawerSlideOutRight = "DrawerSlideOutRight";
|
|
5
|
-
const DrawerSlideInTop = "DrawerSlideInTop";
|
|
6
|
-
const DrawerSlideOutTop = "DrawerSlideOutTop";
|
|
7
|
-
const DrawerSlideInBottom = "DrawerSlideInBottom";
|
|
8
|
-
const DrawerSlideOutBottom = "DrawerSlideOutBottom";
|
|
9
1
|
const styles = {
|
|
10
2
|
"prokodo-Drawer": "prokodo-Drawer",
|
|
11
3
|
"prokodo-Drawer__backdrop": "prokodo-Drawer__backdrop",
|
|
@@ -15,31 +7,15 @@ const styles = {
|
|
|
15
7
|
"prokodo-Drawer__container--fullscreen": "prokodo-Drawer__container--fullscreen",
|
|
16
8
|
"prokodo-Drawer__container--anchor-left": "prokodo-Drawer__container--anchor-left",
|
|
17
9
|
"prokodo-Drawer__container--anchor-left--open": "prokodo-Drawer__container--anchor-left--open",
|
|
18
|
-
DrawerSlideInLeft,
|
|
19
|
-
DrawerSlideOutLeft,
|
|
20
10
|
"prokodo-Drawer__container--anchor-right": "prokodo-Drawer__container--anchor-right",
|
|
21
11
|
"prokodo-Drawer__container--anchor-right--open": "prokodo-Drawer__container--anchor-right--open",
|
|
22
|
-
DrawerSlideInRight,
|
|
23
|
-
DrawerSlideOutRight,
|
|
24
12
|
"prokodo-Drawer__container--anchor-top": "prokodo-Drawer__container--anchor-top",
|
|
25
13
|
"prokodo-Drawer__container--anchor-top--open": "prokodo-Drawer__container--anchor-top--open",
|
|
26
|
-
DrawerSlideInTop,
|
|
27
|
-
DrawerSlideOutTop,
|
|
28
14
|
"prokodo-Drawer__container--anchor-bottom": "prokodo-Drawer__container--anchor-bottom",
|
|
29
15
|
"prokodo-Drawer__container--anchor-bottom--open": "prokodo-Drawer__container--anchor-bottom--open",
|
|
30
|
-
DrawerSlideInBottom,
|
|
31
|
-
DrawerSlideOutBottom,
|
|
32
16
|
"prokodo-Drawer__header": "prokodo-Drawer__header",
|
|
33
17
|
"prokodo-Drawer__content": "prokodo-Drawer__content"
|
|
34
18
|
};
|
|
35
19
|
export {
|
|
36
|
-
DrawerSlideInBottom,
|
|
37
|
-
DrawerSlideInLeft,
|
|
38
|
-
DrawerSlideInRight,
|
|
39
|
-
DrawerSlideInTop,
|
|
40
|
-
DrawerSlideOutBottom,
|
|
41
|
-
DrawerSlideOutLeft,
|
|
42
|
-
DrawerSlideOutRight,
|
|
43
|
-
DrawerSlideOutTop,
|
|
44
20
|
styles as default
|
|
45
21
|
};
|
|
@@ -2,70 +2,102 @@
|
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
|
-
import { forwardRef, useRef, useState,
|
|
5
|
+
import { forwardRef, useRef, useState, useLayoutEffect, useEffect, useCallback, useImperativeHandle } from "react";
|
|
6
6
|
import { DrawerView } from "./Drawer.view.js";
|
|
7
7
|
function DrawerClient({ open = false, closeOnBackdropClick = true, onChange, ...props }, ref) {
|
|
8
8
|
const triggerRef = useRef(null);
|
|
9
9
|
const closeButtonRef = useRef(null);
|
|
10
10
|
const containerRef = useRef(null);
|
|
11
|
-
const [isOpen, setIsOpen] = useState(() => open);
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
setIsOpen(true);
|
|
16
|
-
}, []);
|
|
17
|
-
const closeDrawer = useCallback(
|
|
18
|
-
(reason) => {
|
|
19
|
-
var _a;
|
|
11
|
+
const [isOpen, setIsOpen] = useState(() => Boolean(open));
|
|
12
|
+
const [mounted, setMounted] = useState(() => Boolean(open));
|
|
13
|
+
useLayoutEffect(() => {
|
|
14
|
+
if (!open) {
|
|
20
15
|
setIsOpen(false);
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
(_a = triggerRef.current) == null ? void 0 : _a.focus();
|
|
25
|
-
},
|
|
26
|
-
[onChange]
|
|
27
|
-
);
|
|
16
|
+
setMounted(false);
|
|
17
|
+
}
|
|
18
|
+
}, [open]);
|
|
28
19
|
useEffect(() => {
|
|
29
|
-
|
|
30
|
-
syncingFromPropRef.current = true;
|
|
31
|
-
if (open && !isOpen) {
|
|
20
|
+
if (open) {
|
|
32
21
|
triggerRef.current = document.activeElement;
|
|
33
|
-
|
|
34
|
-
|
|
22
|
+
if (!mounted) setMounted(true);
|
|
23
|
+
requestAnimationFrame(() => {
|
|
24
|
+
requestAnimationFrame(() => {
|
|
25
|
+
var _a;
|
|
26
|
+
(_a = containerRef.current) == null ? void 0 : _a.getBoundingClientRect();
|
|
27
|
+
setIsOpen(true);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
} else {
|
|
35
31
|
setIsOpen(false);
|
|
36
|
-
(_a = triggerRef.current) == null ? void 0 : _a.focus();
|
|
37
32
|
}
|
|
38
|
-
|
|
39
|
-
syncingFromPropRef.current = false;
|
|
40
|
-
});
|
|
41
|
-
}, [open, isOpen]);
|
|
42
|
-
useImperativeHandle(
|
|
43
|
-
ref,
|
|
44
|
-
() => ({
|
|
45
|
-
openDrawer,
|
|
46
|
-
closeDrawer
|
|
47
|
-
}),
|
|
48
|
-
[openDrawer, closeDrawer]
|
|
49
|
-
);
|
|
33
|
+
}, [open, mounted]);
|
|
50
34
|
useEffect(() => {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
35
|
+
if (isOpen || !mounted) return;
|
|
36
|
+
const node = containerRef.current;
|
|
37
|
+
if (!node) {
|
|
38
|
+
setMounted(false);
|
|
39
|
+
return;
|
|
54
40
|
}
|
|
55
|
-
|
|
41
|
+
const onEnd = /* @__PURE__ */ __name((e) => {
|
|
42
|
+
var _a, _b;
|
|
43
|
+
if (e.target !== node) return;
|
|
44
|
+
node.removeEventListener("transitionend", onEnd);
|
|
45
|
+
setMounted(false);
|
|
46
|
+
(_b = (_a = triggerRef.current) == null ? void 0 : _a.focus) == null ? void 0 : _b.call(_a);
|
|
47
|
+
}, "onEnd");
|
|
48
|
+
node.addEventListener("transitionend", onEnd);
|
|
49
|
+
const t = setTimeout(() => {
|
|
50
|
+
var _a, _b;
|
|
51
|
+
node.removeEventListener("transitionend", onEnd);
|
|
52
|
+
setMounted(false);
|
|
53
|
+
(_b = (_a = triggerRef.current) == null ? void 0 : _a.focus) == null ? void 0 : _b.call(_a);
|
|
54
|
+
}, 450);
|
|
55
|
+
return () => {
|
|
56
|
+
node.removeEventListener("transitionend", onEnd);
|
|
57
|
+
clearTimeout(t);
|
|
58
|
+
};
|
|
59
|
+
}, [isOpen, mounted]);
|
|
60
|
+
const closeDrawer = useCallback(
|
|
61
|
+
(reason) => {
|
|
62
|
+
var _a, _b;
|
|
63
|
+
setIsOpen(false);
|
|
64
|
+
onChange == null ? void 0 : onChange({}, reason ?? "backdropClick");
|
|
65
|
+
(_b = (_a = triggerRef.current) == null ? void 0 : _a.focus) == null ? void 0 : _b.call(_a);
|
|
66
|
+
},
|
|
67
|
+
[onChange]
|
|
68
|
+
);
|
|
56
69
|
useEffect(() => {
|
|
57
70
|
if (!isOpen) return;
|
|
58
|
-
const
|
|
71
|
+
const onKey = /* @__PURE__ */ __name((e) => {
|
|
59
72
|
if (e.key === "Escape") {
|
|
60
73
|
e.preventDefault();
|
|
61
74
|
closeDrawer("escapeKeyDown");
|
|
62
75
|
}
|
|
63
|
-
}, "
|
|
64
|
-
window.addEventListener("keydown",
|
|
65
|
-
return () =>
|
|
66
|
-
window.removeEventListener("keydown", handleKey);
|
|
67
|
-
};
|
|
76
|
+
}, "onKey");
|
|
77
|
+
window.addEventListener("keydown", onKey);
|
|
78
|
+
return () => window.removeEventListener("keydown", onKey);
|
|
68
79
|
}, [isOpen, closeDrawer]);
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
if (!isOpen) return;
|
|
82
|
+
const id = requestAnimationFrame(() => {
|
|
83
|
+
var _a, _b;
|
|
84
|
+
(_b = (_a = closeButtonRef.current) == null ? void 0 : _a.focus) == null ? void 0 : _b.call(_a);
|
|
85
|
+
});
|
|
86
|
+
return () => cancelAnimationFrame(id);
|
|
87
|
+
}, [isOpen]);
|
|
88
|
+
const openDrawer = useCallback(() => {
|
|
89
|
+
triggerRef.current = document.activeElement;
|
|
90
|
+
setMounted(true);
|
|
91
|
+
requestAnimationFrame(() => {
|
|
92
|
+
requestAnimationFrame(() => {
|
|
93
|
+
var _a;
|
|
94
|
+
(_a = containerRef.current) == null ? void 0 : _a.getBoundingClientRect();
|
|
95
|
+
setIsOpen(true);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
}, []);
|
|
99
|
+
useImperativeHandle(ref, () => ({ openDrawer, closeDrawer }), [openDrawer, closeDrawer]);
|
|
100
|
+
if (!mounted) return null;
|
|
69
101
|
return /* @__PURE__ */ jsx(
|
|
70
102
|
DrawerView,
|
|
71
103
|
{
|
|
@@ -76,7 +108,7 @@ function DrawerClient({ open = false, closeOnBackdropClick = true, onChange, ...
|
|
|
76
108
|
backdropProps: {
|
|
77
109
|
onMouseDown: /* @__PURE__ */ __name(() => {
|
|
78
110
|
if (isOpen && closeOnBackdropClick) {
|
|
79
|
-
closeDrawer
|
|
111
|
+
closeDrawer("backdropClick");
|
|
80
112
|
}
|
|
81
113
|
}, "onMouseDown")
|
|
82
114
|
},
|
|
@@ -1,16 +1,82 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
4
|
-
import { useEffect } from "react";
|
|
5
|
-
|
|
4
|
+
import { useRef, useEffect } from "react";
|
|
5
|
+
import { isString } from "../../helpers/validations.js";
|
|
6
|
+
const FOCUSABLE = 'a[href], area[href], button:not([disabled]), input:not([disabled]):not([type=hidden]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
7
|
+
const DrawerEffectsLoader = /* @__PURE__ */ __name(({
|
|
8
|
+
isOpen,
|
|
9
|
+
containerRef,
|
|
10
|
+
closeButtonRef,
|
|
11
|
+
onClose
|
|
12
|
+
}) => {
|
|
13
|
+
const lastFocused = useRef(null);
|
|
6
14
|
useEffect(() => {
|
|
7
|
-
if (
|
|
8
|
-
|
|
15
|
+
if (!isOpen) return;
|
|
16
|
+
const { body, documentElement } = document;
|
|
17
|
+
const { scrollY } = window;
|
|
18
|
+
const prev = {
|
|
19
|
+
overflow: body.style.overflow,
|
|
20
|
+
position: body.style.position,
|
|
21
|
+
top: body.style.top,
|
|
22
|
+
width: body.style.width,
|
|
23
|
+
overscroll: documentElement.style.overscrollBehavior
|
|
24
|
+
};
|
|
25
|
+
body.style.overflow = "hidden";
|
|
26
|
+
body.style.position = "fixed";
|
|
27
|
+
body.style.top = `-${scrollY}px`;
|
|
28
|
+
body.style.width = "100%";
|
|
29
|
+
documentElement.style.overscrollBehavior = "none";
|
|
30
|
+
return () => {
|
|
31
|
+
body.style.overflow = prev.overflow;
|
|
32
|
+
body.style.position = prev.position;
|
|
33
|
+
body.style.top = prev.top;
|
|
34
|
+
body.style.width = prev.width;
|
|
35
|
+
documentElement.style.overscrollBehavior = prev.overscroll;
|
|
36
|
+
window.scrollTo(0, scrollY);
|
|
37
|
+
};
|
|
38
|
+
}, [isOpen]);
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
var _a, _b;
|
|
41
|
+
const container = containerRef == null ? void 0 : containerRef.current;
|
|
42
|
+
if (!container) return;
|
|
43
|
+
if (isOpen) {
|
|
44
|
+
lastFocused.current = document.activeElement ?? null;
|
|
45
|
+
if (!container.hasAttribute("tabindex")) container.setAttribute("tabindex", "-1");
|
|
46
|
+
const first = (closeButtonRef == null ? void 0 : closeButtonRef.current) ?? container.querySelector(FOCUSABLE) ?? container;
|
|
47
|
+
first.focus({ preventScroll: true });
|
|
48
|
+
} else {
|
|
49
|
+
(_b = (_a = lastFocused.current) == null ? void 0 : _a.focus) == null ? void 0 : _b.call(_a);
|
|
9
50
|
}
|
|
10
|
-
}, [
|
|
51
|
+
}, [isOpen, containerRef, closeButtonRef]);
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
if (!isOpen) return;
|
|
54
|
+
const container = containerRef == null ? void 0 : containerRef.current;
|
|
55
|
+
if (!container) return;
|
|
56
|
+
const onKeydown = /* @__PURE__ */ __name((e) => {
|
|
57
|
+
if (e.key === "Escape") {
|
|
58
|
+
e.stopPropagation();
|
|
59
|
+
onClose == null ? void 0 : onClose("escapeKeyDown");
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (e.key !== "Tab") return;
|
|
63
|
+
const nodes = Array.from(container.querySelectorAll(FOCUSABLE)).filter((el) => !Boolean(el.hasAttribute("inert")) && !isString(el.getAttribute("aria-hidden")));
|
|
64
|
+
const [first] = nodes;
|
|
65
|
+
const last = nodes.at(-1);
|
|
66
|
+
if (!first || !last) return;
|
|
67
|
+
if (e.shiftKey && document.activeElement === first) {
|
|
68
|
+
e.preventDefault();
|
|
69
|
+
last.focus();
|
|
70
|
+
} else if (!e.shiftKey && document.activeElement === last) {
|
|
71
|
+
e.preventDefault();
|
|
72
|
+
first.focus();
|
|
73
|
+
}
|
|
74
|
+
}, "onKeydown");
|
|
75
|
+
document.addEventListener("keydown", onKeydown, true);
|
|
76
|
+
return () => document.removeEventListener("keydown", onKeydown, true);
|
|
77
|
+
}, [isOpen, containerRef, onClose]);
|
|
11
78
|
return null;
|
|
12
|
-
}
|
|
13
|
-
__name(DrawerEffectsLoader, "DrawerEffectsLoader");
|
|
79
|
+
}, "DrawerEffectsLoader");
|
|
14
80
|
export {
|
|
15
81
|
DrawerEffectsLoader
|
|
16
82
|
};
|
|
@@ -3,6 +3,7 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
|
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
import { DrawerView } from "./Drawer.view.js";
|
|
5
5
|
function DrawerServer(props) {
|
|
6
|
+
if (!Boolean(props.open)) return null;
|
|
6
7
|
return /* @__PURE__ */ jsx(DrawerView, { ...props });
|
|
7
8
|
}
|
|
8
9
|
__name(DrawerServer, "DrawerServer");
|
|
@@ -29,17 +29,28 @@ const DrawerView = /* @__PURE__ */ __name(({
|
|
|
29
29
|
return /* @__PURE__ */ jsxs(
|
|
30
30
|
"div",
|
|
31
31
|
{
|
|
32
|
+
"aria-hidden": isOpen ? void 0 : true,
|
|
32
33
|
className: bem("backdrop", { open: isOpen }),
|
|
33
34
|
...backdropProps,
|
|
34
35
|
children: [
|
|
35
|
-
/* @__PURE__ */ jsx(
|
|
36
|
+
/* @__PURE__ */ jsx(
|
|
37
|
+
DrawerEffectsLoader,
|
|
38
|
+
{
|
|
39
|
+
useSlide: true,
|
|
40
|
+
closeButtonRef,
|
|
41
|
+
containerRef,
|
|
42
|
+
isOpen,
|
|
43
|
+
onClose
|
|
44
|
+
}
|
|
45
|
+
),
|
|
36
46
|
/* @__PURE__ */ jsxs(
|
|
37
47
|
"div",
|
|
38
48
|
{
|
|
39
49
|
ref: containerRef,
|
|
40
50
|
"aria-labelledby": isString(title) ? "drawer-title" : void 0,
|
|
41
|
-
"aria-modal": "true",
|
|
42
51
|
role: "dialog",
|
|
52
|
+
...isOpen ? { "aria-modal": "true" } : { "aria-hidden": "true", inert: true },
|
|
53
|
+
"aria-modal": isOpen ? "true" : void 0,
|
|
43
54
|
className: bem(
|
|
44
55
|
"container",
|
|
45
56
|
{
|