Varendo

Dialog

Native-first modal semantics, focus containment/return and escape policy.

FamilyfeedbackLicenseApache-2.0
StandaloneAvailable

Use the web element directly without the semantic runtime.

Semantic bindingAvailable

A registered presentation adapter can bind this component to host-owned meaning and state.

Automatic adaptationNo standard recipe

The standard recipe resolver does not select this component automatically.

Import and live example

One replayable modal archive confirmation with a host-owned trigger and action.

Interactive preview requires JavaScript.

View the complete example source
import {registerAeliqoElements} from "@varendo/web";
import {
  AeliqoAlertElement,
  AeliqoDialogElement,
  AeliqoDrawerElement,
  AeliqoEmptyStateElement,
  AeliqoPopoverElement,
  AeliqoProgressElement,
  AeliqoSkeletonElement,
  AeliqoToastElement,
  AeliqoTooltipElement,
} from "@varendo/web/feedback";



registerAeliqoElements();

const host = document.querySelector<HTMLElement>("#aeliqo-example") ?? (() => {
  const created = document.createElement("div");
  created.id = "aeliqo-example";
  (document.body ?? document.documentElement).append(created);
  return created;
})();

function createCatalogRoot(container: HTMLElement): HTMLElement {
  const root = document.createElement("div");
  root.dataset.catalogSourceRoot = "true";
  root.style.display = "grid";
  root.style.gap = "12px";
  container.append(root);
  return root;
}

function createCatalogElement<T extends HTMLElement>(tagName: string, container: HTMLElement): T {
  const element = document.createElement(tagName) as T;
  element.setAttribute("data-aeliqo-theme", "light");
  container.append(element);
  return element;
}

function appendSlottedText(root: HTMLElement, slot: string, textContent: string): void {
  const content = document.createElement("span");
  content.slot = slot;
  content.textContent = textContent;
  root.append(content);
}

const root = createCatalogRoot(host);
(((root) => {
		const element = createCatalogElement<AeliqoDialogElement>("aeliqo-dialog", root);
		element.heading = "Confirm archive";
		element.open = false;
		element.modal = true;
		element.closeOnEscape = true;
		const trigger = document.createElement("button");
		trigger.type = "button";
		trigger.textContent = "Open confirmation";
		trigger.addEventListener("click", () => {
			element.open = true;
		});
		const close = async (): Promise<void> => {
			element.open = false;
			await element.updateComplete;
			trigger.focus();
		};
		const action = document.createElement("button");
		action.type = "button";
		action.textContent = "Archive report";
		action.addEventListener("click", () => void close());
		element.append(action);
		element.addEventListener("aeliqo-dialog-close", () => void close());
		root.append(trigger);
	}))(root);

Purpose

A modal dialog that contains focus while open. closeOnEscape controls Escape dismissal; the close button always emits a close request. The host owns the action inside.

When to use it

When to use a different component

Properties and defaults

The host decides when to open and what the slotted action means; the dialog only owns focus and dismissal mechanics.

Properties, ownership, and initial values
PropertyUse and ownershipDeclared typeInitial value
openControls whether the overlay or expandable surface is currently open.booleanfalse
headingProvides the visible overlay or feedback heading and its accessible label.string'Dialog'
modalChooses modal focus containment and background interaction behavior.booleantrue
closeOnEscapeEnables or disables close on escape as explicit host-controlled state.booleantrue

Events

Events, payloads, timing, and application responsibilities
EventPayloadEmittedApplication responsibility
aeliqo-dialog-closeThe close reason supplied by the dialog.After Escape, a close control, or an allowed dismissal.Set open to false and restore focus to the opener.

Events cross the component boundary as user proposals. Validate their detail and current authority before applying a business effect.

Listen for aeliqo-dialog-close

TypeScript example
const element = document.querySelector('aeliqo-dialog');<p>element?.addEventListener('aeliqo-dialog-close', (event) => {
  const proposal = (event as CustomEvent<unknown>).detail;
  // Validate the proposal, update host state, then assign controlled properties.
  applyProposal(proposal);
});

States and failure handling

Relevant states:

Expected result: The modal announces its heading, traps focus while open, and emits a cancellable close request.

Keyboard, focus, and accessibility

Keyboard behavior:

Exposed semantics:

Responsive behavior

Keep modal actions reachable within the viewport. Let long content scroll without covering the close or confirmation controls.

Style hooks

Generated TypeScript declaration

View generated declaration
export declare class AeliqoDialogElement extends AeliqoFoundationElement {
    static readonly properties: {
        open: {
            type: BooleanConstructor;
            reflect: boolean;
        };
        heading: {
            type: StringConstructor;
        };
        modal: {
            type: BooleanConstructor;
        };
        closeOnEscape: {
            type: BooleanConstructor;
            attribute: string;
        };
    };
    static readonly styles: import("lit").CSSResult[];
    open: boolean;
    heading: string;
    modal: boolean;
    closeOnEscape: boolean;
    private readonly overlayFocus;
    private shownModal;
    protected willUpdate(changed: Map<string, unknown>): void;
    protected updated(changed: Map<string, unknown>): void;
    private openDialog;
    private syncDialogMode;
    private showDialog;
    private closeDialog;
    private close;
    private cancel;
    private keydown;
    protected render(): import("lit").TemplateResult<1>;
}

Version

This page documents the Varendo 0.6 component contract.