Sheet

A dialog that slides in from an edge; Drawer adds drag to dismiss.

Import
import { Sheet } from '@texuli/primitives/sheet';
Pattern
Dialog (modal) (WAI-ARIA APG)
Size budget
16.0 KiB gzip for @texuli/primitives/sheet
Reference
packages/primitives/docs/prim-sheet.md

Live demo

Loading the Sheet demo…

Anatomy

Sheet anatomy: each box holds the parts inside it.
  • Sheet.Root
    • Sheet.Trigger
    • Sheet.Portal
      • Sheet.Overlay
      • Sheet.Content
        • Sheet.Title
        • Sheet.Description
        • Sheet.Close

Drawer has the same parts plus a Handle; Panel and ResponsiveModal are variants.

Behavior checks

tests/behavior/scenarios/sheet.spec.ts checks the Sheet scenario in the browser (10 checks) on Chromium, WebKit and the Pixel 7.

  • a sheet is a modal dialog on its side that traps and restores focus
  • a sheet closes on a backdrop press
  • logical start opens on the right in RTL
  • a panel takes focus but leaves the page usable
  • a dismissOutside panel closes on an outside press and outside focus, not on its trigger
  • closeOnEscape closes a panel on Escape anywhere; the default panel ignores Escape outside
  • a drawer steps through its snap points from the keyboard
  • a drawer drags between snap points and swipes away
  • the responsive modal is a dialog on desktop and a drawer on the phone
  • passes axe (${scheme})

Limits

  • Every row passes on every project; a flaky row gets at most two retries.
  • Size: at most 16.0 KiB gzip for @texuli/primitives/sheet (pnpm size).
  • Open-to-focus: p75 at most 150 ms (asserted with TEXULI_PERF=1).