Lit-element: Render to ShadowDOM and LightDOM

Created on 19 Feb 2019  路  3Comments  路  Source: Polymer/lit-element

When I started using the pre-release of Lit-Html, I had already developed my own base class for native web components. It ended up being very similar to what is now provided by Lit-Element. The main difference is that I wrote my base class to be agnostic of how rendering was performed.

Particularly for application container elements (not so much reusable control elements), I often find I want to render into both ShadowDOM (so I can get encapsulated styles for the sub-tree), as well as LightDOM (to keep part of my application sub-tree is the normal Document scope). This seems like a similar objective to what some other people have been asking for with regard to a pseudo slot for elements without a ShadowDOM.

Right now I am able to do this using Lit-Html directly in my custom base class by rendering to both a ShadowRoot target, and the element's LightDOM. As demonstrated below, on first render, I render the ShadowRoot include any slots, and then I also control rendering children in the LightDOM.

  renderCallback() {
    super.renderCallback();

    if (!this.isRendered()) {
      render(html`
        <style>${this.styles}</style>
        <div id="view">
          <a id="logo" href="#!/auth/home">
            <img src="images/logo.png" alt="Logo" />
          </a>
          <slot></slot>
        </div>
      `, this.shadowRoot);
    }

    render(html`
      ${this.state.view === 'home' ? html`<fsc-auth-home></fsc-auth-home>` : null }
      ${this.state.view === 'login' ? html`<fsc-auth-login></fsc-auth-login>` : null }
      ${this.state.view === 'register' ? html`<fsc-auth-register></fsc-auth-register>` : null }
      ${this.state.view === 'reset' ? html`<fsc-auth-reset></fsc-auth-reset>` : null }
    `, this);
  }

I want to migrate my application and reusable controls development to use Lit-Element as my base class, but I can't see how you can accomplish this. Lit-Element seems to be designed to only render to a single target, either the ShadowRoot or the element LightDOM (not both).

Can anyone provide an example of how you can render to both with Lit-Element?

Most helpful comment

You can render to light DOM in addition to Shadow DOM by implementing the firstUpdated method. Here's an example:

https://stackblitz.com/edit/lit-element-demo-c6u7gf?file=src/my-element.js

All 3 comments

This outlines a super simple example, but renders on both side of the boundary: https://medium.com/@westbrook/decorator-pattern-plus-816eefc89824

I'd worry in your context that you were conflating responsibilities here. In that you're preventing the ability to ever write into the Light DOM from the outside render(template, this) will always replace all of the Light DOM. Further, that does not seem like the experience that an implementor would be expecting when applying a web component in their application. Maybe this is all internal, or this is super documented and those things don't matter, or maybe I just don't understand the use case, but I'd be careful allowing an element to manage what amount to the child and parent scope at the same time.

You can render to light DOM in addition to Shadow DOM by implementing the firstUpdated method. Here's an example:

https://stackblitz.com/edit/lit-element-demo-c6u7gf?file=src/my-element.js

make something like this sense in the official documentation? I would think so? if yes pls let me know and I would prepare a PR :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ghost picture ghost  路  3Comments

erikkroes picture erikkroes  路  3Comments

antonioaltamura picture antonioaltamura  路  4Comments

quentin29200 picture quentin29200  路  3Comments

minht11 picture minht11  路  4Comments