You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<templatelwc:render-mode="light"><h2>Slotted content in Light DOM (note missing named slot)</h2><x-leaf><slotname="namedSlot"></slot></x-leaf><x-leaf><slot></slot></x-leaf></template>
// x-light-child
<template><slot></slot></template>
// x-leaf
In the above example, the slotted content "Named Slot Content" should render in the default slot for x-leaf but does not.
Each component that contains a slot will look up the slot's name in a slot map called slotset that determines what's slotted into the component.
This mapping is determined at runtime by traversing through the vnodes and their children.
When a new component containing a slot element is generated, it will look at the slot mapping from its parent to determine both the slot name and the content of what gets slotted.
Since light DOM slots directly return the content rather than the slot element, when there are nested slots, the mapping past the first level is missing and causes the component to render incorrectly.
The above will generate a slot map that looks something like this:
{"nameSlot": <divslot="namedSlot">Named Slot Content</div>,// This is for the named slot"": <div>Unnamed Slot Content</div>// This is for the default slot}// slotset
<templatelwc:render-mode="light"><h2>Slotted content in Light DOM (note missing named slot)</h2><x-leaf><slotname="namedSlot"></slot></x-leaf>
...
</template>
// x-light-child
Based on the slotset mapping, the children of x-leaf will be replaced with the vnode equivalent of <div slot="namedSlot">Named Slot Content</div>
Description
Light DOM slots are not rendering correctly when there are nested slots, repro:
In the above example, the slotted content "Named Slot Content" should render in the default slot for
x-leaf
but does not.This is happening because for light DOM slots, the children are directly returned rather than creating a
slot
element like in synthetic shadow.Root Cause
Each component that contains a
slot
will look up the slot's name in a slot map calledslotset
that determines what's slotted into the component.This mapping is determined at runtime by traversing through the vnodes and their children.
When a new component containing a
slot
element is generated, it will look at the slot mapping from its parent to determine both the slot name and the content of what gets slotted.Since light DOM slots directly return the content rather than the slot element, when there are nested slots, the mapping past the first level is missing and causes the component to render incorrectly.
Details
In the above example, the two
div
elements are mapped to the slot mapping :The above will generate a slot map that looks something like this:
This map is used to determine what will go in the slotted content inside
x-light-child
(value ofslotset
):Based on the
slotset
mapping, the children ofx-leaf
will be replaced with the vnode equivalent of<div slot="namedSlot">Named Slot Content</div>
Once the children have been allocated, they will be used to determine the slot mapping of
x-leaf
:When we finally get to
x-leaf
, since there is no default slot ("" entry in theslotset
), the content ofx-leaf
is not rendered:The
slot
element needs an empty string entry to retrieve the children.To demonstrate this, if we add
name="namedSlot"
the component will render correctly.The extra
slot
element acts as a buffer to help set the default slot mapping.I pushed up a branch to demonstrate a potential fix for the existing issue, although this change causes the karma tests to fail.
The branch also has the example described here to test with.
The text was updated successfully, but these errors were encountered: