UNPKG

@ozen-ui/kit

Version:

React component library

95 lines (94 loc) 6.58 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Modal = exports.cnModal = void 0; var tslib_1 = require("tslib"); require("./Modal.css"); var react_1 = tslib_1.__importStar(require("react")); var react_transition_group_1 = require("react-transition-group"); var environment_1 = require("../../constants/environment"); var useClickOutside_1 = require("../../hooks/useClickOutside"); var useEventListener_1 = require("../../hooks/useEventListener"); var useFocusTrap_1 = require("../../hooks/useFocusTrap"); var useLockBodyScroll_1 = require("../../hooks/useLockBodyScroll"); var useMultiRef_1 = require("../../hooks/useMultiRef"); var usePortalContainer_1 = require("../../hooks/usePortalContainer"); var classname_1 = require("../../utils/classname"); var isKey_1 = require("../../utils/isKey"); var Backdrop_1 = require("../Backdrop"); var PortalBase_1 = require("../PortalBase"); var components_1 = require("./components"); var constants_1 = require("./constants"); var index_1 = require("./index"); exports.cnModal = (0, classname_1.cn)('Modal'); exports.Modal = (0, react_1.forwardRef)(function (_a, ref) { var _b = _a.open, open = _b === void 0 ? constants_1.MODAL_DEFAULT_OPEN : _b, _c = _a.keepMounted, keepMounted = _c === void 0 ? constants_1.MODAL_DEFAULT_KEEP_MOUNTED : _c, _d = _a.hideBackdrop, hideBackdrop = _d === void 0 ? constants_1.MODAL_DEFAULT_HIDE_BACKDROP : _d, _e = _a.disableScrollLock, disableScrollLock = _e === void 0 ? constants_1.MODAL_DEFAULT_DISABLE_SCROLL_LOCK : _e, _f = _a.disableClickOutside, disableClickOutside = _f === void 0 ? constants_1.MODAL_DEFAULT_DISABLE_CLICK_OUTSIDE : _f, _g = _a.disableEscapeKeyDown, disableEscapeKeyDown = _g === void 0 ? constants_1.MODAL_DEFAULT_ESCAPE_KEY_DOWN : _g, children = _a.children, onEnter = _a.onEnter, onEntered = _a.onEntered, onExit = _a.onExit, onExitedProp = _a.onExited, onClose = _a.onClose, backdropProps = _a.backdropProps, windowProps = _a.windowProps, transitionProps = _a.transitionProps, className = _a.className, ignoreClickOutsideRefs = _a.ignoreClickOutsideRefs, _h = _a.container, containerProp = _h === void 0 ? constants_1.MODAL_DEFAULT_PORTAL_CONTAINER : _h, other = tslib_1.__rest(_a, ["open", "keepMounted", "hideBackdrop", "disableScrollLock", "disableClickOutside", "disableEscapeKeyDown", "children", "onEnter", "onEntered", "onExit", "onExited", "onClose", "backdropProps", "windowProps", "transitionProps", "className", "ignoreClickOutsideRefs", "container"]); var hasBackdrop = !hideBackdrop; var rootRef = (0, react_1.useRef)(null); var windowInnerRef = (0, react_1.useRef)(null); var focusedElement = (0, react_1.useRef)(null); var _j = tslib_1.__read((0, react_1.useState)(false), 2), openState = _j[0], setOpenState = _j[1]; var _k = tslib_1.__read((0, react_1.useState)(false), 2), opened = _k[0], setOpened = _k[1]; var container = (0, usePortalContainer_1.usePortalContainer)(containerProp); var _l = (0, index_1.useModalManager)(windowInnerRef, 1000, openState), isTop = _l.isTop, refsClickOutside = _l.refsClickOutside; var portalMultiRef = (0, useMultiRef_1.useMultiRef)([rootRef, ref]); var trapRef = (0, useFocusTrap_1.useFocusTrap)({ active: isTop, focusinTrap: false, }); var modalConsumerMultiRef = (0, useMultiRef_1.useMultiRef)([ windowInnerRef, trapRef, windowProps === null || windowProps === void 0 ? void 0 : windowProps.ref, ]); (0, useClickOutside_1.useClickOutside)({ refs: tslib_1.__spreadArray(tslib_1.__spreadArray([ windowInnerRef ], tslib_1.__read(refsClickOutside), false), tslib_1.__read((ignoreClickOutsideRefs || [])), false), handler: onClose, active: open && !disableClickOutside, }); // Блокирует прокрутку основного окна приложения (0, useLockBodyScroll_1.useLockBodyScroll)(opened && !disableScrollLock); (0, react_1.useEffect)(function () { var _a; // Сохраняем фокус активного элемента до момента открытия всплывающего окна if (open) { setOpened(true); focusedElement.current = document.activeElement; (_a = focusedElement.current) === null || _a === void 0 ? void 0 : _a.blur(); } setOpenState(open); }, [open]); var onExited = (0, react_1.useCallback)(function () { var _a, _b; if (environment_1.isServer) { return; } // Возвращаем фокус активного элемента if (((_a = windowInnerRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement)) || document.activeElement === document.body) { (_b = focusedElement.current) === null || _b === void 0 ? void 0 : _b.focus({ preventScroll: true }); } setOpened(false); onExitedProp === null || onExitedProp === void 0 ? void 0 : onExitedProp(); }, [onExitedProp]); // Нажатие клавиши {ESC} (0, useEventListener_1.useEventListener)({ eventName: 'keydown', handler: function (event) { if (!(0, isKey_1.isKey)(event, 'Escape')) return; onClose === null || onClose === void 0 ? void 0 : onClose(); }, active: isTop && !disableEscapeKeyDown, }); if (!container) { return null; } return (react_1.default.createElement(react_transition_group_1.CSSTransition, tslib_1.__assign({ classNames: (0, exports.cnModal)({ animation: true }), nodeRef: rootRef, timeout: 300 }, transitionProps, { in: openState, onEnter: onEnter, onEntered: onEntered, onExit: onExit, onExited: onExited, unmountOnExit: !keepMounted, appear: true }), react_1.default.createElement(PortalBase_1.PortalBase, tslib_1.__assign({}, other, { container: container, className: (0, exports.cnModal)({ hidden: keepMounted && !openState, hasBackdrop: hasBackdrop }, [className]), ref: portalMultiRef }), !hideBackdrop && (react_1.default.createElement(Backdrop_1.Backdrop, tslib_1.__assign({ zIndex: -1, open: openState }, backdropProps, { className: backdropProps === null || backdropProps === void 0 ? void 0 : backdropProps.className }))), react_1.default.createElement(components_1.ModalConsumer, tslib_1.__assign({}, windowProps, { ref: modalConsumerMultiRef }), children)))); }); exports.Modal.displayName = 'Modal';