Sheet
Side drawer built on Radix Dialog with a directional slide animation. Use for navigation, filters, quick edit, or any off-canvas panel.
Installation
pnpm dlx @hex-core/cli add sheetBottom action sheet
Mobile-friendly Share-to surface using side="bottom" — three destinations as primary actions
<Sheet>
<SheetTrigger asChild>
<Button variant="outline">Share</Button>
</SheetTrigger>
<SheetContent side="bottom">
<SheetHeader>
<SheetTitle>Share to</SheetTitle>
<SheetDescription>Pick where to send this link.</SheetDescription>
</SheetHeader>
<div className="grid grid-cols-3 gap-3 py-4">
<Button variant="outline" onClick={() => shareTo("slack")}>Slack</Button>
<Button variant="outline" onClick={() => shareTo("email")}>Email</Button>
<Button variant="outline" onClick={() => shareTo("copy")}>Copy link</Button>
</div>
</SheetContent>
</Sheet>Variant values
sideWhich edge the sheet slides in from| Value | Description |
|---|---|
top | Slides down from the top edge |
bottom | Slides up from the bottom edge |
left | Slides in from the left edge |
rightdefault | Slides in from the right edge (default) |
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | — | Controlled open state |
defaultOpen | boolean | false | Default open state for uncontrolled usage |
onOpenChange | function | — | Callback when open state changes: (open: boolean) => void |
modal | boolean | true | When true, content outside the sheet is inert |
AI Guidance
When to use
Use for off-canvas panels — mobile nav menus, filter panels, side forms, detail views, or multi-step flows. Slides in from an edge, dismisses on outside click, Escape, or close button.
When not to use
Don't use for center-focused modals (use Dialog). Don't use for transient bottom sheets on mobile (use Drawer). Don't use for dropdown menus or quick popover actions (use DropdownMenu or Popover).
Common mistakes
- Forgetting SheetTitle — Radix warns at runtime and screen readers announce an unnamed dialog
- Putting a full page's content inside a sheet — too much friction; use a route instead
- Overriding the side slide animation without matching the 'side' variant
- Not handling controlled open state after SheetClose — use onOpenChange not manual state
Accessibility
Radix traps focus, handles Escape to close, and wires aria-labelledby/describedby to SheetTitle/Description. The Close button has sr-only text. Always include a SheetTitle.
Token budget: 700
Verified against @hex-core/components@1.12.0