@versini/ui-modal 3.3.1 → 3.3.3
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 +5 -1
- package/dist/index.js +51 -22
- package/package.json +5 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { JSX } from 'react/jsx-runtime';
|
|
2
2
|
import * as React_2 from 'react';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Modal component that supports proper nesting with ESC key handling.
|
|
6
|
+
* Automatically wraps root modals in FloatingTree for nested modal support.
|
|
7
|
+
*/
|
|
8
|
+
export declare function Modal(props: {
|
|
5
9
|
children: React_2.ReactNode;
|
|
6
10
|
} & ModalTypes.Options): JSX.Element;
|
|
7
11
|
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
@versini/ui-modal v3.3.
|
|
2
|
+
@versini/ui-modal v3.3.3
|
|
3
3
|
© 2025 gizmette.com
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { jsx } from "react/jsx-runtime";
|
|
7
|
-
import { FloatingFocusManager, FloatingOverlay, FloatingPortal, useClick, useDismiss, useFloating, useInteractions, useMergeRefs, useRole } from "@floating-ui/react";
|
|
7
|
+
import { FloatingFocusManager, FloatingNode, FloatingOverlay, FloatingPortal, FloatingTree, useClick, useDismiss, useFloating, useFloatingNodeId, useFloatingParentNodeId, useInteractions, useMergeRefs, useRole } from "@floating-ui/react";
|
|
8
8
|
import clsx from "clsx";
|
|
9
9
|
import { cloneElement, createContext, forwardRef, useCallback, useContext, useId, useLayoutEffect, useMemo, useState } from "react";
|
|
10
10
|
|
|
@@ -30,7 +30,10 @@ function useModal({ initialOpen = false, open: controlledOpen, onOpenChange: set
|
|
|
30
30
|
const [descriptionId, setDescriptionId] = useState();
|
|
31
31
|
/* v8 ignore start */ const open = controlledOpen ?? uncontrolledOpen;
|
|
32
32
|
const setOpen = setControlledOpen ?? setUncontrolledOpen;
|
|
33
|
-
/* v8 ignore stop */
|
|
33
|
+
/* v8 ignore stop */ // Subscribe this modal to the FloatingTree for nested modal support
|
|
34
|
+
const nodeId = useFloatingNodeId();
|
|
35
|
+
const data = useFloating({
|
|
36
|
+
nodeId,
|
|
34
37
|
open,
|
|
35
38
|
onOpenChange: setOpen
|
|
36
39
|
});
|
|
@@ -40,7 +43,10 @@ function useModal({ initialOpen = false, open: controlledOpen, onOpenChange: set
|
|
|
40
43
|
});
|
|
41
44
|
const dismiss = useDismiss(context, {
|
|
42
45
|
outsidePress: false,
|
|
43
|
-
outsidePressEvent: "mousedown"
|
|
46
|
+
outsidePressEvent: "mousedown",
|
|
47
|
+
bubbles: {
|
|
48
|
+
escapeKey: false
|
|
49
|
+
}
|
|
44
50
|
});
|
|
45
51
|
const role = useRole(context);
|
|
46
52
|
const interactions = useInteractions([
|
|
@@ -57,7 +63,8 @@ function useModal({ initialOpen = false, open: controlledOpen, onOpenChange: set
|
|
|
57
63
|
descriptionId,
|
|
58
64
|
setLabelId,
|
|
59
65
|
setDescriptionId,
|
|
60
|
-
initialFocus
|
|
66
|
+
initialFocus,
|
|
67
|
+
nodeId
|
|
61
68
|
}), [
|
|
62
69
|
open,
|
|
63
70
|
setOpen,
|
|
@@ -65,7 +72,8 @@ function useModal({ initialOpen = false, open: controlledOpen, onOpenChange: set
|
|
|
65
72
|
data,
|
|
66
73
|
labelId,
|
|
67
74
|
descriptionId,
|
|
68
|
-
initialFocus
|
|
75
|
+
initialFocus,
|
|
76
|
+
nodeId
|
|
69
77
|
]);
|
|
70
78
|
}
|
|
71
79
|
const useModalContext = ()=>{
|
|
@@ -84,15 +92,33 @@ const useModalContext = ()=>{
|
|
|
84
92
|
|
|
85
93
|
|
|
86
94
|
|
|
87
|
-
function
|
|
95
|
+
function ModalComponent({ children, ...options }) {
|
|
88
96
|
const dialog = useModal(options);
|
|
89
97
|
return /*#__PURE__*/ jsx(ModalContext.Provider, {
|
|
90
98
|
value: dialog,
|
|
91
99
|
children: children
|
|
92
100
|
});
|
|
93
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Modal component that supports proper nesting with ESC key handling.
|
|
104
|
+
* Automatically wraps root modals in FloatingTree for nested modal support.
|
|
105
|
+
*/ function Modal(props) {
|
|
106
|
+
const parentId = useFloatingParentNodeId();
|
|
107
|
+
// If this is a root modal (no parent), wrap with FloatingTree
|
|
108
|
+
if (parentId === null) {
|
|
109
|
+
return /*#__PURE__*/ jsx(FloatingTree, {
|
|
110
|
+
children: /*#__PURE__*/ jsx(ModalComponent, {
|
|
111
|
+
...props
|
|
112
|
+
})
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
// Nested modal - FloatingTree already exists
|
|
116
|
+
return /*#__PURE__*/ jsx(ModalComponent, {
|
|
117
|
+
...props
|
|
118
|
+
});
|
|
119
|
+
}
|
|
94
120
|
const Modal_ModalContent = /*#__PURE__*/ forwardRef(function ModalContent(props, propRef) {
|
|
95
|
-
const { context: floatingContext, ...context } = useModalContext();
|
|
121
|
+
const { context: floatingContext, nodeId, ...context } = useModalContext();
|
|
96
122
|
const ref = useMergeRefs([
|
|
97
123
|
context.refs.setFloating,
|
|
98
124
|
propRef
|
|
@@ -105,19 +131,22 @@ const Modal_ModalContent = /*#__PURE__*/ forwardRef(function ModalContent(props,
|
|
|
105
131
|
[`${overlayBackground}`]: overlayBackground,
|
|
106
132
|
"bg-black sm:bg-black/[.8]": !overlayBackground
|
|
107
133
|
});
|
|
108
|
-
return /*#__PURE__*/ jsx(
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
"
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
134
|
+
return /*#__PURE__*/ jsx(FloatingNode, {
|
|
135
|
+
id: nodeId,
|
|
136
|
+
children: /*#__PURE__*/ jsx(FloatingPortal, {
|
|
137
|
+
children: /*#__PURE__*/ jsx(FloatingOverlay, {
|
|
138
|
+
className: overlayClass,
|
|
139
|
+
lockScroll: true,
|
|
140
|
+
children: /*#__PURE__*/ jsx(FloatingFocusManager, {
|
|
141
|
+
context: floatingContext,
|
|
142
|
+
initialFocus: context.initialFocus,
|
|
143
|
+
children: /*#__PURE__*/ jsx("div", {
|
|
144
|
+
ref: ref,
|
|
145
|
+
"aria-labelledby": context.labelId,
|
|
146
|
+
"aria-describedby": context.descriptionId,
|
|
147
|
+
...context.getFloatingProps(rest),
|
|
148
|
+
children: rest.children
|
|
149
|
+
})
|
|
121
150
|
})
|
|
122
151
|
})
|
|
123
152
|
})
|
|
@@ -178,6 +207,6 @@ const Modal_ModalClose = /*#__PURE__*/ forwardRef(function ModalClose(props, ref
|
|
|
178
207
|
});
|
|
179
208
|
|
|
180
209
|
;// CONCATENATED MODULE: ./src/components/index.ts
|
|
181
|
-
|
|
210
|
+
|
|
182
211
|
|
|
183
212
|
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.3.
|
|
3
|
+
"version": "3.3.3",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Arno Versini",
|
|
6
6
|
"publishConfig": {
|
|
@@ -36,11 +36,13 @@
|
|
|
36
36
|
"@versini/ui-types": "8.1.1"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@floating-ui/react": "0.27.16",
|
|
40
39
|
"clsx": "2.1.1"
|
|
41
40
|
},
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"@floating-ui/react": ">=0.27.16"
|
|
43
|
+
},
|
|
42
44
|
"sideEffects": [
|
|
43
45
|
"**/*.css"
|
|
44
46
|
],
|
|
45
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "9fedab179e688f845d193b1f0b5365639dd4beb0"
|
|
46
48
|
}
|