type Fn = (el: Component) => void | Promise
/**
* Component client side initialisation class
*/
export default class Component {
private constructor(public element: T) {}
public handled(value: boolean): this
public handled(): boolean
public handled(value?: boolean): this | boolean {
if (typeof value === 'undefined') {
return typeof this.element.dataset.handled === 'string'
}
this.element.dataset.handled = ''
return this
}
public init(fn: (el: Component) => void | Promise) {
if (this.handled()) {
return
}
fn(this)
this.handled(true)
}
public child(query: string, fn: Fn) {
this.element.querySelectorAll(query).forEach((it) => {
const cp = new Component(it)
cp.init(fn)
})
}
/**
* start handling an element
* @param query the query to get the element
* @param fn the function that is run ONCE per elements
*/
public static handle(query: string, fn: (el: T) => void | Promise) {
document.querySelectorAll(query).forEach((it) => {
const cp = new Component(it)
cp.init((it) => fn(it.element))
})
document.addEventListener('astro:page-load', () => {
document.querySelectorAll(query).forEach((it) => {
const cp = new Component(it)
cp.init((it) => fn(it.element))
})
})
}
}