Varendo

SearchResults

Query state, collection, scoped result count and details with stale-result protection.

FamilycompoundLicenseApache-2.0
StandaloneAvailable

Use the web element directly without the semantic runtime.

Semantic bindingNo built-in binding

Use this component directly or compose it in application code.

Automatic adaptationNo standard recipe

The standard recipe resolver does not select this component automatically.

Import and live example

A research query result with revision metadata and one selected record.

Interactive preview requires JavaScript.

View the complete example source
import {registerAeliqoElements} from "@varendo/web";
import {
  AeliqoBreakdownElement,
  AeliqoComparisonElement,
  AeliqoExplorerElement,
  AeliqoFormFlowElement,
  AeliqoInvestigationElement,
  AeliqoQualityPanelElement,
  AeliqoRecordEditorElement,
  AeliqoSearchResultsElement,
  } from "@varendo/web/compound";

import {AeliqoDateRangeElement, AeliqoTextFieldElement} from "@varendo/web/inputs";
import type {ResultRef, Scalar} from "@varendo/core";
import type {VisualizationBindingContext, VisualizationSpec} from "@varendo/core/visualization";
import type {AeliqoDataColumn, AeliqoDataScope, AeliqoFieldOption} from "@varendo/web/data";
import type {VisualizationDataset} from "@varendo/web/visualization";

const catalogRef: ResultRef = {
  id: "aeliqo-catalog-example",
  revision: "1",
  outputId: "people",
  queryDigest: "catalog-query",
  scopeDigest: "catalog-scope",
};
const catalogRows: readonly Readonly<Record<string, Scalar>>[] = [
  {id: "ada", name: "Ada Lovelace", team: "Research", date: "2026-09-08", amount: 120},
  {id: "lin", name: "Lin Chen", team: "Product", date: "2026-09-09", amount: 96},
  {id: "grace", name: "Grace Hopper", team: "Research", date: "2026-09-10", amount: 144},
];
const catalogColumns: readonly AeliqoDataColumn[] = [
  {key: "id", label: "ID", type: "text", sortable: true},
  {key: "name", label: "Name", type: "text", sortable: true},
  {key: "team", label: "Team", type: "text"},
  {key: "date", label: "Date", type: "date", sortable: true},
  {key: "amount", label: "Amount", type: "integer", align: "end"},
];
const catalogFields: readonly AeliqoFieldOption[] = [
  {id: "name", label: "Name", type: "text"},
  {id: "team", label: "Team", type: "text"},
  {id: "amount", label: "Amount", type: "integer"},
];
const catalogScope: AeliqoDataScope = {loaded: catalogRows.length, filteredTotal: catalogRows.length, populationDigest: catalogRef.scopeDigest, kind: "filtered", label: "Authorized people"};
const catalogVisualizationContext: VisualizationBindingContext = {results: []};
const catalogVisualizationDataset: VisualizationDataset = {result: catalogRef, rows: catalogRows};
const catalogVisualizationSpecs: Readonly<Record<"trend", VisualizationSpec>> = {trend: {version: "1", view: "trend", plot: {version: "1", root: {kind: "unit", mark: "line", result: catalogRef, missing: "gap", encoding: {x: {field: "date", scale: "temporal"}, y: {field: "amount", scale: "linear"}}}}}};

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<AeliqoSearchResultsElement>("aeliqo-search-results", root);
		element.query = "research";
		element.queryRevision = "query-2";
		element.resultRevision = catalogRef.revision;
		element.rows = catalogRows;
		element.columns = catalogColumns;
		element.identity = ["id"];
		element.selectedKey = "string:3:ada";
		element.entity = "person";
		element.result = catalogRef;
		element.scope = catalogScope;
		element.count = catalogRows.length;
		element.detailRecord = catalogRows[0];
		element.detailFields = catalogColumns;
	}))(root);

Purpose

SearchResults binds a query, its result collection, a scoped count, and selected detail. Use it when results can go stale and that must stay visible.

When to use it

When to use a different component

Properties and defaults

Query and result revisions expose stale results explicitly; selection remains an identity request.

Properties, ownership, and initial values
PropertyUse and ownershipDeclared typeInitial value
detailRecordSupplies detail record to the component as application-owned input.AeliqoDataRecord | undefinedundefined
detailFieldsSupplies the bounded ordered detail fields collection used by this component.readonly AeliqoDataColumn[][]
querySupplies the current search or combobox query independently from a committed selection.string''
queryRevisionIdentifies the query version so stale state can be detected explicitly.string''
resultRevisionIdentifies the result version so stale state can be detected explicitly.string''
rowsSupplies the bounded records to render. The component never fetches or widens this set.readonly AeliqoDataRecord[][]
columnsDefines ordered visible fields, labels, formatting, alignment, and supported column interactions.readonly AeliqoDataColumn[][]
identityLists stable identity fields used for selection, detail targeting, and state transfer.readonly string[][]
resultSupplies the Result reference that binds displayed data to its query and scope evidence.ResultRef | undefinedundefined
scopeSupplies the visible authorization and population scope associated with the displayed value or rows.AeliqoDataScope | undefinedundefined
selectedKeyControls the current record selection by stable encoded identity.string''
entityNames the catalog entity whose records and identities are displayed.string'result'
statusSupplies the explicit ready, loading, empty, partial, stale, or error state.AeliqoCompoundStatus'ready'
messageProvides the user-facing status, error, or recovery message.string''
titleProvides the visible title for the current data or compound surface.string'Search results'
countProvides the result count shown to the user. It must match the associated result revision and scope.number | undefinedundefined

Events

Events, payloads, timing, and application responsibilities
EventPayloadEmittedApplication responsibility
aeliqo-search-results-selectionThe selected stable result identity.After a search result is selected.Load authorized detail evidence and update selectedKey.

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

Listen for aeliqo-search-results-selection

TypeScript example
const element = document.querySelector('aeliqo-search-results');<p>element?.addEventListener('aeliqo-search-results-selection', (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 result window labels stale revisions and emits selection requests only for supplied rows.

Keyboard, focus, and accessibility

Keyboard behavior:

Exposed semantics:

Responsive behavior

Keep query and revision state above results when detail moves below them. Show stale status with text as well as tone.

Style hooks

Generated TypeScript declaration

View generated declaration
export declare class AeliqoSearchResultsElement extends AeliqoCompoundElement {
    static readonly styles: import("lit").CSSResult[];
    static readonly properties: {
        detailRecord: {
            attribute: boolean;
        };
        detailFields: {
            attribute: boolean;
        };
        query: {
            type: StringConstructor;
        };
        queryRevision: {
            attribute: string;
            type: StringConstructor;
        };
        resultRevision: {
            attribute: string;
            type: StringConstructor;
        };
        rows: {
            attribute: boolean;
        };
        columns: {
            attribute: boolean;
        };
        identity: {
            attribute: boolean;
        };
        result: {
            attribute: boolean;
        };
        scope: {
            attribute: boolean;
        };
        selectedKey: {
            attribute: string;
            type: StringConstructor;
        };
        entity: {
            type: StringConstructor;
        };
        status: {
            type: StringConstructor;
        };
        message: {
            type: StringConstructor;
        };
        title: {
            type: StringConstructor;
        };
        count: {
            type: NumberConstructor;
        };
    };
    detailRecord: AeliqoDataRecord | undefined;
    detailFields: readonly AeliqoDataColumn[];
    query: string;
    queryRevision: string;
    resultRevision: string;
    rows: readonly AeliqoDataRecord[];
    columns: readonly AeliqoDataColumn[];
    identity: readonly string[];
    result: ResultRef | undefined;
    scope: AeliqoDataScope | undefined;
    selectedKey: string;
    entity: string;
    status: AeliqoCompoundStatus;
    message: string;
    title: string;
    count: number | undefined;
    protected render(): import("lit").TemplateResult<1>;
    private renderResults;
    private renderDetail;
    private readonly forwardSelection;
}

Version

This page documents the Varendo 0.6 component contract.