Skip to content

Instantly share code, notes, and snippets.

@DBC-Works
Last active July 20, 2023 14:10
Show Gist options
  • Save DBC-Works/11c53f82d9073e6d1740f078c538aa9a to your computer and use it in GitHub Desktop.
Save DBC-Works/11c53f82d9073e6d1740f078c538aa9a to your computer and use it in GitHub Desktop.
Abstract LitElement class for main DOM
import { LitElement } from 'lit'
/**
* Abstract LitElement class for main DOM
* This class moves child elements into slots after rendering
* @slot - Derived class can use slot element
*/
export abstract class LitMainDomElement extends LitElement {
//
// Class methods
//
/**
* find slot elements
* @param children target children
* @returns Element[] slot elements
*/
private static findSlots(children: HTMLCollection): Element[] {
let slots: Element[] = []
for (const child of children) {
if (child.tagName === 'SLOT') {
slots.push(child)
} else if (child.tagName.indexOf('-') < 0) {
slots = slots.concat(this.findSlots(child.children))
}
}
return slots
}
//
// fields
//
/**
* slot insertion target elements
*/
private targetElements: Element[] = []
//
// Lifecycle methods
//
/**
* connectedCallback
*/
override connectedCallback() {
super.connectedCallback()
this.targetElements = [...this.children]
}
/**
* firstUpdated
*/
override firstUpdated() {
const slots = LitMainDomElement.findSlots(this.children)
for (const child of this.targetElements) {
let targetSlot = null
if (child.hasAttribute('slot')) {
const slotName = child.attributes.getNamedItem('slot')?.value
targetSlot = slots.find(
(slot) => slot.attributes.getNamedItem('name')?.value === slotName
)
} else {
targetSlot = slots[0]
}
if (targetSlot) {
child.remove()
targetSlot.append(child)
}
}
this.targetElements = []
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment