Vize

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.