Varendo

RecordEditor

Existing primitive form over a host-owned action with entity revision and explicit save/cancel.

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

An Ada record editor with name and reporting-period fields plus explicit entity revision.

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<AeliqoRecordEditorElement>("aeliqo-record-editor", root);
		element.entity = "person";
		element.entityKey = "string:3:ada";
		element.entityRevision = "person-revision-1";
		const name = document.createElement("aeliqo-text-field") as AeliqoTextFieldElement;
		name.label = "Name";
		name.name = "name";
		name.value = "Ada Lovelace";
		const period = document.createElement("aeliqo-date-range") as AeliqoDateRangeElement;
		period.label = "Review period";
		period.name = "period";
		period.start = "2026-09-01";
		period.end = "2026-09-30";
		element.append(name, period);
	}))(root);

Purpose

RecordEditor wraps slotted fields with a record key, revision, and save/cancel actions. Use it when edits must carry version evidence to a host-owned action.

When to use it

When to use a different component

Properties and defaults

The entity key and revision are required evidence for save/cancel requests; the host authorizes the resulting action.

Properties, ownership, and initial values
PropertyUse and ownershipDeclared typeInitial value
entityNames the catalog entity whose records and identities are displayed.string'record'
entityKeySupplies entity key to the component as application-owned input.string''
entityRevisionIdentifies the entity version so stale state can be detected explicitly.string''
actionIdentifies the registered action proposed by this control. Application code authorizes and executes it.VersionRef | undefinedundefined
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'Edit record'
disabledPrevents user interaction while keeping the control and its current value visible.booleanfalse
invalidMarks the current editor state invalid and blocks a valid save proposal.booleanfalse
saveLabelProvides the visible text for the save control or section.string'Save'
cancelLabelProvides the visible text for the cancel control or section.string'Cancel'

Events

Events, payloads, timing, and application responsibilities
EventPayloadEmittedApplication responsibility
aeliqo-record-editor-saveThe entity key, revision, action reference, and validated draft.After the user requests save from a valid editor.Recheck revision and authority, execute the action, and report the outcome.
aeliqo-record-editor-cancelThe entity key, revision, and current draft context.After the user cancels editing.Keep or discard the draft by application policy and restore focus.

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

Listen for aeliqo-record-editor-save

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

Listen for aeliqo-record-editor-cancel

TypeScript example
const element = document.querySelector('aeliqo-record-editor');</p>
<p>element?.addEventListener('aeliqo-record-editor-cancel', (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 editor validates its fields and emits a versioned save or cancel proposal without persisting it.

Keyboard, focus, and accessibility

Keyboard behavior:

Exposed semantics:

Responsive behavior

Stack fields at narrow widths. Keep the entity identity and revision associated with Save and Cancel.

Style hooks

Generated TypeScript declaration

View generated declaration
export declare class AeliqoRecordEditorElement extends AeliqoCompoundElement {
    static readonly properties: {
        entity: {
            type: StringConstructor;
        };
        entityKey: {
            attribute: string;
            type: StringConstructor;
        };
        entityRevision: {
            attribute: string;
            type: StringConstructor;
        };
        action: {
            attribute: boolean;
        };
        status: {
            type: StringConstructor;
        };
        message: {
            type: StringConstructor;
        };
        title: {
            type: StringConstructor;
        };
        disabled: {
            type: BooleanConstructor;
        };
        invalid: {
            type: BooleanConstructor;
        };
        saveLabel: {
            attribute: string;
            type: StringConstructor;
        };
        cancelLabel: {
            attribute: string;
            type: StringConstructor;
        };
    };
    static readonly styles: import("lit").CSSResult[];
    entity: string;
    entityKey: string;
    entityRevision: string;
    action: VersionRef | undefined;
    status: AeliqoCompoundStatus;
    message: string;
    title: string;
    disabled: boolean;
    invalid: boolean;
    saveLabel: string;
    cancelLabel: string;
    protected render(): import("lit").TemplateResult<1>;
    private readonly save;
    private readonly cancel;
}

Version

This page documents the Varendo 0.6 component contract.