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)) }) }) } }