{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "dialog", "files": [ { "path": "registry/new-york/ui/dialog.tsx", "content": "import { X } from \"lucide-react\";\nimport * as React from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { cn } from \"@/lib/utils\";\n\ninterface DialogContextValue {\n\topen: boolean;\n\tonOpenChange: (open: boolean) => void;\n}\n\nconst DialogContext = React.createContext(null);\n\nfunction useDialogContext() {\n\tconst context = React.useContext(DialogContext);\n\tif (!context) {\n\t\tthrow new Error(\"Dialog components must be used within a Dialog\");\n\t}\n\treturn context;\n}\n\ninterface DialogProps {\n\tchildren: React.ReactNode;\n\topen?: boolean;\n\tonOpenChange?: (open: boolean) => void;\n}\n\nfunction Dialog({ children, open: controlledOpen, onOpenChange }: DialogProps) {\n\tconst [uncontrolledOpen, setUncontrolledOpen] = React.useState(false);\n\tconst isControlled = controlledOpen !== undefined;\n\tconst open = isControlled ? controlledOpen : uncontrolledOpen;\n\n\tconst handleOpenChange = React.useCallback(\n\t\t(newOpen: boolean) => {\n\t\t\tif (!isControlled) {\n\t\t\t\tsetUncontrolledOpen(newOpen);\n\t\t\t}\n\t\t\tonOpenChange?.(newOpen);\n\t\t},\n\t\t[isControlled, onOpenChange],\n\t);\n\n\treturn (\n\t\t\n\t\t\t{children}\n\t\t\n\t);\n}\n\ninterface DialogTriggerProps\n\textends React.ButtonHTMLAttributes {\n\tasChild?: boolean;\n}\n\nfunction DialogTrigger({\n\tchildren,\n\tasChild,\n\tonClick,\n\t...props\n}: DialogTriggerProps) {\n\tconst { onOpenChange } = useDialogContext();\n\n\tconst handleClick = (e: React.MouseEvent) => {\n\t\tonClick?.(e);\n\t\tonOpenChange(true);\n\t};\n\n\tif (asChild && React.isValidElement(children)) {\n\t\treturn React.cloneElement(\n\t\t\tchildren as React.ReactElement<{ onClick?: React.MouseEventHandler }>,\n\t\t\t{\n\t\t\t\tonClick: handleClick,\n\t\t\t},\n\t\t);\n\t}\n\n\treturn (\n\t\t\n\t);\n}\n\ninterface DialogContentProps extends React.HTMLAttributes {}\n\nfunction DialogContent({ className, children, ...props }: DialogContentProps) {\n\tconst { open, onOpenChange } = useDialogContext();\n\n\tReact.useEffect(() => {\n\t\tconst handleEscape = (e: KeyboardEvent) => {\n\t\t\tif (e.key === \"Escape\") {\n\t\t\t\tonOpenChange(false);\n\t\t\t}\n\t\t};\n\n\t\tif (open) {\n\t\t\tdocument.addEventListener(\"keydown\", handleEscape);\n\t\t\tdocument.body.style.overflow = \"hidden\";\n\t\t}\n\n\t\treturn () => {\n\t\t\tdocument.removeEventListener(\"keydown\", handleEscape);\n\t\t\tdocument.body.style.overflow = \"\";\n\t\t};\n\t}, [open, onOpenChange]);\n\n\tif (!open) return null;\n\n\treturn createPortal(\n\t\t
\n\t\t\t onOpenChange(false)}\n\t\t\t\tonKeyDown={(e) => e.key === \"Escape\" && onOpenChange(false)}\n\t\t\t\trole=\"button\"\n\t\t\t\ttabIndex={-1}\n\t\t\t\taria-label=\"Close dialog\"\n\t\t\t/>\n\t\t\t\n\t\t\t\t onOpenChange(false)}\n\t\t\t\t>\n\t\t\t\t\t\n\t\t\t\t\tClose\n\t\t\t\t\n\t\t\t\t{children}\n\t\t\t
\n\t\t,\n\t\tdocument.body,\n\t);\n}\n\nfunction DialogHeader({\n\tclassName,\n\t...props\n}: React.HTMLAttributes) {\n\treturn (\n\t\t\n\t);\n}\n\nfunction DialogFooter({\n\tclassName,\n\t...props\n}: React.HTMLAttributes) {\n\treturn (\n\t\t\n\t);\n}\n\nfunction DialogTitle({\n\tclassName,\n\t...props\n}: React.HTMLAttributes) {\n\treturn (\n\t\t\n\t);\n}\n\nfunction DialogDescription({\n\tclassName,\n\t...props\n}: React.HTMLAttributes) {\n\treturn (\n\t\t

\n\t);\n}\n\nfunction DialogClose({\n\tchildren,\n\t...props\n}: React.ButtonHTMLAttributes) {\n\tconst { onOpenChange } = useDialogContext();\n\n\treturn (\n\t\t\n\t);\n}\n\nexport {\n\tDialog,\n\tDialogTrigger,\n\tDialogContent,\n\tDialogHeader,\n\tDialogFooter,\n\tDialogTitle,\n\tDialogDescription,\n\tDialogClose,\n};\n", "type": "registry:ui" } ], "type": "registry:ui" }