import { XMarkIcon } from "@heroicons/react/24/outline"; import { AnimatePresence, motion } from "framer-motion" import { useRouter } from "next/router"; import { useEffect, useState } from "react"; import ReactDOM from "react-dom"; import { useWindowSize } from "usehooks-ts"; import clsxm from "~/common/libs/clsxm"; type Props = { children: React.ReactNode active: boolean title?: string close?: () => void, className?: string, mode?: "mobile" | "desktop" } const Modal = ({ children, active = false, title, close, className, mode }: Props) => { const router = useRouter() const { width } = useWindowSize() const [rendered, setRendered] = useState(false) mode = mode || width >= 768 ? "desktop" : "mobile" useEffect(() => { setRendered(true) }, []) const modalClassNames = clsxm( "fixed bg-white max-h-[80vh] overflow-auto p-4 pt-0 z-[60] border-gray_r-6", { "left-1/2 -translate-x-1/2 translate-y-1/2 bottom-1/2 w-11/12 md:w-[500px] border rounded-xl": mode === 'desktop', "left-0 w-full border-t bottom-0 rounded-t-xl": mode === 'mobile' }, className ) const variant = { initial: { bottom: mode === 'desktop' ? '45%' : '-100%', opacity: 0 }, animate: { bottom: mode === 'desktop' ? '50%' : 0, opacity: 1 }, exit: { bottom: mode === 'desktop' ? '55%' : '-100%', opacity: 0 }, transition: { ease: 'linear', duration: 0.25 } } return rendered && ReactDOM.createPortal( {active && ( )} {active && (
{title}
{close && ( )}
{children}
)}
, document.querySelector('body')! ) } export default Modal