ToroUI

Sheet

A panel that slides in from the edge of the screen, useful for navigation, forms, or detail views.


A composable slide-over panel built on Base UI's Dialog primitive. It supports four slide directions and includes an overlay backdrop with blur, a close button, and structured header/footer/title/description slots.

import {
  Sheet,
  SheetContent,
  SheetDescription,
  SheetHeader,
  SheetTitle,
  SheetTrigger,
} from "@/components/ui/sheet"
import { Button } from "@/components/ui/button"

export default function SheetDemo() {
  return (
    <Sheet>
      <SheetTrigger render={<Button variant="outline" />}>
        Open Sheet
      </SheetTrigger>
      <SheetContent>
        <SheetHeader>
          <SheetTitle>Sheet Title</SheetTitle>
          <SheetDescription>
            This is a sheet description. You can put any content here.
          </SheetDescription>
        </SheetHeader>
        <div className="p-4">
          <p className="text-sm text-muted-foreground">Sheet content goes here.</p>
        </div>
      </SheetContent>
    </Sheet>
  )
}

Anatomy

import {
  Sheet,
  SheetTrigger,
  SheetClose,
  SheetContent,
  SheetHeader,
  SheetFooter,
  SheetTitle,
  SheetDescription,
} from "@/components/ui/sheet"
<Sheet>
  <SheetTrigger>Open</SheetTrigger>
  <SheetContent>
    <SheetHeader>
      <SheetTitle>Sheet Title</SheetTitle>
      <SheetDescription>A brief description of the sheet.</SheetDescription>
    </SheetHeader>
    <div className="p-4">{/* Body content */}</div>
    <SheetFooter>
      <SheetClose>Close</SheetClose>
    </SheetFooter>
  </SheetContent>
</Sheet>

Examples

Right sheet (default)

<Sheet>
  <SheetTrigger asChild>
    <Button variant="outline">Open Sheet</Button>
  </SheetTrigger>
  <SheetContent>
    <SheetHeader>
      <SheetTitle>Edit Profile</SheetTitle>
      <SheetDescription>Make changes to your profile here.</SheetDescription>
    </SheetHeader>
    <div className="p-4">
      <Label htmlFor="name">Name</Label>
      <Input id="name" defaultValue="Jens" />
    </div>
    <SheetFooter>
      <Button type="submit">Save changes</Button>
    </SheetFooter>
  </SheetContent>
</Sheet>

Left sheet

Pass side="left" to slide in from the left edge.

<Sheet>
  <SheetTrigger asChild>
    <Button variant="outline">Navigation</Button>
  </SheetTrigger>
  <SheetContent side="left">
    <SheetHeader>
      <SheetTitle>Menu</SheetTitle>
    </SheetHeader>
    <nav className="flex flex-col gap-2 p-4">
      <a href="/docs">Docs</a>
      <a href="/blog">Blog</a>
    </nav>
  </SheetContent>
</Sheet>

Without close button

Set showCloseButton={false} to hide the default close button, for instance when using a custom close action.

<Sheet>
  <SheetTrigger asChild>
    <Button variant="outline">Open</Button>
  </SheetTrigger>
  <SheetContent showCloseButton={false}>
    <SheetHeader>
      <SheetTitle>Custom Close</SheetTitle>
    </SheetHeader>
    <SheetFooter>
      <SheetClose asChild>
        <Button>Done</Button>
      </SheetClose>
    </SheetFooter>
  </SheetContent>
</Sheet>

Top sheet

<Sheet>
  <SheetTrigger asChild>
    <Button variant="outline">Notifications</Button>
  </SheetTrigger>
  <SheetContent side="top">
    <SheetHeader>
      <SheetTitle>Notifications</SheetTitle>
      <SheetDescription>You have 3 unread messages.</SheetDescription>
    </SheetHeader>
  </SheetContent>
</Sheet>

API Reference

Sheet

The root component. A direct wrapper around Base UI's Dialog.Root.

PropTypeDefaultDescription
openbooleanControlled open state.
onOpenChange(open: boolean) => voidCallback when the open state changes.
childrenReactNode

SheetTrigger

The element that opens the sheet. Renders Base UI's Dialog.Trigger.

PropTypeDefault
classNamestring
childrenReactNode

SheetContent

The slide-in panel. Renders inside a portal with a backdrop overlay.

PropTypeDefaultDescription
side"top" | "right" | "bottom" | "left""right"The edge of the screen from which the sheet slides in.
showCloseButtonbooleantrueWhether to render the default close button in the top-right corner.
classNamestring
childrenReactNode

SheetHeader

A flex-column container for the title and description, with padding.

PropTypeDefault
classNamestring
childrenReactNode

SheetFooter

A flex-column container pushed to the bottom of the sheet via mt-auto.

PropTypeDefault
classNamestring
childrenReactNode

SheetTitle

The accessible title for the sheet. Renders Base UI's Dialog.Title.

PropTypeDefault
classNamestring
childrenReactNode

SheetDescription

The accessible description for the sheet. Renders Base UI's Dialog.Description.

PropTypeDefault
classNamestring
childrenReactNode

SheetClose

A button that closes the sheet. Renders Base UI's Dialog.Close.

PropTypeDefault
classNamestring
childrenReactNode