Sheet
A panel that slides out from the edge of the screen.
Installation
import {
Sheet,
SheetContent,
SheetDescription,
SheetFooter,
SheetHeader,
SheetTitle,
SheetTrigger,
} from "@gradeui/ui"Usage
Examples
Project Settings
Side: Left
Side: Top
Side: Bottom
Props
Sheet
| Prop | Type | Default | Description |
|---|---|---|---|
| open | boolean | - | The controlled open state of the sheet. |
| defaultOpen | boolean | false | The default open state when uncontrolled. |
| onOpenChange | (open: boolean) => void | - | Callback when the open state changes. |
SheetContent
| Prop | Type | Default | Description |
|---|---|---|---|
| side | "top" | "right" | "bottom" | "left" | "right" | The side of the screen the sheet appears from. |
| className | string | - | Additional CSS classes. |
Accessibility
- Built on Radix UI Dialog for full accessibility
- Focus is trapped within the sheet
- Escape key closes the sheet
- Background scroll is locked when open
- Announces content to screen readers
Sidecar
The Markdown sidecar Studio (and the Grade MCP server, when it ships) reads to understand this component — frontmatter, when- to-use guidance, and canonical examples. Authored once at packages/ui/components/ui/sheet.md and shipped inside the published @gradeui/ui tarball.
---
name: Sheet
import: "@gradeui/ui"
subcomponents: [SheetTrigger, SheetContent, SheetHeader, SheetTitle, SheetDescription, SheetFooter, SheetClose]
props:
- Sheet: open?, defaultOpen?, onOpenChange?, modal? (default true)
- SheetTrigger: asChild?: boolean
- SheetContent: side? "top" | "right" | "bottom" | "left" (default "right")
- SheetContent: className?: string — usually set a width (right/left) or height (top/bottom)
- SheetTitle / SheetDescription: identify the sheet to screen readers; required for accessibility even if visually styled differently
- SheetClose: asChild? — usually wraps a Button labelled Cancel or Done
when_to_use: A panel that slides in from a screen edge — mobile nav drawers, side panels for editing a single record without leaving the list, filter trays on small viewports. For a centered focus modal use Dialog. For a transient announcement use Toast (Sonner). For inline reveals use Collapsible.
composes_with: [Form controls (an inline edit sheet), Button (trigger + close), AppShellNav (mobile-only swap)]
aliases: [sheet, drawer, side panel, slide-in, nav drawer, mobile drawer, slide-over, action sheet, modal sheet, bottom sheet, side sheet, react native modal sheet, bottom-sheet, ios action sheet]
---
```jsx
// Edit-record drawer from the right edge.
<Sheet>
<SheetTrigger asChild>
<Button variant="outline">Edit user</Button>
</SheetTrigger>
<SheetContent className="w-full sm:max-w-md">
<SheetHeader>
<SheetTitle>Edit user</SheetTitle>
<SheetDescription>Update Elena's profile and role.</SheetDescription>
</SheetHeader>
<Stack gap="md" className="py-4">
<Stack gap="xs">
<Label htmlFor="name">Name</Label>
<Input id="name" defaultValue="Elena Okafor" />
</Stack>
<Stack gap="xs">
<Label htmlFor="role">Role</Label>
<Select>{/* … */}</Select>
</Stack>
</Stack>
<SheetFooter>
<SheetClose asChild>
<Button variant="ghost">Cancel</Button>
</SheetClose>
<Button>Save changes</Button>
</SheetFooter>
</SheetContent>
</Sheet>
```