Files
irth-new-client-120/src/components/PopupContainer.tsx
T
2025-07-29 13:23:43 +05:00

80 lines
3.0 KiB
TypeScript

/* eslint-disable react-hooks/exhaustive-deps */
import { AnimatePresence, motion } from "motion/react";
import { usePopupStore } from "../stores/usePopupStore";
import clsx from "clsx";
import Button from "./ui/Button";
import CloseIcon from "./icons/CloseIcon";
import { useEffect, useRef } from "react";
function PopupContainer() {
const { position, popup, side, setPopup, setSide } = usePopupStore();
const rootRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (!rootRef.current || !popup) return;
const { bottom, top, left, right } =
rootRef.current.getBoundingClientRect();
if (bottom > innerHeight - 32) setSide("top");
else if (top < 32) setSide("bottom");
else if (left < 32) setSide("right");
else if (right > innerWidth - 32) setSide("left");
}, [popup, position, rootRef.current]);
return (
<AnimatePresence>
{popup && (
<motion.div
ref={rootRef}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.1 }}
style={
innerWidth >= 768
? { top: position.y, left: position.x }
: { bottom: 0, left: 0 }
}
className={clsx(
"fixed md:absolute 2xl:pointer-events-none z-2 2xl:rounded-[1.111vw] 2xl:p-[1.111vw] p-4 md:max-2xl:rounded-2xl rounded-t-2xl bg-white 2xl:w-[17.222vw] md:max-2xl:w-[248px] w-screen shadow-[0_2px_8px_0_rgba(0,0,0,0.15)]",
side === "left" &&
"md:-translate-y-1/2 2xl:-translate-x-[calc(100%+1.25vw)] md:max-2xl:-translate-x-[calc(100%+18px)]",
side === "right" && "md:-translate-y-1/2 2xl:translate-x-[1.25vw]",
side === "top" &&
"md:-translate-x-1/2 2xl:-translate-y-[calc(100%+1.25vw)] md:max-2xl:-translate-y-[calc(100%+18px)]",
side === "bottom" &&
"md:-translate-x-1/2 2xl:translate-y-[1.25vw] md:max-2xl:translate-y-[18px]"
)}
>
<Button
onlyIcon
variant="secondary"
size="small"
className="absolute md:hidden top-4 right-4 !bg-[#F3F3F2]"
onClick={() => setPopup(null)}
>
<span className="size-4">
<CloseIcon />
</span>
</Button>
{popup}
<div
className={clsx(
"max-md:hidden absolute 2xl:border-[0.556vw_0px_0.486vw_0.556vw] [border-width:8px_0px_7px_8px] [border-color:_transparent_transparent_transparent_#fff]",
side === "left" && "top-1/2 [y:-50%] left-full [x:1px]",
side === "right" &&
"top-1/2 [y:-50%] right-full [x:1px] [rotate:180deg]",
side === "top" &&
"left-1/2 [x:100%] top-full [y:1px] [rotate:90deg] origin-top-left",
side === "bottom" &&
"left-1/2 [x:100%] bottom-full [y:1px] [rotate:-90deg] origin-bottom-left"
)}
/>
</motion.div>
)}
</AnimatePresence>
);
}
export default PopupContainer;