Drawer
Edge-anchored slide-over panel for master-detail patterns: the list stays visible while a record is inspected.
Component behavior
Drawer is the master-detail overlay. It anchors to an edge rather than the center so the list or table that launched it stays on screen while the user inspects one record.
Use cases
- Inspecting or editing a record while retaining list context.
- Vertically extended content such as logs, activity, or forms.
- Details opened repeatedly while browsing records.
Alternatives
Modal: the task is self-contained and does not require background context.
PopoverPanel: a small panel belongs beside its trigger.
SettingsModal: navigation must remain visible across views.
A route: the detail view needs its own URL.
Props
Drawer extends HTMLAttributes<HTMLDivElement>. It slides in from the right (or left) with a lighter backdrop so the table behind it remains visible.
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | — | Whether the drawer is visible. |
onClose | () => void | — | Called on Escape or backdrop click. |
width | number | 400 | Panel width in px. |
side | "right" | "left" | "right" | Which edge the drawer slides from. |
children | ReactNode | — | DrawerHeader, DrawerBody, DrawerFooter. |
Sub-components
DrawerHeader
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Title. |
sub | ReactNode | — | Dim mono identifier line under the title. |
right | ReactNode | — | Right-aligned slot before the close button. |
onClose | () => void | — | Renders a close button. |
closeLabel | string | — | Accessible label for the close button. |
density | PanelDensity | "default" | "compact" | "default" | "roomy". |
size | "md" | "lg" | — | Title size. |
plain | boolean | — | Removes the bottom border. |
DrawerBody
| Prop | Type | Default | Description |
|---|---|---|---|
density | PanelDensity | "default" | "compact" | "default" | "roomy". |
scroll | boolean | — | Scrollable body region. |
children | ReactNode | — | Body content. |
DrawerFooter
| Prop | Type | Default | Description |
|---|---|---|---|
left | ReactNode | — | Left-aligned slot. |
children | ReactNode | — | Action buttons (right-aligned). |
Preview
Examples
Basic usage
import {
Drawer,
DrawerHeader,
DrawerBody,
DrawerFooter,
Button,
} from "@solarius/onset";
import { useState } from "react";
function Example() {
const [open, setOpen] = useState(false);
return (
<>
<Button onClick={() => setOpen(true)}>View details</Button>
<Drawer open={open} onClose={() => setOpen(false)}>
<DrawerHeader onClose={() => setOpen(false)}>
Deployment #789
</DrawerHeader>
<DrawerBody>
<p>Detailed deployment information appears here.</p>
</DrawerBody>
<DrawerFooter>
<Button variant="ghost" onClick={() => setOpen(false)}>
Close
</Button>
<Button variant="primary" onClick={() => setOpen(false)}>
Apply
</Button>
</DrawerFooter>
</Drawer>
</>
);
}With record ID and right slot
<Drawer open={open} onClose={onClose}>
<DrawerHeader
sub="rec_01JQ…X9K"
right={<StatusDot tone="ok" />}
onClose={onClose}
>
Payment record
</DrawerHeader>
<DrawerBody>…</DrawerBody>
<DrawerFooter>
<Button variant="primary" onClick={onClose}>
Done
</Button>
</DrawerFooter>
</Drawer>Left-side drawer
<Drawer open={open} onClose={onClose} side="left">
<DrawerHeader onClose={onClose}>Navigation</DrawerHeader>
<DrawerBody>…</DrawerBody>
</Drawer>