{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "dialog",
  "dependencies": [
    "lucide-react",
    "motion",
    "radix-ui"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "src/components/watermelon-ui/dialog.tsx",
      "content": "'use client';\n\nimport * as React from 'react';\nimport { Dialog as DialogPrime } from 'radix-ui';\nimport { AnimatePresence, motion, type HTMLMotionProps } from 'motion/react';\nimport { XIcon } from 'lucide-react';\nimport { cn } from '@/lib/utils';\n\ntype DialogProps = DialogPrimitiveProps;\n\nfunction Dialog(props: DialogProps) {\n  return <DialogPrimitive {...props} />;\n}\n\ntype DialogTriggerProps = DialogTriggerPrimitiveProps;\n\nfunction DialogTrigger(props: DialogTriggerProps) {\n  return <DialogTriggerPrimitive {...props} />;\n}\n\ntype DialogCloseProps = DialogClosePrimitiveProps;\n\nfunction DialogClose(props: DialogCloseProps) {\n  return <DialogClosePrimitive {...props} />;\n}\n\ntype DialogOverlayProps = DialogOverlayPrimitiveProps;\n\nfunction DialogOverlay({ className, ...props }: DialogOverlayProps) {\n  return (\n    <DialogOverlayPrimitive\n      className={cn('fixed inset-0 z-50 bg-black/50', className)}\n      {...props}\n    />\n  );\n}\n\ntype DialogContentProps = DialogContentPrimitiveProps & {\n  showCloseButton?: boolean;\n};\n\nfunction DialogContent({\n  className,\n  children,\n  showCloseButton = true,\n  ...props\n}: DialogContentProps) {\n  return (\n    <DialogPortalPrimitive>\n      <DialogOverlay />\n      <DialogContentPrimitive\n        className={cn(\n          'bg-background fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg sm:max-w-lg',\n          className,\n        )}\n        {...props}\n      >\n        {children}\n        {showCloseButton && (\n          <DialogClosePrimitive className=\"ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\">\n            <XIcon />\n            <span className=\"sr-only\">Close</span>\n          </DialogClosePrimitive>\n        )}\n      </DialogContentPrimitive>\n    </DialogPortalPrimitive>\n  );\n}\n\ntype DialogHeaderProps = DialogHeaderPrimitiveProps;\n\nfunction DialogHeader({ className, ...props }: DialogHeaderProps) {\n  return (\n    <DialogHeaderPrimitive\n      className={cn('flex flex-col gap-2 text-center sm:text-left', className)}\n      {...props}\n    />\n  );\n}\n\ntype DialogFooterProps = DialogFooterPrimitiveProps;\n\nfunction DialogFooter({ className, ...props }: DialogFooterProps) {\n  return (\n    <DialogFooterPrimitive\n      className={cn(\n        'flex flex-col-reverse gap-2 sm:flex-row sm:justify-end',\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\ntype DialogTitleProps = DialogTitlePrimitiveProps;\n\nfunction DialogTitle({ className, ...props }: DialogTitleProps) {\n  return (\n    <DialogTitlePrimitive\n      className={cn('text-lg leading-none font-semibold', className)}\n      {...props}\n    />\n  );\n}\n\ntype DialogDescriptionProps = DialogDescriptionPrimitiveProps;\n\nfunction DialogDescription({ className, ...props }: DialogDescriptionProps) {\n  return (\n    <DialogDescriptionPrimitive\n      className={cn('text-muted-foreground text-sm', className)}\n      {...props}\n    />\n  );\n}\n\nexport {\n  Dialog,\n  DialogTrigger,\n  DialogClose,\n  DialogContent,\n  DialogHeader,\n  DialogFooter,\n  DialogTitle,\n  DialogDescription,\n  type DialogProps,\n  type DialogTriggerProps,\n  type DialogCloseProps,\n  type DialogContentProps,\n  type DialogHeaderProps,\n  type DialogFooterProps,\n  type DialogTitleProps,\n  type DialogDescriptionProps,\n};\n\n\n\ntype DialogContextType = {\n  isOpen: boolean;\n  setIsOpen: DialogProps['onOpenChange'];\n};\n\nconst [DialogProvider, useDialog] =\n  getStrictContext<DialogContextType>('DialogContext');\n\ntype DialogPrimitiveProps = React.ComponentProps<typeof DialogPrime.Root>;\n\nfunction DialogPrimitive(props: DialogPrimitiveProps) {\n  const [isOpen, setIsOpen] = useControlledState({\n    value: props?.open,\n    defaultValue: props?.defaultOpen,\n    onChange: props?.onOpenChange,\n  });\n\n  return (\n    <DialogProvider value={{ isOpen, setIsOpen }}>\n      <DialogPrime.Root\n        data-slot=\"dialog\"\n        {...props}\n        onOpenChange={setIsOpen}\n      />\n    </DialogProvider>\n  );\n}\n\ntype DialogTriggerPrimitiveProps = React.ComponentProps<typeof DialogPrime.Trigger>;\n\nfunction DialogTriggerPrimitive(props: DialogTriggerPrimitiveProps) {\n  return <DialogPrime.Trigger data-slot=\"dialog-trigger\" {...props} />;\n}\n\ntype DialogPortalProps = Omit<\n  React.ComponentProps<typeof DialogPrime.Portal>,\n  'forceMount'\n>;\n\nfunction DialogPortalPrimitive(props: DialogPortalProps) {\n  const { isOpen } = useDialog();\n\n  return (\n    <AnimatePresence>\n      {isOpen && (\n        <DialogPrime.Portal\n          data-slot=\"dialog-portal\"\n          forceMount\n          {...props}\n        />\n      )}\n    </AnimatePresence>\n  );\n}\n\ntype DialogOverlayPrimitiveProps = Omit<\n  React.ComponentProps<typeof DialogPrime.Overlay>,\n  'forceMount' | 'asChild'\n> &\n  HTMLMotionProps<'div'>;\n\nfunction DialogOverlayPrimitive({\n  transition = { duration: 0.2, ease: 'easeInOut' },\n  ...props\n}: DialogOverlayProps) {\n  return (\n    <DialogPrime.Overlay data-slot=\"dialog-overlay\" 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={transition}\n        {...props}\n      />\n    </DialogPrime.Overlay>\n  );\n}\n\ntype DialogFlipDirection = 'top' | 'bottom' | 'left' | 'right';\n\ntype DialogContentPrimitiveProps = Omit<\n  React.ComponentProps<typeof DialogPrime.Content>,\n  'forceMount' | 'asChild'\n> &\n  HTMLMotionProps<'div'> & {\n    from?: DialogFlipDirection;\n  };\n\nfunction DialogContentPrimitive({\n  from = 'top',\n  onOpenAutoFocus,\n  onCloseAutoFocus,\n  onEscapeKeyDown,\n  onPointerDownOutside,\n  onInteractOutside,\n  transition = { type: 'spring', stiffness: 150, damping: 25 },\n  ...props\n}: DialogContentPrimitiveProps) {\n  const initialRotation =\n    from === 'bottom' || from === 'left' ? '20deg' : '-20deg';\n  const isVertical = from === 'top' || from === 'bottom';\n  const rotateAxis = isVertical ? 'rotateX' : 'rotateY';\n\n  return (\n    <DialogPrime.Content\n      asChild\n      forceMount\n      onOpenAutoFocus={onOpenAutoFocus}\n      onCloseAutoFocus={onCloseAutoFocus}\n      onEscapeKeyDown={onEscapeKeyDown}\n      onPointerDownOutside={onPointerDownOutside}\n      onInteractOutside={onInteractOutside}\n    >\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        {...props}\n      />\n    </DialogPrime.Content>\n  );\n}\n\ntype DialogClosePrimitiveProps = React.ComponentProps<typeof DialogPrime.Close>;\n\nfunction DialogClosePrimitive(props: DialogClosePrimitiveProps) {\n  return <DialogPrime.Close data-slot=\"dialog-close\" {...props} />;\n}\n\ntype DialogHeaderPrimitiveProps = React.ComponentProps<'div'>;\n\nfunction DialogHeaderPrimitive(props: DialogHeaderPrimitiveProps) {\n  return <div data-slot=\"dialog-header\" {...props} />;\n}\n\ntype DialogFooterPrimitiveProps = React.ComponentProps<'div'>;\n\nfunction DialogFooterPrimitive(props: DialogFooterPrimitiveProps) {\n  return <div data-slot=\"dialog-footer\" {...props} />;\n}\n\ntype DialogTitlePrimitiveProps = React.ComponentProps<typeof DialogPrime.Title>;\n\nfunction DialogTitlePrimitive(props: DialogTitlePrimitiveProps) {\n  return <DialogPrime.Title data-slot=\"dialog-title\" {...props} />;\n}\n\ntype DialogDescriptionPrimitiveProps = React.ComponentProps<\n  typeof DialogPrime.Description\n>;\n\nfunction DialogDescriptionPrimitive(props: DialogDescriptionPrimitiveProps) {\n  return (\n    <DialogPrime.Description data-slot=\"dialog-description\" {...props} />\n  );\n}\n\n\n\ninterface CommonControlledStateProps<T> {\n  value?: T;\n  defaultValue?: T;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function useControlledState<T, Rest extends any[] = []>(\n  props: CommonControlledStateProps<T> & {\n    onChange?: (value: T, ...args: Rest) => void;\n  },\n): readonly [T, (next: T, ...args: Rest) => void] {\n  const { value, defaultValue, onChange } = props;\n\n  const [state, setInternalState] = React.useState<T>(\n    value !== undefined ? value : (defaultValue as T),\n  );\n\n  React.useEffect(() => {\n    if (value !== undefined) setInternalState(value);\n  }, [value]);\n\n  const setState = React.useCallback(\n    (next: T, ...args: Rest) => {\n      setInternalState(next);\n      onChange?.(next, ...args);\n    },\n    [onChange],\n  );\n\n  return [state, setState] as const;\n}\n\n\nfunction getStrictContext<T>(\n  name?: string,\n): readonly [\n  ({\n    value,\n    children,\n  }: {\n    value: T;\n    children?: React.ReactNode;\n  }) => React.JSX.Element,\n  () => T,\n] {\n  const Context = React.createContext<T | undefined>(undefined);\n\n  const Provider = ({\n    value,\n    children,\n  }: {\n    value: T;\n    children?: React.ReactNode;\n  }) => <Context.Provider value={value}>{children}</Context.Provider>;\n\n  const useSafeContext = () => {\n    const ctx = React.useContext(Context);\n    if (ctx === undefined) {\n      throw new Error(`useContext must be used within ${name ?? 'a Provider'}`);\n    }\n    return ctx;\n  };\n\n  return [Provider, useSafeContext] as const;\n}\n\nexport { getStrictContext };\n",
      "type": "registry:ui",
      "target": "components/ui/dialog.tsx"
    }
  ],
  "type": "registry:ui"
}
