Redpanda UIRedpanda UI

Sheet

Extends the Dialog component to display content that complements the main content of the screen.

Made by imskyleen

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 management

Props

Base UI

Shadcn UI

Animate UI Props

SheetContent

Prop

Type

Keyboard interactions

KeyAction
Enter / Space on SheetTriggerOpens the sheet and focuses the first focusable element.
Tab / Shift+TabCycles focus within the sheet — focus is trapped while open.
EscapeCloses the sheet and restores focus to the trigger.
Click outside SheetContentCloses the sheet.

Accessibility

  • Always include a SheetTitle (visually hidden is fine) — Base UI requires it for the accessible name.
  • Add a SheetDescription when 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-hidden and inert.
  • The sheet behaves exactly like Dialog semantically — 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

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
See full history →
Built by malinskibeniamin. The source code is available on GitHub.

On this page