Sheet

Loading...

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

This example is like Github's profile page. You can see the sheet component is used to display the profile information.

Loading...

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.

Loading...

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.

Loading...

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.

Loading...

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.

Loading...

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.

Loading...

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.

Loading...

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.

Loading...

Sticky

You can use the SheetBody component to make the sheet sticky.

Loading...

Component API

SheetTrigger

SheetTrigger extends the React Aria Components <SheetTrigger> component.

Sheet

Sheet extends the React Aria Components <SheetOverlay> component.

classNamestring
isFloatboolean
Default: false
overlayOmit<SheetOverlayProps, "children" | "position">
snapPointsArray<number | string>
preventDismissalboolean
Default: false
position"bottom" | "top" | "left" | "right" | "start" | "end" | "center"
Default: bottom

SheetHeader

SheetHeader extends the Intent UI <DialogHeader> component.

classNamestring
descriptionstring
titlestring

SheetTitle

SheetTitle extends the Intent UI <DialogTitle> component.

classNamestring

SheetDescription

SheetDescription extends the Intent UI <DialogDescription> component.

classNamestring

SheetBody

SheetBody extends the Intent UI <DialogBody> component.

classNamestring

SheetFooter

SheetFooter extends the Intent UI <DialogFooter> component.

classNamestring

SheetClose

SheetClose extends the Intent UI <DialogClose> component.

classNamestring
intent"primary" | "secondary" | "warning" | "danger" | "success" | "outline" | "plain"
Default: plain

See the React Aria for the full API reference.

Design