Drawer
GitHubDrawer panel with an optional trigger, heading, scrollable body, and footer.
Installation
bash
pnpm dlx shadcn@latest add @cs/drawerUsage
tsx
import { Drawer, DrawerAside } from "@/components/cs/drawer";tsx
<DrawerAside>
<main>
<Drawer
trigger={<button type="button">Open drawer</button>}
title="Project settings"
description="Update how this project is configured."
size="lg"
aside
footer={<button type="button">Save changes</button>}
>
<p>Drawer content</p>
</Drawer>
</main>
</DrawerAside>Large aside drawer
Uses the large desktop width while keeping the remaining page content visible.
tsx
import { Button } from "@/components/ui/button"
import { Drawer, DrawerAside } from "@/registry/cs/ui/drawer"
export default function DrawerAsideLargePreview() {
return (
<div className="min-h-56 w-full border p-4 ">
<DrawerAside>
<p className="text-sm font-medium ">Project members</p>
<p className="mt-1 text-sm text-muted-foreground">
The page reserves twice the default drawer width on desktop.
</p>
<Drawer
trigger={<Button className="mt-4">Manage members</Button>}
title="Project members"
description="Invite collaborators and set their project roles."
size="lg"
aside
footer={<Button>Save members</Button>}
>
<p className="text-sm">Member management controls appear in this panel.</p>
</Drawer>
</DrawerAside>
</div>
)
}
Aside drawer
Reserves desktop page space so the opened drawer sits beside the content.
tsx
import { Button } from "@/components/ui/button"
import { Drawer, DrawerAside } from "@/registry/cs/ui/drawer"
export default function DrawerAsidePreview() {
return (
<div className="min-h-56 w-full border p-4 ">
<DrawerAside>
<p className="text-sm font-medium bg-blue-200">Project overview</p>
<p className="mt-1 text-sm text-muted-foreground bg-blue-200">
This content remains visible next to the drawer.
</p>
<Drawer
trigger={<Button className="mt-4">Open aside drawer</Button>}
title="Project settings"
description="Update how this project is configured."
aside
>
<p className="text-sm">Drawer content is displayed beside the page.</p>
</Drawer>
</DrawerAside>
</div>
)
}
Large drawer
Uses the large desktop panel width for workflows that need more room.
tsx
import { Button } from "@/components/ui/button";
import { Drawer } from "@/registry/cs/ui/drawer";
export default function DrawerLargePreview() {
return (
<Drawer
trigger={<Button>Open large drawer</Button>}
title="Project members"
description="Manage who can access this project."
size="lg"
footer={<Button>Save members</Button>}
>
<div className="space-y-2 text-sm">
<p>Invite collaborators and set their project roles.</p>
<p className="text-muted-foreground">
The large drawer is twice as wide on desktop screens.
</p>
</div>
</Drawer>
);
}
Non-modal drawer
Keeps the surrounding page available while the drawer is open.
tsx
import { Button } from "@/components/ui/button";
import { Drawer } from "@/registry/cs/ui/drawer";
export default function DrawerNonModalPreview() {
return (
<Drawer
trigger={<Button variant="outline">Open non-modal drawer</Button>}
title="Activity"
description="Review recent project updates without blocking the page."
modal={false}
>
<div className="space-y-2 text-sm">
<p>Deployment completed successfully.</p>
<p className="text-muted-foreground">
You can still interact with the page behind this drawer.
</p>
</div>
</Drawer>
);
}
API Reference
DrawerContextProps
tsx
type DrawerContextProps = {
registerAside: (drawer: AsideDrawer) => void
unregisterAside: (id: string) => void
}DrawerAside
Reserves page space for the active desktop aside drawer. Wrap the page content that should remain visible next to a Drawer with aside enabled.
Drawer
Drawer panel with an optional trigger, heading, scrollable body, and footer.
Props
| Name | Type | Default | Description |
|---|---|---|---|
| aside | boolean | false | Keeps desktop page content beside a horizontal drawer instead of behind it. Requires a surrounding DrawerAside and always uses non-modal behavior. |
| children | ReactNode | - | Content displayed in the scrollable drawer body. |
| className | string | - | Additional classes for the scrollable drawer body. |
| description | string | - | Supporting text displayed below the heading. |
| footer | ReactNode | - | Content displayed below the drawer body. |
| footerClassName | string | - | Additional classes for the drawer footer. |
| keepMounted | boolean | - | Keeps the drawer content mounted after the drawer closes. |
| showSwipeHandle | boolean | - | Shows the swipe affordance on touch-capable drawer orientations. |
| size | "md" | "lg" | "md" | Desktop panel width. The large size doubles the default width. |
| title | string | - | Drawer heading. |
| trigger | ComponentProps<typeof DrawerTrigger>["render"] | - | Element rendered as the drawer trigger. |