63 lines
1.7 KiB
JavaScript
63 lines
1.7 KiB
JavaScript
|
// src/internal/slot.ts
|
||
|
var HasSlotController = class {
|
||
|
constructor(host, ...slotNames) {
|
||
|
this.slotNames = [];
|
||
|
this.handleSlotChange = (event) => {
|
||
|
const slot = event.target;
|
||
|
if (this.slotNames.includes("[default]") && !slot.name || slot.name && this.slotNames.includes(slot.name)) {
|
||
|
this.host.requestUpdate();
|
||
|
}
|
||
|
};
|
||
|
(this.host = host).addController(this);
|
||
|
this.slotNames = slotNames;
|
||
|
}
|
||
|
hasDefaultSlot() {
|
||
|
return [...this.host.childNodes].some((node) => {
|
||
|
if (node.nodeType === node.TEXT_NODE && node.textContent.trim() !== "") {
|
||
|
return true;
|
||
|
}
|
||
|
if (node.nodeType === node.ELEMENT_NODE) {
|
||
|
const el = node;
|
||
|
const tagName = el.tagName.toLowerCase();
|
||
|
if (tagName === "sl-visually-hidden") {
|
||
|
return false;
|
||
|
}
|
||
|
if (!el.hasAttribute("slot")) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
});
|
||
|
}
|
||
|
hasNamedSlot(name) {
|
||
|
return this.host.querySelector(`:scope > [slot="${name}"]`) !== null;
|
||
|
}
|
||
|
test(slotName) {
|
||
|
return slotName === "[default]" ? this.hasDefaultSlot() : this.hasNamedSlot(slotName);
|
||
|
}
|
||
|
hostConnected() {
|
||
|
this.host.shadowRoot.addEventListener("slotchange", this.handleSlotChange);
|
||
|
}
|
||
|
hostDisconnected() {
|
||
|
this.host.shadowRoot.removeEventListener("slotchange", this.handleSlotChange);
|
||
|
}
|
||
|
};
|
||
|
function getTextContent(slot) {
|
||
|
if (!slot) {
|
||
|
return "";
|
||
|
}
|
||
|
const nodes = slot.assignedNodes({ flatten: true });
|
||
|
let text = "";
|
||
|
[...nodes].forEach((node) => {
|
||
|
if (node.nodeType === Node.TEXT_NODE) {
|
||
|
text += node.textContent;
|
||
|
}
|
||
|
});
|
||
|
return text;
|
||
|
}
|
||
|
|
||
|
export {
|
||
|
HasSlotController,
|
||
|
getTextContent
|
||
|
};
|