Spaces:
Configuration error
Configuration error
| "use client" | |
| import * as React from "react" | |
| import { cn } from "@/lib/utils" | |
| import { X } from "lucide-react" | |
| interface DialogProps { | |
| open?: boolean | |
| onOpenChange?: (open: boolean) => void | |
| children: React.ReactNode | |
| } | |
| const DialogContext = React.createContext<{ | |
| open: boolean | |
| setOpen: (open: boolean) => void | |
| } | null>(null) | |
| function Dialog({ open: controlledOpen, onOpenChange, children }: DialogProps) { | |
| const [internalOpen, setInternalOpen] = React.useState(false) | |
| const open = controlledOpen !== undefined ? controlledOpen : internalOpen | |
| const setOpen = onOpenChange || setInternalOpen | |
| return ( | |
| <DialogContext.Provider value={{ open, setOpen }}> | |
| {children} | |
| </DialogContext.Provider> | |
| ) | |
| } | |
| function useDialog() { | |
| const context = React.useContext(DialogContext) | |
| if (!context) { | |
| throw new Error("useDialog must be used within a Dialog") | |
| } | |
| return context | |
| } | |
| interface DialogTriggerProps { | |
| children: React.ReactNode | |
| asChild?: boolean | |
| } | |
| function DialogTrigger({ children, asChild }: DialogTriggerProps) { | |
| const { setOpen } = useDialog() | |
| if (asChild && React.isValidElement(children)) { | |
| return React.cloneElement(children as React.ReactElement<any>, { | |
| onClick: (e: React.MouseEvent) => { | |
| (children as React.ReactElement<any>).props.onClick?.(e) | |
| setOpen(true) | |
| } | |
| }) | |
| } | |
| return ( | |
| <button onClick={() => setOpen(true)}> | |
| {children} | |
| </button> | |
| ) | |
| } | |
| interface DialogContentProps { | |
| children: React.ReactNode | |
| className?: string | |
| } | |
| function DialogContent({ children, className }: DialogContentProps) { | |
| const { open, setOpen } = useDialog() | |
| if (!open) return null | |
| return ( | |
| <div className="fixed inset-0 z-50"> | |
| {/* Backdrop */} | |
| <div | |
| className="fixed inset-0 bg-black/80" | |
| onClick={() => setOpen(false)} | |
| /> | |
| {/* Content */} | |
| <div className="fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 sm:rounded-lg"> | |
| <div className={cn("", className)}> | |
| {children} | |
| </div> | |
| {/* Close button */} | |
| <button | |
| 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" | |
| onClick={() => setOpen(false)} | |
| > | |
| <X className="h-4 w-4" /> | |
| <span className="sr-only">Close</span> | |
| </button> | |
| </div> | |
| </div> | |
| ) | |
| } | |
| function DialogHeader({ | |
| className, | |
| ...props | |
| }: React.HTMLAttributes<HTMLDivElement>) { | |
| return ( | |
| <div | |
| className={cn("flex flex-col space-y-1.5 text-center sm:text-left", className)} | |
| {...props} | |
| /> | |
| ) | |
| } | |
| function DialogTitle({ | |
| className, | |
| ...props | |
| }: React.HTMLAttributes<HTMLHeadingElement>) { | |
| return ( | |
| <h2 | |
| className={cn("text-lg font-semibold leading-none tracking-tight", className)} | |
| {...props} | |
| /> | |
| ) | |
| } | |
| function DialogDescription({ | |
| className, | |
| ...props | |
| }: React.HTMLAttributes<HTMLParagraphElement>) { | |
| return ( | |
| <p | |
| className={cn("text-sm text-muted-foreground", className)} | |
| {...props} | |
| /> | |
| ) | |
| } | |
| export { | |
| Dialog, | |
| DialogTrigger, | |
| DialogContent, | |
| DialogHeader, | |
| DialogTitle, | |
| DialogDescription, | |
| } | |