Overlays
Sheet
A panel that slides in from the left or right edge over a scrim, for detail views, edit forms and filters. Same anatomy as Dialog.
- Source
- src/components/ui/sheet.tsx
- Figma
- Sheet.
Usage
Included in the GliaKit boilerplate. Import it where you need it:
import { Sheet, SheetTrigger, SheetClose, SheetContent, SheetBody, SheetFooter,} from "@/components/ui/sheet";When to use
- Showing the details of a row or record without leaving the list.
- Edit forms that are too long for a dialog, or that people fill in while looking at the page.
- Filters and mobile navigation (from the left).
- For a quick confirmation or a two-field form, use a Dialog.
- For content people need to keep open while they work, build a persistent side panel instead of a modal sheet.
Examples
From the left
Set side="left" for navigation, such as a mobile menu. Icon-only triggers need an aria-label.
Edit form
Wrap the body and footer in a form with flex-1 flex-col min-h-0 so the body scrolls and the footer stays pinned.
API reference
Sheet
Radix Dialog.Root. Holds the open state; uncontrolled by default.
| Prop | Type | Default | Description |
|---|---|---|---|
| open | boolean | - | Controlled open state. |
| defaultOpen | boolean | false | Initial open state when uncontrolled. |
| onOpenChange | (open: boolean) => void | - | Called when the sheet opens or closes. |
| modal | boolean | true | When true, the rest of the page is inert and focus is trapped inside. |
SheetTrigger
Radix Dialog.Trigger. Opens the sheet.
| Prop | Type | Default | Description |
|---|---|---|---|
| asChild | boolean | false | Merge trigger behavior into the child element, e.g. a Button. |
SheetClose
Radix Dialog.Close. Closes the sheet when clicked. The title bar already includes an X button.
| Prop | Type | Default | Description |
|---|---|---|---|
| asChild | boolean | false | Merge close behavior into the child element, e.g. a Cancel Button. |
SheetContent
Renders the portal, the scrim and a full-height panel (max width 384px) with a title bar and X button. Extends Radix Dialog.Content props.
| Prop | Type | Default | Description |
|---|---|---|---|
| title | string | - | Required. Rendered as the Radix Dialog.Title, so it labels the sheet. |
| side | "right" | "left" | "right" | Edge the panel slides in from. |
| children | React.ReactNode | - | Usually a SheetBody followed by a SheetFooter. The panel is a flex column. |
SheetBody
Fills the remaining height and scrolls on overflow. Extends native div attributes.
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | - | Extra classes, merged with the defaults. |
SheetFooter
Right-aligned actions pinned to the bottom, with a top border. Extends native div attributes.
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | - | Extra classes, merged with the defaults. |
Accessibility
- Built on Radix Dialog: focus is trapped inside while open and returns to the trigger on close.
- Escape and a click on the scrim close the sheet.
- The required title prop is wired to Dialog.Title, so the sheet has an accessible name.
- Icon-only triggers, such as a menu button, need an aria-label.
- When wrapping SheetBody and SheetFooter in a <form>, give the form flex-1 flex-col min-h-0 so the body still scrolls and the footer stays pinned.