This repository has been archived on 2024-06-14. You can view files and clone it, but cannot push or open issues or pull requests.
icynet-admin/components/common/Modal/ModalRoot/ModalRoot.tsx

71 lines
1.9 KiB
TypeScript
Raw Permalink Normal View History

import { useState, useEffect, useRef } from 'react';
import { ModalSetter } from '../../../../lib/types/modal.interface';
2022-08-30 18:08:54 +00:00
import ModalService from '../services/ModalService';
import styles from './ModalRoot.module.scss';
export default function ModalRoot() {
const [modal, setModal] = useState<ModalSetter<Object> | null>(null);
const ref = useRef<HTMLDivElement>(null);
2022-08-30 18:08:54 +00:00
useEffect(() => {
ModalService.on('open', ({ component, props, target, resolve }) => {
setModal({
component,
props,
resolve,
2022-08-30 18:08:54 +00:00
close: (...args) => {
setModal(null);
resolve?.call(null, ...args);
target?.focus();
},
});
});
}, []);
useEffect(() => {
if (!modal) {
return;
}
function handleEscapeKey(e: KeyboardEvent) {
2022-08-30 18:08:54 +00:00
if (e.key === 'Escape') {
modal?.close?.call(null, false);
}
}
2022-08-30 18:08:54 +00:00
// 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);
}
2022-08-30 18:08:54 +00:00
}
window.addEventListener('keyup', handleEscapeKey);
2022-09-01 14:23:11 +00:00
document.body.style.overflow = 'hidden';
document.addEventListener('mousedown', handleClickOutside);
document.addEventListener('touchstart', handleClickOutside);
2022-08-30 18:08:54 +00:00
return () => {
window.removeEventListener('keyup', handleEscapeKey);
2022-09-01 14:23:11 +00:00
document.body.style.overflow = '';
document.removeEventListener('mousedown', handleClickOutside);
document.removeEventListener('touchstart', handleClickOutside);
2022-08-30 18:08:54 +00:00
};
}, [modal]);
const ModalComponent = modal?.component ? modal.component : null;
return (
<section className={modal?.component ? styles.modalRoot : ''}>
{ModalComponent && (
<ModalComponent {...modal?.props} modalRef={ref} close={modal!.close} />
2022-08-30 18:08:54 +00:00
)}
</section>
);
}