Drawer
A panel that slides in from an edge (Base UI Dialog behavior).
Real use · navigation drawer
Header + Footer · sticky, scrolling content
Using Drawer
Silica ships one design system through three paths. They share a class vocabulary but are not interchangeable — pick the one that matches what you are building.
Plain HTML — CSS classes
The Tailwind v4 plugin. Works in any framework or none — Rails, Django, PHP, Go, a static file. This path ships no JavaScript, so Drawer is styled but inert: its behavior comes from modal. For that behavior with no framework, use the node-tree path below.
/* in your CSS */
@import "tailwindcss";
@plugin "@wizeworks/silicaui";Root class drawer-backdrop, with 7 modifiers:
.drawer-backdrop.drawer-description.drawer-footer.drawer-footer-sticky.drawer-header.drawer-header-sticky.drawer-popup.drawer-title
React
Typed components over those same classes, with behavior and accessibility from Base UI.
npm i @wizeworks/silicaui-reactimport { Drawer } from "@wizeworks/silicaui-react";Props
DrawerContentProps
| Prop | Type | Required | Description |
|---|---|---|---|
| children | React.ReactNode | no | — |
| side | DrawerSide | no | Edge the drawer slides from. Default left. |
| backdropClassName | string | no | Class for the backdrop layer. |
DrawerHeaderProps
| Prop | Type | Required | Description |
|---|---|---|---|
| sticky | boolean | no | Pin this bar in place while the rest of the content scrolls. |
DrawerFooterProps
| Prop | Type | Required | Description |
|---|---|---|---|
| sticky | boolean | no | Pin this bar in place while the rest of the content scrolls. |
Source of the demo above
The exact file that renders the examples above, so it can never drift from them. It imports a few of this site’s own layout helpers (../lib/…), so read it for the component calls rather than copying it whole.
Show source
import {
Drawer,
DrawerTrigger,
DrawerClose,
DrawerContent,
DrawerTitle,
DrawerDescription,
DrawerHeader,
DrawerFooter,
Button,
} from "@wizeworks/silicaui-react";
import { Section, Row } from "../lib/Section";
export function DrawerDemo() {
return (
<>
<Section title="Real use · navigation drawer">
<Row>
{(["left", "right", "top", "bottom"] as const).map((side) => (
<Drawer key={side}>
<DrawerTrigger>
<Button variant="outline" color="neutral">
{side}
</Button>
</DrawerTrigger>
<DrawerContent side={side}>
<DrawerTitle>Navigation</DrawerTitle>
<DrawerDescription>
Slides in from the {side} edge.
</DrawerDescription>
<nav className="flex flex-col gap-2 py-4 text-sm">
<a href="#">Dashboard</a>
<a href="#">Projects</a>
<a href="#">Settings</a>
</nav>
<DrawerClose>
<Button variant="ghost" color="neutral">
Close
</Button>
</DrawerClose>
</DrawerContent>
</Drawer>
))}
</Row>
</Section>
<Section title="Header + Footer · sticky, scrolling content">
<Drawer>
<DrawerTrigger>
<Button variant="outline">Filters (sticky header/footer)</Button>
</DrawerTrigger>
<DrawerContent side="right">
<DrawerHeader sticky>
<DrawerTitle>Filters</DrawerTitle>
<DrawerClose>
<Button variant="ghost" shape="circle" size="sm">
✕
</Button>
</DrawerClose>
</DrawerHeader>
<div className="flex flex-col gap-3 text-sm">
{Array.from({ length: 14 }, (_, i) => (
<label key={i} className="flex items-center gap-2">
<input type="checkbox" /> Filter option {i + 1}
</label>
))}
</div>
<DrawerFooter sticky>
<DrawerClose>
<Button variant="ghost" color="neutral">
Reset
</Button>
</DrawerClose>
<DrawerClose>
<Button>Apply</Button>
</DrawerClose>
</DrawerFooter>
</DrawerContent>
</Drawer>
</Section>
</>
);
}Vanilla — node tree to HTML
Drawer — identical shape to Dialog; props.side becomes a data-side attribute on the panel for the CSS to slide from (render-neutral to the behavior itself). Build a node tree, project it with toHtml(), and let the zero-dependency runtime hydrate it. This is the path for generated or user-authored documents — a site builder, CMS output, a static export.
npm i @wizeworks/silicaui-html @wizeworks/silicaui-behaviorsimport { atom, toHtml } from "@wizeworks/silicaui-html";
const node = atom("Drawer", "drawer-backdrop", { /* props */ }, [/* children */]);
const markup = toHtml(node);Styling on this path is the class string in the second argument — the same classes as the Plain HTML section above. There is no color prop here; write "drawer-backdrop drawer-backdrop-primary" rather than passing a colour as a prop.
- Takes children
- yes
- Hydrated by
modal
Load @wizeworks/silicaui-behaviors on the page or this markup renders correctly and does nothing.
The full API for Drawer, on every path, is available through the Silica MCP server.