[WICG/webcomponents] Manual slot assignment and slot elements in consuming components (Issue #1115)

Schommer475 created an issue (WICG/webcomponents#1115)

I am trying to learn web components and I came to the realization that there are a fair number of use cases (such as any time each slotted item needs to be wrapped) that benefit from manual slot assignment. I found a tutorial on it at [https://knowler.dev/blog/an-intro-to-manual-slot-assignment](https://knowler.dev/blog/an-intro-to-manual-slot-assignment), made some modifications to handle pre-existing children, and ended up with the following custom element:

```
customElements.define("fruit-bowl", class extends HTMLElement {
 constructor() {
  super();
  this.attachShadow({
   mode: "open",
   slotAssignment: "manual",
  });

  const observer = new MutationObserver(() => this.#setContent());
  observer.observe(this, { childList: true });
  this.#setContent();
 }

 #setContent () {
  const { childNodes, shadowRoot } = this;

  shadowRoot.innerHTML = "<ul>";
  const list = shadowRoot.querySelector("ul");

  for (const node of childNodes) {
   if (node.nodeType !== Node.ELEMENT_NODE) continue;

   const listItem = document.createElement("li");
   const slot = document.createElement("slot");
   listItem.append(slot);
   list.append(listItem);
   slot.assign(node);

  }
 }
});
```

However, I want my custom elements to be usable within other custom elements, so I did some testing, creating a simple wrapper element with a slot to populate the fruit-bowl:

```
customElements.define("wrapper-bowl", class extends HTMLElement {
 constructor () {
  super();

  const shadowRoot = this.attachShadow({mode: "open"});

  shadowRoot.innerHTML = `
   <fruit-bowl>
    <slot></slot>
   </fruit-bowl>
  `;
 }
});
```

This did not work as hoped. All children of wrapper-bowl were assigned to the same slot, and since the slot is the child element of fruit-bowl, rather than the elements themselves, only a single list item was created, containing all elements slotted into the wrapper bowl.

I thought that maybe I could fix the problem by getting assignedElements from child nodes that were slots and then manually assigning them. I modified fruit-bowl to do a quick and dirty test, thinking I could try adding observers or listeners if it worked. This is the modified element:

```
customElements.define("fruit-bowl", class extends HTMLElement {
 constructor() {
  super();
  this.attachShadow({
   mode: "open",
   slotAssignment: "manual",
  });

  const observer = new MutationObserver(() => this.#setContent());
  observer.observe(this, { childList: true });
  this.#setContent();
 }

 #setContent () {
  const { childNodes, shadowRoot } = this;

  shadowRoot.innerHTML = "<ul>";
  const list = shadowRoot.querySelector("ul");

  for (const node of childNodes) {
   if (node.nodeType !== Node.ELEMENT_NODE) continue;

   if (node.nodeName === "SLOT") {
    for (const subNode of node.assignedElements({flatten: true})) {
     const listItem = document.createElement("li");
     const slot = document.createElement("slot");
     listItem.append(slot);.
     list.append(listItem);
     slot.assign(subNode);
    }
   } else {
    const listItem = document.createElement("li");
    const slot = document.createElement("slot");
    listItem.append(slot);
    list.append(listItem);
    slot.assign(node);
   }

   
  }
 }
});
```

While the wrapped element now produces the correct number of list items, they do not render the slotted items. I presume because the nodes are already assigned to wrapper-bowl's slot.

While I am confident that I could get around the issue by also using manual slot assignment in wrapper-bowl, I am also confident that it shouldn't be necessary.

I am very new to web components, so if there is something I missed that makes this type of behavior achievable, I apologize and would appreciate being pointed in the right direction.

-- 
Reply to this email directly or view it on GitHub:
https://github.com/WICG/webcomponents/issues/1115
You are receiving this because you are subscribed to this thread.

Message ID: <WICG/webcomponents/issues/1115@github.com>

Received on Friday, 17 October 2025 16:58:22 UTC