1
ComponentsOverlays

Sheet

An edit form from the side in a dialog-based edge flyout for create, edit and save-or-cancel workflows.

Purpose

Use Sheet for side or edge flyouts that contain edit, create and save/cancel workflows. Use Drawer for contextual inspection or gesture-driven panels.

Edge form

import { Sheet, SheetClose, SheetPopup, SheetTrigger } from "@/components/ui/sheet";
import { Button } from "@/components/ui/button";

export function Example() {
  return (
    <Sheet>
      <SheetTrigger render={<Button variant="outline" />}>Edit profile</SheetTrigger>
      <SheetPopup side="right">
        <SheetClose render={<Button />}>Save</SheetClose>
      </SheetPopup>
    </Sheet>
  );
}

Installation

With the Siteplane registry alias configured, add the component and import the installed source from your app.

CLI

pnpm dlx shadcn@4.16.1 add @siteplane/sheet

Import

import {
  Sheet,
  SheetClose,
  SheetDescription,
  SheetFooter,
  SheetHeader,
  SheetPanel,
  SheetPopup,
  SheetTitle,
  SheetTrigger,
} from "@/components/ui/sheet";

Need the machine-readable source metadata? View registry JSON.

Usage

Use Sheet for edit and create forms that slide in from an edge. Use Drawer for contextual inspection.

import { Sheet, SheetClose, SheetPopup, SheetTrigger } from "@/components/ui/sheet";
import { Button } from "@/components/ui/button";

export function Example() {
  return (
    <Sheet>
      <SheetTrigger render={<Button variant="outline" />}>Edit profile</SheetTrigger>
      <SheetPopup side="right">
        <SheetClose render={<Button />}>Save</SheetClose>
      </SheetPopup>
    </Sheet>
  );
}

Examples

Sides, the inset variant, close button control, footer variants and panel scrolling are props of the same primitive.

Sides

The side prop slides the sheet in from any viewport edge. The default is right.

{/* right | left | top | bottom, default right */}
<Sheet>
  <SheetTrigger render={<Button variant="outline" />}>Left</SheetTrigger>
  <SheetPopup side="left">
    <SheetHeader>
      <SheetTitle>Left</SheetTitle>
      <SheetDescription>Sheet sliding in from the left edge.</SheetDescription>
    </SheetHeader>
  </SheetPopup>
</Sheet>

Inset variant

On larger screens the inset variant floats as a rounded panel with a viewport inset.

<SheetPopup variant="inset">
  <SheetHeader>
    <SheetTitle>Inset sheet</SheetTitle>
    <SheetDescription>
      A floating rounded panel instead of an edge-attached one.
    </SheetDescription>
  </SheetHeader>
  <SheetPanel>...</SheetPanel>
</SheetPopup>

Hidden close button

With showCloseButton={false} the footer actions are the only way to close the sheet.

<SheetPopup showCloseButton={false}>
  <SheetHeader>
    <SheetTitle>Review changes</SheetTitle>
    <SheetDescription>
      Close this sheet with one of the footer actions.
    </SheetDescription>
  </SheetHeader>
  <SheetFooter>
    <SheetClose render={<Button variant="outline" />}>Discard</SheetClose>
    <SheetClose render={<Button />}>Apply</SheetClose>
  </SheetFooter>
</SheetPopup>

Scrollable form

SheetPanel wraps a ScrollArea, so a long form scrolls while header and footer stay fixed.

<SheetPopup>
  <SheetHeader>
    <SheetTitle>Edit profile</SheetTitle>
  </SheetHeader>
  <SheetPanel className="grid gap-4">
    {profileFields.map(({ defaultValue, label }) => (
      <Field key={label}>
        <FieldLabel>{label}</FieldLabel>
        <Input defaultValue={defaultValue} />
      </Field>
    ))}
  </SheetPanel>
  <SheetFooter>
    <SheetClose render={<Button variant="ghost" />}>Cancel</SheetClose>
    <SheetClose render={<Button />}>Save</SheetClose>
  </SheetFooter>
</SheetPopup>

API Reference

The reference lists the source-owned exports and props that are easy to miss in visual examples. Inherited Base UI props remain available unless the wrapper narrows them.

  • Compose Sheet, SheetTrigger, SheetPopup, SheetHeader, SheetTitle, SheetDescription, SheetPanel, SheetFooter and SheetClose.
  • SheetPopup accepts side="right" | "left" | "top" | "bottom", variant="default" | "inset", showCloseButton, closeProps and portalProps.
  • closeProps customizes the built-in close control without removing it; showCloseButton={false} removes that control when another explicit close path exists.
  • SheetPanel accepts scrollFade; set scrollFade={false} for a hard scroll edge. SheetFooter accepts variant="default" | "bare".

Motion

Component motion uses the shared Siteplane motion contract. See the global motion guide for provider setup, tokens and reduced-motion behavior.

  • Backdrop and panel use the shared Sheet motion tokens, including side-aware translation and --motion-sheet-x or --motion-sheet-y.
  • Reduced motion removes transform-heavy movement while preserving open, close and focus behavior.

Accessibility

  • Provide SheetTitle and, where helpful, SheetDescription; preserve focus trapping, Escape and focus return.
  • Keep at least one explicit close path through the built-in button or SheetClose.
  • Use semantic form controls and visible labels inside edit flows.

Implementation Guidance

  • Use Sheet for task-oriented forms and Drawer for contextual details or swipe interactions.
  • Customize the built-in close button through closeProps instead of adding a second overlapping control.
  • Keep scroll behavior in SheetPanel and do not add a competing nested vertical scroll container.

On This Page