import { createElement, type CreateElement } from "./html"; export default class NotiveElement extends HTMLElement { static makeFactory(this: { new (): T; }): CreateElement; static makeFactory(): any { throw new Error( "Missing makeFactory implementation. Did you forget to use @customElement?", ); } } export function customElement(tagName: string) { return function (_value: unknown, context: ClassDecoratorContext) { context.addInitializer(function () { window.customElements.define(tagName, this as typeof NotiveElement); (this as typeof NotiveElement).makeFactory = () => ((...args: any[]) => createElement(tagName, ...args)) as CreateElement; }); }; } export function eventHandler(eventName: string) { return function (_value: unknown, context: ClassFieldDecoratorContext) { const privateKey = Symbol(context.name.toString()); context.addInitializer(function () { Object.defineProperty(this, context.name, { get() { return this[privateKey]; }, set(handler) { const oldHandler = this[privateKey]; if (oldHandler) this.removeEventListener(eventName, oldHandler); this[privateKey] = handler; if (handler) this.addEventListener(eventName, handler); }, enumerable: true, configurable: true, }); }); }; }