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