{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "radix-dialog",
  "type": "registry:ui",
  "title": "Dialog",
  "description": "A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.",
  "dependencies": [
    "motion",
    "lucide-react",
    "radix-ui"
  ],
  "files": [
    {
      "path": "registry/radix/dialog/index.tsx",
      "content": "'use client';\n\nimport * as React from 'react';\nimport { Dialog as DialogPrimitive } from 'radix-ui';\nimport { X } from 'lucide-react';\nimport {\n  AnimatePresence,\n  motion,\n  type HTMLMotionProps,\n  type Transition,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype DialogContextType = {\n  isOpen: boolean;\n};\n\nconst DialogContext = React.createContext<DialogContextType | undefined>(\n  undefined,\n);\n\nconst useDialog = (): DialogContextType => {\n  const context = React.useContext(DialogContext);\n  if (!context) {\n    throw new Error('useDialog must be used within a Dialog');\n  }\n  return context;\n};\n\ntype DialogProps = React.ComponentProps<typeof DialogPrimitive.Root>;\n\nfunction Dialog({ children, ...props }: DialogProps) {\n  const [isOpen, setIsOpen] = React.useState(\n    props?.open ?? props?.defaultOpen ?? false,\n  );\n\n  React.useEffect(() => {\n    if (props?.open !== undefined) setIsOpen(props.open);\n  }, [props?.open]);\n\n  const handleOpenChange = React.useCallback(\n    (open: boolean) => {\n      setIsOpen(open);\n      props.onOpenChange?.(open);\n    },\n    [props],\n  );\n\n  return (\n    <DialogContext.Provider value={{ isOpen }}>\n      <DialogPrimitive.Root\n        data-slot=\"dialog\"\n        {...props}\n        onOpenChange={handleOpenChange}\n      >\n        {children}\n      </DialogPrimitive.Root>\n    </DialogContext.Provider>\n  );\n}\n\ntype DialogTriggerProps = React.ComponentProps<typeof DialogPrimitive.Trigger>;\n\nfunction DialogTrigger(props: DialogTriggerProps) {\n  return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />;\n}\n\ntype DialogPortalProps = React.ComponentProps<typeof DialogPrimitive.Portal>;\n\nfunction DialogPortal(props: DialogPortalProps) {\n  return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />;\n}\n\ntype DialogCloseProps = React.ComponentProps<typeof DialogPrimitive.Close>;\n\nfunction DialogClose(props: DialogCloseProps) {\n  return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />;\n}\n\ntype DialogOverlayProps = React.ComponentProps<typeof DialogPrimitive.Overlay>;\n\nfunction DialogOverlay({ className, ...props }: DialogOverlayProps) {\n  return (\n    <DialogPrimitive.Overlay\n      data-slot=\"dialog-overlay\"\n      className={cn(\n        'fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\ntype FlipDirection = 'top' | 'bottom' | 'left' | 'right';\n\ntype DialogContentProps = React.ComponentProps<typeof DialogPrimitive.Content> &\n  HTMLMotionProps<'div'> & {\n    from?: FlipDirection;\n    transition?: Transition;\n  };\n\nfunction DialogContent({\n  className,\n  children,\n  from = 'top',\n  transition = { type: 'spring', stiffness: 150, damping: 25 },\n  ...props\n}: DialogContentProps) {\n  const { isOpen } = useDialog();\n\n  const initialRotation =\n    from === 'top' || from === 'left' ? '20deg' : '-20deg';\n  const isVertical = from === 'top' || from === 'bottom';\n  const rotateAxis = isVertical ? 'rotateX' : 'rotateY';\n\n  return (\n    <AnimatePresence>\n      {isOpen && (\n        <DialogPortal forceMount data-slot=\"dialog-portal\">\n          <DialogOverlay asChild forceMount>\n            <motion.div\n              key=\"dialog-overlay\"\n              initial={{ opacity: 0, filter: 'blur(4px)' }}\n              animate={{ opacity: 1, filter: 'blur(0px)' }}\n              exit={{ opacity: 0, filter: 'blur(4px)' }}\n              transition={{ duration: 0.2, ease: 'easeInOut' }}\n            />\n          </DialogOverlay>\n          <DialogPrimitive.Content asChild forceMount {...props}>\n            <motion.div\n              key=\"dialog-content\"\n              data-slot=\"dialog-content\"\n              initial={{\n                opacity: 0,\n                filter: 'blur(4px)',\n                transform: `perspective(500px) ${rotateAxis}(${initialRotation}) scale(0.8)`,\n              }}\n              animate={{\n                opacity: 1,\n                filter: 'blur(0px)',\n                transform: `perspective(500px) ${rotateAxis}(0deg) scale(1)`,\n              }}\n              exit={{\n                opacity: 0,\n                filter: 'blur(4px)',\n                transform: `perspective(500px) ${rotateAxis}(${initialRotation}) scale(0.8)`,\n              }}\n              transition={transition}\n              className={cn(\n                'fixed left-[50%] top-[50%] z-50 grid w-[calc(100%-2rem)] max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg rounded-xl',\n                className,\n              )}\n              {...props}\n            >\n              {children}\n              <DialogPrimitive.Close className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground\">\n                <X className=\"h-4 w-4\" />\n                <span className=\"sr-only\">Close</span>\n              </DialogPrimitive.Close>\n            </motion.div>\n          </DialogPrimitive.Content>\n        </DialogPortal>\n      )}\n    </AnimatePresence>\n  );\n}\n\ntype DialogHeaderProps = React.ComponentProps<'div'>;\n\nfunction DialogHeader({ className, ...props }: DialogHeaderProps) {\n  return (\n    <div\n      data-slot=\"dialog-header\"\n      className={cn(\n        'flex flex-col space-y-1.5 text-center sm:text-left',\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\ntype DialogFooterProps = React.ComponentProps<'div'>;\n\nfunction DialogFooter({ className, ...props }: DialogFooterProps) {\n  return (\n    <div\n      data-slot=\"dialog-footer\"\n      className={cn(\n        'flex flex-col-reverse sm:flex-row sm:justify-end gap-2',\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\ntype DialogTitleProps = React.ComponentProps<typeof DialogPrimitive.Title>;\n\nfunction DialogTitle({ className, ...props }: DialogTitleProps) {\n  return (\n    <DialogPrimitive.Title\n      data-slot=\"dialog-title\"\n      className={cn(\n        'text-lg font-semibold leading-none tracking-tight',\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\ntype DialogDescriptionProps = React.ComponentProps<\n  typeof DialogPrimitive.Description\n>;\n\nfunction DialogDescription({ className, ...props }: DialogDescriptionProps) {\n  return (\n    <DialogPrimitive.Description\n      data-slot=\"dialog-description\"\n      className={cn('text-sm text-muted-foreground', className)}\n      {...props}\n    />\n  );\n}\n\nexport {\n  Dialog,\n  DialogPortal,\n  DialogOverlay,\n  DialogClose,\n  DialogTrigger,\n  DialogContent,\n  DialogHeader,\n  DialogFooter,\n  DialogTitle,\n  DialogDescription,\n  useDialog,\n  type DialogContextType,\n  type DialogProps,\n  type DialogTriggerProps,\n  type DialogPortalProps,\n  type DialogCloseProps,\n  type DialogOverlayProps,\n  type DialogContentProps,\n  type DialogHeaderProps,\n  type DialogFooterProps,\n  type DialogTitleProps,\n  type DialogDescriptionProps,\n};\n",
      "type": "registry:ui",
      "target": "components/animate-ui/radix/dialog.tsx"
    }
  ]
}