Anil kumar
Anil kumar

Reputation: 1628

Manual slotAssignment doesn't assign contents

class RealTodo extends HTMLElement {
    constructor() {
        super();
        this.attachShadow({ mode: "open", slotAssignment: "manual" });
    }

    connectedCallback() {
        const todoTemplate = document.getElementById("todo_template");
        const todoApp = todoTemplate.content.cloneNode(true);
        this.shadowRoot.appendChild(todoApp);

        const slot = this.shadowRoot.querySelector("slot");
        console.log(slot);

        const li = document.createElement("li");
        li.textContent = "Buy food";
        slot.assign(li);
    }
}
customElements.define("real-todo", RealTodo);
    <template id="todo_template">
    <h1>TODO LIST</h1>
        <ol>
            <slot></slot>
        </ol>
    </template>
  
  <real-todo></real-todo>

I try to assign content inside shadowDom's slot manually. It doesn't assign. No error show. I tested in firefox, chrome.

According to spec slot.assign(nodes); will assign inside slotAssignment: "manual" shadowdom

Upvotes: 1

Views: 388

Answers (1)

Your const li = document.createElement("li"); creates a Node in memory

SLOTElement.assign() only accepts existing DOM Element(s) in first level lightDOM

And you don't want to use append[Child](), because that moves a DOM Element

customElements.define("real-todo", class extends HTMLElement {
  constructor() {
    const button = (props) => Object.assign(document.createElement("button"),props);
    super()
      .attachShadow({mode: "open", slotAssignment: "manual" })
      .append(
        button({ innerHTML:"Food"   , onclick : e => this.showlist("food")   }),
        button({ innerHTML:"Animals", onclick : e => this.showlist("animal") }),
        document.getElementById(this.nodeName).content.cloneNode(true)
      );
  }
  connectedCallback(){
    this.showlist();
  }
  showlist( list=this.getAttribute("list") ){
    this.shadowRoot.querySelector("span").innerHTML = list;
    const li = this.querySelectorAll(`li[list*="${list}"]`);
    this.shadowRoot.querySelector("slot").assign(...li);
  }
});
<template id="REAL-TODO">
    <h1>A <span></span> list</h1>
    <ol>
        <slot></slot>
    </ol>
</template>

<real-todo list="animal">
  <li list="animal">Cat</li>
  <li list="animal">Dog</li>
  <li list="food">Pie</li>
  <li list="food">Beer</li>
  <li list="food">Pizza</li>
  <li list="animal,food">Chicken</li>
  <div>
    <li list="animal,food">Never listed!!</li>
  </div>
</real-todo>

The inspector will show which LI elements are slotted:

Upvotes: 1

Related Questions