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
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);