2022-12-30 23:35:02 +00:00
|
|
|
import "./Modal.css";
|
2023-02-07 20:04:50 +00:00
|
|
|
import { useEffect, useRef } from "react";
|
2023-01-16 17:48:25 +00:00
|
|
|
import * as React from "react";
|
2022-12-30 23:35:02 +00:00
|
|
|
|
2023-01-16 17:48:25 +00:00
|
|
|
export interface ModalProps {
|
2023-02-07 20:04:50 +00:00
|
|
|
className?: string;
|
|
|
|
onClose?: () => void;
|
|
|
|
children: React.ReactNode;
|
2023-01-16 17:48:25 +00:00
|
|
|
}
|
|
|
|
|
2023-02-07 19:47:57 +00:00
|
|
|
function useOnClickOutside(
|
|
|
|
ref: React.MutableRefObject<Element | null>,
|
|
|
|
onClickOutside: () => void
|
|
|
|
) {
|
2023-01-28 22:07:37 +00:00
|
|
|
useEffect(() => {
|
2023-02-07 19:47:57 +00:00
|
|
|
function handleClickOutside(ev: MouseEvent) {
|
|
|
|
if (ref && ref.current && !ref.current.contains(ev.target as Node)) {
|
2023-02-07 20:04:50 +00:00
|
|
|
onClickOutside();
|
2023-01-28 22:07:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
document.addEventListener("mousedown", handleClickOutside);
|
|
|
|
return () => {
|
|
|
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
|
|
};
|
|
|
|
}, [ref]);
|
|
|
|
}
|
|
|
|
|
2023-01-16 17:48:25 +00:00
|
|
|
export default function Modal(props: ModalProps) {
|
2023-02-07 20:04:50 +00:00
|
|
|
const ref = useRef(null);
|
2023-02-07 19:47:57 +00:00
|
|
|
const onClose = props.onClose || (() => undefined);
|
2023-02-07 20:04:50 +00:00
|
|
|
const className = props.className || "";
|
|
|
|
useOnClickOutside(ref, onClose);
|
2022-12-30 23:35:02 +00:00
|
|
|
|
2023-02-07 20:04:50 +00:00
|
|
|
useEffect(() => {
|
|
|
|
document.body.classList.add("scroll-lock");
|
|
|
|
return () => document.body.classList.remove("scroll-lock");
|
|
|
|
}, []);
|
2022-12-30 23:35:02 +00:00
|
|
|
|
2023-02-07 20:04:50 +00:00
|
|
|
return (
|
|
|
|
<div className={`modal ${className}`}>
|
|
|
|
<div ref={ref} className="modal-body">
|
|
|
|
{props.children}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
2023-01-25 18:08:53 +00:00
|
|
|
}
|