This commit is contained in:
2025-03-20 14:26:57 +05:00
commit eb552cbdc8
55 changed files with 2212 additions and 0 deletions
+92
View File
@@ -0,0 +1,92 @@
/* 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 Button from "./Button";
const duration = 300;
function ModalContainer() {
const { modal, setModal, isOpen, setIsOpen } = useModalStore();
const divRef = useRef<HTMLDivElement>(null);
const buttonRef = useRef<HTMLDivElement>(null);
const popoverRef = useRef<HTMLDivElement>(null);
function handleResize() {
if (!popoverRef.current) return;
if (divRef.current!.clientHeight > popoverRef.current!.clientHeight) {
buttonRef.current!.style.height = `${divRef.current!.clientHeight}px`;
} else {
buttonRef.current!.style.height = `100%`;
}
}
function handleKeydown(e: KeyboardEvent) {
if (e.key !== "Escape") return;
setIsOpen(false);
}
useEffect(() => setIsOpen(!!modal), [modal]);
useEffect(() => {
if (isOpen) return;
setTimeout(() => {
setModal(null);
}, duration);
}, [isOpen]);
useEffect(() => {
window.addEventListener("resize", handleResize);
window.addEventListener("keydown", handleKeydown);
return () => {
window.removeEventListener("resize", handleResize);
window.removeEventListener("keydown", handleKeydown);
};
}, []);
return (
<AnimatePresence>
{isOpen && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className={`h-full transition-opacity duration-300`}
>
<div
ref={popoverRef}
className="fixed top-0 left-0 w-full h-full bg-black/70 overflow-y-auto flex flex-col items-center justify-center"
>
<div className="max-h-full">
<div ref={divRef} className="p-[0.972vw]">
<div
ref={buttonRef}
className="absolute top-0 left-0 w-full h-full cursor-pointer"
onClick={() => setIsOpen(false)}
/>
<div className="relative w-full">
{modal}
<Button
onlyIcon
className="absolute top-[1.667vw] right-[1.667vw] p-[0.556vw] !rounded-full bg-[#F9F9F9]"
onClick={() => setIsOpen(false)}
>
<span className="w-[1.389vw] h-[1.389vw] text-black">
<CloseIcon />
</span>
</Button>
</div>
</div>
</div>
</div>
</motion.div>
)}
</AnimatePresence>
);
}
export default ModalContainer;