import React, { MouseEvent, ReactNode } from 'react'; import ReactDOM from 'react-dom'; import Button, { ButtonType } from '../Button'; import { useTransition, animated } from 'react-spring'; import { useLockBodyScroll } from '../../../hooks/useLockBodyScroll'; import LoadingSpinner from '../LoadingSpinner'; interface ModalProps { title?: string; onCancel?: (e: MouseEvent) => void; onOk?: (e: MouseEvent) => void; cancelText?: string; okText?: string; cancelButtonType?: ButtonType; okButtonType?: ButtonType; visible?: boolean; disableScrollLock?: boolean; backgroundClickable?: boolean; iconSvg?: ReactNode; loading?: boolean; } const Modal: React.FC = ({ title, onCancel, onOk, cancelText, okText, cancelButtonType, okButtonType, children, visible, disableScrollLock, backgroundClickable = true, iconSvg, loading = false, }) => { useLockBodyScroll(!!visible, disableScrollLock); const transitions = useTransition(visible, null, { from: { opacity: 0 }, enter: { opacity: 1 }, leave: { opacity: 0 }, config: { tension: 500, velocity: 40, friction: 60 }, }); const containerTransitions = useTransition(visible && !loading, null, { from: { opacity: 0, transform: 'scale(0.5)' }, enter: { opacity: 1, transform: 'scale(1)' }, leave: { opacity: 0, transform: 'scale(0.5)' }, config: { tension: 500, velocity: 40, friction: 60 }, }); const loadingTransitions = useTransition(visible && loading, null, { from: { opacity: 0, transform: 'scale(0.5)' }, enter: { opacity: 1, transform: 'scale(1)' }, leave: { opacity: 0, transform: 'scale(0.5)' }, config: { tension: 500, velocity: 40, friction: 60 }, }); const cancelType = cancelButtonType ?? 'default'; const okType = okButtonType ?? 'primary'; return ( <> {transitions.map( ({ props, item, key }) => item && ReactDOM.createPortal( { if (e.key === 'Escape') { typeof onCancel === 'function' && backgroundClickable ? onCancel : undefined; } }} > {loadingTransitions.map( ({ props, item, key }) => item && ( ) )} {containerTransitions.map( ({ props, item, key }) => item && (
{iconSvg && (
{iconSvg}
)}
{title && ( )} {children && (

{children}

)}
{(onCancel || onOk) && (
{typeof onOk === 'function' && ( )} {typeof onCancel === 'function' && ( )}
)}
) )}
, document.body ) )} ); }; export default Modal;