Sheet
A panel that slides in from any edge of the screen, complementing the main content.
CMS Demo
See how content editors configure sheets in a CMS:
Basic Usage
Installation
pnpm add @corew500/uiUsage
import {
Sheet,
SheetTrigger,
SheetContent,
SheetHeader,
SheetTitle,
SheetDescription,
SheetFooter,
SheetClose,
} from "@mordecai-design-system/ui"<Sheet>
<SheetTrigger>Open Sheet</SheetTrigger>
<SheetContent>
<SheetHeader>
<SheetTitle>Sheet Title</SheetTitle>
<SheetDescription>Description here</SheetDescription>
</SheetHeader>
<p>Sheet content</p>
<SheetFooter>
<SheetClose>Close</SheetClose>
</SheetFooter>
</SheetContent>
</Sheet>Examples
Sides
// Right (default)
<Sheet>
<SheetContent side="right">From right</SheetContent>
</Sheet>
// Left
<Sheet>
<SheetContent side="left">From left</SheetContent>
</Sheet>
// Top
<Sheet>
<SheetContent side="top">From top</SheetContent>
</Sheet>
// Bottom
<Sheet>
<SheetContent side="bottom">From bottom</SheetContent>
</Sheet>Without Close Button
<SheetContent showCloseButton={false}>
<SheetHeader>
<SheetTitle>Custom Close</SheetTitle>
</SheetHeader>
<SheetFooter>
<SheetClose asChild>
<Button>Close Sheet</Button>
</SheetClose>
</SheetFooter>
</SheetContent>Controlled
const [open, setOpen] = useState(false)
<Sheet open={open} onOpenChange={setOpen}>
<SheetTrigger>Open</SheetTrigger>
<SheetContent>
<Button onClick={() => setOpen(false)}>
Close programmatically
</Button>
</SheetContent>
</Sheet>With Form
<SheetContent>
<SheetHeader>
<SheetTitle>Edit Profile</SheetTitle>
<SheetDescription>
Make changes to your profile here.
</SheetDescription>
</SheetHeader>
<form className="py-4 space-y-4">
<Input placeholder="Name" />
<Input type="email" placeholder="Email" />
</form>
<SheetFooter>
<SheetClose asChild>
<Button variant="outline">Cancel</Button>
</SheetClose>
<Button type="submit">Save changes</Button>
</SheetFooter>
</SheetContent>Sub-components
| Component | Description |
|-----------|-------------|
| Sheet | Root component managing open state |
| SheetTrigger | Button that opens the sheet |
| SheetContent | The sliding panel |
| SheetHeader | Header area |
| SheetTitle | Main heading |
| SheetDescription | Supporting text |
| SheetFooter | Footer with actions |
| SheetClose | Button to close |
| SheetOverlay | Background overlay |
Props
SheetContent
| Prop | Type | Default | Description |
|---|---|---|---|
| showCloseButton | enum | true | Whether to display the close button in the top-right corner. |
| initialFocus | enum | — | Determines the element to focus when the dialog is opened. - `false`: Do not move focus. - `true`: Move focus based on the default behavior (first tabbable element or popup). - `RefObject`: Move focus to the ref element. - `function`: Called with the interaction type (`mouse`, `touch`, `pen`, or `keyboard`). Return an element to focus, `true` to use the default behavior, or `false`/`undefined` to do nothing. |
| finalFocus | enum | — | Determines the element to focus when the dialog is closed. - `false`: Do not move focus. - `true`: Move focus based on the default behavior (trigger or previously focused element). - `RefObject`: Move focus to the ref element. - `function`: Called with the interaction type (`mouse`, `touch`, `pen`, or `keyboard`). Return an element to focus, `true` to use the default behavior, or `false`/`undefined` to do nothing. |
| style | enum | — | Style applied to the element, or a function that returns a style object based on the component’s state. |
| className | enum | — | CSS class applied to the element, or a function that returns a class based on the component’s state. |
| render | enum | — | Allows you to replace the component’s HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render. |
| side | enum | right | — |
Sheet
| Prop | Type | Default | Description |
|---|---|---|---|
| open | enum | — | Whether the dialog is currently open. |
| defaultOpen | enum | false | Whether the dialog is initially open. To render a controlled dialog, use the `open` prop instead. |
| modal | enum | true | Determines if the dialog enters a modal state when open. - `true`: user interaction is limited to just the dialog: focus is trapped, document page scroll is locked, and pointer interactions on outside elements are disabled. - `false`: user interaction with the rest of the document is allowed. - `'trap-focus'`: focus is trapped inside the dialog, but document page scroll is not locked and pointer interactions outside of it remain enabled. |
| onOpenChange | (open: boolean, eventDetails: DialogRootChangeEventDetails) => void | — | Event handler called when the dialog is opened or closed. |
| onOpenChangeComplete | (open: boolean) => void | — | Event handler called after any animations complete when the dialog is opened or closed. |
| disablePointerDismissal | enum | false | Determines whether the dialog should close on outside clicks. |
| actionsRef | RefObject<DialogRootActions> | — | A ref to imperative actions. - `unmount`: When specified, the dialog will not be unmounted when closed. Instead, the `unmount` function must be called to unmount the dialog manually. Useful when the dialog's animation is controlled by an external library. - `close`: Closes the dialog imperatively when called. |
| handle | DialogHandle<unknown> | — | A handle to associate the dialog with a trigger. If specified, allows external triggers to control the dialog's open state. Can be created with the Dialog.createHandle() method. |
| triggerId | string | — | ID of the trigger that the dialog is associated with. This is useful in conjunction with the `open` prop to create a controlled dialog. There's no need to specify this prop when the popover is uncontrolled (i.e. when the `open` prop is not set). |
| defaultTriggerId | string | — | ID of the trigger that the dialog is associated with. This is useful in conjunction with the `defaultOpen` prop to create an initially open dialog. |
Sheet vs Drawer
Both Sheet and Drawer slide in from screen edges, but they have different behaviors:
| Feature | Sheet | Drawer | |---------|-------|--------| | Interaction | Click-based | Swipe support | | Mobile | Works well | Optimized | | Snap points | No | Yes | | Handle | No | Yes (bottom) |
Use Sheet for desktop-focused panels and Drawer for mobile-first interactions.