Dialog
import { Dialog } from '@absoluteui/components/dialog';import '@absoluteui/components/dialog/style.css';Using Angular? See Dialog for Angular.
What it does
Section titled “What it does”A modal dialog built on native <dialog>.showModal(). The browser provides top-layer rendering, an inert background, and focus containment. AbsoluteUI adds:
- deterministic Escape and backdrop policy;
- cancelable close events;
- focus restoration;
- scroll lock;
- localization.
When to use
Section titled “When to use”- Tasks that must be completed or dismissed before returning to the page.
- Confirmations of destructive actions (role=alertdialog).
When not to use
Section titled “When not to use”- Non-blocking information: use an inline message, alert, or toast.
- Complex multi-step flows better served by a page or wizard.
- Contextual content anchored to a trigger: use a popover.
Examples
Section titled “Examples”Destructive confirmation (alertdialog)
Section titled “Destructive confirmation (alertdialog)”import { Dialog, type DialogCloseDetail } from '@absoluteui/components/dialog';
const confirm = Dialog.create({ title: 'Delete project?', description: 'This permanently removes the project.', role: 'alertdialog', actions: [ { label: 'Cancel', value: 'cancel', autofocus: true }, { label: 'Delete', value: 'delete', variant: 'danger' }, ],});confirm.element.addEventListener('aui-close', (event) => { const { returnValue } = (event as CustomEvent<DialogCloseDetail>).detail; if (returnValue === 'delete') { // perform deletion }});confirm.open();Prevent closing with unsaved changes
Section titled “Prevent closing with unsaved changes”import { Dialog } from '@absoluteui/components/dialog';
let dirty = true;const editor = Dialog.create({ title: 'Edit profile', closeOnBackdrop: true });editor.element.addEventListener('aui-cancel', (event) => { if (dirty) event.preventDefault();});editor.open();dirty = false;import { Dialog } from '@absoluteui/components/dialog';import '@absoluteui/components/button/style.css';import '@absoluteui/components/dialog/style.css';
const d = Dialog.create({ title: 'Settings', content: 'Preferences are saved automatically.' });document.querySelector('#open')?.addEventListener('click', () => { d.open();});More usage
Section titled “More usage”import { Dialog } from '@absoluteui/components/dialog';
const confirm = Dialog.create({ title: 'Delete project?', role: 'alertdialog', actions: [ { label: 'Cancel', value: 'cancel', autofocus: true }, { label: 'Delete', value: 'delete', variant: 'danger' }, ],});confirm.open();Anatomy
Section titled “Anatomy”<dialog class="aui-dialog aui-dialog--{size}" aria-labelledby aria-describedby [role=alertdialog]> <header class="aui-dialog__header"> <h2 class="aui-dialog__title">title</h2> <button class="aui-button aui-dialog__close" aria-label="Close">icon</button> </header> <p class="aui-dialog__description">description</p> <div class="aui-dialog__body">content</div> <footer class="aui-dialog__footer">action buttons</footer></dialog>API reference
Section titled “API reference”Factory
Section titled “Factory”Dialog.create(options: DialogOptions, doc?: Document): DialogGlobal configuration key: dialog (see Configuration).
Options
Section titled “Options”| Option | Type | Default | Description |
|---|---|---|---|
title |
string |
Accessible name, rendered as the heading. Required. | |
description |
string |
Referenced by aria-describedby. | |
content |
Node | string |
Body content; strings render as text. | |
actions |
readonly DialogAction[] |
Footer buttons; clicking closes with the action value. | |
role |
'dialog' | 'alertdialog' |
"dialog" |
Use alertdialog for urgent confirmations. |
icons |
Partial<{ close: IconRef }> |
Icon slot overrides. | |
closeOnEscape |
boolean |
true |
Escape requests close (cancelable). Globally configurable. |
closeOnBackdrop |
boolean |
false |
Backdrop click requests close (cancelable). Globally configurable. |
showCloseButton |
boolean |
true |
Render the header close button. Globally configurable. |
size |
'sm' | 'md' | 'lg' |
"md" |
Maximum inline size. Globally configurable. |
Properties
Section titled “Properties”| Property | Type | Description |
|---|---|---|
element |
HTMLDialogElement |
The native dialog element. |
body |
HTMLDivElement |
Consumer content area. |
isOpen |
boolean |
Whether the dialog is open. |
Methods
Section titled “Methods”| Method | Description |
|---|---|
open(): void |
Open modally; locks scroll; captures focus for restoration. |
close(returnValue?: string): void |
Close programmatically (not cancelable). |
update(options: Partial<DialogOptions>): void |
Merge and apply options. |
destroy(): void |
Close if open, remove element, listeners, subscriptions. |
Events
Section titled “Events”| Event | Detail | Bubbles | Cancelable | Description |
|---|---|---|---|---|
aui-open |
null |
No | No | After the dialog opened. |
aui-cancel |
{ returnValue: string; reason: 'escape' | 'backdrop' | 'close-button' | 'action' } |
No | Yes | Before a user-initiated close; preventDefault keeps it open. |
aui-close |
{ returnValue: string; reason: DialogCloseReason } |
No | No | After the dialog closed. |
Content areas
Section titled “Content areas”| Area | Description |
|---|---|
body |
Dialog.body (or content option). |
CSS classes
Section titled “CSS classes”All rules live in the aui.components cascade layer, so application styles override them without specificity battles.
| Class | Purpose |
|---|---|
aui-dialog |
Native <dialog> element. |
aui-dialog--sm | --md | --lg |
Size modifiers. |
aui-dialog__header |
Title row with close button. |
aui-dialog__title |
Heading (h2). |
aui-dialog__close |
Close button. |
aui-dialog__description |
Description paragraph. |
aui-dialog__body |
Scrollable content area. |
aui-dialog__footer |
Action buttons. |
Icon slots
Section titled “Icon slots”| Slot | Default icon |
|---|---|
close |
close |
Design tokens
Section titled “Design tokens”Tokens this stylesheet reads (verified in CI). Override them in a theme or with the Theme Designer.
--aui-border-width | --aui-color-backdrop | --aui-color-border | --aui-color-focus-ring | --aui-color-surface | --aui-color-text | --aui-color-text-muted | --aui-dialog-width-lg | --aui-dialog-width-md | --aui-dialog-width-sm | --aui-duration-fast | --aui-easing-standard | --aui-focus-ring-offset | --aui-focus-ring-width | --aui-font-family-sans | --aui-font-size-lg | --aui-font-size-md | --aui-font-size-sm | --aui-font-weight-semibold | --aui-line-height-normal | --aui-line-height-tight | --aui-radius-lg | --aui-shadow-lg | --aui-space-1 | --aui-space-2 | --aui-space-3 | --aui-space-4 | --aui-space-5
TypeScript definitions
Section titled “TypeScript definitions”type DialogCloseReason = 'escape' | 'backdrop' | 'close-button' | 'action' | 'programmatic';interface DialogAction { label: string; value: string; variant?: ButtonVariant; autofocus?: boolean }interface DialogCloseDetail { returnValue: string; reason: DialogCloseReason }interface DialogOptions { title: string; description?: string; content?: Node | string; actions?: readonly DialogAction[]; role?: 'dialog' | 'alertdialog'; icons?: Partial<{ close: IconRef }>; closeOnEscape?: boolean; closeOnBackdrop?: boolean; showCloseButton?: boolean; size?: 'sm' | 'md' | 'lg';}Accessibility
Section titled “Accessibility”Pattern: WAI-ARIA APG Dialog (Modal) and Alert Dialog patterns, implemented with native <dialog>.showModal().
Keyboard
Section titled “Keyboard”| Key | Context | Action |
|---|---|---|
| Tab / Shift+Tab | Dialog open | Moves focus among dialog controls; background is inert (native modal). |
| Escape | Dialog open, closeOnEscape=true | Emits cancelable aui-cancel, then closes and restores focus. |
| Escape | Dialog open, closeOnEscape=false | No effect; the native close request is prevented. |
| Escape | Nested overlay (e.g. combobox listbox) open | Closes only the topmost overlay. |
| Enter / Space | Action or close button focused | Activates the button. |
| Element | Role |
|---|---|
| <dialog> | dialog (native) or alertdialog |
| title | heading level 2 |
ARIA attributes
Section titled “ARIA attributes”| Attribute | Element | Value |
|---|---|---|
aria-labelledby |
<dialog> | id of the title heading |
aria-describedby |
<dialog> | id of the description (when provided) |
aria-label |
close button | Localized ‘Close’ |
On open, focus moves to the autofocus action or first focusable element. On close, focus returns to the element focused before opening.
WCAG 2.2 success criteria addressed
Section titled “WCAG 2.2 success criteria addressed”| Criterion | Level | Note |
|---|---|---|
| 1.3.1 Info and Relationships | A | |
| 2.1.1 Keyboard | A | |
| 2.1.2 No Keyboard Trap | A | |
| 2.4.3 Focus Order | A | |
| 2.4.7 Focus Visible | AA | |
| 4.1.2 Name, Role, Value | A |
Automated test results: Accessibility and compliance.
Notes and known caveats
Section titled “Notes and known caveats”- Background inertness and top-layer rendering are provided by the browser.
- Scroll lock uses scrollbar-gutter to avoid layout shift.
- Manual screen-reader verification (NVDA, JAWS, VoiceOver) is pending.
Behavior
Section titled “Behavior”States
Section titled “States”closed, open, and closing (an aui-cancel listener is pending).
State transitions
Section titled “State transitions”| From | Trigger | To |
|---|---|---|
| closed | open() |
open (focus moves inside, scroll locked) |
| open | Escape / backdrop / close button / action | aui-cancel -> closed, unless prevented |
| open | close() |
closed (no aui-cancel) |
| open | consumer <form method="dialog"> submit |
closed (reason action) |
Accessibility notes
Section titled “Accessibility notes”- Initial focus goes to the action with
autofocus: true, otherwise the first focusable element (native dialog focusing steps). - For alert dialogs, set
autofocuson the least destructive action. - On close, focus returns to the element that was focused before
open(). - Verified with axe (WCAG 2.2 AA) in 3 themes.
- Manual screen-reader verification is pending.
Responsive behavior
Section titled “Responsive behavior”Width is min(size token, 100vw - 2rem) and height is capped at 100dvh - 2rem; the body scrolls. Below 480px, footer actions stack full-width.
Right-to-left
Section titled “Right-to-left”Logical properties throughout; the close button sits at the inline end.
Theming
Section titled “Theming”Token-driven surface, border, radius, shadow, and backdrop. Forced-colors mode uses a CanvasText border.
Global configuration
Section titled “Global configuration”configureAbsoluteUI({ components: { dialog: { closeOnBackdrop: true, size: 'lg' } } });Component configuration
Section titled “Component configuration”Instance options override global and theme defaults. All configurable options are dynamic and re-render the open dialog.
icons.close (default close), resolved through the global icon provider/registry.
Security
Section titled “Security”Title, description, and string content use textContent. No HTML parsing, no inline styles. Verified under a strict CSP with Trusted Types enforced.
Data handling
Section titled “Data handling”No persistence, network access, or telemetry.
Performance
Section titled “Performance”Constant work per open/close: one showModal() call, one scroll-lock reference, and one focus restore point. Budget: open() under 16 ms in headless Chromium (performance test).
Supported data scale
Section titled “Supported data scale”Not data-driven. Body content size is limited only by the consumer; the body scrolls.
Edge cases
Section titled “Edge cases”closeOnEscape: falsealso blocks repeated Escape presses. Chrome would otherwise let the second Escape through without user activation.- Escape in a focused combobox that has a value but a closed listbox clears the combobox first, per the APG.
- Destroying an open dialog releases the scroll lock and restores focus.
Errors
Section titled “Errors”| Code | Category | Cause |
|---|---|---|
DIALOG_TITLE |
configuration | Missing or blank title. |
CFG_INVALID_VALUE / CFG_UNKNOWN_OPTION |
configuration | Invalid or unknown configuration. |
Known limitations
Section titled “Known limitations”- The close transition is not animated; the open transition uses
@starting-styleand is removed under reduced motion. - Only modal dialogs are supported.
- Manual screen-reader verification is pending.
Unsupported scenarios
Section titled “Unsupported scenarios”- Non-modal dialogs.
- HTML strings as content: pass a
Nodeinstead.