"use client"; import { AnimatePresence, motion, useReducedMotion, type Transition, } from "motion/react"; import { type ReactNode, useEffect, } from "react"; import { cn } from "@/lib/utils"; export interface MorphingModalProps { /** Which view is currently shown. `null` closes the modal. */ viewId: string | null; onClose: () => void; children: ReactNode; /** "bottom" anchors to the viewport bottom (mobile-like). "center" centers vertically. */ placement?: "bottom" | "center"; className?: string; } const SPRING: Transition = { type: "spring", stiffness: 400, damping: 38, mass: 0.7 }; export function MorphingModal({ viewId, onClose, children, placement = "bottom", className, }: MorphingModalProps) { const open = viewId !== null; const reduce = useReducedMotion(); const enterY = reduce ? 0 : placement === "bottom" ? 40 : 20; const enterScale = reduce ? 1 : 0.97; useEffect(() => { if (!open) return; const prev = document.body.style.overflow; document.body.style.overflow = "hidden"; return () => { document.body.style.overflow = prev; }; }, [open]); return (
{open ? ( {children} ) : null}
); }