Dialog
Accessible, unstyled modal Dialog compound primitive.
|
|
| Package |
@vizejs/ui/dialog |
| Maturity |
stable |
| Own the source |
vize lib pull dialog |
| Requires |
context, controllable-state, dismissable-layer, focus-guards, focus-scope, id, inert-outside, portal, scroll-lock |
| Aliases |
modal, alert dialog, sheet foundation, overlay dialog |
| Covers |
WAI-ARIA dialog pattern, Radix Dialog, Reka UI Dialog |
Usage
import { Dialog, DialogRoot, DialogClose, DialogContent, DialogDescription, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger } from "@vizejs/ui/dialog";
Or copy the source into your project with vize lib pull dialog (see Source Distribution).
API
Dialog
Source: src/families/overlays/dialog/dialog-root.vue
Props
| Prop |
Type |
Default |
Description |
id |
string | null |
undefined |
Consumer-owned Dialog base id. null and undefined select a deterministic fallback. |
open |
boolean |
undefined |
Controlled open state. undefined selects uncontrolled behavior. |
defaultOpen |
boolean |
false |
Initial open state for uncontrolled use. |
modal |
boolean |
true |
Whether the dialog makes outside content inert, focus-contained, and scroll-locked. |
Events
| Event |
Payload |
Description |
update:open |
[value: boolean] |
Fired when the Dialog requests a controlled open value. |
open-change |
[value: boolean, previous: boolean, nativeEvent: Event | null] |
Fired after any distinct open-state request. |
exit-complete |
[] |
Fired once when an open dialog has fully closed, including without exit motion. |
Slots
| Slot |
Slot props |
Description |
default |
DialogSlotState |
Compound Dialog children. Receives the current open and modal state. |
Exposed
| Member |
Type |
Description |
close |
— |
|
contentId |
— |
|
descriptionId |
— |
|
id |
— |
|
modal |
— |
|
open |
— |
|
openDialog |
— |
|
setOpen |
— |
|
state |
— |
|
titleId |
— |
|
toggle |
— |
|
DialogRoot
Source: src/families/overlays/dialog/dialog-root.vue
Props
| Prop |
Type |
Default |
Description |
id |
string | null |
undefined |
Consumer-owned Dialog base id. null and undefined select a deterministic fallback. |
open |
boolean |
undefined |
Controlled open state. undefined selects uncontrolled behavior. |
defaultOpen |
boolean |
false |
Initial open state for uncontrolled use. |
modal |
boolean |
true |
Whether the dialog makes outside content inert, focus-contained, and scroll-locked. |
Events
| Event |
Payload |
Description |
update:open |
[value: boolean] |
Fired when the Dialog requests a controlled open value. |
open-change |
[value: boolean, previous: boolean, nativeEvent: Event | null] |
Fired after any distinct open-state request. |
exit-complete |
[] |
Fired once when an open dialog has fully closed, including without exit motion. |
Slots
| Slot |
Slot props |
Description |
default |
DialogSlotState |
Compound Dialog children. Receives the current open and modal state. |
Exposed
| Member |
Type |
Description |
open |
boolean |
Whether the dialog content is currently visible and interactive. |
modal |
boolean |
Whether outside content is inert, focus-contained, and scroll-locked. |
state |
DialogState |
Stable state token for styling and tests. |
id |
string |
Root-owned base id for the compound dialog family. |
contentId |
string |
Id wired from DialogTrigger to DialogContent. |
titleId |
string |
Default id consumed by DialogTitle. |
descriptionId |
string |
Default id consumed by DialogDescription. |
setOpen |
(value: boolean, event?: Event | null) => boolean |
Request a specific open value and report whether it differs. |
openDialog |
(event?: Event | null) => boolean |
Request the open state. |
close |
(event?: Event | null) => boolean |
Request the closed state. |
toggle |
(event?: Event | null) => boolean |
Request the opposite open state. |
DialogClose
Source: src/families/overlays/dialog/dialog-close.vue
Props
| Prop |
Type |
Default |
Description |
type |
"button" | "reset" | "submit" |
"button" |
Native button submission behavior. |
disabled |
boolean |
false |
Remove the close button from activation and sequential keyboard focus. |
ariaLabel |
string |
undefined |
Accessible name when no visible label supplies one. |
Events
| Event |
Payload |
Description |
click |
[nativeEvent: MouseEvent] |
Fired before the button requests closing. Call preventDefault() to keep state unchanged. |
Slots
| Slot |
Slot props |
Description |
default |
DialogSlotState & { readonly disabled: boolean } |
Close button contents. Receives the current Dialog state and button availability. |
Exposed
| Member |
Type |
Description |
element |
HTMLButtonElement | null |
Rendered native button. |
focus |
(options?: FocusOptions) => void |
Move focus to the close button. |
DialogContent
Source: src/families/overlays/dialog/dialog-content.vue
Props
| Prop |
Type |
Default |
Description |
role |
DialogRole |
"dialog" |
Dialog role announced by assistive technology. |
forceMount |
boolean |
false |
Keep content mounted while closed. |
trapFocus |
boolean |
true |
Contain focus inside an open modal dialog. |
autoFocus |
boolean |
true |
Move focus into content when it opens. |
restoreFocus |
boolean |
true |
Restore focus when content closes. |
inertOutside |
boolean |
true |
Make outside content inert while the modal dialog is open. |
lockScroll |
boolean |
true |
Lock document scroll while the modal dialog is open. |
closeOnEscape |
boolean |
true |
Let Escape request dismissal. |
closeOnPointerDownOutside |
boolean |
true |
Let outside pointer-down request dismissal. |
closeOnFocusOutside |
boolean |
true |
Let outside focus movement request dismissal. |
ariaLabel |
string |
undefined |
Accessible name when no visible title supplies one. |
ariaLabelledby |
string | null |
undefined |
Space-separated ids that label the dialog. null omits the default title id. |
ariaDescribedby |
string | null |
undefined |
Space-separated ids that describe the dialog. null omits the default description id. |
Events
| Event |
Payload |
Description |
open-auto-focus |
[event: DialogAutoFocusEvent] |
Fired before automatic entry focus is applied. |
close-auto-focus |
[event: DialogAutoFocusEvent] |
Fired before automatic focus restoration is applied. |
escape-key-down |
[event: DismissableLayerEscapeKeyDownEvent] |
Fired before Escape requests dismissal. |
pointer-down-outside |
[event: DismissableLayerPointerDownOutsideEvent] |
Fired before an outside pointer-down requests dismissal. |
focus-outside |
[event: DismissableLayerFocusOutsideEvent] |
Fired before outside focus movement requests dismissal. |
interact-outside |
[event: DismissableLayerInteractOutsideEvent] |
Fired before outside pointer or focus interaction requests dismissal. |
dismiss |
[event: DismissableLayerDismissEvent] |
Fired after an unprevented dismissal request. |
Slots
| Slot |
Slot props |
Description |
default |
DialogSlotState |
Dialog content. Receives the current open and modal state. |
Exposed
| Member |
Type |
Description |
open |
boolean |
Whether the dialog content is currently visible and interactive. |
modal |
boolean |
Whether outside content is inert, focus-contained, and scroll-locked. |
state |
DialogState |
Stable state token for styling and tests. |
element |
HTMLDivElement | null |
Rendered dialog content element. |
focusFirst |
() => HTMLElement | null |
Focus the first eligible descendant in the dialog content. |
focusContent |
(options?: FocusOptions) => void |
Move focus to the content fallback target. |
DialogDescription
Source: src/families/overlays/dialog/dialog-description.vue
Props
| Prop |
Type |
Default |
Description |
id |
string | null |
undefined |
Consumer-owned description id. null and undefined use the Dialog default. |
as |
PrimitiveAs |
"p" |
Native element, custom element, or component to render. |
Slots
| Slot |
Slot props |
Description |
default |
— |
Visible Dialog description. |
Exposed
| Member |
Type |
Description |
element |
Element | null |
Rendered description element or component instance. |
DialogOverlay
Source: src/families/overlays/dialog/dialog-overlay.vue
Props
| Prop |
Type |
Default |
Description |
forceMount |
boolean |
false |
Keep the overlay mounted while the dialog is closed. |
Slots
| Slot |
Slot props |
Description |
default |
DialogSlotState |
Optional overlay contents. Receives the current Dialog state. |
Exposed
| Member |
Type |
Description |
open |
boolean |
Whether the dialog content is currently visible and interactive. |
modal |
boolean |
Whether outside content is inert, focus-contained, and scroll-locked. |
state |
DialogState |
Stable state token for styling and tests. |
element |
HTMLDivElement | null |
Rendered overlay element. |
DialogPortal
Source: src/families/overlays/dialog/dialog-portal.vue
Props
| Prop |
Type |
Default |
Description |
to |
string | HTMLElement |
"body" |
CSS selector or element the dialog layer is moved into. |
disabled |
boolean |
false |
Render in place instead of teleporting. |
defer |
boolean |
true |
Keep content in place until the target exists, avoiding SSR mismatch. |
forceMount |
boolean |
false |
Keep the portal host mounted while the dialog is closed. |
Slots
| Slot |
Slot props |
Description |
default |
DialogSlotState |
Portalled Dialog layer contents. |
Exposed
| Member |
Type |
Description |
open |
boolean |
Whether the dialog content is currently visible and interactive. |
modal |
boolean |
Whether outside content is inert, focus-contained, and scroll-locked. |
state |
DialogState |
Stable state token for styling and tests. |
present |
boolean |
Whether portal contents are rendered. |
DialogTitle
Source: src/families/overlays/dialog/dialog-title.vue
Props
| Prop |
Type |
Default |
Description |
id |
string | null |
undefined |
Consumer-owned title id. null and undefined use the Dialog default. |
as |
PrimitiveAs |
"h2" |
Native element, custom element, or component to render. |
Slots
| Slot |
Slot props |
Description |
default |
— |
Visible Dialog title. |
Exposed
| Member |
Type |
Description |
element |
Element | null |
Rendered title element or component instance. |
DialogTrigger
Source: src/families/overlays/dialog/dialog-trigger.vue
Props
| Prop |
Type |
Default |
Description |
type |
"button" | "reset" | "submit" |
"button" |
Native button submission behavior. |
disabled |
boolean |
false |
Remove the trigger from activation and sequential keyboard focus. |
ariaLabel |
string |
undefined |
Accessible name when no visible label supplies one. |
Events
| Event |
Payload |
Description |
click |
[nativeEvent: MouseEvent] |
Fired before the trigger requests opening. Call preventDefault() to keep state unchanged. |
Slots
| Slot |
Slot props |
Description |
default |
DialogSlotState & { readonly disabled: boolean } |
Trigger contents. Receives the current Dialog state and trigger availability. |
Exposed
| Member |
Type |
Description |
element |
HTMLButtonElement | null |
Rendered native button. |
focus |
(options?: FocusOptions) => void |
Move focus to the trigger. |
Behavior
| Surface |
Contract |
| State |
DialogRoot supports uncontrolled defaultOpen and controlled open with update:open and open-change events. |
| Trigger |
DialogTrigger renders a native button with aria-haspopup="dialog", aria-expanded, and aria-controls wired to content. |
| Portal |
DialogPortal composes Portal, defers teleport until hydration, and can stay mounted with forceMount. |
| Modal layer |
DialogContent uses dismissable layer, focus scope, focus guards, inert outside, and scroll lock while open and modal. |
| Dismissal |
Escape, outside pointer-down, outside focus, and close button request closing unless the preventable callback was canceled. |
| Labelling |
DialogTitle and DialogDescription consume deterministic ids generated by DialogRoot; content may override ARIA ids or label, and null omits the default id. |
| Focus |
Open content auto-focuses the first eligible descendant or the content fallback and restores focus to the trigger on close. |
| SSR |
Server output is deterministic, renders in place through Portal, and activates document controllers only after mount. |
| Composition |
dialogContext is exported so composed families (Drawer) provide the Dialog contract and reuse trigger, title, description, and close parts. |
| Styling |
JavaScript remains headless. Optional @vizejs/ui/component-dialog.css styles the published data-vize-ui, part, and data-state hooks. |
| Exit |
exit-complete fires once after an open dialog closes, including when CSS motion is absent or reduced. Reopening cancels the pending exit. |
| Component |
State x input |
Outcome |
dialog-root.vue |
controlled or uncontrolled open request |
Publishes open, modal, ids, and data-state; emits update:open and open-change only for distinct requests. |
dialog-trigger.vue |
enabled click |
Emits click, then opens the root when the event was not canceled. |
dialog-portal.vue |
open or forceMount |
Renders Portal; otherwise leaves only a hidden host. |
dialog-overlay.vue |
open or forceMount |
Renders an inert-safe backdrop branch with aria-hidden="true". |
dialog-content.vue |
open modal |
Activates dismissal, focus containment, focus guards, inert outside, and scroll lock. |
dialog-title.vue |
no explicit id |
Uses the root deterministic title id for aria-labelledby. |
dialog-description.vue |
no explicit id |
Uses the root deterministic description id for aria-describedby. |
dialog-close.vue |
enabled click |
Emits click, then closes the root when the event was not canceled. |
| Event |
Dispatch timing and payload |
open-auto-focus |
Before automatic entry focus; payload is a preventable focus-scope event. |
close-auto-focus |
Before automatic focus restoration; payload is a preventable focus-scope event. |
escape-key-down |
Before Escape dismissal; payload is the preventable dismissable-layer Escape event. |
pointer-down-outside |
Before pointer dismissal; payload is the preventable outside pointer event. |
focus-outside |
Before focus dismissal; payload is the preventable outside focus event. |
interact-outside |
Before pointer or focus dismissal; payload is the preventable outside interaction event. |
dismiss |
After an unprevented dismissal request; payload records the reason, target, and native event. |
exit-complete |
After an open dialog's visual exit finishes or is skipped; no payload. Initial closed state does not dispatch it. |