{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "drawer", "files": [ { "path": "registry/new-york/ui/drawer.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 DrawerContextValue {\n\topen: boolean;\n\tonOpenChange: (open: boolean) => void;\n}\n\nconst DrawerContext = React.createContext(null);\n\nfunction useDrawerContext() {\n\tconst context = React.useContext(DrawerContext);\n\tif (!context) {\n\t\tthrow new Error(\"Drawer components must be used within a Drawer\");\n\t}\n\treturn context;\n}\n\ninterface DrawerProps {\n\tchildren: React.ReactNode;\n\topen?: boolean;\n\tonOpenChange?: (open: boolean) => void;\n}\n\nfunction Drawer({ children, open: controlledOpen, onOpenChange }: DrawerProps) {\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 DrawerTriggerProps\n\textends React.ButtonHTMLAttributes {\n\tasChild?: boolean;\n}\n\nfunction DrawerTrigger({\n\tchildren,\n\tasChild,\n\tonClick,\n\t...props\n}: DrawerTriggerProps) {\n\tconst { onOpenChange } = useDrawerContext();\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 DrawerContentProps extends React.HTMLAttributes {}\n\nfunction DrawerContent({ className, children, ...props }: DrawerContentProps) {\n\tconst { open, onOpenChange } = useDrawerContext();\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 drawer\"\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 DrawerHeader({\n\tclassName,\n\t...props\n}: React.HTMLAttributes) {\n\treturn (\n\t\t\n\t);\n}\n\nfunction DrawerFooter({\n\tclassName,\n\t...props\n}: React.HTMLAttributes) {\n\treturn (\n\t\t\n\t);\n}\n\nfunction DrawerTitle({\n\tclassName,\n\t...props\n}: React.HTMLAttributes) {\n\treturn (\n\t\t\n\t);\n}\n\nfunction DrawerDescription({\n\tclassName,\n\t...props\n}: React.HTMLAttributes) {\n\treturn (\n\t\t

\n\t);\n}\n\nfunction DrawerClose({\n\tchildren,\n\t...props\n}: React.ButtonHTMLAttributes) {\n\tconst { onOpenChange } = useDrawerContext();\n\n\treturn (\n\t\t\n\t);\n}\n\nexport {\n\tDrawer,\n\tDrawerTrigger,\n\tDrawerContent,\n\tDrawerHeader,\n\tDrawerFooter,\n\tDrawerTitle,\n\tDrawerDescription,\n\tDrawerClose,\n};\n", "type": "registry:ui" } ], "type": "registry:ui" }