Sheet
Shows a swipeable panel that slides in from the edge of the screen.
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
SheetTriggerOwns the open state.
ButtonSheetSheetHandleIn a top sheet, put it last.
SheetHeaderSheetTitleSheetDescriptionOptional
SheetBodyScrolls when the content does not fit.
SheetFooterSheetCloseCan also go in SheetHeader.
Sizes
Inset
Snap points
Set snapPoints to the visible size at each stop. The sheet opens at the first stop.
Edge placement
Swipe the sheet or drag the handle toward its edge to close it. Also install Checkbox group.
Form
Put the form around SheetBody and SheetFooter so the footer stays in view. Also install Form, Text field, Text area, Select and Switch.
Nested sheets
Escape and outside clicks close the top sheet first. Also install Text field.
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.