| 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({ ...props }: React.ComponentProps<typeof DialogPrimitive.Root>) {
|
| 9 | return <DialogPrimitive.Root data-slot="dialog" {...props} />;
|
| 10 | }
|
| 11 |
|
| 12 | function DialogTrigger({ ...props }: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
|
| 13 | return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />;
|
| 14 | }
|
| 15 |
|
| 16 | function DialogPortal({ ...props }: React.ComponentProps<typeof DialogPrimitive.Portal>) {
|
| 17 | return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />;
|
| 18 | }
|
| 19 |
|
| 20 | function DialogClose({ ...props }: React.ComponentProps<typeof DialogPrimitive.Close>) {
|
| 21 | return <DialogPrimitive.Close data-slot="dialog-close" {...props} />;
|
| 22 | }
|
| 23 |
|
| 24 | function DialogOverlay({
|
| 25 | className,
|
| 26 | ...props
|
| 27 | }: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
|
| 28 | return (
|
| 29 | <DialogPrimitive.Overlay
|
| 30 | data-slot="dialog-overlay"
|
| 31 | className={cn(
|
| 32 | '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',
|
| 33 | className,
|
| 34 | )}
|
| 35 | {...props}
|
| 36 | />
|
| 37 | );
|
| 38 | }
|
| 39 |
|
| 40 | function DialogContent({
|
| 41 | className,
|
| 42 | children,
|
| 43 | showCloseButton = true,
|
| 44 | ...props
|
| 45 | }: React.ComponentProps<typeof DialogPrimitive.Content> & {
|
| 46 | showCloseButton?: boolean;
|
| 47 | }) {
|
| 48 | return (
|
| 49 | <DialogPortal data-slot="dialog-portal">
|
| 50 | <DialogOverlay />
|
| 51 | <DialogPrimitive.Content
|
| 52 | data-slot="dialog-content"
|
| 53 | className={cn(
|
| 54 | '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',
|
| 55 | className,
|
| 56 | )}
|
| 57 | {...props}
|
| 58 | >
|
| 59 | {children}
|
| 60 | {showCloseButton && (
|
| 61 | <DialogPrimitive.Close
|
| 62 | data-slot="dialog-close"
|
| 63 | 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"
|
| 64 | >
|
| 65 | <XIcon />
|
| 66 | <span className="sr-only">Close</span>
|
| 67 | </DialogPrimitive.Close>
|
| 68 | )}
|
| 69 | </DialogPrimitive.Content>
|
| 70 | </DialogPortal>
|
| 71 | );
|
| 72 | }
|
| 73 |
|
| 74 | function DialogHeader({ className, ...props }: React.ComponentProps<'div'>) {
|
| 75 | return (
|
| 76 | <div
|
| 77 | data-slot="dialog-header"
|
| 78 | className={cn('flex flex-col gap-2 text-center sm:text-left', className)}
|
| 79 | {...props}
|
| 80 | />
|
| 81 | );
|
| 82 | }
|
| 83 |
|
| 84 | function DialogFooter({
|
| 85 | className,
|
| 86 | showCloseButton = false,
|
| 87 | children,
|
| 88 | ...props
|
| 89 | }: React.ComponentProps<'div'> & {
|
| 90 | showCloseButton?: boolean;
|
| 91 | }) {
|
| 92 | return (
|
| 93 | <div
|
| 94 | data-slot="dialog-footer"
|
| 95 | className={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', className)}
|
| 96 | {...props}
|
| 97 | >
|
| 98 | {children}
|
| 99 | {showCloseButton && (
|
| 100 | <DialogPrimitive.Close asChild>
|
| 101 | <Button variant="outline">Close</Button>
|
| 102 | </DialogPrimitive.Close>
|
| 103 | )}
|
| 104 | </div>
|
| 105 | );
|
| 106 | }
|
| 107 |
|
| 108 | function DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>) {
|
| 109 | return (
|
| 110 | <DialogPrimitive.Title
|
| 111 | data-slot="dialog-title"
|
| 112 | className={cn('text-lg leading-none font-semibold', className)}
|
| 113 | {...props}
|
| 114 | />
|
| 115 | );
|
| 116 | }
|
| 117 |
|
| 118 | function DialogDescription({
|
| 119 | className,
|
| 120 | ...props
|
| 121 | }: React.ComponentProps<typeof DialogPrimitive.Description>) {
|
| 122 | return (
|
| 123 | <DialogPrimitive.Description
|
| 124 | data-slot="dialog-description"
|
| 125 | className={cn('text-sm text-muted-foreground', className)}
|
| 126 | {...props}
|
| 127 | />
|
| 128 | );
|
| 129 | }
|
| 130 |
|
| 131 | export {
|
| 132 | Dialog,
|
| 133 | DialogClose,
|
| 134 | DialogContent,
|
| 135 | DialogDescription,
|
| 136 | DialogFooter,
|
| 137 | DialogHeader,
|
| 138 | DialogOverlay,
|
| 139 | DialogPortal,
|
| 140 | DialogTitle,
|
| 141 | DialogTrigger,
|
| 142 | };
|