Docs
Modal
A modal is a dialog that overlays the primary content with a window, drawing the user's attention exclusively to specific information.
requires interactionclick
Installation
Install dependencies
npm install framer-motion lucide-react
Run the following command
It will create a new file called modal.tsx
inside the components/animata/overlay
directory.
mkdir -p components/animata/overlay && touch components/animata/overlay/modal.tsx
Paste the code
Open the newly created file and paste the following code:
import { useState } from "react";
import { AnimatePresence, motion } from "framer-motion";
import { CircleAlert } from "lucide-react";
import { cn } from "@/lib/utils";
export default function Modal({ modalSize = "lg" }: { modalSize?: "sm" | "lg" }) {
const [isOpen, setIsOpen] = useState(false);
return (
<div>
<button
onClick={() => setIsOpen(true)}
className="rounded bg-indigo-800 p-2 font-medium text-white transition-opacity hover:opacity-90"
>
Open Modal
</button>
<AnimatePresence>
{isOpen && (
<div
onClick={() => setIsOpen(false)}
className="fixed inset-0 z-50 flex cursor-pointer items-center justify-center overflow-y-scroll bg-slate-900/20 p-8 backdrop-blur"
>
<motion.div
initial={{ scale: 0, rotate: "180deg" }}
animate={{
scale: 1,
rotate: "0deg",
transition: {
type: "spring",
bounce: 0.25,
},
}}
exit={{ scale: 0, rotate: "180deg" }}
onClick={(e) => e.stopPropagation()}
className={cn(
"relative w-full max-w-lg cursor-default overflow-hidden rounded-xl bg-gradient-to-r from-indigo-500 via-purple-500 to-indigo-500 p-6 text-white shadow-2xl",
{
"max-w-sm": modalSize === "sm",
},
)}
>
<div className="flex flex-col gap-3">
<CircleAlert className="mx-auto text-white" size={48} />
<h3
className={cn("text-center text-3xl font-bold", {
"text-2xl": modalSize === "sm",
})}
>
Welcome to the modal!
</h3>
<p className="mb-1 text-center">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna.
</p>
<div className="flex gap-2">
<button
onClick={() => setIsOpen(false)}
className="w-full rounded bg-transparent py-2 font-semibold text-white transition-colors hover:bg-white/30"
>
Close!
</button>
<button
onClick={() => setIsOpen(false)}
className="w-full rounded bg-white py-2 font-semibold text-indigo-600 transition-opacity hover:opacity-80"
>
Understood!
</button>
</div>
</div>
</motion.div>
</div>
)}
</AnimatePresence>
</div>
);
}
Credits
Built by Bibek Bhattarai
Inspired by Chakra UI