Skip to content

Commit 931193a

Browse files
committed
feat: create sidebar sheet component.
1 parent 2f69733 commit 931193a

File tree

4 files changed

+152
-0
lines changed

4 files changed

+152
-0
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"@prisma/client": "^5.10.2",
1717
"@radix-ui/react-accordion": "^1.1.2",
1818
"@radix-ui/react-alert-dialog": "^1.0.5",
19+
"@radix-ui/react-dialog": "^1.0.5",
1920
"@radix-ui/react-dropdown-menu": "^2.0.6",
2021
"@radix-ui/react-label": "^2.0.2",
2122
"@radix-ui/react-slot": "^1.0.2",

pnpm-lock.yaml

+4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/sidebar/menu-options.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ const MenuOptions = ({
4141
setIsMounted(true)
4242
}, [])
4343

44+
if (!isMounted) return
45+
4446
return (
4547
<div>MenuOptions</div>
4648
)

src/components/ui/sheet.tsx

+145
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
'use client'
2+
3+
import * as React from 'react'
4+
import * as SheetPrimitive from '@radix-ui/react-dialog'
5+
import { cva, type VariantProps } from 'class-variance-authority'
6+
import { X } from 'lucide-react'
7+
8+
import { cn } from '@/lib/utils'
9+
10+
const Sheet = SheetPrimitive.Root
11+
12+
const SheetTrigger = SheetPrimitive.Trigger
13+
14+
const SheetClose = SheetPrimitive.Close
15+
16+
const SheetPortal = SheetPrimitive.Portal
17+
18+
const SheetOverlay = React.forwardRef<
19+
React.ElementRef<typeof SheetPrimitive.Overlay>,
20+
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
21+
>(({ className, ...props }, ref) => (
22+
<SheetPrimitive.Overlay
23+
className={cn(
24+
'fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
25+
className
26+
)}
27+
{...props}
28+
ref={ref}
29+
/>
30+
))
31+
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName
32+
33+
const sheetVariants = cva(
34+
'fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500',
35+
{
36+
variants: {
37+
side: {
38+
top: 'inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top',
39+
bottom:
40+
'inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom',
41+
left: 'inset-y-0 left-0 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',
42+
right:
43+
'inset-y-0 right-0 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',
44+
},
45+
},
46+
defaultVariants: {
47+
side: 'right',
48+
},
49+
}
50+
)
51+
52+
interface CustomSheetContentProps {
53+
showX?: boolean
54+
}
55+
56+
interface SheetContentProps
57+
extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
58+
CustomSheetContentProps,
59+
VariantProps<typeof sheetVariants> { }
60+
61+
const SheetContent = React.forwardRef<
62+
React.ElementRef<typeof SheetPrimitive.Content>,
63+
SheetContentProps
64+
>(({ side = 'right', className, showX, children, ...props }, ref) => (
65+
<SheetPortal>
66+
<SheetOverlay />
67+
<SheetPrimitive.Content
68+
ref={ref}
69+
className={cn(sheetVariants({ side }), className)}
70+
{...props}
71+
>
72+
{children}
73+
<SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none disabled:pointer-events-none data-[state=open]:bg-secondary">
74+
{showX && <X className="h-4 w-4" />}
75+
<span className="sr-only">Close</span>
76+
</SheetPrimitive.Close>
77+
</SheetPrimitive.Content>
78+
</SheetPortal>
79+
))
80+
SheetContent.displayName = SheetPrimitive.Content.displayName
81+
82+
const SheetHeader = ({
83+
className,
84+
...props
85+
}: React.HTMLAttributes<HTMLDivElement>) => (
86+
<div
87+
className={cn(
88+
'flex flex-col space-y-2 text-center sm:text-left',
89+
className
90+
)}
91+
{...props}
92+
/>
93+
)
94+
SheetHeader.displayName = 'SheetHeader'
95+
96+
const SheetFooter = ({
97+
className,
98+
...props
99+
}: React.HTMLAttributes<HTMLDivElement>) => (
100+
<div
101+
className={cn(
102+
'flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2',
103+
className
104+
)}
105+
{...props}
106+
/>
107+
)
108+
SheetFooter.displayName = 'SheetFooter'
109+
110+
const SheetTitle = React.forwardRef<
111+
React.ElementRef<typeof SheetPrimitive.Title>,
112+
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
113+
>(({ className, ...props }, ref) => (
114+
<SheetPrimitive.Title
115+
ref={ref}
116+
className={cn('text-lg font-semibold text-foreground', className)}
117+
{...props}
118+
/>
119+
))
120+
SheetTitle.displayName = SheetPrimitive.Title.displayName
121+
122+
const SheetDescription = React.forwardRef<
123+
React.ElementRef<typeof SheetPrimitive.Description>,
124+
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
125+
>(({ className, ...props }, ref) => (
126+
<SheetPrimitive.Description
127+
ref={ref}
128+
className={cn('text-sm text-muted-foreground', className)}
129+
{...props}
130+
/>
131+
))
132+
SheetDescription.displayName = SheetPrimitive.Description.displayName
133+
134+
export {
135+
Sheet,
136+
SheetPortal,
137+
SheetOverlay,
138+
SheetTrigger,
139+
SheetClose,
140+
SheetContent,
141+
SheetHeader,
142+
SheetFooter,
143+
SheetTitle,
144+
SheetDescription,
145+
}

0 commit comments

Comments
 (0)