返回 presentation-ai
drawer.tsx
根目录 / src / components / ui / drawer.tsx
1 "use client";
2
3 import * as React from "react";
4 import { Drawer as DrawerPrimitive } from "vaul";
5
6 import { cn } from "@/lib/utils";
7
8 const Drawer = ({
9 shouldScaleBackground = true,
10 ...props
11 }: React.ComponentProps<typeof DrawerPrimitive.Root>) => (
12 <DrawerPrimitive.Root
13 shouldScaleBackground={shouldScaleBackground}
14 {...props}
15 />
16 );
17 Drawer.displayName = "Drawer";
18
19 const DrawerTrigger = DrawerPrimitive.Trigger;
20
21 const DrawerPortal = DrawerPrimitive.Portal;
22
23 const DrawerClose = DrawerPrimitive.Close;
24
25 const DrawerOverlay = React.forwardRef<
26 React.ElementRef<typeof DrawerPrimitive.Overlay>,
27 React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Overlay>
28 >(({ className, ...props }, ref) => (
29 <DrawerPrimitive.Overlay
30 ref={ref}
31 className={cn("fixed inset-0 z-50 bg-black/80", className)}
32 {...props}
33 />
34 ));
35 DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName;
36
37 const DrawerContent = React.forwardRef<
38 React.ElementRef<typeof DrawerPrimitive.Content>,
39 React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Content>
40 >(({ className, children, ...props }, ref) => (
41 <DrawerPortal>
42 <DrawerOverlay />
43 <DrawerPrimitive.Content
44 ref={ref}
45 className={cn(
46 "fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background",
47 className,
48 )}
49 {...props}
50 >
51 <div className="relative z-20 mx-auto mt-4 mb-2 h-2 w-[100px] shrink-0 rounded-full bg-muted" />
52 {children}
53 </DrawerPrimitive.Content>
54 </DrawerPortal>
55 ));
56 DrawerContent.displayName = "DrawerContent";
57
58 const DrawerHeader = ({
59 className,
60 ...props
61 }: React.HTMLAttributes<HTMLDivElement>) => (
62 <div
63 className={cn("grid gap-1.5 p-4 text-center sm:text-left", className)}
64 {...props}
65 />
66 );
67 DrawerHeader.displayName = "DrawerHeader";
68
69 const DrawerFooter = ({
70 className,
71 ...props
72 }: React.HTMLAttributes<HTMLDivElement>) => (
73 <div
74 className={cn("mt-auto flex flex-col gap-2 p-4", className)}
75 {...props}
76 />
77 );
78 DrawerFooter.displayName = "DrawerFooter";
79
80 const DrawerTitle = React.forwardRef<
81 React.ElementRef<typeof DrawerPrimitive.Title>,
82 React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Title>
83 >(({ className, ...props }, ref) => (
84 <DrawerPrimitive.Title
85 ref={ref}
86 className={cn(
87 "text-lg leading-none font-semibold tracking-tight",
88 className,
89 )}
90 {...props}
91 />
92 ));
93 DrawerTitle.displayName = DrawerPrimitive.Title.displayName;
94
95 const DrawerDescription = React.forwardRef<
96 React.ElementRef<typeof DrawerPrimitive.Description>,
97 React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Description>
98 >(({ className, ...props }, ref) => (
99 <DrawerPrimitive.Description
100 ref={ref}
101 className={cn("text-sm text-muted-foreground", className)}
102 {...props}
103 />
104 ));
105 DrawerDescription.displayName = DrawerPrimitive.Description.displayName;
106
107 export {
108 Drawer,
109 DrawerClose,
110 DrawerContent,
111 DrawerDescription,
112 DrawerFooter,
113 DrawerHeader,
114 DrawerOverlay,
115 DrawerPortal,
116 DrawerTitle,
117 DrawerTrigger,
118 };
119
119 lines Plain Text