// DOM events export function fire(el: El, event: string, detail: D) { el.dispatchEvent(new CustomEvent(event, { detail, bubbles: true, cancelable: true })); } export function on(node: GlobalEventHandlers, event: K, selector: string, func: ((e: GlobalEventHandlersEventMap[K], target: Element) => boolean)) { delegate(node, event, { [selector]: func }); } export function leftClick(func: (e: E, t: Target) => void) { return (event: E, target: Target) => { if (event.button === 0) return func(event, target); }; } export function delegate(node: GlobalEventHandlers, event: K, selectors: Record boolean)>) { node.addEventListener(event, e => { for (const selector in selectors) { const evtTarget = e.target as EventTarget | Element | null; if (evtTarget && 'closest' in evtTarget && typeof evtTarget.closest === 'function') { const target = evtTarget.closest(selector); if (target && selectors[selector](e, target) === false) break; } } }); }