import { useEffect } from 'react' ; import { isBrowser , off , on } from './misc/util' ; export interface ListenerType1 { addEventListener ( name , handler , ... args ) ; removeEventListener ( name , handler , ... args ) ; } export interface ListenerType2 { on ( name , handler , ... args ) ; off ( name , handler , ... args ) ; } export type UseEventTarget = ListenerType1 | ListenerType2 ; const defaultTarget = isBrowser ? window : null ; const isListenerType1 = ( target ) : target is ListenerType1 => { return ! ! target . addEventListener ; } ; const isListenerType2 = ( target ) : target is ListenerType2 => { return ! ! target . on ; } ; type AddEventListener < T > = T extends ListenerType1 ? T [ 'addEventListener' ] : T extends ListenerType2 ? T [ 'on' ] : never ; export type UseEventOptions < T > = Parameters < AddEventListener < T > > [ 2 ] ; const useEvent = < T extends UseEventTarget > ( name , handler ? , target = defaultTarget , options ? ) => { useEffect ( ( ) => { if ( ! handler ) { return ; } if ( ! target ) { return ; } if ( isListenerType1 ( target ) ) { on ( target , name , handler , options ) ; } else if ( isListenerType2 ( target ) ) { target . on ( name , handler , options ) ; } return ( ) => { if ( isListenerType1 ( target ) ) { off ( target , name , handler , options ) ; } else if ( isListenerType2 ( target ) ) { target . off ( name , handler , options ) ; } } ; } , [ name , handler , target , JSON . stringify ( options ) ] ) ; } ; export default useEvent ;