@versini/ui-modal 3.0.1 → 3.1.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/index.d.ts +40 -19
- package/dist/index.js +186 -15
- package/package.json +9 -13
- package/dist/components/Modal/Modal.js +0 -53
- package/dist/components/Modal/ModalContext.js +0 -5
- package/dist/components/Modal/ModalHooks.js +0 -41
package/dist/index.d.ts
CHANGED
|
@@ -1,19 +1,40 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
declare const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
1
|
+
import { JSX } from 'react/jsx-runtime';
|
|
2
|
+
import * as React_2 from 'react';
|
|
3
|
+
|
|
4
|
+
export declare function Modal({ children, ...options }: {
|
|
5
|
+
children: React_2.ReactNode;
|
|
6
|
+
} & ModalTypes.Options): JSX.Element;
|
|
7
|
+
|
|
8
|
+
export declare const ModalClose: React_2.ForwardRefExoticComponent<{
|
|
9
|
+
trigger: React_2.ReactElement;
|
|
10
|
+
className?: string;
|
|
11
|
+
} & React_2.RefAttributes<HTMLButtonElement>>;
|
|
12
|
+
|
|
13
|
+
export declare const ModalContent: React_2.ForwardRefExoticComponent<Omit<React_2.HTMLProps<HTMLDivElement> & overlayBackgroundProps, "ref"> & React_2.RefAttributes<HTMLDivElement>>;
|
|
14
|
+
|
|
15
|
+
export declare const ModalDescription: React_2.ForwardRefExoticComponent<Omit<React_2.HTMLProps<HTMLParagraphElement>, "ref"> & React_2.RefAttributes<HTMLParagraphElement>>;
|
|
16
|
+
|
|
17
|
+
export declare const ModalHeading: React_2.ForwardRefExoticComponent<Omit<React_2.HTMLProps<HTMLHeadingElement>, "ref"> & React_2.RefAttributes<HTMLHeadingElement>>;
|
|
18
|
+
|
|
19
|
+
declare namespace ModalTypes {
|
|
20
|
+
type Options = {
|
|
21
|
+
initialOpen?: boolean;
|
|
22
|
+
onOpenChange?: (open: boolean) => void;
|
|
23
|
+
open?: boolean;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
type Context =
|
|
27
|
+
| (ReturnType<Options> & {
|
|
28
|
+
setDescriptionId: React.Dispatch<
|
|
29
|
+
React.SetStateAction<string | undefined>
|
|
30
|
+
>;
|
|
31
|
+
setLabelId: React.Dispatch<React.SetStateAction<string | undefined>>;
|
|
32
|
+
})
|
|
33
|
+
| null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
declare type overlayBackgroundProps = {
|
|
37
|
+
overlayBackground?: string;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export { }
|
package/dist/index.js
CHANGED
|
@@ -1,21 +1,192 @@
|
|
|
1
|
-
import { Modal as _, ModalClose as n, ModalContent as t, ModalDescription as a, ModalHeading as d } from "./components/Modal/Modal.js";
|
|
2
1
|
/*!
|
|
3
|
-
@versini/ui-modal v3.0
|
|
2
|
+
@versini/ui-modal v3.1.0
|
|
4
3
|
© 2025 gizmette.com
|
|
5
4
|
*/
|
|
6
5
|
try {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
6
|
+
if (!window.__VERSINI_UI_MODAL__) {
|
|
7
|
+
window.__VERSINI_UI_MODAL__ = {
|
|
8
|
+
version: "3.1.0",
|
|
9
|
+
buildTime: "11/04/2025 03:43 PM EST",
|
|
10
|
+
homepage: "https://github.com/aversini/ui-components",
|
|
11
|
+
license: "MIT",
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
} catch (error) {
|
|
15
|
+
// nothing to declare officer
|
|
14
16
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
|
|
18
|
+
import { jsx } from "react/jsx-runtime";
|
|
19
|
+
import { FloatingFocusManager, FloatingOverlay, FloatingPortal, useClick, useDismiss, useFloating, useInteractions, useMergeRefs, useRole } from "@floating-ui/react";
|
|
20
|
+
import clsx from "clsx";
|
|
21
|
+
import { cloneElement, createContext, forwardRef, useCallback, useContext, useId, useLayoutEffect, useMemo, useState } from "react";
|
|
22
|
+
|
|
23
|
+
;// CONCATENATED MODULE: external "react/jsx-runtime"
|
|
24
|
+
|
|
25
|
+
;// CONCATENATED MODULE: external "@floating-ui/react"
|
|
26
|
+
|
|
27
|
+
;// CONCATENATED MODULE: external "clsx"
|
|
28
|
+
|
|
29
|
+
;// CONCATENATED MODULE: external "react"
|
|
30
|
+
|
|
31
|
+
;// CONCATENATED MODULE: ./src/components/Modal/ModalContext.tsx
|
|
32
|
+
|
|
33
|
+
const ModalContext = /*#__PURE__*/ createContext(null);
|
|
34
|
+
|
|
35
|
+
;// CONCATENATED MODULE: ./src/components/Modal/ModalHooks.tsx
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
function useModal({ initialOpen = false, open: controlledOpen, onOpenChange: setControlledOpen } = {}) {
|
|
40
|
+
const [uncontrolledOpen, setUncontrolledOpen] = useState(initialOpen);
|
|
41
|
+
const [labelId, setLabelId] = useState();
|
|
42
|
+
const [descriptionId, setDescriptionId] = useState();
|
|
43
|
+
/* v8 ignore next 2 */ const open = controlledOpen ?? uncontrolledOpen;
|
|
44
|
+
const setOpen = setControlledOpen ?? setUncontrolledOpen;
|
|
45
|
+
const data = useFloating({
|
|
46
|
+
open,
|
|
47
|
+
onOpenChange: setOpen
|
|
48
|
+
});
|
|
49
|
+
const context = data.context;
|
|
50
|
+
const click = useClick(context, {
|
|
51
|
+
enabled: controlledOpen == null
|
|
52
|
+
});
|
|
53
|
+
const dismiss = useDismiss(context, {
|
|
54
|
+
outsidePress: false,
|
|
55
|
+
outsidePressEvent: "mousedown"
|
|
56
|
+
});
|
|
57
|
+
const role = useRole(context);
|
|
58
|
+
const interactions = useInteractions([
|
|
59
|
+
click,
|
|
60
|
+
dismiss,
|
|
61
|
+
role
|
|
62
|
+
]);
|
|
63
|
+
return useMemo(()=>({
|
|
64
|
+
open,
|
|
65
|
+
setOpen,
|
|
66
|
+
...interactions,
|
|
67
|
+
...data,
|
|
68
|
+
labelId,
|
|
69
|
+
descriptionId,
|
|
70
|
+
setLabelId,
|
|
71
|
+
setDescriptionId
|
|
72
|
+
}), [
|
|
73
|
+
open,
|
|
74
|
+
setOpen,
|
|
75
|
+
interactions,
|
|
76
|
+
data,
|
|
77
|
+
labelId,
|
|
78
|
+
descriptionId
|
|
79
|
+
]);
|
|
80
|
+
}
|
|
81
|
+
const useModalContext = ()=>{
|
|
82
|
+
const context = useContext(ModalContext);
|
|
83
|
+
/* v8 ignore next 3 */ if (context == null) {
|
|
84
|
+
throw new Error("Modal components must be wrapped in <Modal />");
|
|
85
|
+
}
|
|
86
|
+
return context;
|
|
21
87
|
};
|
|
88
|
+
|
|
89
|
+
;// CONCATENATED MODULE: ./src/components/Modal/Modal.tsx
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
function Modal({ children, ...options }) {
|
|
98
|
+
const dialog = useModal(options);
|
|
99
|
+
return /*#__PURE__*/ jsx(ModalContext.Provider, {
|
|
100
|
+
value: dialog,
|
|
101
|
+
children: children
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
const Modal_ModalContent = /*#__PURE__*/ forwardRef(function ModalContent(props, propRef) {
|
|
105
|
+
const { context: floatingContext, ...context } = useModalContext();
|
|
106
|
+
const ref = useMergeRefs([
|
|
107
|
+
context.refs.setFloating,
|
|
108
|
+
propRef
|
|
109
|
+
]);
|
|
110
|
+
/* v8 ignore next 3 */ if (!floatingContext.open) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
const { overlayBackground, ...rest } = props;
|
|
114
|
+
const overlayClass = clsx("grid place-items-center", {
|
|
115
|
+
[`${overlayBackground}`]: overlayBackground,
|
|
116
|
+
"bg-black sm:bg-black/[.8]": !overlayBackground
|
|
117
|
+
});
|
|
118
|
+
return /*#__PURE__*/ jsx(FloatingPortal, {
|
|
119
|
+
children: /*#__PURE__*/ jsx(FloatingOverlay, {
|
|
120
|
+
className: overlayClass,
|
|
121
|
+
lockScroll: true,
|
|
122
|
+
children: /*#__PURE__*/ jsx(FloatingFocusManager, {
|
|
123
|
+
context: floatingContext,
|
|
124
|
+
children: /*#__PURE__*/ jsx("div", {
|
|
125
|
+
ref: ref,
|
|
126
|
+
"aria-labelledby": context.labelId,
|
|
127
|
+
"aria-describedby": context.descriptionId,
|
|
128
|
+
...context.getFloatingProps(rest),
|
|
129
|
+
children: rest.children
|
|
130
|
+
})
|
|
131
|
+
})
|
|
132
|
+
})
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
const Modal_ModalHeading = /*#__PURE__*/ forwardRef(function ModalHeading({ children, ...props }, ref) {
|
|
136
|
+
const { setLabelId } = useModalContext();
|
|
137
|
+
const id = useId();
|
|
138
|
+
// Only sets `aria-labelledby` on the Modal root element
|
|
139
|
+
// if this component is mounted inside it.
|
|
140
|
+
useLayoutEffect(()=>{
|
|
141
|
+
setLabelId(id);
|
|
142
|
+
return ()=>setLabelId(undefined);
|
|
143
|
+
}, [
|
|
144
|
+
id,
|
|
145
|
+
setLabelId
|
|
146
|
+
]);
|
|
147
|
+
return /*#__PURE__*/ jsx("h1", {
|
|
148
|
+
...props,
|
|
149
|
+
ref: ref,
|
|
150
|
+
id: id,
|
|
151
|
+
children: children
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
const Modal_ModalDescription = /*#__PURE__*/ forwardRef(function ModalDescription({ children, ...props }, ref) {
|
|
155
|
+
const { setDescriptionId } = useModalContext();
|
|
156
|
+
const id = useId();
|
|
157
|
+
// Only sets `aria-describedby` on the Modal root element
|
|
158
|
+
// if this component is mounted inside it.
|
|
159
|
+
useLayoutEffect(()=>{
|
|
160
|
+
setDescriptionId(id);
|
|
161
|
+
return ()=>setDescriptionId(undefined);
|
|
162
|
+
}, [
|
|
163
|
+
id,
|
|
164
|
+
setDescriptionId
|
|
165
|
+
]);
|
|
166
|
+
return /*#__PURE__*/ jsx("div", {
|
|
167
|
+
...props,
|
|
168
|
+
ref: ref,
|
|
169
|
+
id: id,
|
|
170
|
+
children: children
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
const Modal_ModalClose = /*#__PURE__*/ forwardRef(function ModalClose(props, ref) {
|
|
174
|
+
const { setOpen } = useModalContext();
|
|
175
|
+
const { trigger, className, ...rest } = props;
|
|
176
|
+
const handleClose = useCallback(()=>setOpen(false), [
|
|
177
|
+
setOpen
|
|
178
|
+
]);
|
|
179
|
+
return /*#__PURE__*/ jsx("div", {
|
|
180
|
+
className: className,
|
|
181
|
+
children: /*#__PURE__*/ cloneElement(trigger, {
|
|
182
|
+
ref,
|
|
183
|
+
onClick: handleClose,
|
|
184
|
+
...rest
|
|
185
|
+
})
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
;// CONCATENATED MODULE: ./src/components/index.ts
|
|
190
|
+
/* v8 ignore next 1 */
|
|
191
|
+
|
|
192
|
+
export { Modal, Modal_ModalClose as ModalClose, Modal_ModalContent as ModalContent, Modal_ModalDescription as ModalDescription, Modal_ModalHeading as ModalHeading };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@versini/ui-modal",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Arno Versini",
|
|
6
6
|
"publishConfig": {
|
|
@@ -20,24 +20,20 @@
|
|
|
20
20
|
],
|
|
21
21
|
"scripts": {
|
|
22
22
|
"build:check": "tsc",
|
|
23
|
-
"build:js": "
|
|
24
|
-
"build:types": "
|
|
25
|
-
"build": "npm-run-all --serial clean build:check build:js
|
|
23
|
+
"build:js": "rslib build",
|
|
24
|
+
"build:types": "echo 'Types now built with rslib'",
|
|
25
|
+
"build": "npm-run-all --serial clean build:check build:js",
|
|
26
26
|
"clean": "rimraf dist tmp",
|
|
27
|
-
"dev:js": "
|
|
28
|
-
"dev:types": "
|
|
29
|
-
"dev": "
|
|
27
|
+
"dev:js": "rslib build --watch",
|
|
28
|
+
"dev:types": "echo 'Types now watched with rslib'",
|
|
29
|
+
"dev": "rslib build --watch",
|
|
30
30
|
"lint": "biome lint src",
|
|
31
31
|
"lint:fix": "biome check src --write --no-errors-on-unmatched",
|
|
32
32
|
"prettier": "biome check --write --no-errors-on-unmatched",
|
|
33
33
|
"start": "static-server dist --port 5173"
|
|
34
34
|
},
|
|
35
|
-
"peerDependencies": {
|
|
36
|
-
"react": "^19.1.0",
|
|
37
|
-
"react-dom": "^19.1.0"
|
|
38
|
-
},
|
|
39
35
|
"devDependencies": {
|
|
40
|
-
"@versini/ui-types": "6.0.
|
|
36
|
+
"@versini/ui-types": "6.0.2"
|
|
41
37
|
},
|
|
42
38
|
"dependencies": {
|
|
43
39
|
"@floating-ui/react": "0.27.16",
|
|
@@ -46,5 +42,5 @@
|
|
|
46
42
|
"sideEffects": [
|
|
47
43
|
"**/*.css"
|
|
48
44
|
],
|
|
49
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "7484ad443b77ef31e52ae3a7d88b8129bc6cdf1d"
|
|
50
46
|
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { jsx as l } from "react/jsx-runtime";
|
|
2
|
-
import { useMergeRefs as m, FloatingPortal as g, FloatingOverlay as p, FloatingFocusManager as M } from "@floating-ui/react";
|
|
3
|
-
import b from "clsx";
|
|
4
|
-
import * as a from "react";
|
|
5
|
-
import { useId as f } from "react";
|
|
6
|
-
import { ModalContext as C } from "./ModalContext.js";
|
|
7
|
-
import { useModalContext as d, useModal as v } from "./ModalHooks.js";
|
|
8
|
-
function I({
|
|
9
|
-
children: s,
|
|
10
|
-
...t
|
|
11
|
-
}) {
|
|
12
|
-
const n = v(t);
|
|
13
|
-
return /* @__PURE__ */ l(C.Provider, { value: n, children: s });
|
|
14
|
-
}
|
|
15
|
-
const w = a.forwardRef(function(t, n) {
|
|
16
|
-
const { context: r, ...o } = d(), e = m([o.refs.setFloating, n]);
|
|
17
|
-
if (!r.open)
|
|
18
|
-
return null;
|
|
19
|
-
const { overlayBackground: c, ...i } = t, u = b("grid place-items-center", {
|
|
20
|
-
[`${c}`]: c,
|
|
21
|
-
"bg-black sm:bg-black/[.8]": !c
|
|
22
|
-
});
|
|
23
|
-
return /* @__PURE__ */ l(g, { children: /* @__PURE__ */ l(p, { className: u, lockScroll: !0, children: /* @__PURE__ */ l(M, { context: r, children: /* @__PURE__ */ l(
|
|
24
|
-
"div",
|
|
25
|
-
{
|
|
26
|
-
ref: e,
|
|
27
|
-
"aria-labelledby": o.labelId,
|
|
28
|
-
"aria-describedby": o.descriptionId,
|
|
29
|
-
...o.getFloatingProps(i),
|
|
30
|
-
children: i.children
|
|
31
|
-
}
|
|
32
|
-
) }) }) });
|
|
33
|
-
}), D = a.forwardRef(function({ children: t, ...n }, r) {
|
|
34
|
-
const { setLabelId: o } = d(), e = f();
|
|
35
|
-
return a.useLayoutEffect(() => (o(e), () => o(void 0)), [e, o]), /* @__PURE__ */ l("h1", { ...n, ref: r, id: e, children: t });
|
|
36
|
-
}), E = a.forwardRef(function({ children: t, ...n }, r) {
|
|
37
|
-
const { setDescriptionId: o } = d(), e = f();
|
|
38
|
-
return a.useLayoutEffect(() => (o(e), () => o(void 0)), [e, o]), /* @__PURE__ */ l("div", { ...n, ref: r, id: e, children: t });
|
|
39
|
-
}), L = a.forwardRef(function(t, n) {
|
|
40
|
-
const { setOpen: r } = d(), { trigger: o, className: e, ...c } = t, i = a.useCallback(() => r(!1), [r]);
|
|
41
|
-
return /* @__PURE__ */ l("div", { className: e, children: a.cloneElement(o, {
|
|
42
|
-
ref: n,
|
|
43
|
-
onClick: i,
|
|
44
|
-
...c
|
|
45
|
-
}) });
|
|
46
|
-
});
|
|
47
|
-
export {
|
|
48
|
-
I as Modal,
|
|
49
|
-
L as ModalClose,
|
|
50
|
-
w as ModalContent,
|
|
51
|
-
E as ModalDescription,
|
|
52
|
-
D as ModalHeading
|
|
53
|
-
};
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { useFloating as I, useClick as b, useDismiss as w, useRole as O, useInteractions as g } from "@floating-ui/react";
|
|
2
|
-
import * as e from "react";
|
|
3
|
-
import { ModalContext as h } from "./ModalContext.js";
|
|
4
|
-
function D({
|
|
5
|
-
initialOpen: t = !1,
|
|
6
|
-
open: r,
|
|
7
|
-
onOpenChange: u
|
|
8
|
-
} = {}) {
|
|
9
|
-
const [d, p] = e.useState(t), [a, m] = e.useState(), [i, f] = e.useState(), o = r ?? d, n = u ?? p, s = I({
|
|
10
|
-
open: o,
|
|
11
|
-
onOpenChange: n
|
|
12
|
-
}), c = s.context, x = b(c, {
|
|
13
|
-
enabled: r == null
|
|
14
|
-
}), C = w(c, {
|
|
15
|
-
outsidePress: !1,
|
|
16
|
-
outsidePressEvent: "mousedown"
|
|
17
|
-
}), M = O(c), l = g([x, C, M]);
|
|
18
|
-
return e.useMemo(
|
|
19
|
-
() => ({
|
|
20
|
-
open: o,
|
|
21
|
-
setOpen: n,
|
|
22
|
-
...l,
|
|
23
|
-
...s,
|
|
24
|
-
labelId: a,
|
|
25
|
-
descriptionId: i,
|
|
26
|
-
setLabelId: m,
|
|
27
|
-
setDescriptionId: f
|
|
28
|
-
}),
|
|
29
|
-
[o, n, l, s, a, i]
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
const E = () => {
|
|
33
|
-
const t = e.useContext(h);
|
|
34
|
-
if (t == null)
|
|
35
|
-
throw new Error("Modal components must be wrapped in <Modal />");
|
|
36
|
-
return t;
|
|
37
|
-
};
|
|
38
|
-
export {
|
|
39
|
-
D as useModal,
|
|
40
|
-
E as useModalContext
|
|
41
|
-
};
|