Web Components
webc/form-associated
A custom form control is form-associated (formAssociated and attachInternals) and reports its value and validity to the form.
seriousmanualfe-web-components
Why
An <acme-select> whose real input lives in its shadow root is invisible to the surrounding <form>: its value is not submitted, required does nothing, form.reset() skips it, and an outside <label for> cannot reach the inner input, so the field has no accessible name.
Fix
Set static formAssociated = true, call this.internals = this.attachInternals() in the constructor, report the value with this.internals.setFormValue(value) on every change, and validity with this.internals.setValidity({ valueMissing: true }, 'Choose a size', anchor). Implement formResetCallback and formDisabledCallback. A <label for> pointing at the host then labels it, and this.internals.labels lists those labels. ElementInternals is Baseline widely available (MDN). Manual because whether an element is a form control is a design fact the source does not state.
Examples
// bad: the inner input never reaches the form
class AcmeSize extends HTMLElement { /* shadow root with <select> only */ }
// good
class AcmeSize extends HTMLElement {
static formAssociated = true
constructor() { super(); this.internals = this.attachInternals() }
set value(v) { this._value = v; this.internals.setFormValue(v) }
}Sources
Facts
- Id
webc/form-associated- Severity
- serious
- Check
- manual a person reviews it; the report lists it as a checklist
- Applies to
jsxhtml- Taught by the skill
fe-web-componentsWeb components and Lit- Since version
- 0.1.0
Read it in the terminal
npx github:dawidolko/frontend-skills explain webc/form-associated