Issue
Is it possible to assign a text node to a slot when using <template> and <slot>s?
Say I have a template that looks like
<template>
<span>
<slot name="mySlot"></slot>
</span>
</template>
I would like to be able to add only text to the slot, instead of having to add a <span> open and close tag each time I use the template. Is this possible? If not in pure HTML, in JavaScript?
It is also better to pass in the text content only so that no styling is applied on the way in. Currently I'm using an invalid tag <n> to avoid that issue.
Solution
Sure, you can with imperative slot assignment, but not yet in Safari.
- You can not slot a text node into a named slot (declarative).
- Mixing declarative and imperative slots is not possible.
::slotted(*)can not target text nodes.
<script>
customElements.define("slotted-textnodes", class extends HTMLElement {
constructor() {
super().attachShadow({
mode: 'open',
slotAssignment: 'manual' // imperative assign only
}).innerHTML = `<style>::slotted(*){color:red}</style>
Click me! <slot name="title"></slot> <slot>NONE</slot>!!!`;
}
connectedCallback() {
let nodes = [], node;
setTimeout(() => { // wait till lightDOM is parsed
const nodeIterator = document.createNodeIterator(
this, NodeFilter.SHOW_TEXT, {
acceptNode: (node) => node.parentNode == this && (/\S/.test(node.data))
}
);
while ((node = nodeIterator.nextNode())) nodes.push(node);
this.onclick = (e) => {
this.shadowRoot.querySelector("slot:not([name])").assign(nodes[0]);
nodes.push(nodes.shift());
}
})
}
})
</script>
<slotted-textnodes>
Foo
<hr separator>Bar<hr separator>
<b>text INSIDE nodes ignored by iterator filter!</b>
Baz
<span slot="title">Can't mix Declarative and Imperative slots!!!</span>
</slotted-textnodes>
Answered By - Danny '365CSI' Engelman

0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.