Varendo

NumberField

Locale-aware editing separates display text from exact numeric value; do not silently round money.

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 adaptationNo standard recipe

The standard recipe resolver does not select this component automatically.

Import and live example

One currency amount field showing a locale-formatted exact value.

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 element = createCatalogElement<AeliqoNumberFieldElement>("aeliqo-number-field", root);
		element.label = "Amount";
		element.name = "amount";
		element.locale = "en-US";
		element.text = "1,234.50";
		element.value = "1234.50";
		element.unit = "USD";
		element.min = "0";
	}))(root);

Purpose

The host can set the exact value as a decimal string. Typing updates the local text draft and emits it with a canonical value only when valid within the declared minimum, maximum, and step; the host decides what to persist.

When to use it

When to use a different component

Properties and defaults

The host owns numeric meaning and validation; text is the draft representation and value is the committed representation.

Properties, ownership, and initial values
PropertyUse and ownershipDeclared typeInitial value
labelProvides the visible label and accessible name for the component.string''
descriptionProvides supporting text associated with the control or value.string''
errorProvides the current validation or operation error associated with the control.string''
requiredMarks the control as required for validation and native accessibility semantics.booleanfalse
disabledPrevents user interaction while keeping the control and its current value visible.booleanfalse
readOnlyKeeps the current value focusable and readable while preventing edits.booleanfalse
nameProvides the stable form or action name used by the host to identify this control.string''
autocompletePasses an autocomplete purpose to the native input so browsers can offer an appropriate saved value.string'off'
localeSelects locale-sensitive formatting and parsing behavior.string'en-US'
validationStateControls the current idle, pending, valid, or invalid validation state.AeliqoValidationState'idle'
validatorRuns host-provided synchronous validation for a proposed input value.AeliqoValidator<T> | undefinedundefined
textProvides trusted plain text content. The component never interprets it as HTML.string''
valueControls the current value. Apply accepted user proposals back to this property.string | undefinedundefined
defaultValueProvides the initial uncontrolled value. Later updates come from component interaction.string''
minSets the lower bound for min.string''
maxSets the upper bound for max.string''
stepSets the permitted numeric or split-position increment.string''
unitProvides the unit label associated with the numeric value.string''

Events

Events, payloads, timing, and application responsibilities
EventPayloadEmittedApplication responsibility
aeliqo-input-change{source, value, composing?}Whenever the user proposes a draft value change.Validate or store the draft and reassign controlled value or checked state.
aeliqo-input-commit{source, value}After explicit commit, blur, or Enter where the control supports it.Accept or reject the committed value and update authoritative form 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-input-change

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

Listen for aeliqo-input-commit

TypeScript example
const element = document.querySelector('aeliqo-number-field');</p>
<p>element?.addEventListener('aeliqo-input-commit', (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-number-field');</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 amount remains precise while the user edits a locale-aware draft.

Changing value or text or replacing validator cancels validation for the previous value and clears its validator-owned error. An independently supplied host error survives the change. Late results after a reset or disconnect are ignored.

Minimum, maximum, and step checks use exact decimal arithmetic. Signed zero, including -0.00, compares equally to 0; its sign and decimal places remain in the value and displayed text.

Keyboard, focus, and accessibility

Keyboard behavior:

Exposed semantics:

Responsive behavior

Leave room for the localized value and unit. Check the editable draft at 200% text so digits are not clipped.

Style hooks

Generated TypeScript declaration

View generated declaration
export declare class AeliqoNumberFieldElement extends AeliqoFieldElement<AeliqoNumberChange> {
    static readonly properties: {
        label: {
            type: StringConstructor;
        };
        description: {
            type: StringConstructor;
        };
        error: {
            type: StringConstructor;
        };
        required: {
            type: BooleanConstructor;
            reflect: boolean;
        };
        disabled: {
            type: BooleanConstructor;
            reflect: boolean;
        };
        readOnly: {
            attribute: string;
            type: BooleanConstructor;
            reflect: boolean;
        };
        name: {
            type: StringConstructor;
            reflect: boolean;
        };
        autocomplete: {
            type: StringConstructor;
        };
        locale: {
            type: StringConstructor;
        };
        validationState: {
            attribute: string;
            type: StringConstructor;
            reflect: boolean;
        };
        validator: {
            attribute: boolean;
        };
        text: {
            type: StringConstructor;
        };
        value: {
            type: StringConstructor;
            reflect: boolean;
        };
        defaultValue: {
            attribute: string;
            type: StringConstructor;
        };
        min: {
            type: StringConstructor;
        };
        max: {
            type: StringConstructor;
        };
        step: {
            type: StringConstructor;
        };
        unit: {
            type: StringConstructor;
        };
    };
    text: string;
    value: string | undefined;
    defaultValue: string;
    min: string;
    max: string;
    step: string;
    unit: string;
    connectedCallback(): void;
    protected willUpdate(changed: Map<PropertyKey, unknown>): void;
    protected updated(): void;
    protected isCurrentValidationValue(value: AeliqoNumberChange): boolean;
    protected resetField(): void;
    private applyDefaultValue;
    protected render(): import("lit").TemplateResult<1>;
    focus(options?: FocusOptions): void;
    private readonly handleInput;
    private readonly handleCommit;
    private numberValue;
    private native;
    private isValid;
    private canonicalBound;
    private syncNative;
    static readonly styles: import("lit").CSSResult[];
}

Version

This page documents the Varendo 0.6 component contract.