-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Implement <slot> #787
Implement <slot> #787
Conversation
Alright, this is ready now if anyone wants to take a look. The three remaining TODOs are post-release tasks. |
I cloned the repo and did |
'It works for me' is the most unhelpful reply, but, uh, it works for me: This is the code for that: https://gist.github.com/Rich-Harris/cbded6e9a638f0a76b8c95577c79a660
You shouldn't even need to do that — it'll replace |
Alas, I was looking in all the wrong places! I forgot I had begun considering I think there is a bug, though. The following works: <!-- excerpt from Modal.html -->
<slot name="scrim">
<div>just some text</div>
</slot>
<!-- SomewhereElse.html -->
<Modal>
<div slot="scrim"><p>Whatever html you want</p></div>
</Modal> But if I add attributes to the element in the fallback content, I get this error at runtime. <slot name="scrim">
<div class="foo">just some text</div> <!-- will break due to attribute on element -->
</slot>
|
Also note that if there is fallback content with attributes and the fallback content is used (nothing put into the slot), things are fine. Therefore, I suppose that when something is put into the slot, the element in the fallback content is appropriately undefined, but there is undesired code running to apply attributes to the unneeded and non-existent element. |
Yeah, it just needs to wrap the hydration code in a conditional. I basically have it working locally, just need to tweak some stuff. Good catch, thanks |
Should be fixed now. |
Eek. Putting the WIP tag back on. Turns out that A corollary: we can't have the new Thing({
target: document.body,
slots: {
default: someNode,
foo: someOtherNode
}
}); Discovered this because I'm working on an app that has some flexbox styles, and the presence of the |
I was doing this to get around a circular dependency const thing = new Thing({ target })
this.slots.default = makeSlotStuff(thing) The same can still be done with one extra step const slotElement = document.createElement('div')
const thing = new Thing({ target, slots: { default: slotElement })
slotElement.appendChild(makeSlotStuff(thing)) I bet this will change and/or be fixed by your current work, but in case it matters, the latter example currently breaks on
if (slot_content_default) {
while (slot_default.firstChild) appendNode(slot_default.firstChild, slot_content_default);
} |
Fixed — One consequence — the slotted content needs anchors, so that we can unmount it. In that way it's similar to if/each blocks, except that we need an anchor before and after, and similar to raw tags except that we can use comments instead of @m59peacemaker that should fix the problem you identified! 🤞 Another thing that occurs to me: fallback content is another excellent reason to work on #749. If we can analyse the entire app, we can statically determine whether or not a component needs fallback capability for each slot. |
That JS API |
This addresses #763.
{{yield}}
is turned into<slot>
at the parser level, which means we can remove yield-related stuff from the codebase altogether.The only difference anyone will notice is that component contents are now wrapped in<slot>...</slot>
It's already proving to be a more efficient solution — we no longer need to create a new block for component contents, and can instead simply append elements which is cheaper.
TODO:
component.slots
slot
attributes nameddefault
, no dynamicslot
attributes on elements, no attributes other thanname
on<slot>
elements, no duplicate<slot>
elements within components, no nested<slot>
elements, no<slot>
elements ineach
blocks){{yield}}
{{yield}}