Re: [w3c/webcomponents] Need a callback for when children changed or parser finished parsing children (#809)

Another reason for desiring a reliable entry point that works no matter the circumstances, is the following one: **a basic star rate component**.

```js
// <star-rate value=1-5>
customElements.define('star-rate', class extends HTMLElement {
  attributeChangedCallback(name, old, value) { this[name] = value; }
  get observedAttributes() { return ['value']; }
  get value() {
    return this.getAttribute('value');
  }
  set value(value) {
    let input = this.querySelector(`input[value="${value}"]`);
    let changed = false;
    if (input && !input.checked)
      input.checked = (changed = true);
    else {
      input = this.querySelector(`input:checked`);
      if (input && input.checked)
        input.checked = !(changed = true);
    }
    if (changed)
      input.dispatchEvent(new CustomEvent('change', {bubbles: true}));
  }
  connectedCallback() {
    this.addEventListener('change', this);
    // ⚠ the following is unpredictable
    // it might work or not
    const {value} = this;
    if (value)
      this.value = value;
  }
  handleEvent(event) { this[`on${event.type}`](event); }
  onchange(event) {
    const {target} = event;
    this.classList.toggle('checked', target.checked);
  }
});
```

This basic custom element would like to simply expose its own input value, and it can be represented on the HTML as such (so it's SSR compatible out of the box)

```html
<star-rate value="3">
  <input type="radio" name="star-rate" value="1">
  <input type="radio" name="star-rate" value="2">
  <input type="radio" name="star-rate" value="3">
  <input type="radio" name="star-rate" value="4">
  <input type="radio" name="star-rate" value="5">
</star-rate>
```

Star rating is one of the most basic and common Web components out there, and while every framework/library would easily provide a way to do exactly what above custom element definition does, the standard way will likely fail because it's unpredictable.

For instance, the [CodePen](https://codepen.io/WebReflection/pen/PvzeOy?editors=0010) version will always work as expected, because the script is executed **after** the layout has been generated.

However, defining the custom element upfront will _likely_ fail in Chrome, will _probably_ fail in Firefox, and won't likely set it up in Safari.

Try this page to find out https://webreflection.github.io/test/star-rate/ and refresh on Firefox to see it works sometimes, and not some other times.

#### This is awkward (to put it gently)

The fact developers don't have an entry point to setup their own components in a reliable way across browsers is one of the reason people still don't go custom elements.

**Every alternative** for a basic star-rate component **would be easier and more reliable**, with Custom Elements we always have this chicken/egg issue if the definition is known upfront or not, and if the DOM is already live or not.

The strongest point of Custom Elements without Shadow DOM is SSR capability and graceful enhancement, and this is also the weakest feature in practice.

_V0_ used to have a `createdCallback` that was indicating the whole upgrade was done, and IIRC it was OK in that case to check for internal children state, but there's nothing in V1 that helps developers avoid shooting their own foot through the platform.

#### The ideal scenario

All it would take to actually solve every issue, is to be notified when the closing tag of a DOM node has been encountered or not.

I honestly don't care if the platform never offered that, it should IMO.

Until we have that information available, frameworks will always win in reliability too, because their declarations land at once, and whenever the component is initialized (mounted/connected/whatever) internal nodes would be already available to perform any sort of action.

- - -

I hope this extra example would clarify more why we need some mechanism to setup components.

Best Regards

-- 
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/809#issuecomment-491581932

Received on Sunday, 12 May 2019 10:03:50 UTC