Re: [w3c/webcomponents] Consider functional mixin pattern for form-associated custom elements (#812)

I don't have a lot to add to what @domenic said. The fact that we can write useful mixins in userland is great, and seems like the basis for a good standalone library.

I would emphasize that trying to automatically handle `ElementInternals` in a mixin, while also keeping it available to the concrete class is a little tricky because of the lack of protected. I think you'll always need some shared state besides the instance reference itself (say a public field, a WeakMap, etc.).

A mixin can override `attachInternals`, as ugly as that seems it probably composes better if multiple mixins try to get to internals. Something like this, though there may be a critical flaw in this idea:

```js

const setFormValue = Symbol(FormAssociated.'setFormValue');

export const FormAssociated = (base) => class FormAssociated extends base {

  #internals;
  #internalsRetreived = false;

  constructor() {
    super();
    this.#internals = this.attachInternals();
    // allow another attachInternals() call, from the leaf class, or a mixin
    // that follows this pattern
    this.#internalsRetreived = false;
  }

 attachInternals() {
    if (this.#internalsRetreived) {
      throw new InvalidStateError('ElementInternals already requested');
    }
    this.#internalsRetreived = true;
    return this.#internals;
  }

  [setFormValue](value, state) {
    this.#internals.setFormValue(value, state);
  }
}
FormAssociated.setFormValue = setFormValue;
```

```js
import {FormAssociated} from 'form-associated';

class MyControl = FormAssociated(HTMLElement) {
  #internals;

  constructor() {
    // maybe for AOM, pseudo-classes, etc.
    this.#internals = this.attachInternals();
  }

  formResetCallback() {
    this.value = '';
    this[FormAssociated.setFormValue](this.value);
  }
}
```

-- 
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#issuecomment-490603707

Received on Wednesday, 8 May 2019 18:43:30 UTC