Varendo

Form

Native submission semantics, draft validation, error summary and explicit host action; rerender never submits.

FamilyinputLicenseApache-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 adaptationStandard recipe

A standard recipe can select this component when its task, bindings, data, and policy are eligible.

Import and live example

One host-owned form containing a required filter and submit button.

Interactive preview requires JavaScript.

View the complete example source
import {registerAeliqoElements} from "@varendo/web";
import {
  AeliqoCheckboxElement,
  AeliqoComboboxElement,
  AeliqoDateFieldElement,
  AeliqoDateRangeElement,
  AeliqoFieldGroupElement,
  AeliqoFileInputElement,
  AeliqoFormElement,
  AeliqoNumberFieldElement,
  AeliqoRadioGroupElement,
  AeliqoSearchFieldElement,
  AeliqoSelectElement,
  AeliqoSliderElement,
  AeliqoSwitchElement,
  AeliqoTextAreaElement,
  AeliqoTextFieldElement,
  type AeliqoOption,
} from "@varendo/web/inputs";

const options: readonly AeliqoOption[] = [
  {value: "ada", label: "Ada Lovelace", description: "Research"},
  {value: "grace", label: "Grace Hopper", description: "Product"},
  {value: "lin", label: "Lin Chen", 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 form = createCatalogElement<AeliqoFormElement>("aeliqo-form", root);
		form.label = "Report filters";
		const field = document.createElement("aeliqo-text-field") as AeliqoTextFieldElement;
		field.label = "Required filter";
		field.name = "filter";
		field.required = true;
		const submit = document.createElement("button");
		submit.type = "submit";
		submit.textContent = "Apply";
		form.append(field, submit);
	}))(root);

Purpose

A native form boundary around slotted controls that emits a submit proposal after constraint validation. Invalid submits focus an error summary; a rerender never submits.

When to use it

When to use a different component

Properties and defaults

The form coordinates validation and emits a submit proposal; persistence and navigation remain with the host.

Properties, ownership, and initial values
PropertyUse and ownershipDeclared typeInitial value
labelProvides the visible label and accessible name for the component.string''
noValidateDisables native form validation when application validation owns the complete flow.booleanfalse

Events

Events, payloads, timing, and application responsibilities
EventPayloadEmittedApplication responsibility
aeliqo-form-submit{source, submitter}After a valid native submit request.Authorize the command, execute it through the action boundary, and update pending state.
aeliqo-form-resetNo detail payload.After the user requests a form reset.Restore the application-owned initial draft and validation state.
aeliqo-validation{source, state, message}When validation enters pending, valid, or invalid state.Merge the result with application validation and display authoritative errors.

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

Listen for aeliqo-form-submit

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

Listen for aeliqo-form-reset

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

Listen for aeliqo-validation

TypeScript example
const element = document.querySelector('aeliqo-form');</p>
<p>element?.addEventListener('aeliqo-validation', (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 form reports validity and emits a cancellable submit/reset request without executing business effects.

Form data and constraint validation follow native disabled-fieldset rules. Controls in the first legend of a disabled fieldset remain enabled unless another disabled state applies; controls in later legends or the fieldset body are excluded. A valid, enabled DateRange contributes both named endpoints to the form data.

Keyboard, focus, and accessibility

Keyboard behavior:

An invalid submit focuses the rendered error summary after a slotted submit button click, Enter in a field, or requestSubmit().

Exposed semantics:

Responsive behavior

Stack fields and submit actions on narrow screens. Preserve DOM order and keep validation messages beside their fields.

Style hooks

Generated TypeScript declaration

View generated declaration
export declare class AeliqoFormElement extends AeliqoFoundationElement {
    static readonly properties: {
        label: {
            type: StringConstructor;
        };
        noValidate: {
            attribute: string;
            type: BooleanConstructor;
        };
    };
    label: string;
    noValidate: boolean;
    private summary;
    connectedCallback(): void;
    disconnectedCallback(): void;
    /** Request native constraint validation and dispatch the typed host event. */
    requestSubmit(submitter?: HTMLElement): void;
    reset(): void;
    checkValidity(): boolean;
    reportValidity(): boolean;
    formData(): FormData | undefined;
    private appendSlottedNativeValues;
    private isSuccessfulNativeControl;
    private isCheckedInput;
    private isSubmitOnlyControl;
    private appendSlottedFieldValues;
    private fieldName;
    protected render(): import("lit").TemplateResult<1>;
    private readonly handleSubmit;
    private emitSubmit;
    private readonly handleSlottedClick;
    private readonly handleSlottedKeyDown;
    private isSlottedEnter;
    private nativeControlOwnsEnter;
    private submitSlotted;
    private focusSummary;
    private defaultSlottedSubmitter;
    private submitterSkipsValidation;
    private readonly handleReset;
    private collectErrors;
    private formControlErrors;
    private formControlError;
    private unownedNativeControlErrors;
    private slottedFieldErrors;
    private fieldLabel;
    private slottedFields;
    private slottedNativeControls;
    private nativeControlFromEvent;
    private eventFormOwner;
    private ownsEvent;
    private resetSlottedNativeControls;
    private resetNativeControl;
    private resetNativeInput;
    private resetNativeSelect;
    private appendNativeControlValue;
    private nativeControlError;
    private nativeForm;
    static readonly styles: import("lit").CSSResult[];
}

Version

This page documents the Varendo 0.6 component contract.