1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- import React from 'react';
- import useIsomorphicLayoutEffect from './use-isomorphic-layout-effect';
- // MediaQueryList Event based useEventListener interface
- function useEventListener<K extends keyof MediaQueryListEventMap>(
- eventName: K,
- handler: (event: MediaQueryListEventMap[K]) => void,
- element: React.RefObject<MediaQueryList>,
- options?: boolean | AddEventListenerOptions
- ): void
- // Window Event based useEventListener interface
- function useEventListener<K extends keyof WindowEventMap>(
- eventName: K,
- handler: (event: WindowEventMap[K]) => void,
- element?: undefined,
- options?: boolean | AddEventListenerOptions,
- ): void
- // Element Event based useEventListener interface
- function useEventListener<
- K extends keyof HTMLElementEventMap,
- T extends HTMLElement = HTMLDivElement
- >(
- eventName: K,
- handler: (event: HTMLElementEventMap[K]) => void,
- element: React.RefObject<T>,
- options?: boolean | AddEventListenerOptions
- ): void
- // Document Event based useEventListener interface
- function useEventListener<K extends keyof DocumentEventMap>(
- eventName: K,
- handler: (event: DocumentEventMap[K]) => void,
- element: React.RefObject<Document>,
- options?: boolean | AddEventListenerOptions
- ): void
- function useEventListener<
- KW extends keyof WindowEventMap,
- KH extends keyof HTMLElementEventMap,
- KM extends keyof MediaQueryListEventMap,
- T extends HTMLElement | MediaQueryList | void = void
- >(
- eventName: KW | KH | KM,
- handler: (
- event:
- | WindowEventMap[KW]
- | HTMLElementEventMap[KH]
- | MediaQueryListEventMap[KM]
- | Event
- ) => void,
- element?: React.RefObject<T>,
- options?: boolean | AddEventListenerOptions
- ) {
- // Create a ref that stores handler
- const savedHandler = React.useRef(handler)
- useIsomorphicLayoutEffect(() => {
- savedHandler.current = handler
- }, [handler])
- React.useEffect(() => {
- // Define the listening target
- const targetElement: T | Window = element?.current ?? window
- if (!(targetElement && targetElement.addEventListener)) return
- // Create event listener that calls handler function stored in ref
- const listener: typeof handler = (event) => savedHandler.current(event)
- targetElement.addEventListener(eventName, listener, options)
- // Remove event listener on cleanup
- return () => {
- targetElement.removeEventListener(eventName, listener, options)
- }
- }, [eventName, element, options])
- }
- export default useEventListener
|