NRVM

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>
  );
}