UNPKG

@tempots/dom

Version:

Fully-typed frontend framework alternative to React and Angular

300 lines (299 loc) 9.21 kB
import { Renderable } from '../types/domain'; import { HTMLEvents } from '../types/html-events'; import { DOMContext, HandlerOptions } from '../dom/dom-context'; /** * Attaches an event handler to the 'click' event that triggers when a checkbox is checked or unchecked. * @param fn - The callback function to be executed when the checkbox is clicked. * @alpha */ export declare const OnChecked: (fn: (event: boolean, ctx: DOMContext) => void) => Renderable; type EventHandlerMap = { [EN in keyof HTMLEvents]: (handler: (event: HTMLEvents[EN], ctx: DOMContext) => void, options?: HandlerOptions) => Renderable; }; /** * Provides type-safe event handlers for all HTML events. * * The `on` object is a proxy that provides access to all standard HTML events with proper * TypeScript typing. Each event handler receives the native event object and the DOM context. * * Use `on.document` to attach listeners to `document` and `on.window` to attach listeners * to `window`. These listeners are automatically removed when the component is disposed. * * @example * ```typescript * // Basic click handler * html.button( * on.click((event, ctx) => { * console.log('Button clicked!', event.target) * }), * 'Click me' * ) * ``` * * @example * ```typescript * // Input event with value extraction * const text = prop('') * * html.input( * attr.value(text), * on.input((event) => { * text.value = (event.target as HTMLInputElement).value * }) * ) * ``` * * @example * ```typescript * // Multiple event handlers on same element * html.div( * on.mouseenter(() => console.log('Mouse entered')), * on.mouseleave(() => console.log('Mouse left')), * on.click(() => console.log('Clicked')), * 'Hover and click me' * ) * ``` * * @example * ```typescript * // Keyboard event handling * html.input( * on.keydown((event) => { * if (event.key === 'Enter') { * console.log('Enter pressed!') * event.preventDefault() * } * }) * ) * ``` * * @example * ```typescript * // Global keyboard shortcut scoped to a component's lifetime * html.div( * on.document.keydown((event) => { * if (event.key === 'Escape') { * console.log('Escape pressed anywhere!') * } * }), * 'Press Escape anywhere' * ) * ``` * * @example * ```typescript * // Window resize listener scoped to a component's lifetime * html.div( * on.window.resize(() => { * console.log('Window resized!') * }), * 'Resize the window' * ) * ``` * * @public */ export declare const on: EventHandlerMap & { /** * Attaches event listeners to `document`. The listener is automatically * removed when the component is disposed. */ document: EventHandlerMap; /** * Attaches event listeners to `window`. The listener is automatically * removed when the component is disposed. */ window: EventHandlerMap; }; /** * Options for event handlers. * * @public */ export type EmitOptions = { preventDefault?: boolean; stopPropagation?: boolean; stopImmediatePropagation?: boolean; }; /** * Creates an event handler that calls the provided function with the event as an argument. * @param fn - The function to call when the event is triggered. * @returns An event handler function that can be used with event listeners. * @public */ export declare const emit: (fn: (event: Event) => void, options?: EmitOptions) => (event: Event) => void; /** * Creates an event handler that extracts and emits the target element from an event. * * @example * ```typescript * html.input( * on.input(emitTarget((input) => { * console.log('Input value:', input.value) * })) * ) * ``` * * @param fn - Callback function that receives the target element * @returns Event handler function that can be used with event listeners * @public */ export declare const emitTarget: <EL extends HTMLElement>(fn: (element: EL, event: Event) => void, options?: EmitOptions) => (event: Event) => void; /** * Creates an event handler that extracts and emits the string value from an input element. * * This utility simplifies handling input events by automatically extracting the value * from the target element and passing it to your callback function. * * @example * ```typescript * const name = prop('') * * html.input( * attr.value(name), * on.input(emitValue(value => name.value = value)) * ) * ``` * * @example * ```typescript * // With textarea * const description = prop('') * * html.textarea( * attr.value(description), * on.input(emitValue(value => { * description.value = value * console.log('Description updated:', value) * })) * ) * ``` * * @param fn - Callback function that receives the input element's string value * @returns Event handler function that can be used with event listeners * @public */ export declare const emitValue: (fn: (text: string, event: Event) => void, options?: EmitOptions) => (event: Event) => void; /** * Creates an event handler that extracts and emits the numeric value from an input element. * * This utility automatically converts the input's value to a number using the browser's * built-in `valueAsNumber` property, which handles number inputs correctly and returns * `NaN` for invalid numeric values. * * @example * ```typescript * const age = prop(0) * * html.input( * attr.type('number'), * attr.value(age.map(String)), * on.input(emitValueAsNumber(value => { * if (!isNaN(value)) { * age.value = value * } * })) * ) * ``` * * @example * ```typescript * // With range input * const volume = prop(50) * * html.input( * attr.type('range'), * attr.min('0'), * attr.max('100'), * attr.value(volume.map(String)), * on.input(emitValueAsNumber(value => volume.value = value)) * ) * ``` * * @param fn - Callback function that receives the input element's numeric value (may be NaN) * @returns Event handler function that can be used with event listeners * @public */ export declare const emitValueAsNumber: (fn: (num: number, event: Event) => void, options?: EmitOptions) => (event: Event) => void; /** * Converts the value of an HTML input element to a Date object and emits it using the provided callback function. * @param fn - The callback function to be called with the converted Date object. * @returns A function that can be used as an event handler for input events. * @public */ export declare const emitValueAsDate: (fn: (date: Date, event: Event) => void, options?: EmitOptions) => (event: Event) => void; /** * Converts the value of an HTML input element to a Date object or null and emits it using the provided callback function. * @param fn - The callback function to be called with the converted Date object or null. * @returns A function that can be used as an event handler for input events. * @public */ export declare const emitValueAsNullableDate: (fn: (date: Date | null, event: Event) => void, options?: EmitOptions) => (event: Event) => void; /** * Emits the value of an HTMLInputElement as a Date object. * @param fn - The callback function to be called with the emitted Date object. * @returns The event handler function. * @public */ export declare const emitValueAsDateTime: (fn: (date: Date, event: Event) => void, options?: EmitOptions) => (event: Event) => void; /** * Emits the value of an HTMLInputElement as a Date object or null. * @param fn - The callback function to be called with the emitted Date object or null. * @returns The event handler function. * @public */ export declare const emitValueAsNullableDateTime: (fn: (date: Date | null, event: Event) => void, options?: EmitOptions) => (event: Event) => void; /** * Creates an event handler that extracts and emits the checked state from a checkbox or radio input. * * This utility simplifies handling checkbox and radio button state changes by automatically * extracting the `checked` property from the target element. * * @example * ```typescript * const isEnabled = prop(false) * * html.input( * attr.type('checkbox'), * attr.checked(isEnabled), * on.change(emitChecked(checked => isEnabled.value = checked)) * ) * ``` * * @example * ```typescript * // With radio buttons * const selectedOption = prop('') * * html.div( * html.label( * html.input( * attr.type('radio'), * attr.name('option'), * attr.value('A'), * on.change(emitChecked(checked => { * if (checked) selectedOption.value = 'A' * })) * ), * 'Option A' * ), * html.label( * html.input( * attr.type('radio'), * attr.name('option'), * attr.value('B'), * on.change(emitChecked(checked => { * if (checked) selectedOption.value = 'B' * })) * ), * 'Option B' * ) * ) * ``` * * @param fn - Callback function that receives the input element's checked state * @returns Event handler function that can be used with event listeners * @public */ export declare const emitChecked: (fn: (checked: boolean, event: Event) => void, options?: EmitOptions) => (event: Event) => void; export {};