- From: Schommer475 <notifications@github.com>
- Date: Fri, 17 Oct 2025 09:58:18 -0700
- To: WICG/webcomponents <webcomponents@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <WICG/webcomponents/issues/1115@github.com>
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