import {useEffect, useCallback} from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import LoadingOverlay from '@givewp/components/LoadingOverlay'; import styles from './styles.module.scss'; import {__} from '@wordpress/i18n'; const Modal = ({visible = true, type = 'notice', children = {}, isLoading = false, handleClose = () => {}, ...rest}) => { const closeModal = useCallback((event) => { if (event.keyCode === 27 && typeof handleClose === 'function') { handleClose(); } }, []); useEffect(() => { document.addEventListener('keydown', closeModal, false); return () => { document.removeEventListener('keydown', closeModal, false); }; }, []); const handleOverlayClick = (e) => { if (e.target.classList.contains(styles.overlay) && typeof handleClose === 'function') { handleClose(); } }; const modalStyles = classNames({ [styles.modal]: true, [styles.error]: type === 'error' || type === 'failed', [styles.warning]: type === 'warning', [styles.success]: type === 'success', [styles.http]: type === 'http', }); return (
{isLoading && }
{children}
); }; Modal.Title = ({children, ...rest}) => { return (
{children}
); }; Modal.CloseIcon = ({onClick, ...rest}) => { return (
); }; Modal.Section = ({title, content, ...rest}) => { return (
{title}: {content}
); }; Modal.Content = ({children, align, ...rest}) => { const contentClasses = classNames({ [styles.innerContent]: true, [styles.textCenter]: align === 'center', [styles.textRight]: align === 'right', [styles.textLeft]: !align || align === 'left', }); return (
{children}
); }; Modal.AdditionalContext = ({type, context, ...rest}) => { const title = ['error', 'failed'].includes(type) ? __('Error details', 'give') : __('Additional context', 'give'); return (
{title}:
                    {context instanceof Object
                        ? Object.entries(context).map(([key, value]) => {
                              return (
                                  
{key}: {value}
); }) : context}
); }; Modal.propTypes = { // Is visible visible: PropTypes.bool.isRequired, // Is loading isLoading: PropTypes.bool, // Modal type type: PropTypes.string, // Collection of react DOM elements children: PropTypes.arrayOf(PropTypes.object), // Handle close callback handleClose: PropTypes.func, }; Modal.Title.propTypes = { // Collection of react DOM elements children: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.object)]), }; Modal.CloseIcon.propTypes = { // On click callback onClick: PropTypes.func.isRequired, }; Modal.Section.propTypes = { // Section title title: PropTypes.string.isRequired, // Section content content: PropTypes.string.isRequired, }; Modal.Content.propTypes = { // Collection of react DOM elements children: PropTypes.object, }; Modal.AdditionalContext.propTypes = { // Log type type: PropTypes.string.isRequired, // String or Array of objects context: PropTypes.any.isRequired, }; export default Modal;