Skip to content

Commit 0aa9c8e

Browse files
committed
chore: add drawer and hover-card
1 parent 8ed8836 commit 0aa9c8e

File tree

4 files changed

+220
-2
lines changed

4 files changed

+220
-2
lines changed

package-lock.json

Lines changed: 47 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"dependencies": {
1313
"@radix-ui/react-checkbox": "^1.1.4",
1414
"@radix-ui/react-dialog": "^1.1.6",
15+
"@radix-ui/react-hover-card": "^1.1.6",
1516
"@radix-ui/react-popover": "^1.1.6",
1617
"@radix-ui/react-progress": "^1.1.2",
1718
"@radix-ui/react-scroll-area": "^1.2.3",
@@ -33,7 +34,8 @@
3334
"recharts": "^2.15.1",
3435
"tailwind-merge": "^3.0.1",
3536
"tailwindcss": "^4.0.7",
36-
"tailwindcss-animate": "^1.0.7"
37+
"tailwindcss-animate": "^1.0.7",
38+
"vaul": "^1.1.2"
3739
},
3840
"devDependencies": {
3941
"@eslint/js": "^9.19.0",

src/components/ui/drawer.tsx

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import * as React from "react"
2+
import { Drawer as DrawerPrimitive } from "vaul"
3+
4+
import { cn } from "@/lib/utils"
5+
6+
function Drawer({
7+
...props
8+
}: React.ComponentProps<typeof DrawerPrimitive.Root>) {
9+
return <DrawerPrimitive.Root data-slot="drawer" {...props} />
10+
}
11+
12+
function DrawerTrigger({
13+
...props
14+
}: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {
15+
return <DrawerPrimitive.Trigger data-slot="drawer-trigger" {...props} />
16+
}
17+
18+
function DrawerPortal({
19+
...props
20+
}: React.ComponentProps<typeof DrawerPrimitive.Portal>) {
21+
return <DrawerPrimitive.Portal data-slot="drawer-portal" {...props} />
22+
}
23+
24+
function DrawerClose({
25+
...props
26+
}: React.ComponentProps<typeof DrawerPrimitive.Close>) {
27+
return <DrawerPrimitive.Close data-slot="drawer-close" {...props} />
28+
}
29+
30+
function DrawerOverlay({
31+
className,
32+
...props
33+
}: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {
34+
return (
35+
<DrawerPrimitive.Overlay
36+
data-slot="drawer-overlay"
37+
className={cn(
38+
"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-black/80",
39+
className
40+
)}
41+
{...props}
42+
/>
43+
)
44+
}
45+
46+
function DrawerContent({
47+
className,
48+
children,
49+
...props
50+
}: React.ComponentProps<typeof DrawerPrimitive.Content>) {
51+
return (
52+
<DrawerPortal data-slot="drawer-portal">
53+
<DrawerOverlay />
54+
<DrawerPrimitive.Content
55+
data-slot="drawer-content"
56+
className={cn(
57+
"group/drawer-content bg-background fixed z-50 flex h-auto flex-col",
58+
"data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-b-lg",
59+
"data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-t-lg",
60+
"data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:sm:max-w-sm",
61+
"data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:sm:max-w-sm",
62+
className
63+
)}
64+
{...props}
65+
>
66+
<div className="bg-muted mx-auto mt-4 hidden h-2 w-[100px] shrink-0 rounded-full group-data-[vaul-drawer-direction=bottom]/drawer-content:block" />
67+
{children}
68+
</DrawerPrimitive.Content>
69+
</DrawerPortal>
70+
)
71+
}
72+
73+
function DrawerHeader({ className, ...props }: React.ComponentProps<"div">) {
74+
return (
75+
<div
76+
data-slot="drawer-header"
77+
className={cn("flex flex-col gap-1.5 p-4", className)}
78+
{...props}
79+
/>
80+
)
81+
}
82+
83+
function DrawerFooter({ className, ...props }: React.ComponentProps<"div">) {
84+
return (
85+
<div
86+
data-slot="drawer-footer"
87+
className={cn("mt-auto flex flex-col gap-2 p-4", className)}
88+
{...props}
89+
/>
90+
)
91+
}
92+
93+
function DrawerTitle({
94+
className,
95+
...props
96+
}: React.ComponentProps<typeof DrawerPrimitive.Title>) {
97+
return (
98+
<DrawerPrimitive.Title
99+
data-slot="drawer-title"
100+
className={cn("text-foreground font-semibold tracking-tight", className)}
101+
{...props}
102+
/>
103+
)
104+
}
105+
106+
function DrawerDescription({
107+
className,
108+
...props
109+
}: React.ComponentProps<typeof DrawerPrimitive.Description>) {
110+
return (
111+
<DrawerPrimitive.Description
112+
data-slot="drawer-description"
113+
className={cn("text-muted-foreground text-sm", className)}
114+
{...props}
115+
/>
116+
)
117+
}
118+
119+
export {
120+
Drawer,
121+
DrawerPortal,
122+
DrawerOverlay,
123+
DrawerTrigger,
124+
DrawerClose,
125+
DrawerContent,
126+
DrawerHeader,
127+
DrawerFooter,
128+
DrawerTitle,
129+
DrawerDescription,
130+
}

src/components/ui/hover-card.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import * as React from "react"
2+
import * as HoverCardPrimitive from "@radix-ui/react-hover-card"
3+
4+
import { cn } from "@/lib/utils"
5+
6+
function HoverCard({
7+
...props
8+
}: React.ComponentProps<typeof HoverCardPrimitive.Root>) {
9+
return <HoverCardPrimitive.Root data-slot="hover-card" {...props} />
10+
}
11+
12+
function HoverCardTrigger({
13+
...props
14+
}: React.ComponentProps<typeof HoverCardPrimitive.Trigger>) {
15+
return (
16+
<HoverCardPrimitive.Trigger data-slot="hover-card-trigger" {...props} />
17+
)
18+
}
19+
20+
function HoverCardContent({
21+
className,
22+
align = "center",
23+
sideOffset = 4,
24+
...props
25+
}: React.ComponentProps<typeof HoverCardPrimitive.Content>) {
26+
return (
27+
<HoverCardPrimitive.Content
28+
data-slot="hover-card-content"
29+
align={align}
30+
sideOffset={sideOffset}
31+
className={cn(
32+
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-64 rounded-md border p-4 shadow-md outline-hidden",
33+
className
34+
)}
35+
{...props}
36+
/>
37+
)
38+
}
39+
40+
export { HoverCard, HoverCardTrigger, HoverCardContent }

0 commit comments

Comments
 (0)