assignshadow-domslotlit

how to build a slotted hierarchy of lit elements from one JSON data object


i want to build a hierarchy of lit elements - each one in the slot of its parent element - from one JSON data object. e.g. library, books, pages

In my library I want to get the books assigned to a slot, but they appear in the libries shadow dom. the pages are assigned properly.

is there a way to get the books out of the shadowDOM like maybe so:

  library.appendChild(book);
  library.shadowRoot.querySelector("slot[name='books']").assign(book);

thanks in advance

return html`
                            
 <div id="library">
  <slot name="books"></slot>
 </div>

 ${this.items.books.map((book) => html`
  
  <book slot="books">
   <div slot="pages">

   ${book["pages"].map((page) => html`
    <page slot="pages">${page}</page>`
   )}

  </book>`
  
 )}`;

here s my example: lit playground

the pages are assigned to a pages slot in the books <slot name="pages">

the books are not assigned to a books slot in the library

the manually html-coded book is assigned to a books slot in the library, but it is not dynamically rendered


Solution

  • If you want to assign slot manually based on dynamically generated data, you have to enable this option by setting shadowRootOption to slotAssignment to manual

    static shadowRootOptions = {...LitElement.shadowRootOptions, slotAssignment:'manual'};
    

    Then you can render dynamically generated test-book component into host element light DOM like this

    const element = this.items.library.map(
    (book) => html`<test-book slot="books">
       <div slot="pages">${book.book.map(
        (page) => html` <test-page slot="pages">${page.page}</test-page> `
    )}</test-book>`);
    render(element, this);
    

    Finally, you can query all test-book elements, then use the assign() method of the HTMLSlotElement interface to manually set the slot

    const slot = this.shadowRoot.querySelector("slot");
    const testBook = this.querySelectorAll('test-book');
    slot.assign(...testBook);  
    

    Example