-
Notifications
You must be signed in to change notification settings - Fork 376
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Shadow] Slotting indirect children #574
Comments
This was done for both performance and semantics reasons. Since each ancestor of a node can have its own shadow tree, we must define the shadow tree to which a node is assigned, and the latter turned out be tricky. At the end, WebKit team at Apple has argued for supporting this feature but we couldn't reach a consensus to do so in v1. |
Is there any chance that this could be changed for v1? The problem with limitation is that there is no acceptable workaround. The only working (but very bad) solution would be to implement something which is very similar to a shadow dom polyfill. Why is it so tricky to find the shadow to which a node is assigned? I would have suggested the following algorithm:
For most of the nodes 1. or 2. applies. These nodes will not be slowed down at all. For the remaining other nodes, it will have to check a few additional ancestors. Do you remember the exact reasons why it didn't make it into the spec? |
Hey guys, what do you think of something like #576? It is more explicit, although it would also mean that some element could arbitrarily throw content into some other element's shadow root. Is that okay? Or does limiting it to shadow root of an ancestor make more sense? |
@trusktr my tabs example would then become: <my-tabs id="tabs">
<my-tab>
<my-tab-title root-host="tabs" slot="title">
Title 1
</my-tab-title>
<my-tab-content root-host="tabs" slot="content">
Content 1
</my-tab-content>
</my-tab>
...
</my-tabs> Personally, I would like it to be more implicit. I do not think that |
@ebidel in your article about the shadowdom you show how a tabs component can be implemented. Did you choose the "flat markup" approach because of the limitation which is described here or because you think it is good solution? Copy of his markup: <fancy-tabs>
<button slot="title">Title</button>
<button slot="title" selected>Title 2</button>
<button slot="title">Title 3</button>
<section>content panel 1</section>
<section>content panel 2</section>
<section>content panel 3</section>
</fancy-tabs>
<!-- Using <h2>'s and changing the ordering would also work! -->
<fancy-tabs>
<h2 slot="title">Title</h2>
<section>content panel 1</section>
<h2 slot="title" selected>Title 2</h2>
<section>content panel 2</section>
<h2 slot="title">Title 3</h2>
<section>content panel 3</section>
</fancy-tabs> |
Maybe traversing up is a good compromise in terms of modularity. On Sep 28, 2016 8:46 AM, "Joel Richard" notifications@github.com wrote:
|
Slotting indirect children does not make sense. The parent of such indirect children is no-op, isn't it? It is never used. You can omit such a parent in any case, and put children as direct children of the shadow host. Nothing changes after that.
@joelrich |
@hayatoito, right, the parent would be a no-op. However, this does not make it useless. For example, if you want to remove, move or add a tab, then you could do this with one command. Therefore, this is important to keep the tab titles and contents grouped and synchronized. Adding a shadow to Angular Martial Design uses a similar markup: <md-tab-group>
<md-tab>
<template md-tab-label>One</template>
<template md-tab-content>
<h1>Some tab content</h1>
<p>...</p>
</template>
</md-tab>
<md-tab>
<template md-tab-label>Two</template>
<template md-tab-content>
<h1>Some more tab content</h1>
<p>...</p>
</template>
</md-tab>
</md-tab-group> <md-tabs md-selected="selectedIndex">
<img ng-src="img/angular.png" class="centered">
<md-tab ng-repeat="tab in tabs | orderBy:predicate:reversed" md-on-select="onTabSelected(tab)" md-on-deselect="announceDeselected(tab)" ng-disabled="tab.disabled">
<md-tab-label>
{{tab.title}}
<img src="img/removeTab.png" ng-click="removeTab(tab)" class="delete">
</md-tab-label>
<md-tab-body>
{{tab.content}}
</md-tab-body>
</md-tab>
</md-tabs> Please keep in mind that even if Do you have a better idea how to solve this problem than my suggested algorithm? |
I don't think we should close this issue until we've fully explored the problem space. |
I have taken a look the composed DOM in the example, and now I understand why it is impossible. You are correct. Sorry for my misunderstanding. My opinions for this idea:
For example, suppose that users write the following markup: <my-tabs>
<my-tab>
<my-tab-title>
Title 1
</my-tab-title>
<my-tab-content>
Content 1
</my-tab-content>
</my-tab>
<my-tba>
<my-tab-title>
Title 2
</my-tab-title>
<my-tab-content>
Content 2
</my-tab-content>
</my-tab>
</my-tabs> I guess you did not notice the typo in the markup. They wrote
|
Actually, I don't think parent should be a no-op, and I think the event
On Oct 4, 2016 9:32 PM, "Hayato Ito" notifications@github.com wrote:
|
I am afraid that I do not understand your idea fully. Could you help me to understand by explaining how get the parent algorithm for nodes and shadow roots should be? |
Let me close this since the idea was not clearly demonstrated. |
We see some use cases related to this with semantical elements, such as E.g.
Depending on the composition, it's sometimes too difficult to style the caption with simple CSS changes. It'd be helpful to be able to re-distribute it via a nested slot of some sort. Currently, we often |
@dvoytenko Thanks for the feedback. I am trying to understand the use case. Could you possibly tell us what is the outcome you want more clearly? If we could know the desired composition more clearly, that would be great.
It might be a little difficult for me what "nested slot of some sort" means here. |
It looks this bug was closed. If you need to re-open this bug for the discussion, we are happy to re-open this! |
(I'd vastly prefer a new focused issue without all the 2016 noise.) |
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:
The composed DOM should look like this:
(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:
The markup would then have been:
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?
The text was updated successfully, but these errors were encountered: