Drawer
A drawer component.
Installation
Install the following dependencies:
pnpm add vaul
Copy and paste the following code into your project.
"use client";
import { Drawer as DrawerPrimitive } from "vaul";
import { cn } from "~/utils/tailwind";
function Drawer({
shouldScaleBackground = true,
...props
}: React.ComponentProps<typeof DrawerPrimitive.Root>) {
return (
<DrawerPrimitive.Root
shouldScaleBackground={shouldScaleBackground}
{...props}
/>
);
}
const DrawerTrigger = DrawerPrimitive.Trigger;
const DrawerPortal = DrawerPrimitive.Portal;
const DrawerClose = DrawerPrimitive.Close;
function DrawerOverlay({
className,
...props
}: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {
return (
<DrawerPrimitive.Overlay
className={cn("fixed inset-0 z-50 bg-black/80", className)}
{...props}
/>
);
}
function DrawerContent({
className,
children,
...props
}: React.ComponentProps<typeof DrawerPrimitive.Content>) {
return (
<DrawerPortal>
<DrawerOverlay />
<DrawerPrimitive.Content
className={cn(
"fixed inset-x-0 bottom-0 z-50 flex h-auto flex-col rounded-t-2.5 border bg-background p-4",
className,
)}
{...props}
>
<div className="mx-auto mb-3 h-2 w-24 rounded-full bg-muted active:cursor-grabbing" />
{children}
</DrawerPrimitive.Content>
</DrawerPortal>
);
}
function DrawerHeader({ className, ...props }: React.ComponentProps<"div">) {
return (
<div className={cn("flex flex-col gap-y-1 pb-4", className)} {...props} />
);
}
function DrawerBody(props: React.ComponentProps<"div">) {
return <div {...props} />;
}
function DrawerFooter({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
className={cn("mt-auto flex flex-col gap-y-3 pt-8", className)}
{...props}
/>
);
}
function DrawerTitle({
className,
...props
}: React.ComponentProps<typeof DrawerPrimitive.Title>) {
return (
<DrawerPrimitive.Title
className={cn("text-5 font-semibold", className)}
{...props}
/>
);
}
function DrawerDescription({
className,
...props
}: React.ComponentProps<typeof DrawerPrimitive.Description>) {
return (
<DrawerPrimitive.Description
className={cn("text-3.5 text-muted-foreground", className)}
{...props}
/>
);
}
export {
Drawer,
DrawerPortal,
DrawerOverlay,
DrawerTrigger,
DrawerClose,
DrawerContent,
DrawerHeader,
DrawerBody,
DrawerFooter,
DrawerTitle,
DrawerDescription,
};
Update the import paths to match your project setup.
Usage
import {
Drawer,
DrawerClose,
DrawerContent,
DrawerDescription,
DrawerFooter,
DrawerHeader,
DrawerTitle,
DrawerTrigger,
} from "~/components/ui/Drawer";
<Drawer>
<DrawerTrigger>Open</DrawerTrigger>
<DrawerContent>
<DrawerHeader>
<DrawerTitle>Are you absolutely sure?</DrawerTitle>
<DrawerDescription>This action cannot be undone.</DrawerDescription>
</DrawerHeader>
<DrawerFooter>
<Button>Submit</Button>
<DrawerClose>
<Button variant="outline">Cancel</Button>
</DrawerClose>
</DrawerFooter>
</DrawerContent>
</Drawer>