UNPKG

@thibault.sh/hooks

Version:

A comprehensive collection of React hooks for browser storage, UI interactions, and more

1 lines 3.32 kB
{"version":3,"sources":["../src/hooks/useEventListener.ts"],"names":["useEventListener","eventName","handler","element","options","savedHandler","useRef","useEffect","targetElement","eventListener","event"],"mappings":"qCA6CO,SAASA,CACdC,CAAAA,CAAAA,CACAC,CACAC,CAAAA,CAAAA,CACAC,EACM,CACN,IAAMC,CAAeC,CAAAA,MAAAA,CAAOJ,CAAO,CAEnCK,CAAAA,SAAAA,CAAU,IAAM,CACdF,EAAa,OAAUH,CAAAA,EACzB,CAAG,CAAA,CAACA,CAAO,CAAC,CAAA,CAEZK,SAAU,CAAA,IAAM,CACd,IAAMC,CAAAA,CAAAA,CAAgBL,CAAA,EAAA,IAAA,CAAA,KAAA,CAAA,CAAAA,EAAS,OAAW,GAAA,MAAA,CAC1C,GAAI,EAACK,GAAA,IAAAA,EAAAA,CAAAA,CAAe,gBAAkB,CAAA,CAAA,OAEtC,IAAMC,CAAiBC,CAAAA,CAAAA,EAAiB,CACtCL,CAAAA,CAAa,QAAQK,CAAoB,EAC3C,CAEA,CAAA,OAAAF,EAAc,gBAAiBP,CAAAA,CAAAA,CAAWQ,CAAeL,CAAAA,CAAO,EAEzD,IAAM,CACXI,CAAc,CAAA,mBAAA,CAAoBP,EAAWQ,CAAeL,CAAAA,CAAO,EACrE,CACF,EAAG,CAACH,CAAAA,CAAWE,CAASC,CAAAA,CAAO,CAAC,EAClC","file":"useEventListener.mjs","sourcesContent":["import { useEffect, useRef, RefObject } from \"react\";\n\ntype EventMap = WindowEventMap & HTMLElementEventMap & DocumentEventMap;\n\n/**\n * Hook that adds an event listener to a target element with automatic cleanup.\n *\n * Automatically handles adding and removing event listeners, ensuring proper cleanup\n * when the component unmounts or dependencies change. Supports all standard DOM events\n * on window, document, or specific HTML elements.\n *\n * @template K - The event type key from the event map\n * @param eventName - The name of the event to listen for (e.g., 'click', 'keydown', 'resize')\n * @param handler - The event handler function that will be called when the event fires\n * @param element - Optional ref to the target element. Defaults to window if not provided\n * @param options - Optional event listener options (capture, once, passive, etc.)\n *\n * @example\n * ```tsx\n * function Component() {\n * const buttonRef = useRef<HTMLButtonElement>(null);\n *\n * // Listen for clicks on a specific element\n * useEventListener('click', (e) => {\n * console.log('Button clicked!', e);\n * }, buttonRef);r\n *\n * // Listen for window resize events\n * useEventListener('resize', () => {\n * console.log('Window resized');\n * });\n *\n * // Listen for escape key presses\n * useEventListener('keydown', (e) => {\n * if (e.key === 'Escape') {\n * console.log('Escape pressed');\n * }\n * });\n *\n * return <button ref={buttonRef}>Click me</button>;\n * }\n * ```\n *\n * @see https://thibault.sh/hooks/use-event-listener\n */\nexport function useEventListener<K extends keyof EventMap, T extends HTMLElement>(\n eventName: K,\n handler: (event: EventMap[K]) => void,\n element?: RefObject<T | null> | null,\n options?: boolean | AddEventListenerOptions\n): void {\n const savedHandler = useRef(handler);\n\n useEffect(() => {\n savedHandler.current = handler;\n }, [handler]);\n\n useEffect(() => {\n const targetElement = element?.current || window;\n if (!targetElement?.addEventListener) return;\n\n const eventListener = (event: Event) => {\n savedHandler.current(event as EventMap[K]);\n };\n\n targetElement.addEventListener(eventName, eventListener, options);\n\n return () => {\n targetElement.removeEventListener(eventName, eventListener, options);\n };\n }, [eventName, element, options]);\n}\n"]}