Dialog
Overview
Dialog is a headless @vyui/core primitive for an overlay window layered above the page. It ships behavior only: open/close state, portalling, overlay, and dismissal, and it leaves all markup and styling to you. The styled Modal component in @vyui/kit is built on top of it.
@vyui/core. If you want a drop-in styled dialog, reach for VyModal in @vyui/kit instead and only compose these primitives when you need full control.Anatomy
<DialogRoot>
<DialogTrigger />
<DialogPortal>
<DialogOverlay />
<DialogContent>
<DialogTitle />
<DialogDescription />
<DialogClose />
</DialogContent>
</DialogPortal>
</DialogRoot>
Usage
<script setup lang="ts">
import {
DialogClose,
DialogContent,
DialogDescription,
DialogOverlay,
DialogPortal,
DialogRoot,
DialogTitle,
DialogTrigger,
} from '@vyui/core'
const open = ref(false)
</script>
<template>
<DialogRoot v-model:open="open">
<DialogTrigger>
<text>Open dialog</text>
</DialogTrigger>
<DialogPortal>
<DialogOverlay />
<DialogContent>
<DialogTitle>
<text>Confirm changes</text>
</DialogTitle>
<DialogDescription>
<text>This updates your workspace settings.</text>
</DialogDescription>
<DialogClose>
<text>Close</text>
</DialogClose>
</DialogContent>
</DialogPortal>
</DialogRoot>
</template>
Features and behavior
modaldefaults totrue; interaction with content behind the overlay is blocked and assistive tech is confined to the dialog. Setmodal="false"for a non-modal dialog that leaves the rest of the page interactive and reachable.open/v-model:opencontrols visibility;defaultOpenseeds uncontrolled state.DialogContenttraps focus while open and restores it to the trigger on close.DialogCloseand pressing dismiss/back close the dialog and emitupdate:open.DialogPortalrenders the overlay and content at the root of the tree so they layer above sibling content.
API
DialogRoot
| Prop | Default | Type |
|---|---|---|
defaultOpen | false | boolean | undefinedThe open state of the dialog when it is initially rendered. Use when you do not need to control its open state. |
modal | true | boolean | undefinedThe modality of the dialog. When `true`, `DialogOverlay` paints its tap-blocking backdrop and the content confines assistive tech via `exclusiveFocus`. |
open | undefined | boolean | undefinedThe controlled open state of the dialog. Can be bound as `v-model:open`. |
| Event | Payload |
|---|---|
update:open | [value: boolean] |
DialogTrigger
| Prop | Default | Type |
|---|---|---|
as | "view" | AsTag | Component | undefinedThe element or component this component should render as. Can be overwritten by `asChild`. |
asChild | — | boolean | undefinedRender through the passed child element instead of the default one, merging their props and behavior while keeping the primitive's. |
DialogContent
| Prop | Default | Type |
|---|---|---|
as | — | AsTag | Component | undefinedThe element or component this component should render as. Can be overwritten by `asChild`. |
asChild | — | boolean | undefinedRender through the passed child element instead of the default one, merging their props and behavior while keeping the primitive's. |
backdropClass | — | string | undefinedClass merged onto the full-screen backdrop wrapper (the `OverlayBackdrop` that centers the panel). Core ships no dim or animation of its own; the element carries the Presence lifecycle classes and `bindanimation*` hooks, so the styled layer's keyframes drive the lifecycle just like the panel's. |
backdropStyle | — | Record<string, any> | undefinedStyle applied to the full-screen backdrop wrapper. No defaults — pass `backgroundColor`, alignment, etc. here for the modal dim/centering. |
debugLog | — | boolean | undefinedVerbose lifecycle tracing — forwarded to both backdrop + panel Presence. |
transition | — | boolean | undefinedOpt the backdrop / panel into the animating-state classes (`ui-entering` / `ui-leaving` / `ui-animating` alongside `ui-open` / `ui-closed`). Off for callers that don't style transitions. |
| Event | Payload |
|---|---|
interactOutside | [event: DismissableLayerEvent] |
pointerDownOutside | [event: DismissableLayerEvent] |
DialogOverlay
| Prop | Default | Type |
|---|---|---|
as | — | AsTag | Component | undefinedThe element or component this component should render as. Can be overwritten by `asChild`. |
asChild | — | boolean | undefinedRender through the passed child element instead of the default one, merging their props and behavior while keeping the primitive's. |
DialogClose
| Prop | Default | Type |
|---|---|---|
as | "view" | AsTag | Component | undefinedThe element or component this component should render as. Can be overwritten by `asChild`. |
asChild | — | boolean | undefinedRender through the passed child element instead of the default one, merging their props and behavior while keeping the primitive's. |
Accessibility
DialogContentexposes native Lynx dialog semantics; always include aDialogTitleso the dialog is announced.DialogDescriptionis associated with the content as its accessible description.- Lynx has no DOM focus model, so the primitive does not trap focus or restore it to the trigger on close.
Related components
Modalis the styled@vyui/kitdialog built on this primitive.AlertDialogis this primitive withrole="alertdialog"preset — undismissable, with required action/cancel.Sheetis a drag-snappable bottom sheet alternative.