Motivation
Building a form associated custom element requires a lot of common boilerplate:
- Setting
static formAssociated = true
- Attaching ElementInternals
- Setting a default ARIA role
- Calling
internals.setFormValue() when needed
- Representing the element's form value and the element state
- Exposing the value to the element's public API
- Handling
formDisabledCallback()
- Handling
formResetCallback() and formStateRestoreCallback()
Example
A simple-ish FormAssociated() element, with validation, might just forward an input's value to the element's value:
import {FormAssociated, value} from '@lit-labs/form';
class MyFormElement extends FormAssociated(LitElement, {
role: 'textbox'
}) {
@formValue()
accessor value: string = '';
@query()
accessor #input: HTMLInputElement;
render() {
return html`<input .value=${this.value}> @input=${this.#onInput}`;
}
#onInput(e) {
this.value = e.target.value;
}
protected _checkValidity() {
if (this.value.length < 5) {
return {
flags: { tooLong: true },
message: "value is too long",
anchor: this.#input,
};
}
}
}
In this case the FormAssociated mixin would:
- set
static formAssociated = true
- set
internals.role
- call
setFormValue() when value changes
- Implements
formStateRestoreCallback() to reset the value.
How
A FormAssociated() mixin, paired with @internals, @formValue and @formState decorators.
Current Behavior
Desired Behavior
References
Motivation
Building a form associated custom element requires a lot of common boilerplate:
static formAssociated = trueinternals.setFormValue()when neededformDisabledCallback()formResetCallback()andformStateRestoreCallback()Example
A simple-ish
FormAssociated()element, with validation, might just forward an input's value to the element's value:In this case the
FormAssociatedmixin would:static formAssociated = trueinternals.rolesetFormValue()whenvaluechangesformStateRestoreCallback()to reset the value.How
A
FormAssociated()mixin, paired with@internals,@formValueand@formStatedecorators.Current Behavior
Desired Behavior
References