snort/packages/app/src/Element/Modal.tsx

44 lines
1.2 KiB
TypeScript
Raw Normal View History

2022-12-30 23:35:02 +00:00
import "./Modal.css";
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 {
className?: string;
onClose?: () => void;
children: React.ReactNode;
2023-01-16 17:48:25 +00:00
}
2023-02-09 12:26:54 +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)) {
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) {
const ref = useRef(null);
2023-02-07 19:47:57 +00:00
const onClose = props.onClose || (() => undefined);
const className = props.className || "";
useOnClickOutside(ref, onClose);
2022-12-30 23:35:02 +00:00
useEffect(() => {
document.body.classList.add("scroll-lock");
return () => document.body.classList.remove("scroll-lock");
}, []);
2022-12-30 23:35:02 +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
}