Skip to content

Sheet

Shows a swipeable panel that slides in from the edge of the screen.

sheet-basic-demo.tsx

Installation

The CLI adds the files, packages, theme variables, and Tailwind plugin that this component uses. Before you run it, set up your project.

Composition

  • SheetTrigger

    Owns the open state.

    • Button
    • Sheet
      • SheetHandle

        In a top sheet, put it last.

      • SheetHeader
        • SheetTitle
        • SheetDescriptionOptional
      • SheetBody

        Scrolls when the content does not fit.

      • SheetFooter
        • SheetClose

          Can also go in SheetHeader.

Sizes

sheet-sizes-demo.tsx

Inset

sheet-inset-demo.tsx

Snap points

Set snapPoints to the visible size at each stop. The sheet opens at the first stop.

sheet-demo.tsx

Edge placement

Swipe the sheet or drag the handle toward its edge to close it. Also install Checkbox group.

sheet-placement-demo.tsx

Form

Put the form around SheetBody and SheetFooter so the footer stays in view. Also install Form, Text field, Text area, Select and Switch.

sheet-form-demo.tsx

Nested sheets

Escape and outside clicks close the top sheet first. Also install Text field.

sheet-nested-demo.tsx

API reference

vip/ui adds or changes the props below. For all other props, see React Aria Sheet (opens in a new tab).

Sheet

position: "bottom" | "top" | "left" | "right" | "start" | "end" | "center" = "bottom"
The edge the sheet comes from. start and end mirror in right-to-left locales. A top or bottom sheet fits its content up to a maximum height. Set a fixed height with className.
size: "sm" | "md" | "lg" | "xl" | "full" = "md"
A left or right sheet is 20rem, 26rem, 36rem, or 48rem wide, and always leaves 3.5rem of the page visible. A top or bottom sheet has a maximum width of 28rem, 42rem, 56rem, or 72rem. full fills the screen.
inset: boolean = false
Moves the sheet 0.5rem in from the screen edges and rounds all corners.
swipeDirection: "bottom" | "top" | "left" | "right" | "start" | "end" | "vertical" | "horizontal"
The direction of a swipe or handle drag that closes the sheet. vertical and horizontal close toward either edge. Without it, the direction is the same as position. A center sheet uses vertical.
snapPoints: Array<number | string>
The visible size at each stop. Numbers are pixels. Strings are CSS lengths, and percentages are relative to the sheet. The sheet opens at the first stop. You can always drag it to full size. Below full size, a swipe on SheetBody resizes the sheet.
preventDismissal: boolean = false
Stops swipes, Escape, and outside clicks from closing the sheet. Snap points still work.
isOpen: boolean
Whether the sheet is open, controlled. Without isOpen and defaultOpen, a SheetTrigger can own the state instead. Then the Button inside the SheetTrigger opens the sheet.
defaultOpen: boolean
Whether the sheet is open at first, uncontrolled.
onOpenChange: (isOpen: boolean) => void
Receives the new open state. When a SheetTrigger owns the state, set onOpenChange on the SheetTrigger.
--sheet-stack-scale: number
How much the sheet shrinks while a nested sheet is open. The default is 0.94, or 0.96 for a side sheet. Set it in className. Set 1 to keep the size.
--sheet-stack-x: CSS length
How far the sheet moves horizontally while a nested sheet is open. The default moves a side sheet 0.75rem away from its edge. Other sheets do not move horizontally. Set it in className. Set 0 to keep the position.
--sheet-stack-y: CSS length
How far the sheet moves vertically while a nested sheet is open. The default moves a top or bottom sheet 0.5rem away from its edge. Other sheets do not move vertically. Set it in className. Set 0 to keep the position.

SheetClose

Takes all Button props.

children: ReactNode
Text for the button. Without children, it shows an X icon labeled "Close sheet".
variant: "default" | "secondary" | "outline" | "ghost" | "minimal" | "destructive" = "ghost"
Choose default for a primary action, outline for a secondary action, or ghost for dismissal.
iconOnly: boolean
Makes the button a square for one icon. The default is true without children and false with children.
size: "xs" | "sm" | "md" | "lg" | "xl" = "sm" without children, "md" with children
The Button size. An icon-only close button uses sm to stay compact.