Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

leverage getRootNode() for referencing Shadow DOM based parent node reference in JSX output #109

Closed
thescientist13 opened this issue Jan 4, 2023 · 0 comments · Fixed by #131
Assignees
Labels
0.11.0 enhancement Improvement to existing functionality JSX question Further information is requested
Milestone

Comments

@thescientist13
Copy link
Member

thescientist13 commented Jan 4, 2023

Type of Change

  • Enhancement

Summary

So stumbled upon getRootNode() in MDN and this seems this may allow us to make the output of our serialization process a little more compact when handling this references to hosts (components) when calling event handlers or otherwise referencing state that lives at the Custom Element (definition) class level.

⚠️ It should be noted that this will only "work" with Light DOM contents, as without a Shadow Root, getRootNode() will go all the way to the top level document of the page, not the custom element tag.

Details

For example, WCC's JSX let's you write something like this

export default class Counter extends HTMLElement {
  ...
 
  connectedCallback() {
    if (!this.shadowRoot) {
      this.attachShadow({ mode: 'open' });
    }
  }
  
  render() {
    const { count } = this;

    return (
      <div>
        <button onclick={this.count -= 1}> -</button>
        <span>You have clicked <span class="red">{count}</span> times</span>
        <button onclick={this.count += 1}> +</button>
      </div>
    );
  }
}

customElements.define('wcc-counter', Counter)

Which because of how this works, means you would be referencing increment on the <button>, not <wcc-counter>. So get that correct chain of references to the host element (<wcc-counter>) WCC / JSX recursively walks the HTML structure to come up with something like this

export default class Counter extends HTMLElement {
  ...
  
  render() {
      const {count} = this;
      this.shadowRoot.innerHTML = `<div>
        <button onclick="this.parentElement.parentElement.count-=1; this.parentElement.parentElement.render();"> -</button>
        <span>You have clicked ${ undefined.count } times !!!</span>
        <button onclick="this.parentElement.parentElement.count+=1; this.parentElement.parentElement.render();"> +</button>
      </div>`;
  }
}
customElements.define('wcc-counter', Counter);

BUT, it seems like with getRootNode, we could sidestep all that and can just reference this.getRootNode() directly?

export default class Counter extends HTMLElement {
  ...
  
  render() {
      const {count} = this;
      this.shadowRoot.innerHTML = `<div>
        <button onclick="this.getRootNode().count-=1; this.getRootNode().render();"> -</button>
        <span>You have clicked ${count} times !!!</span>
        <button onclick="this.getRootNode().count+=1; this.getRootNode().render();"> +</button>
      </div>`;
  }
}
customElements.define('wcc-counter', Counter);

Presumably this only works with a Shadow Root, as initial testing seemed to indicate that in a Light DOM context, the "root" node was actually the document, or something like that. So should play around with this first in the browser a bit at least just to get a feel for it.

@thescientist13 thescientist13 added question Further information is requested enhancement Improvement to existing functionality JSX labels Jan 4, 2023
@thescientist13 thescientist13 changed the title leverage getRootNode() for more efficient (Shadow DOM based) JSX output leverage getRootNode() for referencing Shadow DOM based parent node reference in JSX output Jan 2, 2024
@thescientist13 thescientist13 self-assigned this Jan 2, 2024
@thescientist13 thescientist13 added this to the 1.0 milestone Jan 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
0.11.0 enhancement Improvement to existing functionality JSX question Further information is requested
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant