返回 oh-my-ppt
Dialog.tsx
根目录 / src / renderer / src / components / ui / Dialog.tsx
1 import * as DialogPrimitive from '@radix-ui/react-dialog'
2 import { X } from 'lucide-react'
3 import React from 'react'
4 import { cn } from '@renderer/lib/utils'
5
6 const Dialog = DialogPrimitive.Root
7 const DialogTrigger = DialogPrimitive.Trigger
8 const DialogClose = DialogPrimitive.Close
9
10 const DialogPortal = DialogPrimitive.Portal
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('fixed inset-0 z-50 bg-[#1f261d]/38 backdrop-blur-sm', className)}
19 {...props}
20 />
21 ))
22 DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
23
24 const DialogContent = React.forwardRef<
25 React.ElementRef<typeof DialogPrimitive.Content>,
26 React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> & { showClose?: boolean }
27 >(({ className, children, showClose = true, ...props }, ref) => (
28 <DialogPortal>
29 <DialogOverlay />
30 <DialogPrimitive.Content
31 ref={ref}
32 onInteractOutside={(e) => e.preventDefault()}
33 className={cn(
34 'fixed left-1/2 top-1/2 z-50 grid w-[calc(100%-2rem)] max-w-md -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl border border-[#d8cfbc]/80 bg-[#fffaf0] p-5 shadow-[0_24px_60px_rgba(64,52,38,0.28)]',
35 className
36 )}
37 {...props}
38 >
39 {children}
40 {showClose && (
41 <DialogPrimitive.Close className="absolute right-4 top-4 rounded-lg p-1 text-[#6f7d62] transition-colors hover:bg-[#ebe4d6]/80 hover:text-[#3e4a32] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring">
42 <X className="h-4 w-4" />
43 <span className="sr-only">Close</span>
44 </DialogPrimitive.Close>
45 )}
46 </DialogPrimitive.Content>
47 </DialogPortal>
48 ))
49 DialogContent.displayName = DialogPrimitive.Content.displayName
50
51 function DialogHeader({
52 className,
53 ...props
54 }: React.HTMLAttributes<HTMLDivElement>): React.JSX.Element {
55 return <div className={cn('flex flex-col gap-1.5 pr-8', className)} {...props} />
56 }
57
58 function DialogFooter({
59 className,
60 ...props
61 }: React.HTMLAttributes<HTMLDivElement>): React.JSX.Element {
62 return <div className={cn('flex justify-end gap-2', className)} {...props} />
63 }
64
65 const DialogTitle = React.forwardRef<
66 React.ElementRef<typeof DialogPrimitive.Title>,
67 React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
68 >(({ className, ...props }, ref) => (
69 <DialogPrimitive.Title
70 ref={ref}
71 className={cn('text-base font-semibold text-[#3e4a32]', className)}
72 {...props}
73 />
74 ))
75 DialogTitle.displayName = DialogPrimitive.Title.displayName
76
77 const DialogDescription = React.forwardRef<
78 React.ElementRef<typeof DialogPrimitive.Description>,
79 React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
80 >(({ className, ...props }, ref) => (
81 <DialogPrimitive.Description
82 ref={ref}
83 className={cn('text-sm leading-6 text-[#6f6658]', className)}
84 {...props}
85 />
86 ))
87 DialogDescription.displayName = DialogPrimitive.Description.displayName
88
89 export {
90 Dialog,
91 DialogClose,
92 DialogContent,
93 DialogDescription,
94 DialogFooter,
95 DialogHeader,
96 DialogTitle,
97 DialogTrigger
98 }
99
99 lines Plain Text