Sheet (side panel)
Preview: Right
Modal panel that slides in from an edge (no swipe gestures). Use Drawer for swipeable, snap-point sheets.
Import
import { Sheet, SheetTrigger } from '@marbleui/ui'Props
<Sheet>
| Prop | Type | Default | Description |
|---|---|---|---|
| children *required | ReactNode | — | |
| description | ReactNode | — | |
| footer | ReactNode | — | |
| overlayProps | Omit<ModalOverlayProps, 'children'> | — | |
| side | Side | 'right' | |
| title | ReactNode | — |
Also accepts React Aria props (81).
<SheetTrigger>alias of DialogTrigger
Re-exported from React Aria DialogTrigger; see its documentation for props.
Accessibility
Keyboard interaction, focus management and ARIA semantics come from the underlying primitives: React Aria Dialog · React Aria DialogTrigger · React Aria Heading · React Aria Modal · React Aria ModalOverlay. Follow the primitive's docs for the full keyboard map.
Usage notes
Modal panel sliding in from an edge for detail views and forms that need more room than a dialog.
<SheetTrigger>
<Button>Edit</Button>
<Sheet side="right" title="Edit issue" footer={<Button>Save</Button>}>…</Sheet>
</SheetTrigger>
titleis required in practice: it names the dialog.- No swipe gestures; use
Drawerfor touch-first, swipe-to-dismiss and snap points.
Example source · show· hide
import { Button } from '../button'
import { Switch } from '../switch'
import { TextField } from '../text-field'
import { Sheet, SheetTrigger } from './sheet'
export const styles = {
Right: () => (
<SheetTrigger>
<Button variant="outline">Edit profile</Button>
<Sheet title="Edit profile" description="Changes are visible to your team." footer={<Button slot="close">Save</Button>}>
<div className="flex flex-col gap-4">
<TextField label="Name" defaultValue="Maya Chen" />
<TextField label="Title" defaultValue="Design Engineer" />
<Switch defaultSelected>Show email on profile</Switch>
</div>
</Sheet>
</SheetTrigger>
),
Left: () => (
<SheetTrigger>
<Button variant="outline">Open navigation</Button>
<Sheet side="left" title="Acme">
<nav className="flex flex-col gap-1 text-fg">
{['Home', 'Projects', 'Team', 'Settings'].map((l) => (
<a key={l} href="#" className="rounded-md px-2 py-1.5 hover:bg-surface-muted">{l}</a>
))}
</nav>
</Sheet>
</SheetTrigger>
),
Bottom: () => (
<SheetTrigger>
<Button variant="outline">Cookie settings</Button>
<Sheet side="bottom" title="Cookies" description="Choose which cookies we may use." footer={<Button slot="close">Done</Button>}>
<div className="mx-auto flex max-w-lg flex-col gap-3">
<Switch isDisabled defaultSelected>Necessary</Switch>
<Switch>Analytics</Switch>
<Switch>Marketing</Switch>
</div>
</Sheet>
</SheetTrigger>
),
}Source: packages/ui/src/sheet/sheet.tsx
Catalog
- Category
- overlays
- Priority
- Core
- Primitive
- react-aria
- React Aria
- Modal + Dialog
- Base UI
- Dialog