import { useEffect , useRef } from 'react' ; export interface UseEventOptions { options ? : Omit < AddEventListenerOptions , 'once' > ; dependencies ? : Array < any > ; enabled ? : boolean | 'once' ; element ? : Document | HTMLElement ; } param type param eventCallback param optional param optional . options param optional . enabled param optional . dependencies param optional . element export default function useEventListener < Type extends keyof DocumentEventMap > ( type , eventCallback , { options , enabled = true , dependencies = [ enabled , type ] , element , } = { } ) { const memoizedEventCallback = useRef ( ( ) => { } ) ; useEffect ( ( ) => { memoizedEventCallback . current = eventCallback ; } , [ eventCallback ] ) ; useEffect ( ( ) => { if ( enabled === false ) { return ; } if ( enabled !== 'once' && enabled !== true ) { console . error ( `Received value of type ${ typeof enabled } for property \`enabled\`. Expected a boolean.` ) ; return ; } const callback = ( e ) => memoizedEventCallback . current ( e ) ; const eventListenerOptions = { ... options , once : enabled === 'once' , } ; ( element ?? document ) . addEventListener ( type , callback as EventListener , eventListenerOptions ) ; return ( ) => { ( element ?? document ) . removeEventListener ( type , callback as EventListener , eventListenerOptions ) ; } ; } , dependencies ) ; }