Components

Dialog

Source
Headless modal/non-modal dialog primitive — trigger, portal, overlay, and content with full focus and dismiss behavior.

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, focus management, and dismissal — and leaves all markup and styling to you. The styled Modal component in @vyui/kit is built on top of it.

This is a layer of @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

  • modal defaults to true; interaction with content behind the overlay is blocked. Set modal="false" for a non-modal dialog that leaves the rest of the page interactive.
  • open / v-model:open controls visibility; defaultOpen seeds uncontrolled state.
  • DialogContent traps focus while open and restores it to the trigger on close.
  • DialogClose and pressing dismiss/back close the dialog and emit update:open.
  • DialogPortal renders the overlay and content at the root of the tree so they layer above sibling content.

API

DialogRoot

PropDefaultType
defaultOpenfalseboolean | undefined

The open state of the dialog when it is initially rendered. Use when you do not need to control its open state.

modaltrueboolean | undefined

The modality of the dialog. When set to `true`, interaction with outside elements will be disabled.

openundefinedboolean | undefined

The controlled open state of the dialog. Can be bound as `v-model:open`.

EventPayload
update:open[value: boolean]

DialogTrigger

PropDefaultType
as"view"AsTag | Component | undefined

The element or component this component should render as. Can be overwritten by `asChild`.

asChildboolean | undefined

Change the default rendered element for the one passed as a child, merging their props and behavior. Use this when you need a component to render through a child element while keeping the primitive's props and behavior.

DialogContent

PropDefaultType
asAsTag | Component | undefined

The element or component this component should render as. Can be overwritten by `asChild`.

asChildboolean | undefined

Change the default rendered element for the one passed as a child, merging their props and behavior. Use this when you need a component to render through a child element while keeping the primitive's props and behavior.

backdropClassstring | undefined

Class merged onto the full-screen backdrop wrapper (the `OverlayBackdrop` that centers the panel). Core ships no dim or animation of its own — the styled layer passes the dim colour + a marker class here so the backdrop fades in step with the panel. The element carries the Presence lifecycle classes (`ui-entering` / `ui-leaving` / `ui-open` / `ui-closed`) and the `bindanimation*` hooks, so the styled layer's keyframes (keyed off those classes) drive the Presence lifecycle just like the panel's.

backdropStyleRecord<string, any> | undefined

Style applied to the full-screen backdrop wrapper. No defaults — pass `backgroundColor`, alignment, etc. here for the modal dim/centering.

debugLogboolean | undefined

Verbose lifecycle tracing — forwarded to both backdrop + panel Presence.

forceMountboolean | undefined

Used to force mounting when more control is needed. Useful when controlling animation with Vue animation libraries.

transitionboolean | undefined

Opt the backdrop / panel into the animating-state classes (`ui-entering` / `ui-leaving` / `ui-animating` alongside the static `ui-open` / `ui-closed` pair). Off by default so callers that don't style transitions don't get extra classes; on for any caller wiring up keyframes.

EventPayload
openAutoFocus[event: any]
closeAutoFocus[event: any]
interactOutside[event: DismissableLayerEvent]
pointerDownOutside[event: DismissableLayerEvent]
escapeKeyDown[event: DismissableLayerEvent]

DialogOverlay

PropDefaultType
asAsTag | Component | undefined

The element or component this component should render as. Can be overwritten by `asChild`.

asChildboolean | undefined

Change the default rendered element for the one passed as a child, merging their props and behavior. Use this when you need a component to render through a child element while keeping the primitive's props and behavior.

forceMountboolean | undefined

Used to force mounting when more control is needed. Useful when controlling animation with Vue animation libraries.

DialogClose

PropDefaultType
as"view"AsTag | Component | undefined

The element or component this component should render as. Can be overwritten by `asChild`.

asChildboolean | undefined

Change the default rendered element for the one passed as a child, merging their props and behavior. Use this when you need a component to render through a child element while keeping the primitive's props and behavior.

Accessibility

  • DialogContent exposes native Lynx dialog semantics and manages a focus trap; always include a DialogTitle so the dialog is announced.
  • DialogDescription is associated with the content as its accessible description.
  • Closing returns focus to the element that opened the dialog.
  • Modal — the styled @vyui/kit dialog built on this primitive.
  • AlertDialog — a focus-trapping confirmation variant with required action/cancel.
  • Sheet — a drag-snappable bottom sheet alternative.