NEW
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
Learn more
Skip to content
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

CLI

pnpm dlx shadcn@latest add https://animata.design/r/overlay/modal.json

Manual

Install dependencies

npm install 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:

"use client";
 
import { CircleAlert } from "lucide-react";
import { AnimatePresence, motion } from "motion/react";
import { useState } from "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-linear-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