UNPKG

@coreui/react

Version:

UI Components Library for React.js

134 lines (131 loc) 6.73 kB
import { __rest, __assign } from '../../node_modules/tslib/tslib.es6.js'; import React, { forwardRef, useRef, useState, useEffect, useLayoutEffect } from 'react'; import PropTypes from 'prop-types'; import classNames from '../../_virtual/index.js'; import { CBackdrop } from '../backdrop/CBackdrop.js'; import { CConditionalPortal } from '../conditional-portal/CConditionalPortal.js'; import { CModalContent } from './CModalContent.js'; import { CModalContext } from './CModalContext.js'; import { CModalDialog } from './CModalDialog.js'; import { useForkedRef } from '../../hooks/useForkedRef.js'; import '@popperjs/core'; import Transition from '../../node_modules/react-transition-group/esm/Transition.js'; var CModal = forwardRef(function (_a, ref) { var children = _a.children, alignment = _a.alignment, _b = _a.backdrop, backdrop = _b === void 0 ? true : _b, className = _a.className, container = _a.container, _c = _a.duration, duration = _c === void 0 ? 150 : _c, _d = _a.focus, focus = _d === void 0 ? true : _d, fullscreen = _a.fullscreen, _e = _a.keyboard, keyboard = _e === void 0 ? true : _e, onClose = _a.onClose, onClosePrevented = _a.onClosePrevented, onShow = _a.onShow, _f = _a.portal, portal = _f === void 0 ? true : _f, scrollable = _a.scrollable, size = _a.size, _g = _a.transition, transition = _g === void 0 ? true : _g, _h = _a.unmountOnClose, unmountOnClose = _h === void 0 ? true : _h, visible = _a.visible, rest = __rest(_a, ["children", "alignment", "backdrop", "className", "container", "duration", "focus", "fullscreen", "keyboard", "onClose", "onClosePrevented", "onShow", "portal", "scrollable", "size", "transition", "unmountOnClose", "visible"]); var activeElementRef = useRef(null); var modalRef = useRef(null); var modalContentRef = useRef(null); var forkedRef = useForkedRef(ref, modalRef); var _j = useState(visible), _visible = _j[0], setVisible = _j[1]; var _k = useState(false), staticBackdrop = _k[0], setStaticBackdrop = _k[1]; var contextValues = { visible: _visible, setVisible: setVisible, }; useEffect(function () { setVisible(visible); }, [visible]); useEffect(function () { var _a; if (_visible) { activeElementRef.current = document.activeElement; document.addEventListener('mouseup', handleClickOutside); document.addEventListener('keydown', handleKeyDown); } else { (_a = activeElementRef.current) === null || _a === void 0 ? void 0 : _a.focus(); } return function () { document.removeEventListener('mouseup', handleClickOutside); document.removeEventListener('keydown', handleKeyDown); }; }, [_visible]); var handleDismiss = function () { if (backdrop === 'static') { return setStaticBackdrop(true); } setVisible(false); }; useLayoutEffect(function () { onClosePrevented && onClosePrevented(); setTimeout(function () { return setStaticBackdrop(false); }, duration); }, [staticBackdrop]); // Set focus to modal after open useLayoutEffect(function () { if (_visible) { document.body.classList.add('modal-open'); if (backdrop) { document.body.style.overflow = 'hidden'; document.body.style.paddingRight = '0px'; } setTimeout(function () { var _a; focus && ((_a = modalRef.current) === null || _a === void 0 ? void 0 : _a.focus()); }, transition ? duration : 0); } else { document.body.classList.remove('modal-open'); if (backdrop) { document.body.style.removeProperty('overflow'); document.body.style.removeProperty('padding-right'); } } return function () { document.body.classList.remove('modal-open'); if (backdrop) { document.body.style.removeProperty('overflow'); document.body.style.removeProperty('padding-right'); } }; }, [_visible]); var handleClickOutside = function (event) { if (modalRef.current && modalRef.current == event.target) { handleDismiss(); } }; var handleKeyDown = function (event) { if (event.key === 'Escape' && keyboard) { handleDismiss(); } }; return (React.createElement(React.Fragment, null, React.createElement(Transition, { in: _visible, mountOnEnter: true, nodeRef: modalRef, onEnter: onShow, onExit: onClose, unmountOnExit: unmountOnClose, timeout: transition ? duration : 0 }, function (state) { return (React.createElement(CConditionalPortal, { container: container, portal: portal }, React.createElement(CModalContext.Provider, { value: contextValues }, React.createElement("div", __assign({ className: classNames('modal', { 'modal-static': staticBackdrop, fade: transition, show: state === 'entered', }, className), tabIndex: -1 }, (_visible ? { 'aria-modal': true, role: 'dialog' } : { 'aria-hidden': 'true' }), { style: __assign({}, (state !== 'exited' && { display: 'block' })) }, rest, { ref: forkedRef }), React.createElement(CModalDialog, { alignment: alignment, fullscreen: fullscreen, scrollable: scrollable, size: size }, React.createElement(CModalContent, { ref: modalContentRef }, children)))))); }), backdrop && (React.createElement(CConditionalPortal, { container: container, portal: portal }, React.createElement(CBackdrop, { visible: _visible }))))); }); CModal.propTypes = { alignment: PropTypes.oneOf(['top', 'center']), backdrop: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['static'])]), children: PropTypes.node, className: PropTypes.string, container: PropTypes.any, // HTMLElement duration: PropTypes.number, focus: PropTypes.bool, fullscreen: PropTypes.oneOfType([ PropTypes.bool, PropTypes.oneOf(['sm', 'md', 'lg', 'xl', 'xxl']), ]), keyboard: PropTypes.bool, onClose: PropTypes.func, onClosePrevented: PropTypes.func, onShow: PropTypes.func, portal: PropTypes.bool, scrollable: PropTypes.bool, size: PropTypes.oneOf(['sm', 'lg', 'xl']), transition: PropTypes.bool, unmountOnClose: PropTypes.bool, visible: PropTypes.bool, }; CModal.displayName = 'CModal'; export { CModal }; //# sourceMappingURL=CModal.js.map