Files
bookhoard/web/src/events.ts
T
john-okeefe 149d14f5eb refactor(ts): Add ES module exports to core utilities
Phase 0/1 of ESBuild migration: Add ES exports to all utility modules
while maintaining Alpine.js registration for template compatibility.

Core utility modules now support both:
- ES module imports for TypeScript→TypeScript dependencies
- Alpine.js global namespace for template onclick handlers

Modules updated:
- api.ts: Export apiGet, apiPost, apiPut, apiDelete, apiPatch, and handlers
- toast.ts: Export showToast function (Alpine namespace already present)
- storage.ts: Export localStorage helpers (already had exports)
- dom.ts: Export DOM manipulation helpers (already had exports)
- events.ts: Export event delegation helpers
- theme.ts: Export theme management functions
- woodPaneling.ts: Export wood paneling functions

Pattern: Each module now has dual exports
- ES module exports for internal TS dependencies
- Alpine.global() registration for template access
- Removed direct window exports where Alpine registration exists

This enables Phase 1 (converting internal window reads to imports) while
maintaining template functionality through Alpine.

Migration progress: Phase 0 complete, Phase 1 in progress
Next: Convert 193+ internal window reads across consumer modules
2026-03-08 01:14:20 -05:00

136 lines
2.9 KiB
TypeScript

function onDelegatedClick(
selector: string,
handler: (element: HTMLElement, event: MouseEvent) => void,
): void {
document.addEventListener("click", (event: MouseEvent) => {
const target = event.target as HTMLElement;
const element = target.closest(selector) as HTMLElement | null;
if (element) {
handler(element, event);
}
});
}
function onDelegatedSubmit(
selector: string,
handler: (form: HTMLFormElement, event: Event) => void,
): void {
document.addEventListener("submit", (event: Event) => {
const target = event.target as HTMLElement;
const form = target.closest(selector) as HTMLFormElement | null;
if (form) {
handler(form, event);
}
});
}
function onDelegatedChange(
selector: string,
handler: (element: HTMLElement, event: Event) => void,
): void {
document.addEventListener("change", (event: Event) => {
const target = event.target as HTMLElement;
const element = target.closest(selector) as HTMLElement | null;
if (element) {
handler(element, event);
}
});
}
function onDelegatedKeydown(
selector: string,
handler: (element: HTMLElement, event: KeyboardEvent) => void,
): void {
document.addEventListener("keydown", (event: KeyboardEvent) => {
const target = event.target as HTMLElement;
const element = target.closest(selector) as HTMLElement | null;
if (element) {
handler(element, event);
}
});
}
function getDataAttribute(
element: HTMLElement,
name: string,
): string | undefined {
return element.dataset[name];
}
function setDataAttribute(
element: HTMLElement,
name: string,
value: string,
): void {
element.dataset[name] = value;
}
function onClick(
element: HTMLElement | null,
handler: (event: MouseEvent) => void,
): void {
if (element) {
element.addEventListener("click", handler);
}
}
function onSubmit(
element: HTMLFormElement | null,
handler: (event: Event) => void,
): void {
if (element) {
element.addEventListener("submit", handler);
}
}
function onChange(
element: HTMLElement | null,
handler: (event: Event) => void,
): void {
if (element) {
element.addEventListener("change", handler);
}
}
function onKeydown(
element: HTMLElement | null,
handler: (event: KeyboardEvent) => void,
): void {
if (element) {
element.addEventListener("keydown", handler);
}
}
function onInput(
element: HTMLElement | null,
handler: (event: Event) => void,
): void {
if (element) {
element.addEventListener("input", handler);
}
}
function preventDefault(event: Event): void {
event.preventDefault();
}
function stopPropagation(event: Event): void {
event.stopPropagation();
}
export {
getDataAttribute,
onChange,
onClick,
onDelegatedChange,
onDelegatedClick,
onDelegatedKeydown,
onDelegatedSubmit,
onInput,
onKeydown,
onSubmit,
preventDefault,
setDataAttribute,
stopPropagation,
};