Dialog

A modal window that traps focus, makes the page inert and restores focus on close.

Import
import * as Dialog from '@texuli/primitives/dialog';
Pattern
Dialog (modal) (WAI-ARIA APG)
Size budget
12.0 KiB gzip for @texuli/primitives/dialog
Reference
packages/primitives/docs/prim-dialog.md

Live demo

Loading the Dialog demo…

Anatomy

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

Behavior checks

tests/behavior/scenarios/dialog.spec.ts runs 14 rows against the Dialog scenario on Chromium, WebKit and the Pixel 7. Each row asserts what a user or assistive technology can observe, held to the WAI-ARIA Authoring Practices pattern.

All 14 rows
  1. contained: the backdrop fills only the container, stays out of the top layer, and the content is on top
  2. a dialog mounted already open has focus on its first field, and typing reaches it
  3. the trigger is a button that says it opens a dialog
  4. the dialog is named by its title and described by its description
  5. opening moves focus into the dialog
  6. Tab and Shift+Tab stay inside the dialog
  7. Escape closes it and focus returns to the trigger
  8. the Close button closes it
  9. with a nested dialog open, Escape closes only the top one
  10. the page behind the dialog is inert while it is open
  11. the page does not scroll while the dialog is open
  12. the page scrolls again once the dialog closes
  13. a pointer press outside closes it
  14. it reports opening and closing once each, in order

Limits

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