shadimage
corr
componentanimated-dialogsource: ok · hit

Animated Dialog

A dialog wrapper with subtle Motion transitions for confirmation and form flows.

npx shadcn add "https://ui.corr.sh/r/animated-dialog.json"
free

Interaction

modal

Tags auto-generated by rules on 9/24/2026 — empty means no evidence, not lack of support.

Dependencies

Bundle weight · light

Registry dependencies

buttondialog

Files1 · source cached 10/8/2026, 7:45:30 PM

registry/corr/components/animated-dialog.tsx
"use client"

import type { ReactNode } from "react"

import { Button } from "@/components/ui/button"
import {
  Dialog,
  DialogClose,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog"
import { cn } from "@/lib/utils"

export type AnimatedDialogAnimation =
  | "zoom"
  | "slide-from-left"
  | "slide-from-right"
  | "slide-from-top"
  | "slide-from-bottom"

const animationClassName: Record<AnimatedDialogAnimation, string> = {
  zoom:
    "transition-none! data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 data-open:duration-300 data-closed:duration-150",
  "slide-from-left":
    "transition-none! data-open:animate-in data-open:fade-in-0 data-open:zoom-in-100 data-open:slide-in-from-left-8 data-closed:animate-out data-closed:fade-out-0 data-closed:slide-out-to-left-6 data-open:duration-300 data-closed:duration-150",
  "slide-from-right":
    "transition-none! data-open:animate-in data-open:fade-in-0 data-open:zoom-in-100 data-open:slide-in-from-right-8 data-closed:animate-out data-closed:fade-out-0 data-closed:slide-out-to-right-6 data-open:duration-300 data-closed:duration-150",
  "slide-from-top":
    "transition-none! data-open:animate-in data-open:fade-in-0 data-open:zoom-in-100 data-open:slide-in-from-top-8 data-closed:animate-out data-closed:fade-out-0 data-closed:slide-out-to-top-6 data-open:duration-300 data-closed:duration-150",
  "slide-from-bottom":
    "transition-none! data-open:animate-in data-open:fade-in-0 data-open:zoom-in-100 data-open:slide-in-from-bottom-8 data-closed:animate-out data-closed:fade-out-0 data-closed:slide-out-to-bottom-6 data-open:duration-300 data-closed:duration-150",
}

export function AnimatedDialog({
  trigger,
  title,
  description,
  children,
  actionLabel = "Continue",
  cancelLabel = "Cancel",
  animation = "zoom",
  className,
  onAction,
}: {
  trigger: ReactNode
  title: string
  description?: string
  children?: ReactNode
  actionLabel?: string
  cancelLabel?: string
  animation?: AnimatedDialogAnimation
  className?: string
  onAction?: () => void
}) {
  return (
    <Dialog>
      <DialogTrigger asChild>{trigger}</DialogTrigger>
      <DialogContent
        className={cn(
          "sm:max-w-[425px]",
          animationClassName[animation],
          className
        )}
      >
        <DialogHeader>
          <DialogTitle>{title}</DialogTitle>
          {description ? (
            <DialogDescription>{description}</DialogDescription>
          ) : null}
        </DialogHeader>
        {children ? <div className="text-sm">{children}</div> : null}
        <DialogFooter>
          <DialogClose asChild>
            <Button variant="outline">{cancelLabel}</Button>
          </DialogClose>
          <DialogClose asChild>
            <Button onClick={onAction}>{actionLabel}</Button>
          </DialogClose>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}

More from corr

Browse all components in this library →