Back to Discover
ModalsIntermediate
Minimal Modal
A fully functional, animated dialog powered by Framer Motion.
Live Preview
"use client";
import { useState } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { X } from "lucide-react";
export function MinimalModal() {
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 bg-foreground text-background px-4 py-2 text-sm font-medium hover:bg-[#e0e0e0] transition-colors z-0"
>
Open Dialog
</button>
<AnimatePresence>
{isOpen && (
<div className="absolute inset-0 z-50 flex items-center justify-center p-4">
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="absolute inset-0 bg-background/80 backdrop-blur-sm"
onClick={() => setIsOpen(false)}
/>
<motion.div
initial={{ opacity: 0, scale: 0.95, y: 10 }}
animate={{ opacity: 1, scale: 1, y: 0 }}
exit={{ opacity: 0, scale: 0.95, y: 10 }}
transition={{ type: "spring", damping: 25, stiffness: 300 }}
className="relative w-full max-w-lg rounded-xl border border-border bg-[#050505] p-6 shadow-2xl"
>
<button
onClick={() => setIsOpen(false)}
className="absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none"
>
<X className="h-4 w-4 text-muted-foreground hover:text-foreground" />
<span className="sr-only">Close</span>
</button>
<div className="flex flex-col space-y-1.5 mb-4 text-left">
<h2 className="text-lg font-semibold leading-none tracking-tight text-foreground">Edit Profile</h2>
<p className="text-sm text-muted-foreground">Make changes to your profile here. Click save when you're done.</p>
</div>
<div className="space-y-4 py-4 text-left">
<div className="grid grid-cols-4 items-center gap-4">
<label className="text-right text-sm font-medium text-foreground">Name</label>
<input className="col-span-3 rounded-md border border-border bg-transparent px-3 py-2 text-sm focus:outline-none focus:ring-1 focus:ring-foreground" defaultValue="Pedro Duarte" />
</div>
<div className="grid grid-cols-4 items-center gap-4">
<label className="text-right text-sm font-medium text-foreground">Username</label>
<input className="col-span-3 rounded-md border border-border bg-transparent px-3 py-2 text-sm focus:outline-none focus:ring-1 focus:ring-foreground" defaultValue="@peduarte" />
</div>
</div>
<div className="flex justify-end mt-4">
<button
onClick={() => setIsOpen(false)}
className="rounded-md bg-foreground text-background px-4 py-2 text-sm font-medium hover:bg-[#e0e0e0] transition-colors"
>
Save changes
</button>
</div>
</motion.div>
</div>
)}
</AnimatePresence>
</div>
);
}