# Sheet A slide-in panel that appears from the left or right edge of the viewport. Can operate as a modal dialog with a backdrop or as a popover that allows interaction with content behind it. Supports a title, description, action buttons, and optional form wrapping. Controlled via an imperative ref with `open()` and `close()` methods. ```tsx demo import { Button } from "@tenstorrent/vesper/button"; import { Sheet, useSheet } from "@tenstorrent/vesper/sheet"; export default function SheetDemo() { const sheet = useSheet(); return ( <> Sheet content goes here. ); } ``` ## Options | Prop | Type | Description | Default | | ------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | --------- | | `title` | `string` | The title text displayed in the sheet header. Used for `aria-labelledby`. **Required.** | — | | `description` | `string` | A description displayed below the title. Used for `aria-describedby`. **Required.** | — | | `side` | `"left" \| "right"` | The side of the viewport the sheet slides in from. | `"right"` | | `popover` | `boolean` | When `true`, renders as a popover without a backdrop, allowing interaction behind it. | `false` | | `buttons` | `ButtonProps[]` | An optional array of button props for action buttons. The last button defaults to `"contrast"` variant; others default to `"tertiary"`. | — | | `ref` | `Ref` | A ref exposing imperative `open()` and `close()` methods. | — | | `form` | `FormProps` | When provided, wraps the sheet content in a `
` element with the given form attributes. | — | | `children` | `ReactNode` | The content displayed inside the sheet body. | — | All other props are forwarded to the underlying `` element. Use a `Sheet` for supplementary content alongside the current view, such as filters, settings, or the details of a selected row. When the content demands the user's full attention before they can carry on, reach for [the `Modal` component](./modal.mdx) instead. ## Examples ### Opening and closing a sheet A `Sheet` renders closed, and is opened imperatively. The `useSheet` hook returns everything needed for this: a `ref` to forward to the sheet, plus `open()` and `close()` functions: ```tsx demo import { Button } from "@tenstorrent/vesper/button"; import { Sheet, useSheet } from "@tenstorrent/vesper/sheet"; export default function BasicSheet() { const sheet = useSheet(); return ( <> Sheet content goes here. ); } ``` A sheet closes when the user presses `Escape`, clicks the close button in its header, or (in the default modal mode) clicks the backdrop behind it. ### Choosing a side A sheet slides in from the right by default. Pass `side="left"` to have it slide in from the left instead, which tends to suit navigation: ```tsx demo import { Button } from "@tenstorrent/vesper/button"; import { Sheet, useSheet } from "@tenstorrent/vesper/sheet"; export default function LeftSheet() { const sheet = useSheet(); return ( <> Sheet content goes here. ); } ``` ### Popover mode By default a `Sheet` behaves like a modal dialog: it renders a backdrop, traps focus, and blocks interaction with the rest of the page. Passing `popover` renders it as a popover instead, with no backdrop, so the user can keep working with the content behind it: ```tsx demo import { Button } from "@tenstorrent/vesper/button"; import { Sheet, useSheet } from "@tenstorrent/vesper/sheet"; export default function PopoverSheet() { const sheet = useSheet(); return ( <> This sheet does not block interaction with the page behind it, so you can keep scrolling and clicking while it is open. ); } ``` Use popover mode for panels the user consults while working, such as inspectors and help content, and stick with the default modal mode when the panel's task should be finished before anything else happens. ### Action buttons Pass an array of button props to `buttons` to render action buttons along the bottom of the sheet. The last button defaults to the `contrast` variant and the rest default to `tertiary`, which can be overridden with the `variant` prop: ```tsx demo import { Button } from "@tenstorrent/vesper/button"; import { Sheet, useSheet } from "@tenstorrent/vesper/sheet"; import { TextInput } from "@tenstorrent/vesper/text-input"; export default function SheetWithButtons() { const sheet = useSheet(); return ( <> ); } ``` ### Usage in forms Passing the `form` prop wraps the sheet's contents in a `` element, so the action buttons can submit it natively with `type="submit"`, and native validation runs before the submit handler fires: ```tsx demo import { useState } from "react"; import { Button } from "@tenstorrent/vesper/button"; import { Sheet, useSheet } from "@tenstorrent/vesper/sheet"; import { TextInput } from "@tenstorrent/vesper/text-input"; import { Typography } from "@tenstorrent/vesper/typography"; export default function FormSheet() { const sheet = useSheet(); const [submitted, setSubmitted] = useState(null); return (
{submitted && ( Invited: {submitted} )} { event.preventDefault(); const data = new FormData(event.currentTarget); setSubmitted(String(data.get("email") ?? "")); sheet.close(); }, }} buttons={[ { children: "Cancel", type: "button", onClick: sheet.close }, { children: "Send invite", type: "submit" }, ]} > Enter your teammate's email
); } ``` > [!NOTE] > > Buttons rendered inside a `form` default to `type="submit"`, so give any button that should not submit an explicit `type="button"`, as the cancel button above does.