[w3c/webcomponents] [Shadow] Slotting indirect children (#574)

I am trying to implement a tabs custom element and had to realise that it is probably not possible to implement what I want to do. Let's start with the markup I would like to use:

```html
<my-tabs>
 <my-tab>
  <my-tab-title>
   Title 1
  </my-tab-title>
  <my-tab-content>
   Content 1
  </my-tab-content>
 </my-tab>
 <my-tab>
  <my-tab-title>
   Title 2
  </my-tab-title>
  <my-tab-content>
   Content 2
  </my-tab-content>
 </my-tab>
</my-tabs>

```

The composed DOM should look like this:

```html
<my-tabs>
 <ul>
  <li>Title 1</li>
  <li>Title 2</li>
 </ul>
 <article>
  Content 1
 </article>
 <article hidden>
  Content 2
 </article>
</my-tabs>
```

(The titles and contents could still be wrapped with their custom element.)

My first attempt was to attach a shadow to my-tabs and use a named slot for the titles and contents:

```javascript
shadowRoot.innerHTML = `
<slot name="title"><slot>
<slot name="content"><slot>
`;
```

The markup would then have been:

```html
<my-tabs>
 <my-tab>
  <my-tab-title slot="title">
   Title 1
  </my-tab-title>
  <my-tab-content slot="content">
   Content 1
  </my-tab-content>
 </my-tab>
 ...
</my-tabs>

```

This didn't work because it seems that a slot can only render elements which are a direct child of the shadow holder element. I was already surprised about the fact that I had to set the slot attribute (#343), but I thought that I could still work around this by setting the slot attributes with a MutationObserver if I really wanted to. This, however, seems to be a limitation which cannot be worked around.

Next, I tried to implement the tabs component without using any slots by coping/cloning the parts I need in a MutationObserver. I quickly had to realise that this solution is simply not good enough because if the titles/contents contain a stateful element, I cannot just copy the HTML/clone the DOM if the user interacts with the stateful element and changes its internal state.

Unfortunately, it seems like there is not even an imperative API which would allow me to set the slot of an element manually apart from setting the slot attribute. My hope was that assignedSlot might be writeable which would have allowed me to set the slot of the titles/contents without having this direct child limitation. Well, it's readonly.

Did I miss anything?

What is the reason that you cannot slot an indirect child? Is it performance? If the slot attribute is set and the shadow does not contain a slot with this name, couldn't it just check the next parent until it finds a slot with this name?

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

Received on Friday, 23 September 2016 17:59:21 UTC