Files
graff-mate-client/src/components/ModalContainer.tsx
T

94 lines
2.9 KiB
TypeScript

/* eslint-disable react-hooks/exhaustive-deps */
import { useEffect, useRef } from "react";
import useModalStore from "../stores/useModalStore";
import { AnimatePresence, motion } from "motion/react";
import CloseIcon from "./icons/CloseIcon";
import { clsx as cn } from "clsx";
import NewButton from "./NewButton";
function ModalContainer() {
const { modal, setModal, position } = useModalStore();
const divRef = useRef<HTMLDivElement>(null);
const backdropRef = useRef<HTMLDivElement>(null);
const popoverRef = useRef<HTMLDivElement>(null);
const containerRef = useRef<HTMLDivElement>(null);
function handleResize() {
if (!popoverRef.current) return;
if (divRef.current!.clientHeight > popoverRef.current!.clientHeight) {
backdropRef.current!.style.height = `${divRef.current!.clientHeight}px`;
} else {
backdropRef.current!.style.height = `100%`;
}
}
function handleKeydown(e: KeyboardEvent) {
if (e.key !== "Escape") return;
setModal(null);
}
useEffect(() => {
window.addEventListener("resize", handleResize);
window.addEventListener("keydown", handleKeydown);
return () => {
window.removeEventListener("resize", handleResize);
window.removeEventListener("keydown", handleKeydown);
};
}, []);
return (
<AnimatePresence>
{modal && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="h-full"
>
<div
ref={popoverRef}
className={cn(
"fixed inset-0 bg-black/70 overflow-y-auto flex flex-col justify-center",
position === "center" && "items-center",
position === "right" && "items-end"
)}
>
<div className="max-h-full">
<div ref={divRef} className="p-[0.972vw]">
<div
ref={backdropRef}
className="absolute inset-0 cursor-pointer"
onClick={() => setModal(null)}
/>
<div
ref={containerRef}
className="relative w-full"
// style={{
// height: `calc(${backdropRef.current?.clientHeight}px - 0.972vw * 2)`,
// }}
>
{modal}
<NewButton
size="small"
variant="secondary"
className="absolute top-[1.389vw] right-[1.389vw] p-[0.556vw]"
onClick={() => setModal(null)}
>
<span className="w-[0.972vw] h-[0.972vw] text-[#7D7D7D]">
<CloseIcon />
</span>
</NewButton>
</div>
</div>
</div>
</div>
</motion.div>
)}
</AnimatePresence>
);
}
export default ModalContainer;