Overlays/Sheet

Sheet

Extends the Dialog component to display content in a sheet.

Themed

When to Use

Use Sheet when you need to:

  • Display supplementary content without navigating away from the current page
  • Present a form or editing interface that relates to the main view (e.g., profile settings, filters)
  • Build navigation panels that slide in from the side on mobile or tablet
  • Show detailed information about a selected item while keeping context visible
  • Create multi-step flows that feel lightweight compared to full-page navigations

When Not to Use

  • Simple confirmation prompts - use Alert Dialog instead
  • Focused tasks that need full attention - use Dialog for centered modals
  • Mobile-first bottom panels with drag-to-dismiss - use Drawer instead
  • Persistent application navigation - use Sidebar for always-visible side panels

Default

A sheet with form fields for editing a profile. Opens from the right by default.

Side

Use the side prop on SheetContent to control which edge the sheet appears from: top, right, bottom, or left.

Custom Size

Override the default max-width by passing a className with custom width values.

With Footer Actions

Use SheetFooter to pin confirmation and cancel actions to the bottom of the sheet.

Scrollable Content

For long content, use overflow-y-auto on the content area while keeping header and footer fixed.

UX & Design Guidelines

Side Selection

Use side="right" (default) for detail panels and editing forms. Use side="left" for navigation or filtering panels that mirror sidebar patterns. Use side="bottom" for mobile-friendly actions, and side="top" sparingly for banners or announcements.

Sizing & Width

The default width is 75% on mobile capped at sm:max-w-sm (384px) on larger screens. Override with className="w-[540px]" for wider content like data tables. Avoid exceeding 50% of the viewport width on desktop to maintain context visibility.

Content Structure

Always include SheetHeader with a SheetTitle and SheetDescription for accessibility. Pin primary actions in SheetFooter using mt-auto to push them to the bottom. Use overflow-y-auto on the body content for scrollable sheets.

Animation & Transitions

Sheets use slide-in/slide-out animations with a 500ms open and 300ms close duration. The overlay fades in simultaneously using bg-black/50. Animations are directional based on the side prop, providing natural spatial feedback for the user.

Accessibility

Keyboard Navigation

  • Tab — Move focus through focusable elements inside the sheet
  • Shift + Tab — Move focus backwards through the sheet
  • Escape — Close the sheet and return focus to the trigger
  • Enter or Space — Activate the trigger to open the sheet

Focus Management

Focus is automatically trapped within the sheet when open, preventing interaction with background content. On open, focus moves to the first focusable element inside the sheet. On close, focus returns to the trigger element. Use onOpenAutoFocus and onCloseAutoFocus to customize this behavior.

Screen Reader Support

  • Uses role="dialog" to identify the sheet as a dialog to assistive technology
  • SheetTitle provides the accessible name via aria-labelledby
  • SheetDescription provides additional context via aria-describedby
  • The close button includes a sr-only "Close" label for screen readers

Modal Behavior

By default, sheets are modal: they block interaction with background content and apply aria-hidden to sibling elements. Set modal={false} for non-modal sheets where users should retain access to the background content (e.g., persistent sidebars).

ARIA Attributes

{/* Sheet with proper labelling */}
<Sheet>
  <SheetTrigger asChild>
    <Button aria-haspopup="dialog">Open Settings</Button>
  </SheetTrigger>
  <SheetContent>
    <SheetHeader>
      <SheetTitle>Settings</SheetTitle>
      <SheetDescription>
        Manage your account settings and preferences.
      </SheetDescription>
    </SheetHeader>
    {/* Content */}
  </SheetContent>
</Sheet>

{/* Non-modal sheet for sidebars */}
<Sheet modal={false}>
  <SheetTrigger asChild>
    <Button>Toggle Sidebar</Button>
  </SheetTrigger>
  <SheetContent
    side="left"
    onInteractOutside={(e) => e.preventDefault()}
  >
    {/* Sidebar navigation */}
  </SheetContent>
</Sheet>

API Reference

The Sheet component is composed of several subcomponents. Each accepts the following props in addition to standard HTML attributes.

Sheet

The root component that manages the sheet open/close state.

PropTypeDefaultDescription
openbooleanThe controlled open state of the sheet.
onOpenChange(open: boolean) => voidEvent handler called when the open state changes.
defaultOpenbooleanfalseThe default open state when initially rendered.
modalbooleantrueWhether the sheet should be modal (block interaction outside).

SheetContent

The content panel that slides in from the edge of the screen.

PropTypeDefaultDescription
side"top" | "right" | "bottom" | "left""right"The edge of the screen where the sheet appears.
classNamestringAdditional CSS classes for styling (use for custom widths).
onOpenAutoFocus(event: Event) => voidEvent handler called when auto-focus occurs on open.
onCloseAutoFocus(event: Event) => voidEvent handler called when auto-focus occurs on close.
onEscapeKeyDown(event: KeyboardEvent) => voidEvent handler called when Escape key is pressed.
onInteractOutside(event: PointerDownOutsideEvent) => voidEvent handler called when clicking outside the sheet.

SheetTrigger

The button that opens the sheet when clicked.

PropTypeDefaultDescription
asChildbooleanfalseChange the default rendered element to the child element, merging props and behavior.

SheetClose

A button that closes the sheet when clicked.

PropTypeDefaultDescription
asChildbooleanfalseChange the default rendered element to the child element, merging props and behavior.