import { useState, useEffect, useRef } from 'react'; import { ModalSetter } from '../../../../lib/types/modal.interface'; import ModalService from '../services/ModalService'; import styles from './ModalRoot.module.scss'; export default function ModalRoot() { const [modal, setModal] = useState | null>(null); const ref = useRef(null); useEffect(() => { ModalService.on('open', ({ component, props, target, resolve }) => { setModal({ component, props, resolve, close: (...args) => { setModal(null); resolve?.call(null, ...args); target?.focus(); }, }); }); }, []); useEffect(() => { if (!modal) { return; } function handleEscapeKey(e: KeyboardEvent) { if (e.key === 'Escape') { modal?.close?.call(null, false); } } // Off click listener function handleClickOutside(event: MouseEvent | TouchEvent) { if ( ref.current && !(ref.current as unknown as HTMLElement).contains( event.target as HTMLElement ) ) { modal?.close?.call(null, false); } } window.addEventListener('keyup', handleEscapeKey); document.body.style.overflow = 'hidden'; document.addEventListener('mousedown', handleClickOutside); document.addEventListener('touchstart', handleClickOutside); return () => { window.removeEventListener('keyup', handleEscapeKey); document.body.style.overflow = ''; document.removeEventListener('mousedown', handleClickOutside); document.removeEventListener('touchstart', handleClickOutside); }; }, [modal]); const ModalComponent = modal?.component ? modal.component : null; return (
{ModalComponent && ( )}
); }