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

PropTypeDefaultDescription
openboolean-The controlled open state of the sheet.
defaultOpenbooleanfalseThe default open state when uncontrolled.
onOpenChange(open: boolean) => void-Callback when the open state changes.

SheetContent

PropTypeDefaultDescription
side"top" | "right" | "bottom" | "left""right"The side of the screen the sheet appears from.
classNamestring-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>
```