FileInput
Native file selection; host owns upload and validation; no file bytes enter agent by default.
Use the web element directly without the semantic runtime.
A registered presentation adapter can bind this component to host-owned meaning and state.
The standard recipe resolver does not select this component automatically.
Import and live example#
One single CSV evidence input with a two-megabyte host limit.
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<AeliqoFileInputElement>("aeliqo-file-input", root);
element.label = "Evidence file";
element.name = "evidence";
element.accept = ".csv,text/csv";
element.multiple = false;
element.maxFiles = 1;
element.maxBytes = 2e6;
}))(root);
Purpose#
Opens the native file picker and updates its local selected metadata when the selection changes.
maxFiles limits the count and maxBytes limits the combined size; the host owns file bytes, upload,
and server validation.
When to use it#
- People choose local files to attach or upload.
- The form must declare file count or size limits.
- The host needs file names and sizes before deciding to upload.
When to use a different component#
- Use Form when the file selection submits with other fields.
- Use FieldGroup when the picker belongs inside a labelled group.
Properties and defaults#
Only file metadata crosses the component boundary; the host owns upload and persistence.
| Property | Use and ownership | Declared type | Initial value |
|---|---|---|---|
label | Provides the visible label and accessible name for the component. | string | '' |
description | Provides supporting text associated with the control or value. | string | '' |
error | Provides the current validation or operation error associated with the control. | string | '' |
required | Marks the control as required for validation and native accessibility semantics. | boolean | false |
disabled | Prevents user interaction while keeping the control and its current value visible. | boolean | false |
readOnly | Keeps the current value focusable and readable while preventing edits. | boolean | false |
name | Provides the stable form or action name used by the host to identify this control. | string | '' |
autocomplete | Passes an autocomplete purpose to the native input so browsers can offer an appropriate saved value. | string | 'off' |
locale | Selects locale-sensitive formatting and parsing behavior. | string | 'en-US' |
validationState | Controls the current idle, pending, valid, or invalid validation state. | AeliqoValidationState | 'idle' |
validator | Runs host-provided synchronous validation for a proposed input value. | AeliqoValidator<T> | undefined | undefined |
accept | Lists the file types the picker should offer. The host must still validate selected metadata and file content. | string | '' |
multiple | Allows selection of more than one file. | boolean | false |
capture | Hints which device camera should satisfy a file capture request on supporting browsers. | string | '' |
maxFiles | Sets the maximum number of selected files. | number | 0 |
maxBytes | Sets the maximum accepted size for each selected file. The host must enforce the same limit before upload. | number | 0 |
selected | Supplies selected file metadata; application code owns file content and upload state. | readonly AeliqoFileMetadata[] | [] |
Events#
| Event | Payload | Emitted | Application responsibility |
|---|---|---|---|
aeliqo-file-change | {source, files} with file metadata only. | After the native picker selection changes. | Validate metadata, obtain file content from the trusted host path, and own any upload. |
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-file-change
const element = document.querySelector('aeliqo-file-input');<p>element?.addEventListener('aeliqo-file-change', (event) => {
const proposal = (event as CustomEvent<unknown>).detail;
// Validate the proposal, update host state, then assign controlled properties.
applyProposal(proposal);
});Listen for aeliqo-validation
const element = document.querySelector('aeliqo-file-input');</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:
- ready
- disabled
- invalid
- pending
Expected result: The user can choose bounded file metadata without an implicit upload.
Changing selected metadata 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.
Replace the readonly selected metadata array to change the host value.
Mutating the existing array or its entries in place is unsupported and does
not schedule a component update.
maxFiles and maxBytes mark a selected set invalid when its file count or
combined byte size exceeds the configured bound; the metadata event still
reports that selection. They are not upload quotas or server-side validation.
An application must check file content and size again before storing anything.
accept and capture are browser picker hints, not proof of type or origin.
Keyboard, focus, and accessibility#
Keyboard behavior:
- Tab
- Enter
- Space
Exposed semantics:
- aria-describedby
- aria-invalid
- aria-readonly
- input
- li
- role
- ul
Responsive behavior#
Keep file type and size limits in visible helper text. Let long file names wrap instead of moving actions offscreen.
Style hooks#
- Shadow parts:
description,error,field,files,input,label,pending - Varendo design tokens referenced:
--aeliqo-color-muted
Performance limits#
- Public workload controls: `maxFiles` (default 0), `maxBytes` (default 0).
Related components#
Generated TypeScript declaration#
View generated declaration
export declare class AeliqoFileInputElement extends AeliqoFieldElement<readonly AeliqoFileMetadata[]> {
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;
};
accept: {
type: StringConstructor;
};
multiple: {
type: BooleanConstructor;
reflect: boolean;
};
capture: {
type: StringConstructor;
};
maxFiles: {
attribute: string;
type: NumberConstructor;
};
maxBytes: {
attribute: string;
type: NumberConstructor;
};
selected: {
attribute: boolean;
};
};
accept: string;
multiple: boolean;
capture: string;
maxFiles: number;
maxBytes: number;
selected: readonly AeliqoFileMetadata[];
protected updated(): void;
protected isCurrentValidationValue(value: readonly AeliqoFileMetadata[]): boolean;
protected resetField(): void;
protected render(): import("lit").TemplateResult<1>;
focus(options?: FocusOptions): void;
private readonly handleChange;
private native;
private syncNative;
private isValidSelection;
private selectionError;
static readonly styles: import("lit").CSSResult[];
}Version#
This page documents the Varendo 0.6 component contract.
