# Sheet

> The side sheet for details, inspectors, filters and edit forms, on Base UI's Drawer. It slides from any edge, floating or flush, and swipes away on touch. Header and footer stay pinned, with dividers only once content scrolls under them. Nested sheets stack, the one behind stepping back and dimming. confirmClose turns every dismissal into a "Discard unsaved changes?" bar.

- Slug: `sheet`
- Category: [Dialogs](https://www.assembli.design/category/dialogs.md)
- Type: component
- Tags: sheet, drawer, side-panel, inspector, nested, swipe, unsaved-changes
- npm dependencies: @base-ui/react, lucide-react
- shadcn/ui dependencies: none
- Live preview: https://www.assembli.design/preview/sheet
- Page: https://www.assembli.design/components/sheet

![Sheet preview](https://www.assembli.design/thumbnails/sheet-light.png)

## Props

Other props pass through to the root element.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `open` | `boolean` |  |  |
| `defaultOpen` | `boolean` | `false` |  |
| `onOpenChange` | `(open: boolean) => void` |  |  |
| `trigger` | `React.ReactElement<Record<string, unknown>>` |  | An element that opens the sheet, e.g. a `<button>`. It is rendered as the trigger, so it keeps its own styles. |
| `side` | `SheetSide` | `"right"` | The edge it slides from, and the direction a swipe dismisses it. |
| `size` | `SheetSize` | `"md"` | Width for left and right sheets, max width for top and bottom ones. |
| `inset` | `boolean` | `true` | A floating, rounded panel held off the edge. Set `false` for a flush panel. |
| `title` (required) | `React.ReactNode` |  |  |
| `description` | `React.ReactNode` |  |  |
| `icon` | `React.ReactNode` |  | A small mark before the title: an icon tile, avatar or status dot. |
| `actions` | `React.ReactNode` |  | Header buttons placed before the close button. Use `SheetAction` for matching icon buttons. |
| `footer` | `React.ReactNode` |  | A pinned row under the content, e.g. Cancel and Save. Use `SheetClose` for a button that closes. |
| `children` | `React.ReactNode` |  |  |
| `confirmClose` | `boolean \| SheetConfirmClose` |  | Ask before closing, e.g. while a form is dirty. Escape, the backdrop, a swipe and the close button all stop at a "Discard unsaved changes?" bar in the footer instead of closing. |
| `container` | `HTMLElement \| React.RefObject<HTMLElement \| null> \| null` |  | Mount inside this element instead of `<body>`, covering only it (a pane, a canvas, a preview frame). Nested sheets inherit it. |
| `modal` | `boolean` | `true` | Traps focus, locks page scroll and blocks outside clicks. Defaults to `true`. |
| `hideClose` | `boolean` |  |  |
| `bodyClassName` | `string` |  | Classes for the scrolling body; `className` goes on the panel. |

## Install

One-time setup (needs a subscription):

1. Add the registry to the project's `components.json`: `{"@assembli":{"url":"https://www.assembli.design/r/{name}.json","headers":{"Authorization":"Bearer ${ASSEMBLI_API_KEY}"}}}` (merge into `"registries"`).
2. Put an API key from https://www.assembli.design/account in `.env.local` as `ASSEMBLI_API_KEY=asm_…`.

Then install with the shadcn CLI (writes `components/sheet/sheet.tsx` and installs dependencies):

```bash
npx shadcn@latest add @assembli/sheet
```

Registry item JSON: https://www.assembli.design/r/sheet.json (send `Authorization: Bearer <api key>`)

## Code

> Component source needs an Assembli subscription ($12/month or $96/year) and an API key sent as `Authorization: Bearer <key>`. To get one without copying anything, POST https://www.assembli.design/api/agent/login (or call the MCP tool connect_account), show the user the link it returns, and poll https://www.assembli.design/api/agent/token for the key. Or subscribe at https://www.assembli.design/pricing and create a key at https://www.assembli.design/account.
