import { Ref , useCallback , useEffect , useMemo , useRef } from "react" ; interface Options { /**
     * Condition which if true, will enable the event listeners
     */ when ? : boolean ; /**
     * Keyboardevent types to listen for. Valid options are keyDown, keyPress and keyUp
     */ eventTypes ? : Array < string | number > ; /**
     * target ref on which the events should be listened. If no target is specified,
     * events are listened to on the window
     */ target ? : Ref < HTMLElement > | null ; } const defaultOptions = { when : true , eventTypes : [ "keydown" ] , } ; param { [ string | number ] } keyList param { function } callback param { Options } options function useKey ( input , callback , opts ? ) { const keyList = useMemo ( ( ) => ( Array . isArray ( input ) ? input : [ input ] ) , [ input ] ) ; const options = Object . assign ( { } , defaultOptions , opts ) ; const { when , eventTypes } = options ; const callbackRef = useRef < ( e : KeyboardEvent ) => any > ( callback ) ; const { target } = options ; useEffect ( ( ) => { callbackRef . current = callback ; } ) ; const handle = useCallback ( ( e ) => { if ( keyList . some ( ( k ) => e . key === k || e . code === k ) ) { callbackRef . current ( e ) ; } } , [ keyList ] ) ; useEffect ( ( ) : any => { if ( when && typeof window !== "undefined" ) { const targetNode = target ? target [ "current" ] : window ; eventTypes . forEach ( ( eventType ) => { targetNode && targetNode . addEventListener ( eventType , handle ) ; } ) ; return ( ) => { eventTypes . forEach ( ( eventType ) => { targetNode && targetNode . removeEventListener ( eventType , handle ) ; } ) ; } ; } } , [ when , eventTypes , keyList , target , callback ] ) ; } export { useKey } ;