SearchResults
Query state, collection, scoped result count and details with stale-result protection.
Use the web element directly without the semantic runtime.
Use this component directly or compose it in application code.
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#
- A query drives a result list, a scoped count, and an optional detail pane.
- Query and result revisions can diverge, so stale results need labeling.
- Selection must stay an identity request for a supplied row.
- The host owns running the search; the component reflects query state.
When to use a different component#
- Use RecordList when query revisions and stale handling are unnecessary.
- Use Explorer when filtering and browsing matter more than a query string.
- Use SearchField alone for query entry without a managed result view.
Properties and defaults#
Query and result revisions expose stale results explicitly; selection remains an identity request.
| Property | Use and ownership | Declared type | Initial value |
|---|---|---|---|
detailRecord | Supplies detail record to the component as application-owned input. | AeliqoDataRecord | undefined | undefined |
detailFields | Supplies the bounded ordered detail fields collection used by this component. | readonly AeliqoDataColumn[] | [] |
query | Supplies the current search or combobox query independently from a committed selection. | string | '' |
queryRevision | Identifies the query version so stale state can be detected explicitly. | string | '' |
resultRevision | Identifies the result version so stale state can be detected explicitly. | string | '' |
rows | Supplies the bounded records to render. The component never fetches or widens this set. | readonly AeliqoDataRecord[] | [] |
columns | Defines ordered visible fields, labels, formatting, alignment, and supported column interactions. | readonly AeliqoDataColumn[] | [] |
identity | Lists stable identity fields used for selection, detail targeting, and state transfer. | readonly string[] | [] |
result | Supplies the Result reference that binds displayed data to its query and scope evidence. | ResultRef | undefined | undefined |
scope | Supplies the visible authorization and population scope associated with the displayed value or rows. | AeliqoDataScope | undefined | undefined |
selectedKey | Controls the current record selection by stable encoded identity. | string | '' |
entity | Names the catalog entity whose records and identities are displayed. | string | 'result' |
status | Supplies the explicit ready, loading, empty, partial, stale, or error state. | AeliqoCompoundStatus | 'ready' |
message | Provides the user-facing status, error, or recovery message. | string | '' |
title | Provides the visible title for the current data or compound surface. | string | 'Search results' |
count | Provides the result count shown to the user. It must match the associated result revision and scope. | number | undefined | undefined |
Events#
| Event | Payload | Emitted | Application responsibility |
|---|---|---|---|
aeliqo-search-results-selection | The 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
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:
- ready
- stale
- empty
- loading
- partial
- error
Expected result: The result window labels stale revisions and emits selection requests only for supplied rows.
Keyboard, focus, and accessibility#
Keyboard behavior:
- Tab
- Enter
- Space
- focus follows stable identity
Exposed semantics:
- aria-label
- role
- section
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#
- Shadow parts:
detail,header,query,root,scope,status - Varendo design tokens referenced: none referenced directly by this class lineage.
Related components#
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.
