1. Documentation
  2. Overlays
  3. Sheet
ReadmenpmGitHub
  • Introduction
  • Installation
  • Theming
  • Icons
  • Accordion
  • Card
  • Scroll Area
  • Separator
  • Sidebar
  • Field
  • Label
  • Input
  • Textarea
  • Number Field
  • OTP Field
  • Select
  • Combobox
  • Checkbox
  • Radio
  • Switch
  • Slider
  • Toggle
  • Calendar
  • Date Picker
  • File Upload
  • Button
  • Copy Button
  • Dropdown
  • Command
  • Tabs
  • Breadcrumb
  • Pagination
  • Tree
  • Table
  • Data Table
  • Stat
  • Timeline
  • Avatar
  • Status Bar
  • Badge
  • Meter
  • Empty
  • Skeleton
  • Spinner
  • Toast
  • Dialog
  • Sheet
  • Popover
  • Tooltip
  • Text
  • Kbd
  • Code Block
  • Utilities
  • Design rules

Sheet

A panel that slides in from an edge — for a side quest, not for a task.

Loading documentation…

Dialog< PreviousPopoverNext >

Powered by heyo

On this page

UsageSidesSizesDismissingPropertiesSheetSheet.ContentThe parts
<Sheet><Sheet.Trigger render={<Button>Open details</Button>} /><Sheet.Content>  <Sheet.Header>    <Sheet.Title>acme-api</Sheet.Title>    <Sheet.Description>Deployed 4 minutes ago from main@8f21c3d.</Sheet.Description>  </Sheet.Header>  <Sheet.Body>    <Stat label="Requests" value="142,318" delta={12.4} />  </Sheet.Body>  <Sheet.Footer>    <Sheet.Close render={<Button variant="ghost">Close</Button>} />    <Button variant="primary">Redeploy</Button>  </Sheet.Footer></Sheet.Content></Sheet>

A Sheet is a Dialog with a different geometry, and it exists as its own component for one reason: the edge it comes from decides the size axis, the animation and the border, and none of that is a sensible prop on a centred dialog.

Reach for it when the content is a side quest to the page — a detail pane, a filter panel, a record's full record — rather than a task that has to end before the page continues.

Usage

tsx
import { Button, Sheet } from "@heyo-sh/heyo-ui";<Sheet>  <Sheet.Trigger render={<Button>Details</Button>} />  <Sheet.Content side="right">…</Sheet.Content></Sheet>;

Sides

right is the default, and it is right almost always: it is where a detail pane lives, and it leaves the navigation on the left untouched. left is for navigation itself, bottom for something that belongs to the bottom of the viewport.

<Sheet><Sheet.Trigger render={<Button>Right</Button>} /><Sheet.Content side="right">…</Sheet.Content></Sheet><Sheet><Sheet.Trigger render={<Button>Left</Button>} /><Sheet.Content side="left">…</Sheet.Content></Sheet><Sheet><Sheet.Trigger render={<Button>Bottom</Button>} /><Sheet.Content side="bottom">…</Sheet.Content></Sheet>

Sizes

sm, base, lg and xl set the width for a left or right sheet and the height for a top or bottom one — the axis follows the edge, which is exactly why this is a separate component.

Dismissing

Like Dialog, a sheet is dismissible by default. dismissible={false} is for the rare panel that must be answered; for a side quest it is almost always wrong, since the whole point is that the page is still there behind it.

Not a bottom sheet

heyo-ui ships no phone-style drawer. side="bottom" is the same component with a different edge, and it behaves like a dialog — because that is what it is.

Properties

Sheet

dismissiblebooleanoptional

Whether the backdrop and Escape close it. It defaults to true.

open / defaultOpenbooleanoptional

Controlled and uncontrolled state.

onOpenChange(open: boolean) => voidoptional

Fires on open and close.

Sheet.Content

side"right" | "left" | "top" | "bottom"optional

The edge it slides from. It defaults to right.

size"sm" | "base" | "lg" | "xl"optional

Width for a left or right sheet, height for a top or bottom one.

hideClosebooleanoptional

Hides the corner close button.

The parts

Sheet.Trigger / Closerenderoptional

Open and close it. Both take render to become a Button.

Sheet.Header / Title / Description—optional

The heading block, wired to the panel's accessible name.

Sheet.Body—optional

The scrolling content column.

Sheet.Footer—optional

Right-aligned actions, pinned to the bottom edge.