UNPKG

@geezee/react-ui

Version:

Modern and minimalist React UI library.

113 lines (98 loc) 3.37 kB
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import React, { useState, useEffect, useMemo, forwardRef, useImperativeHandle } from 'react'; import { createPortal } from 'react-dom'; import usePortal from '../utils/use-portal'; import ModalWrapper from './modal-wrapper'; import ModalAction from './modal-action'; import ModalActions from './modal-actions'; import Backdrop from '../shared/backdrop'; import { ModalContext } from './modal-context'; import { pickChild } from '../utils/collections'; import useBodyScroll from '../utils/use-body-scroll'; import ModalIcon from './modal-icon'; import useTheme from '../styles/use-theme'; var defaultProps = { width: '30rem', wrapClassName: '', disableBackdropClick: false, closable: false }; var Modal = forwardRef(function (_ref, ref) { var children = _ref.children, disableBackdropClick = _ref.disableBackdropClick, onClose = _ref.onClose, onOpen = _ref.onOpen, open = _ref.open, wrapperWidth = _ref.width, wrapClassName = _ref.wrapClassName, closable = _ref.closable; var portal = usePortal('modal'); var _useState = useState(false), _useState2 = _slicedToArray(_useState, 2), visible = _useState2[0], _setVisible = _useState2[1]; var _useBodyScroll = useBodyScroll(), _useBodyScroll2 = _slicedToArray(_useBodyScroll, 2), setBodyHidden = _useBodyScroll2[1]; var _pickChild = pickChild(children, ModalAction), _pickChild2 = _slicedToArray(_pickChild, 2), withoutActionsChildren = _pickChild2[0], ActionsChildren = _pickChild2[1]; var hasActions = ActionsChildren && React.Children.count(ActionsChildren) > 0; var theme = useTheme(); var closeModal = function closeModal() { onClose && onClose(); if (open === undefined) { _setVisible(false); setBodyHidden(false); } }; useImperativeHandle(ref, function () { return { setVisible: function setVisible() { var visible = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; _setVisible(visible); }, getVisible: function getVisible() { return visible; } }; }); useEffect(function () { if (open === undefined) return; if (open) { onOpen && onOpen(); } if (!open) { onClose && onClose(); } _setVisible(open); setBodyHidden(open); }, [open]); var closeFromBackdrop = function closeFromBackdrop() { if (disableBackdropClick && hasActions) return; closeModal(); }; var modalConfig = useMemo(function () { return { close: closeModal }; }, []); if (!portal) return null; return createPortal( /*#__PURE__*/React.createElement(ModalContext.Provider, { value: modalConfig }, /*#__PURE__*/React.createElement(Backdrop, { onClick: closeFromBackdrop, visible: visible }, /*#__PURE__*/React.createElement(ModalWrapper, { visible: visible, className: "modal ".concat(wrapClassName), width: wrapperWidth }, closable && /*#__PURE__*/React.createElement(ModalIcon, { size: 16, color: theme.palette.cNeutral5, onClick: closeModal }), withoutActionsChildren, hasActions && /*#__PURE__*/React.createElement(ModalActions, null, ActionsChildren)))), portal); }); Modal.defaultProps = defaultProps; export default Modal;