# Sheet

A dialog that slides in from an edge of the screen and runs along it: details of a row, filters, settings, a form next to the page it changes. It shares Dialog's scrim, raised surface and close button; only the side that faces the content has a border and page corners.

## Usage

### When to use

- Work next to the page: the details of a row, filters, a short form.
- Navigation on a narrow screen, from the start edge, or a few choices on a phone, from the bottom.

### When not to use

- Confirming an action that destroys data. Use AlertDialog.
- A focused task that stands on its own, such as renaming a project. Use Dialog.
- A menu of actions. Use DropdownMenu.

## Variants

### side

Set on SheetContent. The edge it slides in from. right for details and forms next to a list; left for navigation; bottom for short choices on a phone; top rarely.

Values: `top`, `right`, `bottom`, `left`. Default: `right`.

### size

Set on SheetContent. Widest it gets on the left and right (sm 320px, md 448px, lg 672px), tallest on the top and bottom (a third, half, three quarters of the screen). full covers the screen along that side, with no corners.

Values: `sm`, `md`, `lg`, `full`. Default: `md`.

## Examples

### Edit details

```tsx
<Sheet>
  <SheetTrigger asChild>
    <Button variant="secondary">Edit project</Button>
  </SheetTrigger>
  <SheetContent>
    <SheetHeader>
      <SheetTitle>Edit project</SheetTitle>
      <SheetDescription>Changes are visible to everyone on your team.</SheetDescription>
    </SheetHeader>
    <Field>
      <FieldLabel>Name</FieldLabel>
      <FieldControl>
        <Input defaultValue="Werewolf" />
      </FieldControl>
    </Field>
    <SheetFooter>
      <SheetClose asChild>
        <Button variant="secondary">Cancel</Button>
      </SheetClose>
      <Button>Save</Button>
    </SheetFooter>
  </SheetContent>
</Sheet>
```

### From the bottom

Short choices on a phone, with the main action one tap away.

```tsx
<Sheet>
  <SheetTrigger asChild>
    <Button variant="secondary">Sort</Button>
  </SheetTrigger>
  <SheetContent side="bottom" size="sm">
    <SheetHeader>
      <SheetTitle>Sort projects</SheetTitle>
    </SheetHeader>
    <RadioGroup aria-label="Sort projects" defaultValue="recent">
      <RadioGroupItem value="recent" label="Recently edited" />
      <RadioGroupItem value="name" label="Name" />
    </RadioGroup>
  </SheetContent>
</Sheet>
```

## Do and don't

### Do

- Use it for work next to the page: the details of a row, filters, a short form.
- Give it a title, and put the main action in the footer.
- Keep it open while the user works in it; close it when the action is done.

### Don't

- Don't use it for a short confirmation; use AlertDialog or Dialog.
- Don't open a sheet from a sheet.
- Don't use it for a menu of actions; use DropdownMenu.

## Props

| Name | Type | Values | Default | Description |
| --- | --- | --- | --- | --- |
| `open` | `boolean` |  |  | Set on Sheet. Whether it is open, when you control it. Pair it with onOpenChange. |
| `defaultOpen` | `boolean` |  | `false` | Set on Sheet. Opens it on first render, when you don't control it. |
| `onOpenChange` | `function` |  |  | Set on Sheet. Called with true or false when it opens or closes (trigger, close button, Escape, scrim). |
| `side` | `enum` | `top`, `right`, `bottom`, `left` | `right` | Set on SheetContent. The edge it slides in from. right for details and forms next to a list; left for navigation; bottom for short choices on a phone; top rarely. |
| `size` | `enum` | `sm`, `md`, `lg`, `full` | `md` | Set on SheetContent. Widest it gets on the left and right (sm 320px, md 448px, lg 672px), tallest on the top and bottom (a third, half, three quarters of the screen). full covers the screen along that side, with no corners. |
| `showCloseButton` | `boolean` |  | `true` | Set on SheetContent. The corner close button. Hide it only when the footer has a Cancel or Close. |

### Slots

| Name | Required | Description |
| --- | --- | --- |
| `trigger` | no | SheetTrigger with asChild around a Button. |
| `title` | yes | SheetTitle, required for a11y. |
| `description` | no | Optional SheetDescription. |
| `content` | no | The body: fields, details, a list. It scrolls with the panel. |
| `footer` | no | SheetFooter with the actions. |

## Anatomy

| Part | Description |
| --- | --- |
| `root` | Sheet. Holds the open state. |
| `overlay` | The scrim behind the sheet, the same as Dialog's. |
| `content` | The panel: raised fill, shadow-high, p-xl, gap-lg. It covers the full length of its side; the border and the page corners are only on the side that faces the content. |
| `header` | Top block for the title and description, gap-sm. |
| `title` | The name of the sheet: 16px medium. |
| `description` | Optional supporting text: 13px secondary. |
| `footer` | Actions at the end of the panel, however short the content is. |
| `close` | Icon button in the corner that closes the sheet, the same as Dialog's. |
| `icon` | Tabler X in the close button, 16px. |
| `hitArea` | Transparent ::before on the close button, never smaller than size-target-min. |

## Accessibility

Role: `dialog`

| Keys | Action |
| --- | --- |
| `Escape` | Closes the sheet and returns focus to the trigger. |
| `Tab` | Cycles focus inside the sheet (focus trap). |

- A modal dialog: it traps focus, hides the rest of the page from assistive tech and closes on Escape or a scrim press.
- Always provide a SheetTitle (visible or sr-only), so the sheet has a name.
- The corner close is a button with a visually hidden Close label and a Tabler X. With showCloseButton={false}, the footer must have a Cancel or Close.
- It slides in only when the user allows motion; under prefers-reduced-motion it fades in. It closes at once.
- Do not open a sheet from a sheet.

## Install

```bash
npx shadcn add https://werewolf-ui.vercel.app/r/sheet.json
```

This also adds `styles/werewolf.css`, the tokens every component uses, and any other component it needs. Import that file once in your root CSS, after `@import "tailwindcss"`, with a path relative to that CSS file (from `app/globals.css` it is `@import "../styles/werewolf.css"`).
