1 | "use strict";
|
2 |
|
3 | var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
|
4 |
|
5 | var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
6 |
|
7 | exports.__esModule = true;
|
8 | exports["default"] = void 0;
|
9 |
|
10 | var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
11 |
|
12 | var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
|
13 |
|
14 | var _activeElement = _interopRequireDefault(require("dom-helpers/activeElement"));
|
15 |
|
16 | var _contains = _interopRequireDefault(require("dom-helpers/contains"));
|
17 |
|
18 | var _canUseDOM = _interopRequireDefault(require("dom-helpers/canUseDOM"));
|
19 |
|
20 | var _listen = _interopRequireDefault(require("dom-helpers/listen"));
|
21 |
|
22 | var _propTypes = _interopRequireDefault(require("prop-types"));
|
23 |
|
24 | var _react = _interopRequireWildcard(require("react"));
|
25 |
|
26 | var _reactDom = _interopRequireDefault(require("react-dom"));
|
27 |
|
28 | var _useMounted = _interopRequireDefault(require("@restart/hooks/useMounted"));
|
29 |
|
30 | var _useWillUnmount = _interopRequireDefault(require("@restart/hooks/useWillUnmount"));
|
31 |
|
32 | var _usePrevious = _interopRequireDefault(require("@restart/hooks/usePrevious"));
|
33 |
|
34 | var _useEventCallback = _interopRequireDefault(require("@restart/hooks/useEventCallback"));
|
35 |
|
36 | var _ModalManager = _interopRequireDefault(require("./ModalManager"));
|
37 |
|
38 | var _useWaitForDOMRef = _interopRequireDefault(require("./useWaitForDOMRef"));
|
39 |
|
40 |
|
41 | var manager;
|
42 |
|
43 | function getManager() {
|
44 | if (!manager) manager = new _ModalManager["default"]();
|
45 | return manager;
|
46 | }
|
47 |
|
48 | function useModalManager(provided) {
|
49 | var modalManager = provided || getManager();
|
50 | var modal = (0, _react.useRef)({
|
51 | dialog: null,
|
52 | backdrop: null
|
53 | });
|
54 | return Object.assign(modal.current, {
|
55 | add: function add(container, className) {
|
56 | return modalManager.add(modal.current, container, className);
|
57 | },
|
58 | remove: function remove() {
|
59 | return modalManager.remove(modal.current);
|
60 | },
|
61 | isTopModal: function isTopModal() {
|
62 | return modalManager.isTopModal(modal.current);
|
63 | },
|
64 | setDialogRef: (0, _react.useCallback)(function (ref) {
|
65 | modal.current.dialog = ref;
|
66 | }, []),
|
67 | setBackdropRef: (0, _react.useCallback)(function (ref) {
|
68 | modal.current.backdrop = ref;
|
69 | }, [])
|
70 | });
|
71 | }
|
72 |
|
73 | var Modal = (0, _react.forwardRef)(function (_ref, ref) {
|
74 | var _ref$show = _ref.show,
|
75 | show = _ref$show === void 0 ? false : _ref$show,
|
76 | _ref$role = _ref.role,
|
77 | role = _ref$role === void 0 ? 'dialog' : _ref$role,
|
78 | className = _ref.className,
|
79 | style = _ref.style,
|
80 | children = _ref.children,
|
81 | _ref$backdrop = _ref.backdrop,
|
82 | backdrop = _ref$backdrop === void 0 ? true : _ref$backdrop,
|
83 | _ref$keyboard = _ref.keyboard,
|
84 | keyboard = _ref$keyboard === void 0 ? true : _ref$keyboard,
|
85 | onBackdropClick = _ref.onBackdropClick,
|
86 | onEscapeKeyDown = _ref.onEscapeKeyDown,
|
87 | transition = _ref.transition,
|
88 | backdropTransition = _ref.backdropTransition,
|
89 | _ref$autoFocus = _ref.autoFocus,
|
90 | autoFocus = _ref$autoFocus === void 0 ? true : _ref$autoFocus,
|
91 | _ref$enforceFocus = _ref.enforceFocus,
|
92 | enforceFocus = _ref$enforceFocus === void 0 ? true : _ref$enforceFocus,
|
93 | _ref$restoreFocus = _ref.restoreFocus,
|
94 | restoreFocus = _ref$restoreFocus === void 0 ? true : _ref$restoreFocus,
|
95 | restoreFocusOptions = _ref.restoreFocusOptions,
|
96 | renderDialog = _ref.renderDialog,
|
97 | _ref$renderBackdrop = _ref.renderBackdrop,
|
98 | renderBackdrop = _ref$renderBackdrop === void 0 ? function (props) {
|
99 | return _react["default"].createElement("div", props);
|
100 | } : _ref$renderBackdrop,
|
101 | providedManager = _ref.manager,
|
102 | containerRef = _ref.container,
|
103 | containerClassName = _ref.containerClassName,
|
104 | onShow = _ref.onShow,
|
105 | _ref$onHide = _ref.onHide,
|
106 | onHide = _ref$onHide === void 0 ? function () {} : _ref$onHide,
|
107 | onExit = _ref.onExit,
|
108 | onExited = _ref.onExited,
|
109 | onExiting = _ref.onExiting,
|
110 | onEnter = _ref.onEnter,
|
111 | onEntering = _ref.onEntering,
|
112 | onEntered = _ref.onEntered,
|
113 | rest = (0, _objectWithoutPropertiesLoose2["default"])(_ref, ["show", "role", "className", "style", "children", "backdrop", "keyboard", "onBackdropClick", "onEscapeKeyDown", "transition", "backdropTransition", "autoFocus", "enforceFocus", "restoreFocus", "restoreFocusOptions", "renderDialog", "renderBackdrop", "manager", "container", "containerClassName", "onShow", "onHide", "onExit", "onExited", "onExiting", "onEnter", "onEntering", "onEntered"]);
|
114 | var container = (0, _useWaitForDOMRef["default"])(containerRef);
|
115 | var modal = useModalManager(providedManager);
|
116 | var isMounted = (0, _useMounted["default"])();
|
117 | var prevShow = (0, _usePrevious["default"])(show);
|
118 |
|
119 | var _useState = (0, _react.useState)(!show),
|
120 | exited = _useState[0],
|
121 | setExited = _useState[1];
|
122 |
|
123 | var lastFocusRef = (0, _react.useRef)(null);
|
124 | (0, _react.useImperativeHandle)(ref, function () {
|
125 | return modal;
|
126 | }, [modal]);
|
127 |
|
128 | if (_canUseDOM["default"] && !prevShow && show) {
|
129 | lastFocusRef.current = (0, _activeElement["default"])();
|
130 | }
|
131 |
|
132 | if (!transition && !show && !exited) {
|
133 | setExited(true);
|
134 | } else if (show && exited) {
|
135 | setExited(false);
|
136 | }
|
137 |
|
138 | var handleShow = (0, _useEventCallback["default"])(function () {
|
139 | modal.add(container, containerClassName);
|
140 | removeKeydownListenerRef.current = (0, _listen["default"])(document, 'keydown', handleDocumentKeyDown);
|
141 | removeFocusListenerRef.current = (0, _listen["default"])(document, 'focus',
|
142 |
|
143 | function () {
|
144 | return setTimeout(handleEnforceFocus);
|
145 | }, true);
|
146 |
|
147 | if (onShow) {
|
148 | onShow();
|
149 | }
|
150 |
|
151 |
|
152 |
|
153 | if (autoFocus) {
|
154 | var currentActiveElement = (0, _activeElement["default"])(document);
|
155 |
|
156 | if (modal.dialog && currentActiveElement && !(0, _contains["default"])(modal.dialog, currentActiveElement)) {
|
157 | lastFocusRef.current = currentActiveElement;
|
158 | modal.dialog.focus();
|
159 | }
|
160 | }
|
161 | });
|
162 | var handleHide = (0, _useEventCallback["default"])(function () {
|
163 | modal.remove();
|
164 | removeKeydownListenerRef.current == null ? void 0 : removeKeydownListenerRef.current();
|
165 | removeFocusListenerRef.current == null ? void 0 : removeFocusListenerRef.current();
|
166 |
|
167 | if (restoreFocus) {
|
168 | var _lastFocusRef$current;
|
169 |
|
170 |
|
171 | (_lastFocusRef$current = lastFocusRef.current) == null ? void 0 : _lastFocusRef$current.focus == null ? void 0 : _lastFocusRef$current.focus(restoreFocusOptions);
|
172 | lastFocusRef.current = null;
|
173 | }
|
174 | });
|
175 |
|
176 |
|
177 |
|
178 | (0, _react.useEffect)(function () {
|
179 | if (!show || !container) return;
|
180 | handleShow();
|
181 | }, [show, container,
|
182 |
|
183 | handleShow]);
|
184 |
|
185 |
|
186 |
|
187 | (0, _react.useEffect)(function () {
|
188 | if (!exited) return;
|
189 | handleHide();
|
190 | }, [exited, handleHide]);
|
191 | (0, _useWillUnmount["default"])(function () {
|
192 | handleHide();
|
193 | });
|
194 |
|
195 | var handleEnforceFocus = (0, _useEventCallback["default"])(function () {
|
196 | if (!enforceFocus || !isMounted() || !modal.isTopModal()) {
|
197 | return;
|
198 | }
|
199 |
|
200 | var currentActiveElement = (0, _activeElement["default"])();
|
201 |
|
202 | if (modal.dialog && currentActiveElement && !(0, _contains["default"])(modal.dialog, currentActiveElement)) {
|
203 | modal.dialog.focus();
|
204 | }
|
205 | });
|
206 | var handleBackdropClick = (0, _useEventCallback["default"])(function (e) {
|
207 | if (e.target !== e.currentTarget) {
|
208 | return;
|
209 | }
|
210 |
|
211 | onBackdropClick == null ? void 0 : onBackdropClick(e);
|
212 |
|
213 | if (backdrop === true) {
|
214 | onHide();
|
215 | }
|
216 | });
|
217 | var handleDocumentKeyDown = (0, _useEventCallback["default"])(function (e) {
|
218 | if (keyboard && e.keyCode === 27 && modal.isTopModal()) {
|
219 | onEscapeKeyDown == null ? void 0 : onEscapeKeyDown(e);
|
220 |
|
221 | if (!e.defaultPrevented) {
|
222 | onHide();
|
223 | }
|
224 | }
|
225 | });
|
226 | var removeFocusListenerRef = (0, _react.useRef)();
|
227 | var removeKeydownListenerRef = (0, _react.useRef)();
|
228 |
|
229 | var handleHidden = function handleHidden() {
|
230 | setExited(true);
|
231 |
|
232 | for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
233 | args[_key] = arguments[_key];
|
234 | }
|
235 |
|
236 | onExited == null ? void 0 : onExited.apply(void 0, args);
|
237 | };
|
238 |
|
239 | var Transition = transition;
|
240 |
|
241 | if (!container || !(show || Transition && !exited)) {
|
242 | return null;
|
243 | }
|
244 |
|
245 | var dialogProps = (0, _extends2["default"])({
|
246 | role: role,
|
247 | ref: modal.setDialogRef,
|
248 |
|
249 | 'aria-modal': role === 'dialog' ? true : undefined
|
250 | }, rest, {
|
251 | style: style,
|
252 | className: className,
|
253 | tabIndex: -1
|
254 | });
|
255 | var dialog = renderDialog ? renderDialog(dialogProps) : _react["default"].createElement("div", dialogProps, _react["default"].cloneElement(children, {
|
256 | role: 'document'
|
257 | }));
|
258 |
|
259 | if (Transition) {
|
260 | dialog = _react["default"].createElement(Transition, {
|
261 | appear: true,
|
262 | unmountOnExit: true,
|
263 | "in": !!show,
|
264 | onExit: onExit,
|
265 | onExiting: onExiting,
|
266 | onExited: handleHidden,
|
267 | onEnter: onEnter,
|
268 | onEntering: onEntering,
|
269 | onEntered: onEntered
|
270 | }, dialog);
|
271 | }
|
272 |
|
273 | var backdropElement = null;
|
274 |
|
275 | if (backdrop) {
|
276 | var BackdropTransition = backdropTransition;
|
277 | backdropElement = renderBackdrop({
|
278 | ref: modal.setBackdropRef,
|
279 | onClick: handleBackdropClick
|
280 | });
|
281 |
|
282 | if (BackdropTransition) {
|
283 | backdropElement = _react["default"].createElement(BackdropTransition, {
|
284 | appear: true,
|
285 | "in": !!show
|
286 | }, backdropElement);
|
287 | }
|
288 | }
|
289 |
|
290 | return _react["default"].createElement(_react["default"].Fragment, null, _reactDom["default"].createPortal( _react["default"].createElement(_react["default"].Fragment, null, backdropElement, dialog), container));
|
291 | });
|
292 | var propTypes = {
|
293 | |
294 |
|
295 |
|
296 | show: _propTypes["default"].bool,
|
297 |
|
298 | |
299 |
|
300 |
|
301 |
|
302 |
|
303 |
|
304 | container: _propTypes["default"].any,
|
305 |
|
306 | |
307 |
|
308 |
|
309 | onShow: _propTypes["default"].func,
|
310 |
|
311 | |
312 |
|
313 |
|
314 |
|
315 |
|
316 |
|
317 | onHide: _propTypes["default"].func,
|
318 |
|
319 | |
320 |
|
321 |
|
322 | backdrop: _propTypes["default"].oneOfType([_propTypes["default"].bool, _propTypes["default"].oneOf(['static'])]),
|
323 |
|
324 | |
325 |
|
326 |
|
327 |
|
328 |
|
329 |
|
330 |
|
331 |
|
332 | renderDialog: _propTypes["default"].func,
|
333 |
|
334 | |
335 |
|
336 |
|
337 |
|
338 |
|
339 |
|
340 |
|
341 |
|
342 | renderBackdrop: _propTypes["default"].func,
|
343 |
|
344 | |
345 |
|
346 |
|
347 |
|
348 |
|
349 | onEscapeKeyDown: _propTypes["default"].func,
|
350 |
|
351 | |
352 |
|
353 |
|
354 | onBackdropClick: _propTypes["default"].func,
|
355 |
|
356 | |
357 |
|
358 |
|
359 |
|
360 | containerClassName: _propTypes["default"].string,
|
361 |
|
362 | |
363 |
|
364 |
|
365 | keyboard: _propTypes["default"].bool,
|
366 |
|
367 | |
368 |
|
369 |
|
370 |
|
371 | transition: _propTypes["default"].elementType,
|
372 |
|
373 | |
374 |
|
375 |
|
376 |
|
377 | backdropTransition: _propTypes["default"].elementType,
|
378 |
|
379 | |
380 |
|
381 |
|
382 |
|
383 |
|
384 |
|
385 |
|
386 |
|
387 | autoFocus: _propTypes["default"].bool,
|
388 |
|
389 | |
390 |
|
391 |
|
392 |
|
393 |
|
394 |
|
395 | enforceFocus: _propTypes["default"].bool,
|
396 |
|
397 | |
398 |
|
399 |
|
400 |
|
401 | restoreFocus: _propTypes["default"].bool,
|
402 |
|
403 | |
404 |
|
405 |
|
406 |
|
407 |
|
408 | restoreFocusOptions: _propTypes["default"].shape({
|
409 | preventScroll: _propTypes["default"].bool
|
410 | }),
|
411 |
|
412 | |
413 |
|
414 |
|
415 | onEnter: _propTypes["default"].func,
|
416 |
|
417 | |
418 |
|
419 |
|
420 | onEntering: _propTypes["default"].func,
|
421 |
|
422 | |
423 |
|
424 |
|
425 | onEntered: _propTypes["default"].func,
|
426 |
|
427 | |
428 |
|
429 |
|
430 | onExit: _propTypes["default"].func,
|
431 |
|
432 | |
433 |
|
434 |
|
435 | onExiting: _propTypes["default"].func,
|
436 |
|
437 | |
438 |
|
439 |
|
440 | onExited: _propTypes["default"].func,
|
441 |
|
442 | |
443 |
|
444 |
|
445 |
|
446 | manager: _propTypes["default"].instanceOf(_ModalManager["default"])
|
447 | };
|
448 | Modal.displayName = 'Modal';
|
449 | Modal.propTypes = propTypes;
|
450 |
|
451 | var _default = Object.assign(Modal, {
|
452 | Manager: _ModalManager["default"]
|
453 | });
|
454 |
|
455 | exports["default"] = _default;
|
456 | module.exports = exports.default; |
\ | No newline at end of file |