- 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