Sheet
Extends the Dialog component to display content that complements the main content of the screen.
Made by imskyleenPowered by
Installation
Loading component...
When to use
Sheets display supplementary content that slides from screen edges. Use this decision tree:
Usage
<Sheet>
<SheetTrigger>Open Sheet</SheetTrigger>
<SheetContent>
<SheetHeader>
<SheetTitle>Title</SheetTitle>
<SheetDescription>Description</SheetDescription>
</SheetHeader>
<p>Sheet Content</p>
<SheetFooter>
<button>Close</button>
</SheetFooter>
</SheetContent>
</Sheet>Anatomy
The Sheet component extends Dialog for side-sliding content:
<Sheet> (Dialog-based)
├── <SheetTrigger> (Button)
├── <SheetContent> (Sliding Panel)
│ ├── Side positioning (top/right/bottom/left)
│ ├── Animation (slide + fade)
│ ├── <SheetHeader>
│ │ ├── <SheetTitle> (h2)
│ │ └── <SheetDescription>
│ ├── Content Area (scrollable)
│ └── <SheetFooter>
├── Sheet Overlay (backdrop)
└── Focus managementProps
Base UI
Shadcn UI
Animate UI Props
SheetContent
Prop
Type
Keyboard interactions
| Key | Action |
|---|---|
Enter / Space on SheetTrigger | Opens the sheet and focuses the first focusable element. |
Tab / Shift+Tab | Cycles focus within the sheet — focus is trapped while open. |
Escape | Closes the sheet and restores focus to the trigger. |
Click outside SheetContent | Closes the sheet. |
Accessibility
- Always include a
SheetTitle(visually hidden is fine) — Base UI requires it for the accessible name. - Add a
SheetDescriptionwhen the purpose isn't obvious from the title. - Focus is trapped inside the panel while open and returned to the trigger on close; background is
aria-hiddenand inert. - The sheet behaves exactly like
Dialogsemantically — it's a side-docked Dialog with a slide transition.
Controlled vs uncontrolled
Uncontrolled — let the sheet own open state:
<Sheet onOpenChange={(open) => console.log('open:', open)}>
<SheetTrigger>Open</SheetTrigger>
<SheetContent side="right">{/* ... */}</SheetContent>
</Sheet>Controlled — drive open from parent state (e.g. to open the sheet from a table row action):
const [open, setOpen] = useState(false);
<Sheet open={open} onOpenChange={setOpen}>
<SheetContent side="right">
<SheetHeader>
<SheetTitle>Edit topic</SheetTitle>
</SheetHeader>
{/* ... */}
</SheetContent>
</Sheet>Credits
- We use Base UI for the sheet component.
- We take our inspiration from Shadcn UI for the sheet style.
- We use Animate UI from imskyleen for all the animations.
Recent changes
- patchv1.2.0Pin shipped dependency floors to the version we develop against. Registry items now declare ranges like `^5.1.9` (the actual installed version) instead of collapsing to `^5.0.0`, so consumers start on the known-tested b…#133
- minorv1.1.0Theme docs refresh, readability pass on semantic foregrounds, and consumer-facing Base UI regression fixes.#121
- minorv1.0.0Post-Base-UI polish. Public API unchanged.#116
- majorv1.0.0Migrate every Radix-based primitive to `@base-ui/react@^1.4.0` (Base UI).#114
- patchv0.3.1**Accordion** - `AccordionTrigger` now shows `cursor-pointer` on hover.#112
Built by malinskibeniamin. The source code is available on GitHub.