Skip to content
Redpanda UI
Esc
↑↓navigate↵open⌘Jpreview
Made by imskyleen
Edit on GitHub

Sheet

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

Installation

bash
npx shadcn@latest add @redpanda/sheet
bash
pnpm dlx shadcn@latest add @redpanda/sheet
bash
yarn dlx shadcn@latest add @redpanda/sheet
bash
bunx shadcn@latest add @redpanda/sheet
bash
nubx shadcn@latest add @redpanda/sheet
bash
aube dlx shadcn@latest add @redpanda/sheet

When to use

Sheets display supplementary content that slides from screen edges. Use this decision tree:

Usage

tsx
<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:

plaintext
<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

SheetContent

PropType
side?'top' | 'right' | 'bottom' | 'left'

Viewport edge the panel docks to and slides in from.

Type'top' | 'right' | 'bottom' | 'left'
Default'right'
size?'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full'

Caps how wide a left or right sheet grows. A top or bottom sheet spans the full viewport width and takes its height from its content, so size does not apply to it.

Type'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full'
Default'xl'
showCloseButton?boolean

Render the top-right close affordance.

Typeboolean
Defaulttrue
closeButtonGutter?boolean

Pad the top so content starts below the close button. Opt-in because it moves content down. Ignored when showCloseButton is false.

Typeboolean
Defaultfalse

The close button sits over the content, so a top-right control of your own (a code block’s copy button, a banner’s dismiss) collides with it. Set closeButtonGutter to start the content below it:

tsx
<SheetContent closeButtonGutter>  <SimpleCodeBlock code={bootstrapServers} language="bash" /></SheetContent>

Validated sheet form

The profile example keeps its actions visible while the field area scrolls. It uses the standard Sheet spacing and Field composition: invalid inputs are associated with every visible error. Website is optional; non-empty values must be complete HTTP or HTTPS URLs, not just a protocol prefix. Save closes the demo only after validation passes; it does not send a profile update to a server.

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 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:

tsx
<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):

tsx
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.

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 baseline while caret semantics still allow any compatible release within the same major.#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## 🚧 Updated#112
See full history →

Last updated on

Was this page helpful?