Conversation
✅ Deploy Preview for elenajs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Dependency ReviewThe following issues were found:
Snapshot WarningsEnsure that dependencies are being submitted on PR branches and consider enabling retry-on-snapshot-warnings. See the documentation for more information and troubleshooting advice. License Issuesdocs/package.json
OpenSSF ScorecardScorecard details
Scanned Files
|
slot()
slot()slot() for Primitive Components
slot() for Primitive Componentsslot()
slot()<slot/> substitute
|
I would not recommend vending this. It's too easy to confuse with the actual slot element and expect it to work like it does. It does not and cannot without a full polyfill. Here is a codepen that I tried with your linked preview above and it didn't work. This is just an example of the can of worms this opens. Feel free to explore of course, but I think you'll likely conclude that this is too weird and there are just too many edge cases. Instead, for composable light DOM rendering I think your |
|
@sorvell yeah, I am starting to think that this may be too difficult path to go down without also accounting for a million edge cases. I did get the example you shared working locally btw (the codepen you linked is using the old release from unpgk ( Thanks for the good feedback so far! Will explore the other direction a tad later in a separate PR. |
Overview
This PR adds a
slot()template helper that projects the host element’s children into a Primitive Component’s rendered<template>, similar to how<slot>works in Shadow DOM, but for Light DOM.This is an alternative and more performant approach to #10 (MutationObserver). Instead of observing external DOM mutations, this inverts the logic: the component explicitly declares where external content goes, and Elena leaves it alone. Inspired by the slottable-request community protocol.
slot()documentation for moreWhy is this being introduced?
Elena's Primitive Components own their internal DOM through
render()while still using Light DOM. The problem is that on first render,replaceChildren()replaces everything inside the host with the component’s own rendered template (on purpose). But this leads to any children that a framework may put there being destroyed.This means frameworks can't pass dynamic content as children:
The workaround with the text prop:
slot()solves this by letting the component declare where children go in its template. With these proposed changes, Elena saves the original children, renders the template around them, and marks that area as off-limits during re-renders. Frameworks keep ownership of the projected nodes and can update them freely.Before (workaround via
textprop):After:
You can now also pass any html to a Primitive Component, not just text:
How it works
slot()produces a comment marker (<!--slotId-->) that survives template stringification.textContentandappendChildon the host are redirected to the projected element, so frameworks can update content without destroying the<template>.Closes #9, closes #24, supersedes #10
TODO
@elenajs/ssrcompatibilityslot()instead${slot(this)}