| 1 | import * as React from "react"
|
| 2 | import { XIcon } from "lucide-react"
|
| 3 | import { Dialog as DialogPrimitive } from "radix-ui"
|
| 4 |
|
| 5 | import { cn } from "@/lib/utils"
|
| 6 | import { Button } from "@/components/ui/button"
|
| 7 |
|
| 8 | function Dialog({
|
| 9 | ...props
|
| 10 | }: React.ComponentProps<typeof DialogPrimitive.Root>) {
|
| 11 | return <DialogPrimitive.Root data-slot="dialog" {...props} />
|
| 12 | }
|
| 13 |
|
| 14 | function DialogTrigger({
|
| 15 | ...props
|
| 16 | }: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
|
| 17 | return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />
|
| 18 | }
|
| 19 |
|
| 20 | function DialogPortal({
|
| 21 | ...props
|
| 22 | }: React.ComponentProps<typeof DialogPrimitive.Portal>) {
|
| 23 | return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />
|
| 24 | }
|
| 25 |
|
| 26 | function DialogClose({
|
| 27 | ...props
|
| 28 | }: React.ComponentProps<typeof DialogPrimitive.Close>) {
|
| 29 | return <DialogPrimitive.Close data-slot="dialog-close" {...props} />
|
| 30 | }
|
| 31 |
|
| 32 | function DialogOverlay({
|
| 33 | className,
|
| 34 | ...props
|
| 35 | }: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
|
| 36 | return (
|
| 37 | <DialogPrimitive.Overlay
|
| 38 | data-slot="dialog-overlay"
|
| 39 | className={cn(
|
| 40 | "fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0",
|
| 41 | className
|
| 42 | )}
|
| 43 | {...props}
|
| 44 | />
|
| 45 | )
|
| 46 | }
|
| 47 |
|
| 48 | function DialogContent({
|
| 49 | className,
|
| 50 | children,
|
| 51 | showCloseButton = true,
|
| 52 | ...props
|
| 53 | }: React.ComponentProps<typeof DialogPrimitive.Content> & {
|
| 54 | showCloseButton?: boolean
|
| 55 | }) {
|
| 56 | return (
|
| 57 | <DialogPortal data-slot="dialog-portal">
|
| 58 | <DialogOverlay />
|
| 59 | <DialogPrimitive.Content
|
| 60 | data-slot="dialog-content"
|
| 61 | className={cn(
|
| 62 | "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 bg-background p-6 shadow-lg duration-200 outline-none data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 sm:max-w-lg",
|
| 63 | className
|
| 64 | )}
|
| 65 | {...props}
|
| 66 | >
|
| 67 | {children}
|
| 68 | {showCloseButton && (
|
| 69 | <DialogPrimitive.Close
|
| 70 | data-slot="dialog-close"
|
| 71 | className="absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
|
| 72 | >
|
| 73 | <XIcon />
|
| 74 | <span className="sr-only">Close</span>
|
| 75 | </DialogPrimitive.Close>
|
| 76 | )}
|
| 77 | </DialogPrimitive.Content>
|
| 78 | </DialogPortal>
|
| 79 | )
|
| 80 | }
|
| 81 |
|
| 82 | function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
|
| 83 | return (
|
| 84 | <div
|
| 85 | data-slot="dialog-header"
|
| 86 | className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
|
| 87 | {...props}
|
| 88 | />
|
| 89 | )
|
| 90 | }
|
| 91 |
|
| 92 | function DialogFooter({
|
| 93 | className,
|
| 94 | showCloseButton = false,
|
| 95 | children,
|
| 96 | ...props
|
| 97 | }: React.ComponentProps<"div"> & {
|
| 98 | showCloseButton?: boolean
|
| 99 | }) {
|
| 100 | return (
|
| 101 | <div
|
| 102 | data-slot="dialog-footer"
|
| 103 | className={cn(
|
| 104 | "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
|
| 105 | className
|
| 106 | )}
|
| 107 | {...props}
|
| 108 | >
|
| 109 | {children}
|
| 110 | {showCloseButton && (
|
| 111 | <DialogPrimitive.Close asChild>
|
| 112 | <Button variant="outline">Close</Button>
|
| 113 | </DialogPrimitive.Close>
|
| 114 | )}
|
| 115 | </div>
|
| 116 | )
|
| 117 | }
|
| 118 |
|
| 119 | function DialogTitle({
|
| 120 | className,
|
| 121 | ...props
|
| 122 | }: React.ComponentProps<typeof DialogPrimitive.Title>) {
|
| 123 | return (
|
| 124 | <DialogPrimitive.Title
|
| 125 | data-slot="dialog-title"
|
| 126 | className={cn("text-lg leading-none font-semibold", className)}
|
| 127 | {...props}
|
| 128 | />
|
| 129 | )
|
| 130 | }
|
| 131 |
|
| 132 | function DialogDescription({
|
| 133 | className,
|
| 134 | ...props
|
| 135 | }: React.ComponentProps<typeof DialogPrimitive.Description>) {
|
| 136 | return (
|
| 137 | <DialogPrimitive.Description
|
| 138 | data-slot="dialog-description"
|
| 139 | className={cn("text-sm text-muted-foreground", className)}
|
| 140 | {...props}
|
| 141 | />
|
| 142 | )
|
| 143 | }
|
| 144 |
|
| 145 | export {
|
| 146 | Dialog,
|
| 147 | DialogClose,
|
| 148 | DialogContent,
|
| 149 | DialogDescription,
|
| 150 | DialogFooter,
|
| 151 | DialogHeader,
|
| 152 | DialogOverlay,
|
| 153 | DialogPortal,
|
| 154 | DialogTitle,
|
| 155 | DialogTrigger,
|
| 156 | }
|