- From: Jan Miksovsky <notifications@github.com>
- Date: Tue, 07 May 2019 14:22:39 -0700
- To: w3c/webcomponents <webcomponents@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <w3c/webcomponents/issues/812@github.com>
Rather than incorporating support for forms into all custom elements, I was wondering whether it’s worth exploring a functional mixin pattern for defining form support. This would keep form features from affecting components that don’t need those features.
In this approach, form participation would be defined through a mixin function that can be applied a base class (either `HTMLElement`, or a class deriving from it) to return a new form-capable class. JavaScript pseudo-code for such a mixin would look like:
```js
function FormAssociatedMixin(Base) {
return FormAssociated extends Base {
// … Form-related methods/properties defined here, become part of resulting class …
static get formAssociated() { return true; }
};
}
```
Authors creating custom elements with forms in mind would then apply this `FormAssociatedMixin` to the base class they extend. The sample custom element from the [Form Participation Explainer](https://docs.google.com/document/d/1JO8puctCSpW-ZYGU8lF-h4FWRIDQNDVexzHoOQ2iQmY/edit?pli=1#) might look like:
```js
class MyControl extends FormAssociatedMixin(HTMLElement) {
formAssociatedCallback() { … }
formDisabledCallback() { … }
formStateRestoreCallback(state, mode) { … }
}
customElements.define('my-control', MyControl);
```
If someone wants form support, they extend `FormAssociatedMixin(HTMLElement)`; if they don’t intend their component to be used with forms, they extend `HTMLElement` as they do now.
Among other things, this could keep `ElementInternals` clean for components that don’t support forms. The form-related properties and methods currently planned for `ElementInternals` could become private properties and methods:
```js
function FormAssociatedMixin(Base) {
return FormAssociated extends Base {
static get formAssociated() { return true; }
#setFormValue(value, state) { … }
#checkValidity() { … }
#reportValidity() { … }
…
};
}
```
And then invoked directly on `this`, rather than on `ElementInternals`:
```js
class MyControl extends FormAssociatedMixin(HTMLElement) {
…
formResetCallback() {
this.value = '';
this.#setFormValue('');
}
…
}
```
I make this suggestion only because the Elix project I lead has gotten so much mileage out of the extensive set of functional [mixins](https://component.kitchen/elix/mixins); we’ve defined this way. After several years of creating components, I can say that it’s really nice to keep optional behavior out of base classes, and only bring them into play when needed. I think form participation is a good example of such optional behavior, so perhaps a mixin approach would work well for it.
--
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3c/webcomponents/issues/812
Received on Tuesday, 7 May 2019 21:23:01 UTC