sheet.tsx raw
1 "use client";
2
3 import * as React from "react";
4 import { XIcon } from "lucide-react";
5 import { Dialog as SheetPrimitive } from "radix-ui";
6
7 import { cn } from "src/lib/utils";
8
9 function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
10 return <SheetPrimitive.Root data-slot="sheet" {...props} />;
11 }
12
13 function SheetTrigger({
14 ...props
15 }: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
16 return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />;
17 }
18
19 function SheetClose({
20 ...props
21 }: React.ComponentProps<typeof SheetPrimitive.Close>) {
22 return <SheetPrimitive.Close data-slot="sheet-close" {...props} />;
23 }
24
25 function SheetPortal({
26 ...props
27 }: React.ComponentProps<typeof SheetPrimitive.Portal>) {
28 return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />;
29 }
30
31 function SheetOverlay({
32 className,
33 ...props
34 }: React.ComponentProps<typeof SheetPrimitive.Overlay>) {
35 return (
36 <SheetPrimitive.Overlay
37 data-slot="sheet-overlay"
38 className={cn(
39 "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",
40 className
41 )}
42 {...props}
43 />
44 );
45 }
46
47 function SheetContent({
48 className,
49 children,
50 side = "right",
51 showCloseButton = true,
52 ...props
53 }: React.ComponentProps<typeof SheetPrimitive.Content> & {
54 side?: "top" | "right" | "bottom" | "left";
55 showCloseButton?: boolean;
56 }) {
57 return (
58 <SheetPortal>
59 <SheetOverlay />
60 <SheetPrimitive.Content
61 data-slot="sheet-content"
62 className={cn(
63 "fixed z-50 flex flex-col gap-4 bg-background shadow-lg transition ease-in-out data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:animate-in data-[state=open]:duration-500",
64 side === "right" &&
65 "inset-y-0 right-0 h-full max-h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
66 side === "left" &&
67 "inset-y-0 left-0 h-full max-h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
68 side === "top" &&
69 "inset-x-0 top-0 h-auto border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
70 side === "bottom" &&
71 "inset-x-0 bottom-0 h-auto border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
72 className
73 )}
74 {...props}
75 >
76 {children}
77 {showCloseButton && (
78 <SheetPrimitive.Close 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-secondary">
79 <XIcon className="size-4" />
80 <span className="sr-only">Close</span>
81 </SheetPrimitive.Close>
82 )}
83 </SheetPrimitive.Content>
84 </SheetPortal>
85 );
86 }
87
88 function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
89 return (
90 <div
91 data-slot="sheet-header"
92 className={cn("flex flex-col gap-1.5 p-4", className)}
93 {...props}
94 />
95 );
96 }
97
98 function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
99 return (
100 <div
101 data-slot="sheet-footer"
102 className={cn("mt-auto flex flex-col gap-2 p-4", className)}
103 {...props}
104 />
105 );
106 }
107
108 function SheetTitle({
109 className,
110 ...props
111 }: React.ComponentProps<typeof SheetPrimitive.Title>) {
112 return (
113 <SheetPrimitive.Title
114 data-slot="sheet-title"
115 className={cn("font-semibold text-foreground", className)}
116 {...props}
117 />
118 );
119 }
120
121 function SheetDescription({
122 className,
123 ...props
124 }: React.ComponentProps<typeof SheetPrimitive.Description>) {
125 return (
126 <SheetPrimitive.Description
127 data-slot="sheet-description"
128 className={cn("text-sm text-muted-foreground", className)}
129 {...props}
130 />
131 );
132 }
133
134 export {
135 Sheet,
136 SheetTrigger,
137 SheetClose,
138 SheetContent,
139 SheetHeader,
140 SheetFooter,
141 SheetTitle,
142 SheetDescription,
143 };
144