54 lines
1.3 KiB
TypeScript
54 lines
1.3 KiB
TypeScript
import { useState, useEffect } from 'react';
|
|
import { ModalDetail } from '../../../../lib/types/modal.interface';
|
|
import ModalService from '../services/ModalService';
|
|
import styles from './ModalRoot.module.scss';
|
|
|
|
export default function ModalRoot() {
|
|
const [modal, setModal] = useState<ModalDetail<unknown> | null>(null);
|
|
|
|
useEffect(() => {
|
|
ModalService.on('open', ({ component, props, target, resolve }) => {
|
|
setModal({
|
|
component,
|
|
props,
|
|
close: (...args) => {
|
|
setModal(null);
|
|
resolve?.call(null, ...args);
|
|
target?.focus();
|
|
},
|
|
});
|
|
});
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
const handler = (e: KeyboardEvent) => {
|
|
if (e.key === 'Escape') {
|
|
modal?.close?.call(null, false);
|
|
}
|
|
};
|
|
|
|
if (!modal) {
|
|
return;
|
|
}
|
|
|
|
window.addEventListener('keyup', handler);
|
|
return () => {
|
|
window.removeEventListener('keyup', handler);
|
|
};
|
|
}, [modal]);
|
|
|
|
const ModalComponent = modal?.component ? modal.component : null;
|
|
|
|
return (
|
|
<section className={modal?.component ? styles.modalRoot : ''}>
|
|
{ModalComponent && (
|
|
<ModalComponent
|
|
{...modal?.props}
|
|
close={modal?.close}
|
|
className={ModalComponent ? 'd-block' : ''}
|
|
/>
|
|
)}
|
|
</section>
|
|
);
|
|
}
|