Varendo

Tabs

Named panels with stable selection; automatic activation only when latency permits.

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

Three report tabs with one disabled history tab and manual activation.

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<AeliqoTabsElement>("aeliqo-tabs", root);
		element.items = tabs;
		element.value = "overview";
		element.activation = "manual";
	}))(root);

Purpose

Switches between named panels with one selected value. activation='manual' waits for Enter or Space when changing panels is expensive.

When to use it

When to use a different component

Properties and defaults

Item IDs and the selected value are stable; manual activation lets the host decide when selection commits.

Properties, ownership, and initial values
PropertyUse and ownershipDeclared typeInitial value
itemsSupplies the ordered bounded items with stable IDs and display labels.readonly AeliqoTabItem[][]
valueControls the current value. Apply accepted user proposals back to this property.string''
defaultValueProvides the initial uncontrolled value. Later updates come from component interaction.string''
activationChooses automatic or manual tab activation. Use manual activation when panel work is not immediate.AeliqoTabsActivation'automatic'
orientationSets the horizontal or vertical orientation and associated keyboard behavior.'horizontal' | 'vertical''horizontal'
idPrefixSupplies id prefix to the component as application-owned input.string'aeliqo-tabs'

Events

Events, payloads, timing, and application responsibilities
EventPayloadEmittedApplication responsibility
aeliqo-tabs-changeThe proposed stable tab ID.After activation according to automatic or manual mode.Load any required panel data and update controlled value.

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

Listen for aeliqo-tabs-change

TypeScript example
const element = document.querySelector('aeliqo-tabs');<p>element?.addEventListener('aeliqo-tabs-change', (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 active panel follows a stable tab ID and emits a cancellable change request.

Keyboard, focus, and accessibility

Keyboard behavior:

Exposed semantics:

Responsive behavior

Keep each tab label distinct at narrow widths. Ensure the selected state and keyboard focus remain visible when the tab row overflows.

Style hooks

Generated TypeScript declaration

View generated declaration
export declare class AeliqoTabsElement extends AeliqoFoundationElement {
    static readonly properties: {
        items: {
            attribute: boolean;
        };
        value: {
            type: StringConstructor;
        };
        defaultValue: {
            type: StringConstructor;
        };
        activation: {
            type: StringConstructor;
        };
        orientation: {
            type: StringConstructor;
        };
        idPrefix: {
            type: StringConstructor;
            attribute: string;
        };
    };
    static readonly styles: import("lit").CSSResult[];
    items: readonly AeliqoTabItem[];
    value: string;
    defaultValue: string;
    activation: AeliqoTabsActivation;
    orientation: 'horizontal' | 'vertical';
    idPrefix: string;
    private internalValue;
    protected willUpdate(changed: Map<string, unknown>): void;
    private get selectedId();
    private setSelected;
    private moveFocus;
    protected render(): import("lit").TemplateResult<1>;
}

Version

This page documents the Varendo 0.6 component contract.