import hotkeys , { HotkeysEvent , KeyHandler } from 'hotkeys-js' ; import React , { useCallback , useEffect , useRef } from 'react' ; type AvailableTags = 'INPUT' | 'TEXTAREA' | 'SELECT' ; hotkeys . filter = ( ) => true ; const tagFilter = ( { target } , enableOnTags ? ) => { const targetTagName = target && ( target as HTMLElement ) . tagName ; return Boolean ( ( targetTagName && enableOnTags && enableOnTags . includes ( targetTagName as AvailableTags ) ) ) ; } ; const isKeyboardEventTriggeredByInput = ( ev ) => { return tagFilter ( ev , [ 'INPUT' , 'TEXTAREA' , 'SELECT' ] ) ; } ; export type Options = { enabled ? : boolean ; filter ? : typeof hotkeys . filter ; filterPreventDefault ? : boolean ; enableOnTags ? : AvailableTags [ ] ; enableOnContentEditable ? : boolean ; splitKey ? : string ; scope ? : string ; keyup ? : boolean ; keydown ? : boolean ; } ; export function useHotkeys < T extends Element > ( keys , callback , options ? ) ; export function useHotkeys < T extends Element > ( keys , callback , deps ? ) ; export function useHotkeys < T extends Element > ( keys , callback , options ? , deps ? ) ; export function useHotkeys < T extends Element > ( keys , callback , options ? , deps ? ) { if ( options instanceof Array ) { deps = options ; options = undefined ; } const { enableOnTags , filter , keyup , keydown , filterPreventDefault = true , enabled = true , enableOnContentEditable = false , } = options as Options || { } ; const ref = useRef < T | null > ( null ) ; const memoisedCallback = useCallback ( ( keyboardEvent , hotkeysEvent ) => { if ( filter && ! filter ( keyboardEvent ) ) { return ! filterPreventDefault ; } if ( ( isKeyboardEventTriggeredByInput ( keyboardEvent ) && ! tagFilter ( keyboardEvent , enableOnTags ) ) || ( ( keyboardEvent . target as HTMLElement ) ?. isContentEditable && ! enableOnContentEditable ) ) { return true ; } if ( ref . current === null || document . activeElement === ref . current ) { callback ( keyboardEvent , hotkeysEvent ) ; return true ; } return false ; } , deps ? [ ref , enableOnTags , filter , ... deps ] : [ ref , enableOnTags , filter ] ) ; useEffect ( ( ) => { if ( ! enabled ) { hotkeys . unbind ( keys , memoisedCallback ) ; return ; } if ( keyup && keydown !== true ) { ( options as Options ) . keydown = false ; } hotkeys ( keys , ( options as Options ) || { } , memoisedCallback ) ; return ( ) => hotkeys . unbind ( keys , memoisedCallback ) ; } , [ memoisedCallback , keys , enabled ] ) ; return ref ; }