{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "use-event-listener", "description": "A custom hook to add and remove event listeners.", "registryDependencies": [ "https://reactusekit.vercel.app/r/use-isomorphic-layout-effect.json" ], "files": [ { "path": "src/registry/new-york/hooks/use-event-listener.ts", "content": "import { type RefObject, useEffect, useRef } from \"react\";\nimport { useIsomorphicLayoutEffect } from \"./use-isomorphic-layout-effect\";\n\n/**\n * A custom hook that adds an event listener to a specified element or the window.\n * @param eventName - The name of the event to listen for.\n * @param handler - The function to call when the event is triggered.\n * @param element - The element to attach the event listener to. Defaults to `window`.\n * @param options - Options for the event listener.\n */\n\nfunction useEventListener(\n eventName: K,\n handler: (event: MediaQueryListEventMap[K]) => void,\n element: RefObject,\n options?: boolean | AddEventListenerOptions,\n): void;\n\nfunction useEventListener(\n eventName: K,\n handler: (event: WindowEventMap[K]) => void,\n element?: undefined,\n options?: boolean | AddEventListenerOptions,\n): void;\n\nfunction useEventListener<\n K extends keyof HTMLElementEventMap,\n T extends HTMLElement = HTMLDivElement,\n>(\n eventName: K,\n handler: (event: HTMLElementEventMap[K]) => void,\n element: RefObject,\n options?: boolean | AddEventListenerOptions,\n): void;\n\nfunction useEventListener(\n eventName: K,\n handler: (event: DocumentEventMap[K]) => void,\n element: RefObject,\n options?: boolean | AddEventListenerOptions,\n): void;\n\nfunction useEventListener<\n KW extends keyof WindowEventMap,\n KH extends keyof HTMLElementEventMap,\n KM extends keyof MediaQueryListEventMap,\n T extends HTMLElement | MediaQueryList | undefined = undefined,\n>(\n eventName: KW | KH | KM,\n handler: (\n event:\n | WindowEventMap[KW]\n | HTMLElementEventMap[KH]\n | MediaQueryListEventMap[KM]\n | Event,\n ) => void,\n element?: RefObject,\n options?: boolean | AddEventListenerOptions,\n) {\n const savedHandler = useRef(handler);\n\n useIsomorphicLayoutEffect(() => {\n savedHandler.current = handler;\n }, [handler]);\n\n useEffect(() => {\n const targetElement: T | Window = element?.current ?? window;\n\n if (!targetElement?.addEventListener) return;\n\n const listener: typeof handler = (event) => savedHandler.current(event);\n\n targetElement.addEventListener(eventName, listener, options);\n\n return () => {\n targetElement.removeEventListener(eventName, listener, options);\n };\n }, [eventName, element, options]);\n}\n\nexport default useEventListener;\n", "type": "registry:hook" } ], "type": "registry:hook" }