A dialog that becomes a sheet on phones — full-screen for forms, or a bottom dock for confirms — with the header and footer pinned while the body scrolls between them.
FullDockDesktop card
Narrow the window below 480px to see the phone presentation.
<Sheet open={editing} variant="full" title="Edit project" onclose={close}> <Field label="Name"><TextInput bind:value={name} /></Field> {#snippet footer()}<Button variant="primary">Save</Button>{/snippet}</Sheet>Installation
pnpm add @chanrg/4uiImport the stylesheet once, at the root of your app:
import '@chanrg/4ui/styles.css';Usage
import { Sheet } from '@chanrg/4ui';<Sheet open={editing} variant="full" title="Edit project" onclose={close}> <Field label="Name"><TextInput bind:value={name} /></Field> {#snippet footer()}<Button variant="primary">Save</Button>{/snippet}</Sheet>Composition
Use the following composition to build a sheet:
Sheet ├── header (snippet) ├── children └── footer (snippet)
Bottom dock
Use variant="dock" for confirms and small pickers; on a phone it rises from the bottom edge.
Narrow the window below 480px to see it rise from the bottom edge.
<Sheet open={confirming} variant="dock" title="Delete service" onclose={close}> <p>This cannot be undone.</p> {#snippet footer()}<Button variant="danger">Delete</Button>{/snippet}</Sheet>API reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | false | Visibility. |
variant | full | dock | full | Phone presentation: 100dvh sheet, or an 85dvh bottom dock. |
size | sm | md | lg | md | Desktop width cap; on phones the sheet is full-bleed. |
showHandle | boolean | true | Grab affordance on the dock variant. |
header / children / footer | Snippet | — | Title row, the scrolling body, and the pinned action row. |
closeOnBackdrop / onclose | boolean / () => void | true / — | Backdrop and Escape both request a close. |
CSS variables
| Variable | Description |
|---|---|
--4ui-surface | Primary component surface. |
--4ui-text | Primary foreground color. |
--4ui-border | Default control and panel border. |
--4ui-safe-bottom | Home-indicator inset added under the sheet. |
Accessibility
- Focus is trapped inside the sheet and restored to the opener on close.
- Escape closes; the dialog is labelled by its title.
- The body is the only scrolling region, so the header and footer never scroll out of reach.