Varendo

Menu

Action menu with focus return and keyboard behavior; no layout-generated business actions.

FamilynavigationLicenseApache-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

An open report action menu with one disabled item.

Interactive preview requires JavaScript.

View the complete example source
import {registerAeliqoElements} from "@varendo/web";
import {
  AeliqoBreadcrumbElement,
  AeliqoMenuElement,
  AeliqoPaginationElement,
  AeliqoTabsElement,
  AeliqoTreeNavElement,
  type AeliqoBreadcrumbItem,
  type AeliqoMenuItem,
  type AeliqoTabItem,
  type AeliqoTreeNavNode,
} from "@varendo/web/navigation";

const tabs: readonly AeliqoTabItem[] = [
  {id: "overview", label: "Overview", content: "Overview content"},
  {id: "details", label: "Details", content: "Details content"},
  {id: "history", label: "History", content: "History content", disabled: true},
];
const breadcrumb: readonly AeliqoBreadcrumbItem[] = [
  {id: "home", label: "Home", href: "/"},
  {id: "reports", label: "Reports", href: "/reports"},
  {id: "current", label: "Weekly report", current: true},
];
const menuItems: readonly AeliqoMenuItem[] = [
  {id: "open", label: "Open report"},
  {id: "archive", label: "Archive"},
  {id: "disabled", label: "Unavailable", disabled: true},
];
const treeNodes: readonly AeliqoTreeNavNode[] = [
  {id: "reports", label: "Reports", children: [{id: "weekly", label: "Weekly"}, {id: "monthly", label: "Monthly"}]},
  {id: "settings", label: "Settings", disabled: true},
];

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<AeliqoMenuElement>("aeliqo-menu", root);
		element.items = menuItems;
		element.label = "Report actions";
		element.open = true;
	}))(root);

Purpose

A short list of app-supplied commands with roving keyboard focus. Selecting an item emits its ID; your app performs the action and controls open state.

When to use it

When to use a different component

Properties and defaults

Menu item IDs are stable and action effects remain with the host.

Properties, ownership, and initial values
PropertyUse and ownershipDeclared typeInitial value
itemsSupplies the ordered bounded items with stable IDs and display labels.readonly AeliqoMenuItem[][]
labelProvides the visible label and accessible name for the component.string'Menu'
openControls whether the overlay or expandable surface is currently open.booleanfalse

Events

Events, payloads, timing, and application responsibilities
EventPayloadEmittedApplication responsibility
aeliqo-menu-actionThe selected enabled menu item ID.After Enter, Space, or pointer activation.Authorize the command, perform it, and close or update the menu.

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

Listen for aeliqo-menu-action

TypeScript example
const element = document.querySelector('aeliqo-menu');<p>element?.addEventListener('aeliqo-menu-action', (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 menu manages roving focus and emits only the chosen enabled action.

Keyboard, focus, and accessibility

Keyboard behavior:

Exposed semantics:

Use Home and End to move focus to the first or last enabled command.

Responsive behavior

Keep the menu within the visible viewport and its commands keyboard reachable. Avoid relying on hover to expose actions.

Style hooks

Generated TypeScript declaration

View generated declaration
export declare class AeliqoMenuElement extends AeliqoFoundationElement {
    static readonly properties: {
        items: {
            attribute: boolean;
        };
        label: {
            type: StringConstructor;
        };
        open: {
            type: BooleanConstructor;
            reflect: boolean;
        };
    };
    static readonly styles: import("lit").CSSResult[];
    items: readonly AeliqoMenuItem[];
    label: string;
    open: boolean;
    private returnFocus;
    private stopOutside;
    protected updated(changed: Map<string, unknown>): void;
    disconnectedCallback(): void;
    private close;
    private activate;
    private keydown;
    protected render(): import("lit").TemplateResult<1>;
}

Version

This page documents the Varendo 0.6 component contract.