返回 JoyAI-Echo
dialog.tsx
1 import * as React from "react";
2 import * as DialogPrimitive from "@radix-ui/react-dialog";
3 import { X } from "lucide-react";
4
5 import { cn } from "@/lib/utils";
6
7 const Dialog = DialogPrimitive.Root;
8 const DialogTrigger = DialogPrimitive.Trigger;
9 const DialogPortal = DialogPrimitive.Portal;
10 const DialogClose = DialogPrimitive.Close;
11
12 const DialogOverlay = React.forwardRef<
13 React.ElementRef<typeof DialogPrimitive.Overlay>,
14 React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
15 >(({ className, ...props }, ref) => (
16 <DialogPrimitive.Overlay
17 ref={ref}
18 className={cn(
19 "fixed inset-0 z-50 bg-black/60 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
20 className,
21 )}
22 {...props}
23 />
24 ));
25 DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
26
27 const DialogContent = React.forwardRef<
28 React.ElementRef<typeof DialogPrimitive.Content>,
29 React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
30 >(({ className, children, ...props }, ref) => (
31 <DialogPortal>
32 <DialogOverlay />
33 <DialogPrimitive.Content
34 ref={ref}
35 className={cn(
36 "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 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 sm:rounded-lg",
37 className,
38 )}
39 {...props}
40 >
41 {children}
42 <DialogPrimitive.Close 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 disabled:pointer-events-none">
43 <X className="h-4 w-4" />
44 <span className="sr-only">Close</span>
45 </DialogPrimitive.Close>
46 </DialogPrimitive.Content>
47 </DialogPortal>
48 ));
49 DialogContent.displayName = DialogPrimitive.Content.displayName;
50
51 const DialogHeader = ({
52 className,
53 ...props
54 }: React.HTMLAttributes<HTMLDivElement>) => (
55 <div
56 className={cn(
57 "flex flex-col space-y-1.5 text-center sm:text-left",
58 className,
59 )}
60 {...props}
61 />
62 );
63 DialogHeader.displayName = "DialogHeader";
64
65 const DialogFooter = ({
66 className,
67 ...props
68 }: React.HTMLAttributes<HTMLDivElement>) => (
69 <div
70 className={cn(
71 "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
72 className,
73 )}
74 {...props}
75 />
76 );
77 DialogFooter.displayName = "DialogFooter";
78
79 const DialogTitle = React.forwardRef<
80 React.ElementRef<typeof DialogPrimitive.Title>,
81 React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
82 >(({ className, ...props }, ref) => (
83 <DialogPrimitive.Title
84 ref={ref}
85 className={cn(
86 "text-lg font-semibold leading-none tracking-tight",
87 className,
88 )}
89 {...props}
90 />
91 ));
92 DialogTitle.displayName = DialogPrimitive.Title.displayName;
93
94 const DialogDescription = React.forwardRef<
95 React.ElementRef<typeof DialogPrimitive.Description>,
96 React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
97 >(({ className, ...props }, ref) => (
98 <DialogPrimitive.Description
99 ref={ref}
100 className={cn("text-sm text-muted-foreground", className)}
101 {...props}
102 />
103 ));
104 DialogDescription.displayName = DialogPrimitive.Description.displayName;
105
106 export {
107 Dialog,
108 DialogClose,
109 DialogContent,
110 DialogDescription,
111 DialogFooter,
112 DialogHeader,
113 DialogPortal,
114 DialogTitle,
115 DialogTrigger,
116 };
117
117 lines Plain Text