react-responsive-modal 5.2.6 → 6.2.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 +2 -7
- package/dist/CloseIcon.d.ts +2 -2
- package/dist/FocusTrap.d.ts +2 -1
- package/dist/index.d.ts +23 -5
- package/dist/modalManager.d.ts +11 -17
- package/dist/react-responsive-modal.cjs.development.js +160 -117
- package/dist/react-responsive-modal.cjs.development.js.map +1 -1
- package/dist/react-responsive-modal.cjs.production.min.js +1 -1
- package/dist/react-responsive-modal.cjs.production.min.js.map +1 -1
- package/dist/react-responsive-modal.esm.js +160 -117
- package/dist/react-responsive-modal.esm.js.map +1 -1
- package/dist/useScrollLock.d.ts +1 -0
- package/dist/utils.d.ts +0 -2
- package/package.json +18 -27
- package/src/CloseIcon.tsx +3 -4
- package/src/FocusTrap.tsx +18 -5
- package/src/index.tsx +229 -179
- package/src/lib/focusTrapJs.ts +29 -2
- package/src/modalManager.ts +22 -19
- package/src/useScrollLock.ts +25 -0
- package/src/utils.ts +0 -16
- package/styles.css +59 -17
- package/CHANGELOG.md +0 -41
- package/LICENSE +0 -21
package/README.md
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/react-responsive-modal)
|
|
4
4
|
[](https://www.npmjs.com/package/react-responsive-modal)
|
|
5
5
|
[](https://codecov.io/gh/pradel/react-responsive-modal)
|
|
6
|
-
[](https://david-dm.org/pradel/react-responsive-modal)
|
|
7
6
|
|
|
8
7
|
A simple responsive and accessible react modal.
|
|
9
8
|
|
|
@@ -13,6 +12,8 @@ A simple responsive and accessible react modal.
|
|
|
13
12
|
- Multiple modals.
|
|
14
13
|
- Accessible modals.
|
|
15
14
|
- Easily customizable via props.
|
|
15
|
+
- Typescript support
|
|
16
|
+
- [Small bundle size](https://bundlephobia.com/result?p=react-responsive-modal)
|
|
16
17
|
|
|
17
18
|
## Documentation
|
|
18
19
|
|
|
@@ -21,12 +22,6 @@ A simple responsive and accessible react modal.
|
|
|
21
22
|
- [Usage](https://react-responsive-modal.leopradel.com/#usage)
|
|
22
23
|
- [Props](https://react-responsive-modal.leopradel.com/#props)
|
|
23
24
|
- [Licence](https://react-responsive-modal.leopradel.com/#license)
|
|
24
|
-
- [Examples](https://react-responsive-modal.leopradel.com/examples)
|
|
25
|
-
- [Centered modal](https://react-responsive-modal.leopradel.com/examples#centered-modal)
|
|
26
|
-
- [Multiple modal](https://react-responsive-modal.leopradel.com/examples#multiple-modal)
|
|
27
|
-
- [Custom styling](https://react-responsive-modal.leopradel.com/examples#custom-styling)
|
|
28
|
-
- [Custom animation](https://react-responsive-modal.leopradel.com/examples#custom-animation)
|
|
29
|
-
- [Custom container](https://react-responsive-modal.leopradel.com/examples#custom-container)
|
|
30
25
|
|
|
31
26
|
## Installation
|
|
32
27
|
|
package/dist/CloseIcon.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ interface CloseIconProps {
|
|
|
13
13
|
classes: {
|
|
14
14
|
closeButton?: string;
|
|
15
15
|
};
|
|
16
|
-
|
|
16
|
+
onClick: () => void;
|
|
17
17
|
}
|
|
18
|
-
declare const CloseIcon: ({ classes, classNames, styles, id, closeIcon,
|
|
18
|
+
declare const CloseIcon: ({ classes, classNames, styles, id, closeIcon, onClick, }: CloseIconProps) => JSX.Element;
|
|
19
19
|
export default CloseIcon;
|
package/dist/FocusTrap.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
interface FocusTrapProps {
|
|
3
3
|
container?: React.RefObject<HTMLElement> | null;
|
|
4
|
+
initialFocusRef?: React.RefObject<HTMLElement>;
|
|
4
5
|
}
|
|
5
|
-
export declare const FocusTrap: ({ container }: FocusTrapProps) => null;
|
|
6
|
+
export declare const FocusTrap: ({ container, initialFocusRef }: FocusTrapProps) => null;
|
|
6
7
|
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -30,6 +30,8 @@ export interface ModalProps {
|
|
|
30
30
|
blockScroll?: boolean;
|
|
31
31
|
/**
|
|
32
32
|
* Show the close icon.
|
|
33
|
+
*
|
|
34
|
+
* Default to true.
|
|
33
35
|
*/
|
|
34
36
|
showCloseIcon?: boolean;
|
|
35
37
|
/**
|
|
@@ -46,28 +48,40 @@ export interface ModalProps {
|
|
|
46
48
|
* Default to true.
|
|
47
49
|
*/
|
|
48
50
|
focusTrapped?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Element to focus when focus trap is used.
|
|
53
|
+
*
|
|
54
|
+
* Default to undefined.
|
|
55
|
+
*/
|
|
56
|
+
initialFocusRef?: React.RefObject<HTMLElement>;
|
|
49
57
|
/**
|
|
50
58
|
* You can specify a container prop which should be of type `Element`.
|
|
51
59
|
* The portal will be rendered inside that element.
|
|
52
60
|
* The default behavior will create a div node and render it at the at the end of document.body.
|
|
53
61
|
*/
|
|
54
|
-
container?: Element;
|
|
62
|
+
container?: Element | null;
|
|
55
63
|
/**
|
|
56
64
|
* An object containing classNames to style the modal.
|
|
57
65
|
*/
|
|
58
66
|
classNames?: {
|
|
67
|
+
root?: string;
|
|
59
68
|
overlay?: string;
|
|
69
|
+
overlayAnimationIn?: string;
|
|
70
|
+
overlayAnimationOut?: string;
|
|
71
|
+
modalContainer?: string;
|
|
60
72
|
modal?: string;
|
|
73
|
+
modalAnimationIn?: string;
|
|
74
|
+
modalAnimationOut?: string;
|
|
61
75
|
closeButton?: string;
|
|
62
76
|
closeIcon?: string;
|
|
63
|
-
animationIn?: string;
|
|
64
|
-
animationOut?: string;
|
|
65
77
|
};
|
|
66
78
|
/**
|
|
67
79
|
* An object containing the styles objects to style the modal.
|
|
68
80
|
*/
|
|
69
81
|
styles?: {
|
|
82
|
+
root?: React.CSSProperties;
|
|
70
83
|
overlay?: React.CSSProperties;
|
|
84
|
+
modalContainer?: React.CSSProperties;
|
|
71
85
|
modal?: React.CSSProperties;
|
|
72
86
|
closeButton?: React.CSSProperties;
|
|
73
87
|
closeIcon?: React.CSSProperties;
|
|
@@ -75,7 +89,7 @@ export interface ModalProps {
|
|
|
75
89
|
/**
|
|
76
90
|
* Animation duration in milliseconds.
|
|
77
91
|
*
|
|
78
|
-
* Default to
|
|
92
|
+
* Default to 300.
|
|
79
93
|
*/
|
|
80
94
|
animationDuration?: number;
|
|
81
95
|
/**
|
|
@@ -92,6 +106,10 @@ export interface ModalProps {
|
|
|
92
106
|
* ARIA description for modal
|
|
93
107
|
*/
|
|
94
108
|
ariaDescribedby?: string;
|
|
109
|
+
/**
|
|
110
|
+
* Avoid unpleasant flickering effect when body overflow is hidden. For more information see https://www.npmjs.com/package/body-scroll-lock
|
|
111
|
+
*/
|
|
112
|
+
reserveScrollBarGap?: boolean;
|
|
95
113
|
/**
|
|
96
114
|
* id attribute for modal
|
|
97
115
|
*/
|
|
@@ -114,5 +132,5 @@ export interface ModalProps {
|
|
|
114
132
|
onAnimationEnd?: () => void;
|
|
115
133
|
children?: React.ReactNode;
|
|
116
134
|
}
|
|
117
|
-
export declare const Modal:
|
|
135
|
+
export declare const Modal: React.ForwardRefExoticComponent<ModalProps & React.RefAttributes<HTMLDivElement>>;
|
|
118
136
|
export default Modal;
|
package/dist/modalManager.d.ts
CHANGED
|
@@ -1,26 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
blockScroll: boolean;
|
|
8
|
-
}[];
|
|
1
|
+
import { Ref } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Handle the order of the modals.
|
|
4
|
+
* Inspired by the material-ui implementation.
|
|
5
|
+
*/
|
|
6
|
+
export declare const modalManager: {
|
|
9
7
|
/**
|
|
10
8
|
* Register a new modal
|
|
11
9
|
*/
|
|
12
|
-
add: (newModal:
|
|
10
|
+
add: (newModal: Ref<Element>) => void;
|
|
13
11
|
/**
|
|
14
12
|
* Remove a modal
|
|
15
13
|
*/
|
|
16
|
-
remove: (oldModal:
|
|
14
|
+
remove: (oldModal: Ref<Element>) => void;
|
|
17
15
|
/**
|
|
18
|
-
*
|
|
16
|
+
* When multiple modals are rendered will return true if current modal is the last one
|
|
19
17
|
*/
|
|
20
|
-
isTopModal: (modal:
|
|
18
|
+
isTopModal: (modal: Ref<Element>) => boolean;
|
|
21
19
|
};
|
|
22
|
-
|
|
23
|
-
* Handle the order of the modals.
|
|
24
|
-
* Inspired by the material-ui implementation.
|
|
25
|
-
*/
|
|
26
|
-
export default _default;
|
|
20
|
+
export declare function useModalManager(ref: Ref<Element>, open: boolean): void;
|
|
@@ -8,7 +8,8 @@ var React = require('react');
|
|
|
8
8
|
var React__default = _interopDefault(React);
|
|
9
9
|
var ReactDom = _interopDefault(require('react-dom'));
|
|
10
10
|
var cx = _interopDefault(require('classnames'));
|
|
11
|
-
var
|
|
11
|
+
var bodyScrollLock = require('body-scroll-lock');
|
|
12
|
+
var useForwardedRef = _interopDefault(require('@bedrock-layout/use-forwarded-ref'));
|
|
12
13
|
|
|
13
14
|
function _extends() {
|
|
14
15
|
_extends = Object.assign || function (target) {
|
|
@@ -34,17 +35,16 @@ var CloseIcon = function CloseIcon(_ref) {
|
|
|
34
35
|
styles = _ref.styles,
|
|
35
36
|
id = _ref.id,
|
|
36
37
|
closeIcon = _ref.closeIcon,
|
|
37
|
-
|
|
38
|
+
onClick = _ref.onClick;
|
|
38
39
|
return React__default.createElement("button", {
|
|
39
40
|
id: id,
|
|
40
41
|
className: cx(classes.closeButton, classNames == null ? void 0 : classNames.closeButton),
|
|
41
42
|
style: styles == null ? void 0 : styles.closeButton,
|
|
42
|
-
onClick:
|
|
43
|
+
onClick: onClick,
|
|
43
44
|
"data-testid": "close-button"
|
|
44
45
|
}, closeIcon ? closeIcon : React__default.createElement("svg", {
|
|
45
46
|
className: classNames == null ? void 0 : classNames.closeIcon,
|
|
46
47
|
style: styles == null ? void 0 : styles.closeIcon,
|
|
47
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
48
48
|
width: 28,
|
|
49
49
|
height: 28,
|
|
50
50
|
viewBox: "0 0 36 36",
|
|
@@ -54,74 +54,9 @@ var CloseIcon = function CloseIcon(_ref) {
|
|
|
54
54
|
})));
|
|
55
55
|
};
|
|
56
56
|
|
|
57
|
-
var _modals = [];
|
|
58
|
-
/**
|
|
59
|
-
* Handle the order of the modals.
|
|
60
|
-
* Inspired by the material-ui implementation.
|
|
61
|
-
*/
|
|
62
|
-
|
|
63
|
-
var modalManager = {
|
|
64
|
-
/**
|
|
65
|
-
* Return the modals array
|
|
66
|
-
*/
|
|
67
|
-
modals: function modals() {
|
|
68
|
-
return _modals;
|
|
69
|
-
},
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Register a new modal
|
|
73
|
-
*/
|
|
74
|
-
add: function add(newModal, blockScroll) {
|
|
75
|
-
if (_modals.findIndex(function (modal) {
|
|
76
|
-
return modal.element === newModal;
|
|
77
|
-
}) === -1) {
|
|
78
|
-
_modals.push({
|
|
79
|
-
element: newModal,
|
|
80
|
-
blockScroll: blockScroll
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
},
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Remove a modal
|
|
87
|
-
*/
|
|
88
|
-
remove: function remove(oldModal) {
|
|
89
|
-
var index = _modals.findIndex(function (modal) {
|
|
90
|
-
return modal.element === oldModal;
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
if (index !== -1) {
|
|
94
|
-
_modals.splice(index, 1);
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Check if the modal is the first one on the screen
|
|
100
|
-
*/
|
|
101
|
-
isTopModal: function isTopModal(modal) {
|
|
102
|
-
var _modals2;
|
|
103
|
-
|
|
104
|
-
return !!_modals.length && ((_modals2 = _modals[_modals.length - 1]) == null ? void 0 : _modals2.element) === modal;
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
|
|
108
57
|
var isBrowser = typeof window !== 'undefined';
|
|
109
|
-
var blockNoScroll = function blockNoScroll() {
|
|
110
|
-
noScroll.on();
|
|
111
|
-
};
|
|
112
|
-
var unblockNoScroll = function unblockNoScroll() {
|
|
113
|
-
// Restore the scroll only if there is no modal on the screen
|
|
114
|
-
// We filter the modals that are not affecting the scroll
|
|
115
|
-
var modals = modalManager.modals().filter(function (modal) {
|
|
116
|
-
return modal.blockScroll;
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
if (modals.length === 0) {
|
|
120
|
-
noScroll.off();
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
58
|
|
|
124
|
-
// https://github.com/alexandrzavalii/focus-trap-js/blob/master/src/index.js v1.0
|
|
59
|
+
// https://github.com/alexandrzavalii/focus-trap-js/blob/master/src/index.js v1.1.0
|
|
125
60
|
var candidateSelectors = ['input', 'select', 'textarea', 'a[href]', 'button', '[tabindex]', 'audio[controls]', 'video[controls]', '[contenteditable]:not([contenteditable="false"])'];
|
|
126
61
|
|
|
127
62
|
function isHidden(node) {
|
|
@@ -130,14 +65,34 @@ function isHidden(node) {
|
|
|
130
65
|
return node.offsetParent === null || getComputedStyle(node).visibility === 'hidden';
|
|
131
66
|
}
|
|
132
67
|
|
|
68
|
+
function getCheckedRadio(nodes, form) {
|
|
69
|
+
for (var i = 0; i < nodes.length; i++) {
|
|
70
|
+
if (nodes[i].checked && nodes[i].form === form) {
|
|
71
|
+
return nodes[i];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function isNotRadioOrTabbableRadio(node) {
|
|
77
|
+
if (node.tagName !== 'INPUT' || node.type !== 'radio' || !node.name) {
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
var radioScope = node.form || node.ownerDocument;
|
|
82
|
+
var radioSet = radioScope.querySelectorAll('input[type="radio"][name="' + node.name + '"]');
|
|
83
|
+
var checked = getCheckedRadio(radioSet, node.form);
|
|
84
|
+
return checked === node || checked === undefined && radioSet[0] === node;
|
|
85
|
+
}
|
|
86
|
+
|
|
133
87
|
function getAllTabbingElements(parentElem) {
|
|
88
|
+
var currentActiveElement = document.activeElement;
|
|
134
89
|
var tabbableNodes = parentElem.querySelectorAll(candidateSelectors.join(','));
|
|
135
90
|
var onlyTabbable = [];
|
|
136
91
|
|
|
137
92
|
for (var i = 0; i < tabbableNodes.length; i++) {
|
|
138
93
|
var node = tabbableNodes[i];
|
|
139
94
|
|
|
140
|
-
if (!node.disabled && getTabindex(node) > -1 && !isHidden(node)) {
|
|
95
|
+
if (currentActiveElement === node || !node.disabled && getTabindex(node) > -1 && !isHidden(node) && isNotRadioOrTabbableRadio(node)) {
|
|
141
96
|
onlyTabbable.push(node);
|
|
142
97
|
}
|
|
143
98
|
}
|
|
@@ -191,7 +146,8 @@ function isContentEditable(node) {
|
|
|
191
146
|
}
|
|
192
147
|
|
|
193
148
|
var FocusTrap = function FocusTrap(_ref) {
|
|
194
|
-
var container = _ref.container
|
|
149
|
+
var container = _ref.container,
|
|
150
|
+
initialFocusRef = _ref.initialFocusRef;
|
|
195
151
|
var refLastFocus = React.useRef();
|
|
196
152
|
/**
|
|
197
153
|
* Handle focus lock on the modal
|
|
@@ -210,9 +166,7 @@ var FocusTrap = function FocusTrap(_ref) {
|
|
|
210
166
|
|
|
211
167
|
|
|
212
168
|
if (isBrowser && (container == null ? void 0 : container.current)) {
|
|
213
|
-
var
|
|
214
|
-
|
|
215
|
-
if (allTabbingElements[0]) {
|
|
169
|
+
var savePreviousFocus = function savePreviousFocus() {
|
|
216
170
|
// First we save the last focused element
|
|
217
171
|
// only if it's a focusable element
|
|
218
172
|
if (candidateSelectors.findIndex(function (selector) {
|
|
@@ -222,8 +176,23 @@ var FocusTrap = function FocusTrap(_ref) {
|
|
|
222
176
|
}) !== -1) {
|
|
223
177
|
refLastFocus.current = document.activeElement;
|
|
224
178
|
}
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
if (initialFocusRef) {
|
|
182
|
+
savePreviousFocus(); // We need to schedule focusing on a next frame - this allows to focus on the modal root
|
|
183
|
+
|
|
184
|
+
requestAnimationFrame(function () {
|
|
185
|
+
var _initialFocusRef$curr;
|
|
225
186
|
|
|
226
|
-
|
|
187
|
+
(_initialFocusRef$curr = initialFocusRef.current) == null ? void 0 : _initialFocusRef$curr.focus();
|
|
188
|
+
});
|
|
189
|
+
} else {
|
|
190
|
+
var allTabbingElements = getAllTabbingElements(container.current);
|
|
191
|
+
|
|
192
|
+
if (allTabbingElements[0]) {
|
|
193
|
+
savePreviousFocus();
|
|
194
|
+
allTabbingElements[0].focus();
|
|
195
|
+
}
|
|
227
196
|
}
|
|
228
197
|
}
|
|
229
198
|
|
|
@@ -236,20 +205,85 @@ var FocusTrap = function FocusTrap(_ref) {
|
|
|
236
205
|
(_refLastFocus$current = refLastFocus.current) == null ? void 0 : _refLastFocus$current.focus();
|
|
237
206
|
}
|
|
238
207
|
};
|
|
239
|
-
}, [container]);
|
|
208
|
+
}, [container, initialFocusRef]);
|
|
240
209
|
return null;
|
|
241
210
|
};
|
|
242
211
|
|
|
212
|
+
var modals = [];
|
|
213
|
+
/**
|
|
214
|
+
* Handle the order of the modals.
|
|
215
|
+
* Inspired by the material-ui implementation.
|
|
216
|
+
*/
|
|
217
|
+
|
|
218
|
+
var modalManager = {
|
|
219
|
+
/**
|
|
220
|
+
* Register a new modal
|
|
221
|
+
*/
|
|
222
|
+
add: function add(newModal) {
|
|
223
|
+
modals.push(newModal);
|
|
224
|
+
},
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Remove a modal
|
|
228
|
+
*/
|
|
229
|
+
remove: function remove(oldModal) {
|
|
230
|
+
modals = modals.filter(function (modal) {
|
|
231
|
+
return modal !== oldModal;
|
|
232
|
+
});
|
|
233
|
+
},
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* When multiple modals are rendered will return true if current modal is the last one
|
|
237
|
+
*/
|
|
238
|
+
isTopModal: function isTopModal(modal) {
|
|
239
|
+
return !!modals.length && modals[modals.length - 1] === modal;
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
function useModalManager(ref, open) {
|
|
243
|
+
React.useEffect(function () {
|
|
244
|
+
if (open) {
|
|
245
|
+
modalManager.add(ref);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return function () {
|
|
249
|
+
modalManager.remove(ref);
|
|
250
|
+
};
|
|
251
|
+
}, [open, ref]);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
var useScrollLock = function useScrollLock(refModal, open, showPortal, blockScroll, reserveScrollBarGap) {
|
|
255
|
+
var oldRef = React.useRef(null);
|
|
256
|
+
React.useEffect(function () {
|
|
257
|
+
if (open && refModal.current && blockScroll) {
|
|
258
|
+
oldRef.current = refModal.current;
|
|
259
|
+
bodyScrollLock.disableBodyScroll(refModal.current, {
|
|
260
|
+
reserveScrollBarGap: reserveScrollBarGap
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return function () {
|
|
265
|
+
if (oldRef.current) {
|
|
266
|
+
bodyScrollLock.enableBodyScroll(oldRef.current);
|
|
267
|
+
oldRef.current = null;
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
}, [open, showPortal, refModal, blockScroll, reserveScrollBarGap]);
|
|
271
|
+
};
|
|
272
|
+
|
|
243
273
|
var classes = {
|
|
274
|
+
root: 'react-responsive-modal-root',
|
|
244
275
|
overlay: 'react-responsive-modal-overlay',
|
|
276
|
+
overlayAnimationIn: 'react-responsive-modal-overlay-in',
|
|
277
|
+
overlayAnimationOut: 'react-responsive-modal-overlay-out',
|
|
278
|
+
modalContainer: 'react-responsive-modal-container',
|
|
279
|
+
modalContainerCenter: 'react-responsive-modal-containerCenter',
|
|
245
280
|
modal: 'react-responsive-modal-modal',
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
animationOut: 'react-responsive-modal-fadeOut'
|
|
281
|
+
modalAnimationIn: 'react-responsive-modal-modal-in',
|
|
282
|
+
modalAnimationOut: 'react-responsive-modal-modal-out',
|
|
283
|
+
closeButton: 'react-responsive-modal-closeButton'
|
|
250
284
|
};
|
|
251
|
-
var Modal = function
|
|
252
|
-
var _classNames$
|
|
285
|
+
var Modal = /*#__PURE__*/React__default.forwardRef(function (_ref, ref) {
|
|
286
|
+
var _classNames$overlayAn, _classNames$overlayAn2, _classNames$modalAnim, _classNames$modalAnim2;
|
|
253
287
|
|
|
254
288
|
var open = _ref.open,
|
|
255
289
|
center = _ref.center,
|
|
@@ -266,8 +300,10 @@ var Modal = function Modal(_ref) {
|
|
|
266
300
|
closeIcon = _ref.closeIcon,
|
|
267
301
|
_ref$focusTrapped = _ref.focusTrapped,
|
|
268
302
|
focusTrapped = _ref$focusTrapped === void 0 ? true : _ref$focusTrapped,
|
|
303
|
+
_ref$initialFocusRef = _ref.initialFocusRef,
|
|
304
|
+
initialFocusRef = _ref$initialFocusRef === void 0 ? undefined : _ref$initialFocusRef,
|
|
269
305
|
_ref$animationDuratio = _ref.animationDuration,
|
|
270
|
-
animationDuration = _ref$animationDuratio === void 0 ?
|
|
306
|
+
animationDuration = _ref$animationDuratio === void 0 ? 300 : _ref$animationDuratio,
|
|
271
307
|
classNames = _ref.classNames,
|
|
272
308
|
styles = _ref.styles,
|
|
273
309
|
_ref$role = _ref.role,
|
|
@@ -279,7 +315,9 @@ var Modal = function Modal(_ref) {
|
|
|
279
315
|
onEscKeyDown = _ref.onEscKeyDown,
|
|
280
316
|
onOverlayClick = _ref.onOverlayClick,
|
|
281
317
|
onAnimationEnd = _ref.onAnimationEnd,
|
|
282
|
-
children = _ref.children
|
|
318
|
+
children = _ref.children,
|
|
319
|
+
reserveScrollBarGap = _ref.reserveScrollBarGap;
|
|
320
|
+
var refDialog = useForwardedRef(ref);
|
|
283
321
|
var refModal = React.useRef(null);
|
|
284
322
|
var refShouldClose = React.useRef(null);
|
|
285
323
|
var refContainer = React.useRef(null); // Lazily create the ref instance
|
|
@@ -293,15 +331,14 @@ var Modal = function Modal(_ref) {
|
|
|
293
331
|
|
|
294
332
|
var _useState = React.useState(false),
|
|
295
333
|
showPortal = _useState[0],
|
|
296
|
-
setShowPortal = _useState[1];
|
|
334
|
+
setShowPortal = _useState[1]; // Hook used to manage multiple modals opened at the same time
|
|
297
335
|
|
|
298
|
-
var handleOpen = function handleOpen() {
|
|
299
|
-
modalManager.add(refContainer.current, blockScroll);
|
|
300
336
|
|
|
301
|
-
|
|
302
|
-
blockNoScroll();
|
|
303
|
-
}
|
|
337
|
+
useModalManager(refModal, open); // Hook used to manage the scroll
|
|
304
338
|
|
|
339
|
+
useScrollLock(refModal, open, showPortal, blockScroll, reserveScrollBarGap);
|
|
340
|
+
|
|
341
|
+
var handleOpen = function handleOpen() {
|
|
305
342
|
if (refContainer.current && !container && !document.body.contains(refContainer.current)) {
|
|
306
343
|
document.body.appendChild(refContainer.current);
|
|
307
344
|
}
|
|
@@ -310,12 +347,6 @@ var Modal = function Modal(_ref) {
|
|
|
310
347
|
};
|
|
311
348
|
|
|
312
349
|
var handleClose = function handleClose() {
|
|
313
|
-
modalManager.remove(refContainer.current);
|
|
314
|
-
|
|
315
|
-
if (blockScroll) {
|
|
316
|
-
unblockNoScroll();
|
|
317
|
-
}
|
|
318
|
-
|
|
319
350
|
if (refContainer.current && !container && document.body.contains(refContainer.current)) {
|
|
320
351
|
document.body.removeChild(refContainer.current);
|
|
321
352
|
}
|
|
@@ -325,7 +356,7 @@ var Modal = function Modal(_ref) {
|
|
|
325
356
|
|
|
326
357
|
var handleKeydown = function handleKeydown(event) {
|
|
327
358
|
// Only the last modal need to be escaped when pressing the esc key
|
|
328
|
-
if (event.keyCode !== 27 || !modalManager.isTopModal(
|
|
359
|
+
if (event.keyCode !== 27 || !modalManager.isTopModal(refModal)) {
|
|
329
360
|
return;
|
|
330
361
|
}
|
|
331
362
|
|
|
@@ -338,8 +369,8 @@ var Modal = function Modal(_ref) {
|
|
|
338
369
|
|
|
339
370
|
React.useEffect(function () {
|
|
340
371
|
return function () {
|
|
341
|
-
// When the component is unmounted directly we want to unblock the scroll
|
|
342
372
|
if (showPortal) {
|
|
373
|
+
// When the modal is closed or removed directly, cleanup the listeners
|
|
343
374
|
handleClose();
|
|
344
375
|
}
|
|
345
376
|
};
|
|
@@ -376,10 +407,6 @@ var Modal = function Modal(_ref) {
|
|
|
376
407
|
refShouldClose.current = false;
|
|
377
408
|
};
|
|
378
409
|
|
|
379
|
-
var handleClickCloseIcon = function handleClickCloseIcon() {
|
|
380
|
-
onClose();
|
|
381
|
-
};
|
|
382
|
-
|
|
383
410
|
var handleAnimationEnd = function handleAnimationEnd() {
|
|
384
411
|
if (!open) {
|
|
385
412
|
setShowPortal(false);
|
|
@@ -389,38 +416,54 @@ var Modal = function Modal(_ref) {
|
|
|
389
416
|
};
|
|
390
417
|
|
|
391
418
|
var containerModal = container || refContainer.current;
|
|
419
|
+
var overlayAnimation = open ? (_classNames$overlayAn = classNames == null ? void 0 : classNames.overlayAnimationIn) != null ? _classNames$overlayAn : classes.overlayAnimationIn : (_classNames$overlayAn2 = classNames == null ? void 0 : classNames.overlayAnimationOut) != null ? _classNames$overlayAn2 : classes.overlayAnimationOut;
|
|
420
|
+
var modalAnimation = open ? (_classNames$modalAnim = classNames == null ? void 0 : classNames.modalAnimationIn) != null ? _classNames$modalAnim : classes.modalAnimationIn : (_classNames$modalAnim2 = classNames == null ? void 0 : classNames.modalAnimationOut) != null ? _classNames$modalAnim2 : classes.modalAnimationOut;
|
|
392
421
|
return showPortal && containerModal ? ReactDom.createPortal(React__default.createElement("div", {
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
className: cx(classes.overlay, classNames == null ? void 0 : classNames.overlay),
|
|
397
|
-
onClick: handleClickOverlay,
|
|
398
|
-
onAnimationEnd: handleAnimationEnd,
|
|
399
|
-
"data-testid": "overlay"
|
|
422
|
+
className: cx(classes.root, classNames == null ? void 0 : classNames.root),
|
|
423
|
+
style: styles == null ? void 0 : styles.root,
|
|
424
|
+
"data-testid": "root"
|
|
400
425
|
}, React__default.createElement("div", {
|
|
426
|
+
className: cx(classes.overlay, classNames == null ? void 0 : classNames.overlay),
|
|
427
|
+
"data-testid": "overlay",
|
|
428
|
+
"aria-hidden": true,
|
|
429
|
+
style: _extends({
|
|
430
|
+
animation: overlayAnimation + " " + animationDuration + "ms"
|
|
431
|
+
}, styles == null ? void 0 : styles.overlay)
|
|
432
|
+
}), React__default.createElement("div", {
|
|
401
433
|
ref: refModal,
|
|
402
|
-
className: cx(classes.
|
|
403
|
-
style: styles == null ? void 0 : styles.
|
|
434
|
+
className: cx(classes.modalContainer, center && classes.modalContainerCenter, classNames == null ? void 0 : classNames.modalContainer),
|
|
435
|
+
style: styles == null ? void 0 : styles.modalContainer,
|
|
436
|
+
"data-testid": "modal-container",
|
|
437
|
+
onClick: handleClickOverlay
|
|
438
|
+
}, React__default.createElement("div", {
|
|
439
|
+
ref: refDialog,
|
|
440
|
+
className: cx(classes.modal, classNames == null ? void 0 : classNames.modal),
|
|
441
|
+
style: _extends({
|
|
442
|
+
animation: modalAnimation + " " + animationDuration + "ms"
|
|
443
|
+
}, styles == null ? void 0 : styles.modal),
|
|
404
444
|
onMouseDown: handleModalEvent,
|
|
405
445
|
onMouseUp: handleModalEvent,
|
|
406
446
|
onClick: handleModalEvent,
|
|
447
|
+
onAnimationEnd: handleAnimationEnd,
|
|
407
448
|
id: modalId,
|
|
408
449
|
role: role,
|
|
409
450
|
"aria-modal": "true",
|
|
410
451
|
"aria-labelledby": ariaLabelledby,
|
|
411
452
|
"aria-describedby": ariaDescribedby,
|
|
412
|
-
"data-testid": "modal"
|
|
453
|
+
"data-testid": "modal",
|
|
454
|
+
tabIndex: -1
|
|
413
455
|
}, focusTrapped && React__default.createElement(FocusTrap, {
|
|
414
|
-
container:
|
|
456
|
+
container: refDialog,
|
|
457
|
+
initialFocusRef: initialFocusRef
|
|
415
458
|
}), children, showCloseIcon && React__default.createElement(CloseIcon, {
|
|
416
459
|
classes: classes,
|
|
417
460
|
classNames: classNames,
|
|
418
461
|
styles: styles,
|
|
419
462
|
closeIcon: closeIcon,
|
|
420
|
-
|
|
463
|
+
onClick: onClose,
|
|
421
464
|
id: closeIconId
|
|
422
|
-
}))), containerModal) : null;
|
|
423
|
-
};
|
|
465
|
+
})))), containerModal) : null;
|
|
466
|
+
});
|
|
424
467
|
|
|
425
468
|
exports.Modal = Modal;
|
|
426
469
|
exports.default = Modal;
|