Sheet
Installation
Install the component via the CLI in one command.
npx shadcn@latest add @intentui/sheet
Composed components
When you install this component via the CLI, it automatically loads all composed components, so you don’t need to add them individually.
Manual installation
Use this approach if you prefer to install and wire up the component yourself instead of using the CLI.
npm install react-aria-components cn tailwind-variants
Add the backdrop and stacking animations to your global CSS using @theme inline. The CLI adds this CSS automatically.
@theme inline {
--animate-sheet-backdrop: sheet-backdrop 300ms linear both;
--animate-sheet-scale-back: sheet-scale-back 300ms ease-out both;
@keyframes sheet-backdrop {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes sheet-scale-back {
to {
transform: translate(
var(--sheet-stack-x, 0px),
var(--sheet-stack-y, 0px)
) scale(0.95);
}
}
}
@supports not (animation-timeline: view()) {
.react-aria-sheet[data-has-descendants] {
transform: translate(
var(--sheet-stack-x, 0px),
var(--sheet-stack-y, 0px)
) scale(0.95);
}
}sheet-backdrop animates the backdrop opacity from 0 to 1. React Aria uses it through swipeAnimation to keep the fade synchronized with the sheet’s movement.
sheet-scale-back scales the sheet behind to 0.95 and offsets it by 8px toward the opposite edge. Sheet sets --sheet-stack-x or --sheet-stack-y based on its position. The smaller offset keeps the close button behind the front sheet. The @supports rule provides the stacked appearance in browsers without view timelines.
Anatomy
import { Button } from "@/components/ui/button"
import { Sheet, SheetBody, SheetClose, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger } from "@/components/ui/sheet"<SheetTrigger>
<Button>Open</Button>
<Sheet position="right">
<SheetHeader>
<SheetTitle>Sheet Title</SheetTitle>
<SheetDescription>Sheet Description</SheetDescription>
</SheetHeader>
<SheetBody>Sheet Body</SheetBody>
<SheetFooter>
<SheetClose>Cancel</SheetClose>
<Button>Save</Button>
</SheetFooter>
</Sheet>
</SheetTrigger>Examples
Menu
This example is like Github's profile page. You can see the sheet component is used to display the profile information.
Stacking
Nest a SheetTrigger inside another sheet to open a new panel on top. The sheet behind scales down and moves back as the next sheet opens. Each sheet has its own close action, so closing the top sheet returns you to the previous one. This example uses three levels: workspace settings, team access, and member permissions.
Controlled
You can control the open state of the sheet by using the isOpen prop. You can also use the onOpenChange prop to listen to the open state change.
Positioning
Use the position prop to choose top, bottom, left, right, start, end, or center. The default is bottom.
left and right are physical positions. start and end follow the locale direction: in LTR they map to left and right, and in RTL they map to right and left. center displays a centered panel with a responsive width.
Snap points
Set snapPoints to control how much of the sheet is visible at each stop. Numbers are pixels; percentages are relative to the sheet’s size. The sheet opens at the first snap point. Set an explicit height for a bottom or top sheet when using percentage snap points.
Prevent dismissal
Set preventDismissal to prevent closing by swiping, pressing Escape, or interacting outside. A SheetClose action can still close the sheet. This defaults to false.
Custom close
Sheets do not include a built-in close icon. Use SheetClose for an explicit close action. Dismissible sheets at bottom show a drag handle above the sheet content.
You can customize the close button by using the SheetClose component. This example demonstrates how to use the SheetClose component to create a custom close button.
Float
isFloat defaults to false, so sheets attach to the screen edge. Set isFloat={true} to make a sheet float with spacing from the screen edges and rounded corners. Top and bottom sheets retain their maximum width and side borders when not floating. A sheet with position="center" remains centered in either mode.
Sticky
You can use the SheetBody component to make the sheet sticky.
Component API
SheetTrigger
SheetTrigger extends the React Aria Components <SheetTrigger> component.
Sheet
Sheet extends the React Aria Components <SheetOverlay> component.
classNamestringisFloatbooleanfalseoverlayOmit<SheetOverlayProps, "children" | "position">snapPointsArray<number | string>preventDismissalbooleanfalseposition"bottom" | "top" | "left" | "right" | "start" | "end" | "center"bottomSheetHeader
SheetHeader extends the Intent UI <DialogHeader> component.
classNamestringdescriptionstringtitlestringSheetTitle
SheetTitle extends the Intent UI <DialogTitle> component.
classNamestringSheetDescription
SheetDescription extends the Intent UI <DialogDescription> component.
classNamestringSheetBody
SheetBody extends the Intent UI <DialogBody> component.
classNamestringSheetFooter
SheetFooter extends the Intent UI <DialogFooter> component.
classNamestringSheetClose
SheetClose extends the Intent UI <DialogClose> component.
classNamestringintent"primary" | "secondary" | "warning" | "danger" | "success" | "outline" | "plain"plainSee the React Aria for the full API reference.
