Dialog primitive
Headless Dialog: the behavior, keyboard support and ARIA of the WAI-ARIA Dialog (Modal) pattern, with no styles.
@ndop/primitives/dialog- WAI-ARIA: Dialog (Modal)
Import
Primitives ship in the @ndop/primitives package and have no styles. Their state is on data attributes for you to style. The styled Dialog is built on this one.
import {
NdDialog,
NdDialogClose,
NdDialogContent,
NdDialogDescription,
NdDialogOverlay,
NdDialogPortal,
NdDialogTitle,
NdDialogTrigger,
} from '@ndop/primitives/dialog';Accessibility
Implements the Dialog (Modal) pattern of the WAI-ARIA Authoring Practices.
Keyboard
Keys the component handles.
| Key | Action |
|---|---|
| Tab | Moves focus to the next focusable element inside the dialog; from the last one, wraps to the first. |
| ShiftTab | Moves focus to the previous focusable element inside the dialog; from the first one, wraps to the last. |
| Escape | Closes the dialog, unless closeOnEscape is false. |
Focus
- On open: focus moves to the first focusable element in the content, or to the content element itself when it has none.
- While open: focus is trapped in the content.
- On close: focus returns to the element that had it before opening, usually the trigger.
Right-to-left
Nothing mirrors: the dialog is centered, and Tab order follows the DOM.
API reference
NdDialog
[ndDialog]from @ndop/primitives/dialogRoot of a modal dialog (WAI-ARIA Dialog (Modal) pattern). Holds the open
state and renders the ng-template[ndDialogPortal] content into a CDK
overlay while open: page scroll is blocked, focus is trapped in the
content and returned on close, and Escape closes. Put it on an
ng-container so it adds no element.
The dialog never renders open on the server; an initial open state takes
effect after hydration.
| NdDialog binding | Type | Default |
|---|---|---|
[defaultOpen]Initial open state when open is not bound. | boolean | false |
[closeOnEscape]Whether Escape closes the dialog. | boolean | true |
[closeOnOverlayClick]Whether a click on [ndDialogOverlay] closes the dialog. | boolean | true |
[(open)]Whether the dialog is open. Two-way bindable with [(open)]. | boolean | false |
NdDialogClose
[ndDialogClose]from @ndop/primitives/dialogButton that closes its NdDialog.
NdDialogContent
[ndDialogContent]role dialogfrom @ndop/primitives/dialogThe dialog box: role="dialog", aria-modal="true", tabindex="-1",
and aria-labelledby / aria-describedby pointing at the title and
description. Focus is trapped inside it while open.
Manages aria-modal, aria-labelledby, aria-describedby.
| Data attribute | Values |
|---|---|
data-state | โ |
NdDialogDescription
[ndDialogDescription]from @ndop/primitives/dialogThe dialog's description; its id describes the content
(aria-describedby). Keeps an id the element already has.
NdDialogOverlay
[ndDialogOverlay]from @ndop/primitives/dialogOptional backdrop rendered behind the content. Hidden from assistive
technology; a click on it closes the dialog unless closeOnOverlayClick
is false.
Manages aria-hidden.
| Data attribute | Values |
|---|---|
data-state | โ |
NdDialogPortal
ng-template[ndDialogPortal]from @ndop/primitives/dialogMarks the ng-template whose content the NdDialog renders while
open.
NdDialogTitle
[ndDialogTitle]from @ndop/primitives/dialogThe dialog's title; its id labels the content (aria-labelledby). Keeps
an id the element already has.
NdDialogTrigger
[ndDialogTrigger]from @ndop/primitives/dialogButton that opens and closes its NdDialog.
Sets aria-haspopup="dialog", aria-expanded, aria-controls (only
while open, since the content doesn't exist when closed) and
data-state.
Manages aria-haspopup, aria-expanded, aria-controls.
| Data attribute | Values |
|---|---|
data-state | โ |