react-hotkeys-hook 4.1.0-0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/useHotkeys.ts CHANGED
@@ -21,8 +21,6 @@ const stopPropagation = (e: KeyboardEvent): void => {
21
21
 
22
22
  const useSafeLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect
23
23
 
24
- const pressedDownKeys = new Set<string>()
25
-
26
24
  export default function useHotkeys<T extends HTMLElement>(
27
25
  keys: Keys,
28
26
  callback: HotkeyCallback,
@@ -30,6 +28,7 @@ export default function useHotkeys<T extends HTMLElement>(
30
28
  dependencies?: OptionsOrDependencyArray,
31
29
  ) {
32
30
  const ref = useRef<RefType<T>>(null)
31
+ const hasTriggeredRef = useRef(false)
33
32
 
34
33
  const _options: Options | undefined = !(options instanceof Array) ? (options as Options) : !(dependencies instanceof Array) ? (dependencies as Options) : undefined
35
34
  const _deps: DependencyList = options instanceof Array ? options : dependencies instanceof Array ? dependencies : []
@@ -65,7 +64,9 @@ export default function useHotkeys<T extends HTMLElement>(
65
64
  parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => {
66
65
  const hotkey = parseHotkey(key, memoisedOptions?.combinationKey)
67
66
 
68
- if (isHotkeyMatchingKeyboardEvent(e, hotkey, pressedDownKeys) || hotkey.keys?.includes('*')) {
67
+ if ((isHotkeyMatchingKeyboardEvent(e, hotkey) || hotkey.keys?.includes('*')) && !hasTriggeredRef.current) {
68
+ hasTriggeredRef.current = true
69
+
69
70
  maybePreventDefault(e, hotkey, memoisedOptions?.preventDefault)
70
71
 
71
72
  if (!isHotkeyEnabled(e, hotkey, memoisedOptions?.enabled)) {
@@ -74,6 +75,7 @@ export default function useHotkeys<T extends HTMLElement>(
74
75
  return
75
76
  }
76
77
 
78
+ // Execute the user callback for that hotkey
77
79
  cb(e, hotkey)
78
80
  }
79
81
  })
@@ -85,8 +87,6 @@ export default function useHotkeys<T extends HTMLElement>(
85
87
  return
86
88
  }
87
89
 
88
- pressedDownKeys.add(event.key.toLowerCase())
89
-
90
90
  if ((memoisedOptions?.keydown === undefined && memoisedOptions?.keyup !== true) || memoisedOptions?.keydown) {
91
91
  listener(event)
92
92
  }
@@ -98,12 +98,7 @@ export default function useHotkeys<T extends HTMLElement>(
98
98
  return
99
99
  }
100
100
 
101
- if (event.key.toLowerCase() !== 'meta') {
102
- pressedDownKeys.delete(event.key.toLowerCase())
103
- } else {
104
- // On macOS pressing down the meta key prevents triggering the keyup event for any other key https://stackoverflow.com/a/57153300/735226.
105
- pressedDownKeys.clear()
106
- }
101
+ hasTriggeredRef.current = false
107
102
 
108
103
  if (memoisedOptions?.keyup) {
109
104
  listener(event)
package/src/validators.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { FormTags, Hotkey, Scopes, Trigger } from './types'
2
2
  import { isHotkeyPressed } from './isHotkeyPressed'
3
+ import { mapKey } from './parseHotkeys'
3
4
 
4
5
  export function maybePreventDefault(e: KeyboardEvent, hotkey: Hotkey, preventDefault?: Trigger): void {
5
6
  if ((typeof preventDefault === 'function' && preventDefault(e, hotkey)) || preventDefault === true) {
@@ -45,7 +46,7 @@ export function isScopeActive(activeScopes: string[], scopes?: Scopes): boolean
45
46
  return activeScopes.some(scope => scopes.includes(scope)) || activeScopes.includes('*')
46
47
  }
47
48
 
48
- export const isHotkeyMatchingKeyboardEvent = (e: KeyboardEvent, hotkey: Hotkey, pressedDownKeys: Set<string>): boolean => {
49
+ export const isHotkeyMatchingKeyboardEvent = (e: KeyboardEvent, hotkey: Hotkey): boolean => {
49
50
  const { alt, meta, mod, shift, keys } = hotkey
50
51
  const { key: pressedKeyUppercase, code } = e
51
52
 
@@ -54,7 +55,7 @@ export const isHotkeyMatchingKeyboardEvent = (e: KeyboardEvent, hotkey: Hotkey,
54
55
  const metaKey = isHotkeyPressed('meta')
55
56
  const ctrlKey = isHotkeyPressed('ctrl')
56
57
 
57
- const keyCode = code.toLowerCase().replace('key', '')
58
+ const keyCode = mapKey(code)
58
59
  const pressedKey = pressedKeyUppercase.toLowerCase()
59
60
 
60
61
  if (altKey !== alt && pressedKey !== 'alt') {
@@ -82,7 +83,7 @@ export const isHotkeyMatchingKeyboardEvent = (e: KeyboardEvent, hotkey: Hotkey,
82
83
  return true
83
84
  } else if (keys) {
84
85
  // Check if all keys are present in pressedDownKeys set
85
- return keys.every(key => pressedDownKeys.has(key))
86
+ return isHotkeyPressed(keys)
86
87
  }
87
88
  else if (!keys) {
88
89
  // If the key is not set, we only listen for modifiers, that check went alright, so we return true