Back to Discover
ModalsIntermediate
Drawer Modal
A mobile-friendly, slide-up bottom drawer using Framer Motion.
Live Preview
"use client";
import { useState } from "react";
import { motion, AnimatePresence } from "framer-motion";
export function DrawerModal() {
const [isOpen, setIsOpen] = useState(false);
return (
<div className="flex items-center justify-center h-full w-full relative">
<button
onClick={() => setIsOpen(true)}
className="rounded-md border border-border bg-transparent px-4 py-2 text-sm font-medium hover:bg-muted transition-colors"
>
Open Drawer
</button>
<AnimatePresence>
{isOpen && (
<>
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="absolute inset-0 bg-background/80 backdrop-blur-sm z-40"
onClick={() => setIsOpen(false)}
/>
<motion.div
initial={{ y: "100%" }}
animate={{ y: 0 }}
exit={{ y: "100%" }}
transition={{ type: "spring", damping: 25, stiffness: 200 }}
className="absolute bottom-0 left-0 right-0 z-50 rounded-t-3xl border-t border-border bg-[#050505] p-6 shadow-2xl h-[60%]"
>
<div className="mx-auto w-12 h-1.5 rounded-full bg-muted mb-8" />
<h2 className="text-2xl font-bold mb-2">Drawer Content</h2>
<p className="text-muted-foreground mb-6">
Slide-up drawers are an excellent pattern for mobile-first interfaces,
feeling more natural than centered modals on smaller screens.
</p>
<div className="w-full h-32 rounded-xl border border-dashed border-border flex items-center justify-center text-muted-foreground text-sm">
Placeholder
</div>
</motion.div>
</>
)}
</AnimatePresence>
</div>
);
}