Drawer
A panel that slides out from a side of the screen.
Installation
npx @rahimstack@latest add drawer
Usage
Side
You can set the side of the drawer by passing the side
prop.
Example
<Drawer
{...props}
side="left"
>
{/*...*/}
</Drawer>
Outside interactions
You can allow outside interactions like scrolling by setting the allowOutsideInteraction
prop to true
.
This will also make other elements visible to screen readers.
Example
<Drawer
{...props}
allowOutsideInteraction
>
{/*...*/}
</Drawer>
Controlled
const [open, setOpen] = React.useState(false)
return (
<Drawer
{...props}
open={open}
onOpenChange={setOpen}
>
{/*...*/}
</Drawer>
)
API Reference
const DrawerAnatomy = defineStyleAnatomy({
overlay: cva([
"UI-Drawer__overlay",
"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",
]),
content: cva([
"UI-Drawer__content",
"fixed z-50 w-full gap-4 bg-[--background] p-6 shadow-lg overflow-y-auto",
"transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-500 data-[state=open]:duration-500",
], {
variants: {
side: {
top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
bottom: "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
left: "inset-y-0 left-0 h-full border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left",
right: "inset-y-0 right-0 h-full border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right",
},
size: { sm: null, md: null, lg: null, xl: null, full: "w-[90%]" },
},
defaultVariants: {
side: "right",
size: "md",
},
compoundVariants: [
{ size: "sm", side: "left", className: "sm:max-w-sm" },
{ size: "sm", side: "right", className: "sm:max-w-sm" },
{ size: "md", side: "left", className: "sm:max-w-md" },
{ size: "md", side: "right", className: "sm:max-w-md" },
{ size: "lg", side: "left", className: "sm:max-w-2xl" },
{ size: "lg", side: "right", className: "sm:max-w-2xl" },
{ size: "xl", side: "left", className: "sm:max-w-5xl" },
{ size: "xl", side: "right", className: "sm:max-w-5xl" },
/**/
{ size: "full", side: "top", className: "h-dvh" },
{ size: "full", side: "bottom", className: "h-dvh" },
],
}),
close: cva([
"UI-Drawer__close",
"absolute right-4 top-4",
]),
header: cva([
"UI-Drawer__header",
"flex flex-col space-y-1.5 text-center sm:text-left",
]),
footer: cva([
"UI-Drawer__footer",
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
]),
title: cva([
"UI-Drawer__title",
"text-xl font-semibold leading-none tracking-tight",
]),
description: cva([
"UI-Drawer__description",
"text-sm text-[--muted]",
]),
})