Skip to content

YueDialog API ​

This page describes the frozen public contract. Load the token sheet before the Dialog stylesheet.

ts
import { YueDialog } from '@yue-ui/vue/dialog'
import '@yue-ui/design-tokens/index.css'
import '@yue-ui/vue/dialog.css'

YueDialog ​

Props ​

PropTypeDefaultDescription
modelValuebooleanundefinedControlled open state; when present, internal close requests only notify the parent via update:modelValue
titlestringundefinedBuilt-in heading text, automatically wired to aria-labelledby
descriptionstringundefinedSupporting copy, participates in aria-describedby
variant'default' | 'danger''default'danger promotes the role to alertdialog and turns off Esc and scrim close by default
surface'modal' | 'fullscreen''modal'modal is a centred card over a scrim; fullscreen is a full-viewport surface. Both are modal by default; modality is controlled separately by modeless
size'sm' | 'md' | 'lg' | 'xl''md'Width preset; overridden when width is set
widthstring | numberundefinedExplicit width override; numbers are CSS pixels, still bounded by the viewport safe margin
scrollablebooleanfalsePin header/footer and scroll only the body; otherwise the whole card scrolls
persistentbooleanfalseSuppress every non-button close (Esc + scrim) and keep content mounted
closeOnEscapebooleanDerived from variantAn explicit value always wins; danger defaults to false
closeOnScrimbooleanDerived from variantAn explicit value always wins; danger defaults to false
beforeClose(reason: YueDialogCloseReason) => boolean | Promise<boolean>undefinedGuard before a close is committed; returning false, a Promise resolving false, or rejecting aborts the close
confirmTextstringdialog.confirmBuilt-in confirm button label, falls back to the locale key
cancelTextstringdialog.cancelBuilt-in cancel button label, falls back to the locale key
closeboolean | { ariaLabel?: string }trueIcon-only corner close control; false removes it, an object overrides the accessible name
teleportboolean | string | HTMLElement'body'Mount target for the detached surface; false keeps it in place
triggerYueDialogTriggerundefinedAnchor for the fly-in origin and conditional return focus; an element or a getter returning one
restoreFocusbooleantrueReturn focus only when the close was keyboard- or program-triggered
ariaLabelstringundefinedExplicit accessible name; takes precedence over the auto aria-labelledby
modelessbooleanfalseNon-modal surface: no aria-modal, no background inert, no scroll lock, no focus trap; the page stays interactive
loadingbooleanfalseForce the confirm button into a busy state (spinner + disabled) and suppress Esc and scrim close; entered automatically while beforeClose returns a pending Promise
showConfirmbooleantrueWhether the built-in confirm button renders; false yields a single-action dialog
showCancelbooleantrueWhether the built-in cancel button renders; false yields a single-action dialog
lazybooleanfalseDefer content instantiation until first open, then keep it mounted across closes
classNamesPartial<Record<'overlay' | 'scrim' | 'panel' | 'header' | 'body' | 'footer' | 'close', string>>undefinedClasses merged onto each structural part
stylesPartial<Record<'overlay' | 'scrim' | 'panel' | 'header' | 'body' | 'footer' | 'close', CSSProperties>>undefinedInline styles merged onto each structural part

Controlled versus uncontrolled: when modelValue is present the parent owns the state; when omitted the component maintains internal state.

Events ​

EventPayloadWhen
update:modelValuebooleanControlled open state is requested to change
open—After opening is accepted
close{ reason: YueDialogCloseReason; event?: Event }When a close is requested (before the guard)
confirm—The user triggers the confirm action
closed{ reason: YueDialogCloseReason }After the guard allows the close and state closes
after-open—Enter transition completes
after-close—Leave transition completes; content then unmounts

close.reason is one of confirm, cancel, close-btn, escape, scrim, or programmatic. The close pipeline order is fixed: close → beforeClose → update:modelValue → transition → after-close.

Slots ​

SlotScopeDescription
header{ titleId }Custom heading; bind titleId to the heading element's id
default{ close }Dialog body content
footer{ close, confirm, cancel }Custom action area; supplying this slot fully replaces the built-in confirm/cancel buttons
close-icon—Replaces the built-in close glyph; the button and its accessible name stay intact

When the footer slot is present no built-in buttons render, so no dialog.* locale text is emitted.

Expose ​

MethodReturnPurpose
open()voidOpen the instance
close(reason?)voidClose with the given reason (default programmatic), still routed through beforeClose
updatePosition()voidRecompute the fly-in origin

DOM refs and overlay internals are not exposed.

DOM and attributes ​

  • The component uses inheritAttrs: false.
  • class and style land on the overlay root; remaining attributes fall through to the dialog card root.
  • classNames / styles merge per structural part (overlay/scrim/panel/header/body/footer/close), letting a caller customise one part without replacing the built-in classes.
  • The card defaults to role="dialog" and uses role="alertdialog" for variant="danger".
  • Both scrim and card carry a data-yue-overlay marker so the modal-chain inert computation excludes sibling overlays.

Tokens ​

CategoryTokens
SurfaceReads the Box contract directly: --box-background-dialog, --box-color-dialog, and siblings
Width--dialog-width-sm, --dialog-width-md, --dialog-width-lg, --dialog-width-xl
Geometry--dialog-header-height, --dialog-footer-gap, --dialog-section-padding
Motion--dialog-duration-enter, --dialog-duration-exit, --dialog-ease
Layer--layer-modal (the level the scrim and card occupy)

Accessibility ​

  • Focus trap: Tab wraps inside the card, and the background is set inert per the modal chain without blocking sibling teleported overlays.
  • Initial focus lands on the tabindex="-1" card container so assistive tech reads the name and description first.
  • Conditional return focus on close: keyboard- or program-triggered closes return to the anchor; a scrim click does not steal focus.
  • Escape is protected by IME isComposing; with several instances only the topmost responds.
  • Reduced motion removes enter/leave animation, and forced colors restore boundaries and focus visibility with system colors.

Limitations ​

Dialog does not implement an imperative open() factory, back-button interception, dragging, resizing, or a built-in multi-layer notification stack. Domain copy beyond confirm/cancel is supplied by the consumer through the footer slot or confirmText/cancelText.

Breaking changes ​

This is a new component. The API is frozen before implementation; changes require a spec amendment.