react-hotkeys-hook 4.0.8 → 4.1.0-1

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.
@@ -1,3 +1 @@
1
1
  export declare function isHotkeyPressed(key: string | string[], splitKey?: string): boolean;
2
- export declare function pushToCurrentlyPressedKeys(key: string | string[]): void;
3
- export declare function removeFromCurrentlyPressedKeys(key: string | string[]): void;
@@ -1,3 +1,4 @@
1
1
  import { Hotkey, Keys } from './types';
2
+ export declare function isHotkeyModifier(key: string): boolean;
2
3
  export declare function parseKeysHookInput(keys: Keys, splitKey?: string): string[];
3
4
  export declare function parseHotkey(hotkey: string, combinationKey?: string): Hotkey;
@@ -17,37 +17,6 @@ function _extends() {
17
17
  };
18
18
  return _extends.apply(this, arguments);
19
19
  }
20
- function _unsupportedIterableToArray(o, minLen) {
21
- if (!o) return;
22
- if (typeof o === "string") return _arrayLikeToArray(o, minLen);
23
- var n = Object.prototype.toString.call(o).slice(8, -1);
24
- if (n === "Object" && o.constructor) n = o.constructor.name;
25
- if (n === "Map" || n === "Set") return Array.from(o);
26
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
27
- }
28
- function _arrayLikeToArray(arr, len) {
29
- if (len == null || len > arr.length) len = arr.length;
30
- for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
31
- return arr2;
32
- }
33
- function _createForOfIteratorHelperLoose(o, allowArrayLike) {
34
- var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
35
- if (it) return (it = it.call(o)).next.bind(it);
36
- if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
37
- if (it) o = it;
38
- var i = 0;
39
- return function () {
40
- if (i >= o.length) return {
41
- done: true
42
- };
43
- return {
44
- done: false,
45
- value: o[i++]
46
- };
47
- };
48
- }
49
- throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
50
- }
51
20
 
52
21
  var reservedModifierKeywords = ['shift', 'alt', 'meta', 'mod'];
53
22
  var mappedKeys = {
@@ -67,6 +36,9 @@ var mappedKeys = {
67
36
  '8': 'digit8',
68
37
  '9': 'digit9'
69
38
  };
39
+ function isHotkeyModifier(key) {
40
+ return reservedModifierKeywords.includes(key);
41
+ }
70
42
  function parseKeysHookInput(keys, splitKey) {
71
43
  if (splitKey === void 0) {
72
44
  splitKey = ',';
@@ -99,6 +71,61 @@ function parseHotkey(hotkey, combinationKey) {
99
71
  });
100
72
  }
101
73
 
74
+ var currentlyPressedKeys = /*#__PURE__*/new Set();
75
+ function isHotkeyPressed(key, splitKey) {
76
+ if (splitKey === void 0) {
77
+ splitKey = ',';
78
+ }
79
+ var hotkeyArray = Array.isArray(key) ? key : key.split(splitKey);
80
+ return hotkeyArray.every(function (hotkey) {
81
+ return currentlyPressedKeys.has(hotkey.trim().toLowerCase());
82
+ });
83
+ }
84
+ function pushToCurrentlyPressedKeys(key) {
85
+ var hotkeyArray = Array.isArray(key) ? key : [key];
86
+ /*
87
+ Due to a weird behavior on macOS we need to clear the set if the user pressed down the meta key and presses another key.
88
+ https://stackoverflow.com/questions/11818637/why-does-javascript-drop-keyup-events-when-the-metakey-is-pressed-on-mac-browser
89
+ Otherwise the set will hold all ever pressed keys while the meta key is down which leads to wrong results.
90
+ */
91
+ if (currentlyPressedKeys.has('meta')) {
92
+ currentlyPressedKeys.forEach(function (key) {
93
+ return !isHotkeyModifier(key) && currentlyPressedKeys["delete"](key);
94
+ });
95
+ }
96
+ hotkeyArray.forEach(function (hotkey) {
97
+ return currentlyPressedKeys.add(hotkey.toLowerCase());
98
+ });
99
+ }
100
+ function removeFromCurrentlyPressedKeys(key) {
101
+ /*
102
+ Due to a weird behavior on macOS we need to clear the set if the user pressed down the meta key and presses another key.
103
+ https://stackoverflow.com/questions/11818637/why-does-javascript-drop-keyup-events-when-the-metakey-is-pressed-on-mac-browser
104
+ Otherwise the set will hold all ever pressed keys while the meta key is down which leads to wrong results.
105
+ */
106
+ if (key === 'meta') {
107
+ currentlyPressedKeys.clear();
108
+ } else {
109
+ currentlyPressedKeys["delete"](key);
110
+ }
111
+ }
112
+ (function () {
113
+ document.addEventListener('keydown', function (e) {
114
+ if (e.key === undefined) {
115
+ // Synthetic event (e.g., Chrome autofill). Ignore.
116
+ return;
117
+ }
118
+ pushToCurrentlyPressedKeys(e.key.toLowerCase());
119
+ });
120
+ document.addEventListener('keyup', function (e) {
121
+ if (e.key === undefined) {
122
+ // Synthetic event (e.g., Chrome autofill). Ignore.
123
+ return;
124
+ }
125
+ removeFromCurrentlyPressedKeys(e.key.toLowerCase());
126
+ });
127
+ })();
128
+
102
129
  function maybePreventDefault(e, hotkey, preventDefault) {
103
130
  if (typeof preventDefault === 'function' && preventDefault(e, hotkey) || preventDefault === true) {
104
131
  e.preventDefault();
@@ -138,18 +165,18 @@ function isScopeActive(activeScopes, scopes) {
138
165
  return scopes.includes(scope);
139
166
  }) || activeScopes.includes('*');
140
167
  }
141
- var isHotkeyMatchingKeyboardEvent = function isHotkeyMatchingKeyboardEvent(e, hotkey, pressedDownKeys) {
168
+ var isHotkeyMatchingKeyboardEvent = function isHotkeyMatchingKeyboardEvent(e, hotkey) {
142
169
  var alt = hotkey.alt,
143
170
  meta = hotkey.meta,
144
171
  mod = hotkey.mod,
145
172
  shift = hotkey.shift,
146
173
  keys = hotkey.keys;
147
- var altKey = e.altKey,
148
- ctrlKey = e.ctrlKey,
149
- metaKey = e.metaKey,
150
- shiftKey = e.shiftKey,
151
- pressedKeyUppercase = e.key,
174
+ var pressedKeyUppercase = e.key,
152
175
  code = e.code;
176
+ var altKey = isHotkeyPressed('alt');
177
+ var shiftKey = isHotkeyPressed('shift');
178
+ var metaKey = isHotkeyPressed('meta');
179
+ var ctrlKey = isHotkeyPressed('ctrl');
153
180
  var keyCode = code.toLowerCase().replace('key', '');
154
181
  var pressedKey = pressedKeyUppercase.toLowerCase();
155
182
  if (altKey !== alt && pressedKey !== 'alt') {
@@ -169,14 +196,12 @@ var isHotkeyMatchingKeyboardEvent = function isHotkeyMatchingKeyboardEvent(e, ho
169
196
  }
170
197
  }
171
198
  // All modifiers are correct, now check the key
172
- // If the key is set we check for the key
199
+ // If the key is set, we check for the key
173
200
  if (keys && keys.length === 1 && (keys.includes(pressedKey) || keys.includes(keyCode))) {
174
201
  return true;
175
202
  } else if (keys) {
176
203
  // Check if all keys are present in pressedDownKeys set
177
- return keys.every(function (key) {
178
- return pressedDownKeys.has(key);
179
- });
204
+ return isHotkeyPressed(keys);
180
205
  } else if (!keys) {
181
206
  // If the key is not set, we only listen for modifiers, that check went alright, so we return true
182
207
  return true;
@@ -314,7 +339,6 @@ var stopPropagation = function stopPropagation(e) {
314
339
  e.stopImmediatePropagation();
315
340
  };
316
341
  var useSafeLayoutEffect = typeof window !== 'undefined' ? react.useLayoutEffect : react.useEffect;
317
- var pressedDownKeys = /*#__PURE__*/new Set();
318
342
  function useHotkeys(keys, callback, options, dependencies) {
319
343
  var ref = react.useRef(null);
320
344
  var _options = !(options instanceof Array) ? options : !(dependencies instanceof Array) ? dependencies : undefined;
@@ -345,12 +369,13 @@ function useHotkeys(keys, callback, options, dependencies) {
345
369
  parseKeysHookInput(keys, memoisedOptions == null ? void 0 : memoisedOptions.splitKey).forEach(function (key) {
346
370
  var _hotkey$keys;
347
371
  var hotkey = parseHotkey(key, memoisedOptions == null ? void 0 : memoisedOptions.combinationKey);
348
- if (isHotkeyMatchingKeyboardEvent(e, hotkey, pressedDownKeys) || (_hotkey$keys = hotkey.keys) != null && _hotkey$keys.includes('*')) {
372
+ if (isHotkeyMatchingKeyboardEvent(e, hotkey) || (_hotkey$keys = hotkey.keys) != null && _hotkey$keys.includes('*')) {
349
373
  maybePreventDefault(e, hotkey, memoisedOptions == null ? void 0 : memoisedOptions.preventDefault);
350
374
  if (!isHotkeyEnabled(e, hotkey, memoisedOptions == null ? void 0 : memoisedOptions.enabled)) {
351
375
  stopPropagation(e);
352
376
  return;
353
377
  }
378
+ // Execute the user callback for that hotkey
354
379
  cb(e, hotkey);
355
380
  }
356
381
  });
@@ -360,7 +385,6 @@ function useHotkeys(keys, callback, options, dependencies) {
360
385
  // Synthetic event (e.g., Chrome autofill). Ignore.
361
386
  return;
362
387
  }
363
- pressedDownKeys.add(event.key.toLowerCase());
364
388
  if ((memoisedOptions == null ? void 0 : memoisedOptions.keydown) === undefined && (memoisedOptions == null ? void 0 : memoisedOptions.keyup) !== true || memoisedOptions != null && memoisedOptions.keydown) {
365
389
  listener(event);
366
390
  }
@@ -370,12 +394,6 @@ function useHotkeys(keys, callback, options, dependencies) {
370
394
  // Synthetic event (e.g., Chrome autofill). Ignore.
371
395
  return;
372
396
  }
373
- if (event.key.toLowerCase() !== 'meta') {
374
- pressedDownKeys["delete"](event.key.toLowerCase());
375
- } else {
376
- // On macOS pressing down the meta key prevents triggering the keyup event for any other key https://stackoverflow.com/a/57153300/735226.
377
- pressedDownKeys.clear();
378
- }
379
397
  if (memoisedOptions != null && memoisedOptions.keyup) {
380
398
  listener(event);
381
399
  }
@@ -404,65 +422,6 @@ function useHotkeys(keys, callback, options, dependencies) {
404
422
  return ref;
405
423
  }
406
424
 
407
- var currentlyPressedKeys = /*#__PURE__*/new Set();
408
- function isHotkeyPressed(key, splitKey) {
409
- if (splitKey === void 0) {
410
- splitKey = ',';
411
- }
412
- var hotkeyArray = Array.isArray(key) ? key : key.split(splitKey);
413
- return hotkeyArray.every(function (hotkey) {
414
- var parsedHotkey = parseHotkey(hotkey);
415
- for (var _iterator = _createForOfIteratorHelperLoose(currentlyPressedKeys), _step; !(_step = _iterator()).done;) {
416
- var pressedHotkey = _step.value;
417
- if (deepEqual(parsedHotkey, pressedHotkey)) {
418
- return true;
419
- }
420
- }
421
- });
422
- }
423
- function pushToCurrentlyPressedKeys(key) {
424
- var hotkeyArray = Array.isArray(key) ? key : [key];
425
- hotkeyArray.forEach(function (hotkey) {
426
- return currentlyPressedKeys.add(parseHotkey(hotkey));
427
- });
428
- }
429
- function removeFromCurrentlyPressedKeys(key) {
430
- var hotkeyArray = Array.isArray(key) ? key : [key];
431
- hotkeyArray.forEach(function (hotkey) {
432
- var parsedHotkey = parseHotkey(hotkey);
433
- for (var _iterator2 = _createForOfIteratorHelperLoose(currentlyPressedKeys), _step2; !(_step2 = _iterator2()).done;) {
434
- var _pressedHotkey$keys;
435
- var pressedHotkey = _step2.value;
436
- if ((_pressedHotkey$keys = pressedHotkey.keys) != null && _pressedHotkey$keys.every(function (key) {
437
- var _parsedHotkey$keys;
438
- return (_parsedHotkey$keys = parsedHotkey.keys) == null ? void 0 : _parsedHotkey$keys.includes(key);
439
- })) {
440
- currentlyPressedKeys["delete"](pressedHotkey);
441
- }
442
- }
443
- });
444
- }
445
- (function () {
446
- if (typeof window !== 'undefined') {
447
- window.addEventListener('DOMContentLoaded', function () {
448
- document.addEventListener('keydown', function (e) {
449
- if (e.key === undefined) {
450
- // Synthetic event (e.g., Chrome autofill). Ignore.
451
- return;
452
- }
453
- pushToCurrentlyPressedKeys(e.key);
454
- });
455
- document.addEventListener('keyup', function (e) {
456
- if (e.key === undefined) {
457
- // Synthetic event (e.g., Chrome autofill). Ignore.
458
- return;
459
- }
460
- removeFromCurrentlyPressedKeys(e.key);
461
- });
462
- });
463
- }
464
- })();
465
-
466
425
  exports.HotkeysProvider = HotkeysProvider;
467
426
  exports.isHotkeyPressed = isHotkeyPressed;
468
427
  exports.useHotkeys = useHotkeys;
@@ -1 +1 @@
1
- {"version":3,"file":"react-hotkeys-hook.cjs.development.js","sources":["../src/parseHotkeys.ts","../src/validators.ts","../src/BoundHotkeysProxyProvider.tsx","../src/deepEqual.ts","../src/HotkeysProvider.tsx","../src/useDeepEqualMemo.ts","../src/useHotkeys.ts","../src/isHotkeyPressed.ts"],"sourcesContent":["import { Hotkey, KeyboardModifiers, Keys } from './types'\n\nconst reservedModifierKeywords = ['shift', 'alt', 'meta', 'mod']\n\nconst mappedKeys: Record<string, string> = {\n esc: 'escape',\n return: 'enter',\n left: 'arrowleft',\n up: 'arrowup',\n right: 'arrowright',\n down: 'arrowdown',\n '1': 'digit1',\n '2': 'digit2',\n '3': 'digit3',\n '4': 'digit4',\n '5': 'digit5',\n '6': 'digit6',\n '7': 'digit7',\n '8': 'digit8',\n '9': 'digit9',\n}\n\nexport function parseKeysHookInput(keys: Keys, splitKey: string = ','): string[] {\n if (typeof keys === 'string') {\n return keys.split(splitKey)\n }\n\n return keys\n}\n\nexport function parseHotkey(hotkey: string, combinationKey: string = '+'): Hotkey {\n const keys = hotkey\n .toLocaleLowerCase()\n .split(combinationKey)\n .map(k => k.trim())\n .map(k => mappedKeys[k] || k)\n\n const modifiers: KeyboardModifiers = {\n alt: keys.includes('alt'),\n shift: keys.includes('shift'),\n meta: keys.includes('meta'),\n mod: keys.includes('mod'),\n }\n\n const singleCharKeys = keys.filter((k) => !reservedModifierKeywords.includes(k))\n\n return {\n ...modifiers,\n keys: singleCharKeys,\n }\n}\n","import { FormTags, Hotkey, Scopes, Trigger } from './types'\n\nexport function maybePreventDefault(e: KeyboardEvent, hotkey: Hotkey, preventDefault?: Trigger): void {\n if ((typeof preventDefault === 'function' && preventDefault(e, hotkey)) || preventDefault === true) {\n e.preventDefault()\n }\n}\n\nexport function isHotkeyEnabled(e: KeyboardEvent, hotkey: Hotkey, enabled?: Trigger): boolean {\n if (typeof enabled === 'function') {\n return enabled(e, hotkey)\n }\n\n return enabled === true || enabled === undefined\n}\n\nexport function isKeyboardEventTriggeredByInput(ev: KeyboardEvent): boolean {\n return isHotkeyEnabledOnTag(ev, ['input', 'textarea', 'select'])\n}\n\nexport function isHotkeyEnabledOnTag({ target }: KeyboardEvent, enabledOnTags: FormTags[] | boolean = false): boolean {\n const targetTagName = target && (target as HTMLElement).tagName\n\n if (enabledOnTags instanceof Array) {\n return Boolean(targetTagName && enabledOnTags && enabledOnTags.some(tag => tag.toLowerCase() === targetTagName.toLowerCase()))\n }\n\n return Boolean(targetTagName && enabledOnTags && enabledOnTags === true)\n}\n\nexport function isScopeActive(activeScopes: string[], scopes?: Scopes): boolean {\n if (activeScopes.length === 0 && scopes) {\n console.warn(\n 'A hotkey has the \"scopes\" option set, however no active scopes were found. If you want to use the global scopes feature, you need to wrap your app in a <HotkeysProvider>'\n )\n\n return true\n }\n\n if (!scopes) {\n return true\n }\n\n return activeScopes.some(scope => scopes.includes(scope)) || activeScopes.includes('*')\n}\n\nexport const isHotkeyMatchingKeyboardEvent = (e: KeyboardEvent, hotkey: Hotkey, pressedDownKeys: Set<string>): boolean => {\n const { alt, meta, mod, shift, keys } = hotkey\n const { altKey, ctrlKey, metaKey, shiftKey, key: pressedKeyUppercase, code } = e\n\n const keyCode = code.toLowerCase().replace('key', '')\n const pressedKey = pressedKeyUppercase.toLowerCase()\n\n if (altKey !== alt && pressedKey !== 'alt') {\n return false\n }\n\n if (shiftKey !== shift && pressedKey !== 'shift') {\n return false\n }\n\n // Mod is a special key name that is checking for meta on macOS and ctrl on other platforms\n if (mod) {\n if (!metaKey && !ctrlKey) {\n return false\n }\n } else {\n if (metaKey !== meta && ctrlKey !== meta && keyCode !== 'meta' && keyCode !== 'ctrl') {\n return false\n }\n }\n\n // All modifiers are correct, now check the key\n // If the key is set we check for the key\n if (keys && keys.length === 1 && (keys.includes(pressedKey) || keys.includes(keyCode))) {\n return true\n } else if (keys) {\n // Check if all keys are present in pressedDownKeys set\n return keys.every(key => pressedDownKeys.has(key))\n }\n else if (!keys) {\n // If the key is not set, we only listen for modifiers, that check went alright, so we return true\n return true\n }\n\n // There is nothing that matches.\n return false\n}\n","import { createContext, ReactNode, useContext } from 'react'\nimport { Hotkey } from './types'\n\ntype BoundHotkeysProxyProviderType = {\n addHotkey: (hotkey: Hotkey) => void,\n removeHotkey: (hotkey: Hotkey) => void,\n}\n\nconst BoundHotkeysProxyProvider = createContext<BoundHotkeysProxyProviderType | undefined>(undefined)\n\nexport const useBoundHotkeysProxy = () => {\n return useContext(BoundHotkeysProxyProvider)\n}\n\ninterface Props {\n children: ReactNode\n addHotkey: (hotkey: Hotkey) => void\n removeHotkey: (hotkey: Hotkey) => void\n}\n\nexport default function BoundHotkeysProxyProviderProvider({ addHotkey, removeHotkey, children }: Props) {\n return <BoundHotkeysProxyProvider.Provider value={{addHotkey, removeHotkey}}>{children}</BoundHotkeysProxyProvider.Provider>\n}\n","export default function deepEqual(x: any, y: any): boolean {\n //@ts-ignore\n return (x && y && typeof x === 'object' && typeof y === 'object')\n //@ts-ignore\n ? (Object.keys(x).length === Object.keys(y).length) && Object.keys(x).reduce(function(isEqual, key) {\n return isEqual && deepEqual(x[key], y[key])\n }, true)\n : (x === y)\n}\n","import { Hotkey } from './types'\nimport { createContext, ReactNode, useState, useContext, useCallback } from 'react'\nimport BoundHotkeysProxyProviderProvider from './BoundHotkeysProxyProvider'\nimport deepEqual from './deepEqual'\n\nexport type HotkeysContextType = {\n hotkeys: ReadonlyArray<Hotkey>\n enabledScopes: string[]\n toggleScope: (scope: string) => void\n enableScope: (scope: string) => void\n disableScope: (scope: string) => void\n}\n\n// The context is only needed for special features like global scoping, so we use a graceful default fallback\nconst HotkeysContext = createContext<HotkeysContextType>({\n hotkeys: [],\n enabledScopes: [], // This array has to be empty instead of containing '*' as default, to check if the provider is set or not\n toggleScope: () => {},\n enableScope: () => {},\n disableScope: () => {},\n})\n\nexport const useHotkeysContext = () => {\n return useContext(HotkeysContext)\n}\n\ninterface Props {\n initiallyActiveScopes?: string[]\n children: ReactNode\n}\n\nexport const HotkeysProvider = ({initiallyActiveScopes = ['*'], children}: Props) => {\n const [internalActiveScopes, setInternalActiveScopes] = useState(initiallyActiveScopes?.length > 0 ? initiallyActiveScopes : ['*'])\n const [boundHotkeys, setBoundHotkeys] = useState<Hotkey[]>([]);\n\n const enableScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.includes('*')) {\n return [scope]\n }\n\n return Array.from(new Set([...prev, scope]))\n })\n }, [])\n\n const disableScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.filter(s => s !== scope).length === 0) {\n return ['*']\n } else {\n return prev.filter(s => s !== scope)\n }\n })\n }, [])\n\n const toggleScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.includes(scope)) {\n if (prev.filter(s => s !== scope).length === 0) {\n return ['*']\n } else {\n return prev.filter(s => s !== scope)\n }\n } else {\n if (prev.includes('*')) {\n return [scope]\n }\n\n return Array.from(new Set([...prev, scope]))\n }\n })\n }, [])\n\n const addBoundHotkey = useCallback((hotkey: Hotkey) => {\n setBoundHotkeys((prev) => [...prev, hotkey])\n }, [])\n\n const removeBoundHotkey = useCallback((hotkey: Hotkey) => {\n setBoundHotkeys((prev) => prev.filter(h => !deepEqual(h, hotkey)))\n }, [])\n\n return (\n <HotkeysContext.Provider value={{enabledScopes: internalActiveScopes, hotkeys: boundHotkeys, enableScope, disableScope, toggleScope}}>\n <BoundHotkeysProxyProviderProvider addHotkey={addBoundHotkey} removeHotkey={removeBoundHotkey}>\n {children}\n </BoundHotkeysProxyProviderProvider>\n </HotkeysContext.Provider>\n )\n}\n","import { useRef } from 'react'\nimport deepEqual from './deepEqual'\n\nexport default function useDeepEqualMemo<T>(value: T) {\n const ref = useRef<T | undefined>(undefined)\n\n if (!deepEqual(ref.current, value)) {\n ref.current = value\n }\n\n return ref.current\n}\n","import { HotkeyCallback, Keys, Options, OptionsOrDependencyArray, RefType } from './types'\nimport { DependencyList, useCallback, useEffect, useLayoutEffect, useRef } from 'react'\nimport { parseHotkey, parseKeysHookInput } from './parseHotkeys'\nimport {\n isHotkeyEnabled,\n isHotkeyEnabledOnTag,\n isHotkeyMatchingKeyboardEvent,\n isKeyboardEventTriggeredByInput,\n isScopeActive,\n maybePreventDefault,\n} from './validators'\nimport { useHotkeysContext } from './HotkeysProvider'\nimport { useBoundHotkeysProxy } from './BoundHotkeysProxyProvider'\nimport useDeepEqualMemo from './useDeepEqualMemo'\n\nconst stopPropagation = (e: KeyboardEvent): void => {\n e.stopPropagation()\n e.preventDefault()\n e.stopImmediatePropagation()\n}\n\nconst useSafeLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect\n\nconst pressedDownKeys = new Set<string>()\n\nexport default function useHotkeys<T extends HTMLElement>(\n keys: Keys,\n callback: HotkeyCallback,\n options?: OptionsOrDependencyArray,\n dependencies?: OptionsOrDependencyArray,\n) {\n const ref = useRef<RefType<T>>(null)\n\n const _options: Options | undefined = !(options instanceof Array) ? (options as Options) : !(dependencies instanceof Array) ? (dependencies as Options) : undefined\n const _deps: DependencyList = options instanceof Array ? options : dependencies instanceof Array ? dependencies : []\n\n const cb = useCallback(callback, [..._deps])\n const memoisedOptions = useDeepEqualMemo(_options)\n\n const { enabledScopes } = useHotkeysContext()\n const proxy = useBoundHotkeysProxy()\n\n useSafeLayoutEffect(() => {\n if (memoisedOptions?.enabled === false || !isScopeActive(enabledScopes, memoisedOptions?.scopes)) {\n return\n }\n\n const listener = (e: KeyboardEvent) => {\n if (isKeyboardEventTriggeredByInput(e) && !isHotkeyEnabledOnTag(e, memoisedOptions?.enableOnFormTags)) {\n return\n }\n\n // TODO: SINCE THE EVENT IS NOW ATTACHED TO THE REF, THE ACTIVE ELEMENT CAN NEVER BE INSIDE THE REF. THE HOTKEY ONLY TRIGGERS IF THE\n // REF IS THE ACTIVE ELEMENT. THIS IS A PROBLEM SINCE FOCUSED SUB COMPONENTS WON'T TRIGGER THE HOTKEY.\n if (ref.current !== null && document.activeElement !== ref.current && !ref.current.contains(document.activeElement)) {\n stopPropagation(e)\n\n return\n }\n\n if (((e.target as HTMLElement)?.isContentEditable && !memoisedOptions?.enableOnContentEditable)) {\n return\n }\n\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => {\n const hotkey = parseHotkey(key, memoisedOptions?.combinationKey)\n\n if (isHotkeyMatchingKeyboardEvent(e, hotkey, pressedDownKeys) || hotkey.keys?.includes('*')) {\n maybePreventDefault(e, hotkey, memoisedOptions?.preventDefault)\n\n if (!isHotkeyEnabled(e, hotkey, memoisedOptions?.enabled)) {\n stopPropagation(e)\n\n return\n }\n\n cb(e, hotkey)\n }\n })\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n pressedDownKeys.add(event.key.toLowerCase())\n\n if ((memoisedOptions?.keydown === undefined && memoisedOptions?.keyup !== true) || memoisedOptions?.keydown) {\n listener(event)\n }\n }\n\n const handleKeyUp = (event: KeyboardEvent) => {\n if (event.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n if (event.key.toLowerCase() !== 'meta') {\n pressedDownKeys.delete(event.key.toLowerCase())\n } else {\n // On macOS pressing down the meta key prevents triggering the keyup event for any other key https://stackoverflow.com/a/57153300/735226.\n pressedDownKeys.clear()\n }\n\n if (memoisedOptions?.keyup) {\n listener(event)\n }\n }\n\n // @ts-ignore\n (ref.current || document).addEventListener('keyup', handleKeyUp);\n // @ts-ignore\n (ref.current || document).addEventListener('keydown', handleKeyDown)\n\n if (proxy) {\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => proxy.addHotkey(parseHotkey(key, memoisedOptions?.combinationKey)))\n }\n\n return () => {\n // @ts-ignore\n (ref.current || document).removeEventListener('keyup', handleKeyUp);\n // @ts-ignore\n (ref.current || document).removeEventListener('keydown', handleKeyDown)\n\n if (proxy) {\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => proxy.removeHotkey(parseHotkey(key, memoisedOptions?.combinationKey)))\n }\n }\n }, [keys, cb, memoisedOptions, enabledScopes])\n\n return ref\n}\n","import { Hotkey } from './types'\nimport { parseHotkey } from './parseHotkeys'\nimport deepEqual from './deepEqual'\n\nconst currentlyPressedKeys: Set<Hotkey> = new Set<Hotkey>()\n\nexport function isHotkeyPressed(key: string | string[], splitKey: string = ','): boolean {\n const hotkeyArray = Array.isArray(key) ? key : key.split(splitKey)\n\n return hotkeyArray.every((hotkey) => {\n const parsedHotkey = parseHotkey(hotkey)\n\n for (const pressedHotkey of currentlyPressedKeys) {\n if (deepEqual(parsedHotkey, pressedHotkey)) {\n return true\n }\n }\n })\n}\n\nexport function pushToCurrentlyPressedKeys(key: string | string[]): void {\n const hotkeyArray = Array.isArray(key) ? key : [key]\n\n hotkeyArray.forEach(hotkey => currentlyPressedKeys.add(parseHotkey(hotkey)))\n}\n\nexport function removeFromCurrentlyPressedKeys(key: string | string[]): void {\n const hotkeyArray = Array.isArray(key) ? key : [key]\n\n hotkeyArray.forEach((hotkey) => {\n const parsedHotkey = parseHotkey(hotkey)\n\n for (const pressedHotkey of currentlyPressedKeys) {\n if (pressedHotkey.keys?.every((key) => parsedHotkey.keys?.includes(key))) {\n currentlyPressedKeys.delete(pressedHotkey)\n }\n }\n })\n}\n\n(() => {\n if (typeof window !== 'undefined') {\n window.addEventListener('DOMContentLoaded', () => {\n document.addEventListener('keydown', e => {\n if (e.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n pushToCurrentlyPressedKeys(e.key)\n })\n\n document.addEventListener('keyup', e => {\n if (e.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n removeFromCurrentlyPressedKeys(e.key)\n })\n })\n }\n})()\n"],"names":["reservedModifierKeywords","mappedKeys","esc","left","up","right","down","parseKeysHookInput","keys","splitKey","split","parseHotkey","hotkey","combinationKey","toLocaleLowerCase","map","k","trim","modifiers","alt","includes","shift","meta","mod","singleCharKeys","filter","maybePreventDefault","e","preventDefault","isHotkeyEnabled","enabled","undefined","isKeyboardEventTriggeredByInput","ev","isHotkeyEnabledOnTag","enabledOnTags","target","targetTagName","tagName","Array","Boolean","some","tag","toLowerCase","isScopeActive","activeScopes","scopes","length","console","warn","scope","isHotkeyMatchingKeyboardEvent","pressedDownKeys","altKey","ctrlKey","metaKey","shiftKey","pressedKeyUppercase","key","code","keyCode","replace","pressedKey","every","has","BoundHotkeysProxyProvider","createContext","useBoundHotkeysProxy","useContext","BoundHotkeysProxyProviderProvider","addHotkey","removeHotkey","children","_jsx","deepEqual","x","y","Object","reduce","isEqual","HotkeysContext","hotkeys","enabledScopes","toggleScope","enableScope","disableScope","useHotkeysContext","HotkeysProvider","initiallyActiveScopes","useState","internalActiveScopes","setInternalActiveScopes","boundHotkeys","setBoundHotkeys","useCallback","prev","from","Set","s","addBoundHotkey","removeBoundHotkey","h","useDeepEqualMemo","value","ref","useRef","current","stopPropagation","stopImmediatePropagation","useSafeLayoutEffect","window","useLayoutEffect","useEffect","useHotkeys","callback","options","dependencies","_options","_deps","cb","memoisedOptions","proxy","listener","enableOnFormTags","document","activeElement","contains","isContentEditable","enableOnContentEditable","forEach","handleKeyDown","event","add","keydown","keyup","handleKeyUp","clear","addEventListener","removeEventListener","currentlyPressedKeys","isHotkeyPressed","hotkeyArray","isArray","parsedHotkey","pressedHotkey","pushToCurrentlyPressedKeys","removeFromCurrentlyPressedKeys"],"mappings":"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"}
1
+ {"version":3,"file":"react-hotkeys-hook.cjs.development.js","sources":["../src/parseHotkeys.ts","../src/isHotkeyPressed.ts","../src/validators.ts","../src/BoundHotkeysProxyProvider.tsx","../src/deepEqual.ts","../src/HotkeysProvider.tsx","../src/useDeepEqualMemo.ts","../src/useHotkeys.ts"],"sourcesContent":["import { Hotkey, KeyboardModifiers, Keys } from './types'\n\nconst reservedModifierKeywords = ['shift', 'alt', 'meta', 'mod']\n\nconst mappedKeys: Record<string, string> = {\n esc: 'escape',\n return: 'enter',\n left: 'arrowleft',\n up: 'arrowup',\n right: 'arrowright',\n down: 'arrowdown',\n '1': 'digit1',\n '2': 'digit2',\n '3': 'digit3',\n '4': 'digit4',\n '5': 'digit5',\n '6': 'digit6',\n '7': 'digit7',\n '8': 'digit8',\n '9': 'digit9',\n}\n\nexport function isHotkeyModifier(key: string) {\n return reservedModifierKeywords.includes(key)\n}\n\nexport function parseKeysHookInput(keys: Keys, splitKey: string = ','): string[] {\n if (typeof keys === 'string') {\n return keys.split(splitKey)\n }\n\n return keys\n}\n\nexport function parseHotkey(hotkey: string, combinationKey: string = '+'): Hotkey {\n const keys = hotkey\n .toLocaleLowerCase()\n .split(combinationKey)\n .map(k => k.trim())\n .map(k => mappedKeys[k] || k)\n\n const modifiers: KeyboardModifiers = {\n alt: keys.includes('alt'),\n shift: keys.includes('shift'),\n meta: keys.includes('meta'),\n mod: keys.includes('mod'),\n }\n\n const singleCharKeys = keys.filter((k) => !reservedModifierKeywords.includes(k))\n\n return {\n ...modifiers,\n keys: singleCharKeys,\n }\n}\n","import { isHotkeyModifier } from './parseHotkeys'\n\nconst currentlyPressedKeys: Set<string> = new Set<string>()\n\nexport function isHotkeyPressed(key: string | string[], splitKey: string = ','): boolean {\n const hotkeyArray = Array.isArray(key) ? key : key.split(splitKey)\n\n return hotkeyArray.every((hotkey) => currentlyPressedKeys.has(hotkey.trim().toLowerCase()))\n}\n\nfunction pushToCurrentlyPressedKeys(key: string | string[]): void {\n const hotkeyArray = Array.isArray(key) ? key : [key]\n\n /*\n Due to a weird behavior on macOS we need to clear the set if the user pressed down the meta key and presses another key.\n https://stackoverflow.com/questions/11818637/why-does-javascript-drop-keyup-events-when-the-metakey-is-pressed-on-mac-browser\n Otherwise the set will hold all ever pressed keys while the meta key is down which leads to wrong results.\n */\n if (currentlyPressedKeys.has('meta')) {\n currentlyPressedKeys.forEach(key => !isHotkeyModifier(key) && currentlyPressedKeys.delete(key))\n }\n\n hotkeyArray.forEach(hotkey => currentlyPressedKeys.add(hotkey.toLowerCase()))\n}\n\nfunction removeFromCurrentlyPressedKeys(key: string): void {\n /*\n Due to a weird behavior on macOS we need to clear the set if the user pressed down the meta key and presses another key.\n https://stackoverflow.com/questions/11818637/why-does-javascript-drop-keyup-events-when-the-metakey-is-pressed-on-mac-browser\n Otherwise the set will hold all ever pressed keys while the meta key is down which leads to wrong results.\n */\n if (key === 'meta') {\n currentlyPressedKeys.clear()\n } else {\n currentlyPressedKeys.delete(key)\n }\n}\n\n(() => {\n document.addEventListener('keydown', e => {\n if (e.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n pushToCurrentlyPressedKeys(e.key.toLowerCase())\n })\n\n document.addEventListener('keyup', e => {\n if (e.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n removeFromCurrentlyPressedKeys(e.key.toLowerCase())\n })\n})()\n","import { FormTags, Hotkey, Scopes, Trigger } from './types'\nimport { isHotkeyPressed } from './isHotkeyPressed'\n\nexport function maybePreventDefault(e: KeyboardEvent, hotkey: Hotkey, preventDefault?: Trigger): void {\n if ((typeof preventDefault === 'function' && preventDefault(e, hotkey)) || preventDefault === true) {\n e.preventDefault()\n }\n}\n\nexport function isHotkeyEnabled(e: KeyboardEvent, hotkey: Hotkey, enabled?: Trigger): boolean {\n if (typeof enabled === 'function') {\n return enabled(e, hotkey)\n }\n\n return enabled === true || enabled === undefined\n}\n\nexport function isKeyboardEventTriggeredByInput(ev: KeyboardEvent): boolean {\n return isHotkeyEnabledOnTag(ev, ['input', 'textarea', 'select'])\n}\n\nexport function isHotkeyEnabledOnTag({ target }: KeyboardEvent, enabledOnTags: FormTags[] | boolean = false): boolean {\n const targetTagName = target && (target as HTMLElement).tagName\n\n if (enabledOnTags instanceof Array) {\n return Boolean(targetTagName && enabledOnTags && enabledOnTags.some(tag => tag.toLowerCase() === targetTagName.toLowerCase()))\n }\n\n return Boolean(targetTagName && enabledOnTags && enabledOnTags === true)\n}\n\nexport function isScopeActive(activeScopes: string[], scopes?: Scopes): boolean {\n if (activeScopes.length === 0 && scopes) {\n console.warn(\n 'A hotkey has the \"scopes\" option set, however no active scopes were found. If you want to use the global scopes feature, you need to wrap your app in a <HotkeysProvider>'\n )\n\n return true\n }\n\n if (!scopes) {\n return true\n }\n\n return activeScopes.some(scope => scopes.includes(scope)) || activeScopes.includes('*')\n}\n\nexport const isHotkeyMatchingKeyboardEvent = (e: KeyboardEvent, hotkey: Hotkey): boolean => {\n const { alt, meta, mod, shift, keys } = hotkey\n const { key: pressedKeyUppercase, code } = e\n\n const altKey = isHotkeyPressed('alt')\n const shiftKey = isHotkeyPressed('shift')\n const metaKey = isHotkeyPressed('meta')\n const ctrlKey = isHotkeyPressed('ctrl')\n\n const keyCode = code.toLowerCase().replace('key', '')\n const pressedKey = pressedKeyUppercase.toLowerCase()\n\n if (altKey !== alt && pressedKey !== 'alt') {\n return false\n }\n\n if (shiftKey !== shift && pressedKey !== 'shift') {\n return false\n }\n\n // Mod is a special key name that is checking for meta on macOS and ctrl on other platforms\n if (mod) {\n if (!metaKey && !ctrlKey) {\n return false\n }\n } else {\n if (metaKey !== meta && ctrlKey !== meta && keyCode !== 'meta' && keyCode !== 'ctrl') {\n return false\n }\n }\n\n // All modifiers are correct, now check the key\n // If the key is set, we check for the key\n if (keys && keys.length === 1 && (keys.includes(pressedKey) || keys.includes(keyCode))) {\n return true\n } else if (keys) {\n // Check if all keys are present in pressedDownKeys set\n return isHotkeyPressed(keys)\n }\n else if (!keys) {\n // If the key is not set, we only listen for modifiers, that check went alright, so we return true\n return true\n }\n\n // There is nothing that matches.\n return false\n}\n","import { createContext, ReactNode, useContext } from 'react'\nimport { Hotkey } from './types'\n\ntype BoundHotkeysProxyProviderType = {\n addHotkey: (hotkey: Hotkey) => void,\n removeHotkey: (hotkey: Hotkey) => void,\n}\n\nconst BoundHotkeysProxyProvider = createContext<BoundHotkeysProxyProviderType | undefined>(undefined)\n\nexport const useBoundHotkeysProxy = () => {\n return useContext(BoundHotkeysProxyProvider)\n}\n\ninterface Props {\n children: ReactNode\n addHotkey: (hotkey: Hotkey) => void\n removeHotkey: (hotkey: Hotkey) => void\n}\n\nexport default function BoundHotkeysProxyProviderProvider({ addHotkey, removeHotkey, children }: Props) {\n return <BoundHotkeysProxyProvider.Provider value={{addHotkey, removeHotkey}}>{children}</BoundHotkeysProxyProvider.Provider>\n}\n","export default function deepEqual(x: any, y: any): boolean {\n //@ts-ignore\n return (x && y && typeof x === 'object' && typeof y === 'object')\n //@ts-ignore\n ? (Object.keys(x).length === Object.keys(y).length) && Object.keys(x).reduce(function(isEqual, key) {\n return isEqual && deepEqual(x[key], y[key])\n }, true)\n : (x === y)\n}\n","import { Hotkey } from './types'\nimport { createContext, ReactNode, useState, useContext, useCallback } from 'react'\nimport BoundHotkeysProxyProviderProvider from './BoundHotkeysProxyProvider'\nimport deepEqual from './deepEqual'\n\nexport type HotkeysContextType = {\n hotkeys: ReadonlyArray<Hotkey>\n enabledScopes: string[]\n toggleScope: (scope: string) => void\n enableScope: (scope: string) => void\n disableScope: (scope: string) => void\n}\n\n// The context is only needed for special features like global scoping, so we use a graceful default fallback\nconst HotkeysContext = createContext<HotkeysContextType>({\n hotkeys: [],\n enabledScopes: [], // This array has to be empty instead of containing '*' as default, to check if the provider is set or not\n toggleScope: () => {},\n enableScope: () => {},\n disableScope: () => {},\n})\n\nexport const useHotkeysContext = () => {\n return useContext(HotkeysContext)\n}\n\ninterface Props {\n initiallyActiveScopes?: string[]\n children: ReactNode\n}\n\nexport const HotkeysProvider = ({initiallyActiveScopes = ['*'], children}: Props) => {\n const [internalActiveScopes, setInternalActiveScopes] = useState(initiallyActiveScopes?.length > 0 ? initiallyActiveScopes : ['*'])\n const [boundHotkeys, setBoundHotkeys] = useState<Hotkey[]>([]);\n\n const enableScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.includes('*')) {\n return [scope]\n }\n\n return Array.from(new Set([...prev, scope]))\n })\n }, [])\n\n const disableScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.filter(s => s !== scope).length === 0) {\n return ['*']\n } else {\n return prev.filter(s => s !== scope)\n }\n })\n }, [])\n\n const toggleScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.includes(scope)) {\n if (prev.filter(s => s !== scope).length === 0) {\n return ['*']\n } else {\n return prev.filter(s => s !== scope)\n }\n } else {\n if (prev.includes('*')) {\n return [scope]\n }\n\n return Array.from(new Set([...prev, scope]))\n }\n })\n }, [])\n\n const addBoundHotkey = useCallback((hotkey: Hotkey) => {\n setBoundHotkeys((prev) => [...prev, hotkey])\n }, [])\n\n const removeBoundHotkey = useCallback((hotkey: Hotkey) => {\n setBoundHotkeys((prev) => prev.filter(h => !deepEqual(h, hotkey)))\n }, [])\n\n return (\n <HotkeysContext.Provider value={{enabledScopes: internalActiveScopes, hotkeys: boundHotkeys, enableScope, disableScope, toggleScope}}>\n <BoundHotkeysProxyProviderProvider addHotkey={addBoundHotkey} removeHotkey={removeBoundHotkey}>\n {children}\n </BoundHotkeysProxyProviderProvider>\n </HotkeysContext.Provider>\n )\n}\n","import { useRef } from 'react'\nimport deepEqual from './deepEqual'\n\nexport default function useDeepEqualMemo<T>(value: T) {\n const ref = useRef<T | undefined>(undefined)\n\n if (!deepEqual(ref.current, value)) {\n ref.current = value\n }\n\n return ref.current\n}\n","import { HotkeyCallback, Keys, Options, OptionsOrDependencyArray, RefType } from './types'\nimport { DependencyList, useCallback, useEffect, useLayoutEffect, useRef } from 'react'\nimport { parseHotkey, parseKeysHookInput } from './parseHotkeys'\nimport {\n isHotkeyEnabled,\n isHotkeyEnabledOnTag,\n isHotkeyMatchingKeyboardEvent,\n isKeyboardEventTriggeredByInput,\n isScopeActive,\n maybePreventDefault,\n} from './validators'\nimport { useHotkeysContext } from './HotkeysProvider'\nimport { useBoundHotkeysProxy } from './BoundHotkeysProxyProvider'\nimport useDeepEqualMemo from './useDeepEqualMemo'\n\nconst stopPropagation = (e: KeyboardEvent): void => {\n e.stopPropagation()\n e.preventDefault()\n e.stopImmediatePropagation()\n}\n\nconst useSafeLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect\n\nexport default function useHotkeys<T extends HTMLElement>(\n keys: Keys,\n callback: HotkeyCallback,\n options?: OptionsOrDependencyArray,\n dependencies?: OptionsOrDependencyArray,\n) {\n const ref = useRef<RefType<T>>(null)\n\n const _options: Options | undefined = !(options instanceof Array) ? (options as Options) : !(dependencies instanceof Array) ? (dependencies as Options) : undefined\n const _deps: DependencyList = options instanceof Array ? options : dependencies instanceof Array ? dependencies : []\n\n const cb = useCallback(callback, [..._deps])\n const memoisedOptions = useDeepEqualMemo(_options)\n\n const { enabledScopes } = useHotkeysContext()\n const proxy = useBoundHotkeysProxy()\n\n useSafeLayoutEffect(() => {\n if (memoisedOptions?.enabled === false || !isScopeActive(enabledScopes, memoisedOptions?.scopes)) {\n return\n }\n\n const listener = (e: KeyboardEvent) => {\n if (isKeyboardEventTriggeredByInput(e) && !isHotkeyEnabledOnTag(e, memoisedOptions?.enableOnFormTags)) {\n return\n }\n\n // TODO: SINCE THE EVENT IS NOW ATTACHED TO THE REF, THE ACTIVE ELEMENT CAN NEVER BE INSIDE THE REF. THE HOTKEY ONLY TRIGGERS IF THE\n // REF IS THE ACTIVE ELEMENT. THIS IS A PROBLEM SINCE FOCUSED SUB COMPONENTS WON'T TRIGGER THE HOTKEY.\n if (ref.current !== null && document.activeElement !== ref.current && !ref.current.contains(document.activeElement)) {\n stopPropagation(e)\n\n return\n }\n\n if (((e.target as HTMLElement)?.isContentEditable && !memoisedOptions?.enableOnContentEditable)) {\n return\n }\n\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => {\n const hotkey = parseHotkey(key, memoisedOptions?.combinationKey)\n\n if (isHotkeyMatchingKeyboardEvent(e, hotkey) || hotkey.keys?.includes('*')) {\n maybePreventDefault(e, hotkey, memoisedOptions?.preventDefault)\n\n if (!isHotkeyEnabled(e, hotkey, memoisedOptions?.enabled)) {\n stopPropagation(e)\n\n return\n }\n\n // Execute the user callback for that hotkey\n cb(e, hotkey)\n }\n })\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n if ((memoisedOptions?.keydown === undefined && memoisedOptions?.keyup !== true) || memoisedOptions?.keydown) {\n listener(event)\n }\n }\n\n const handleKeyUp = (event: KeyboardEvent) => {\n if (event.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n if (memoisedOptions?.keyup) {\n listener(event)\n }\n }\n\n // @ts-ignore\n (ref.current || document).addEventListener('keyup', handleKeyUp);\n // @ts-ignore\n (ref.current || document).addEventListener('keydown', handleKeyDown)\n\n if (proxy) {\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => proxy.addHotkey(parseHotkey(key, memoisedOptions?.combinationKey)))\n }\n\n return () => {\n // @ts-ignore\n (ref.current || document).removeEventListener('keyup', handleKeyUp);\n // @ts-ignore\n (ref.current || document).removeEventListener('keydown', handleKeyDown)\n\n if (proxy) {\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => proxy.removeHotkey(parseHotkey(key, memoisedOptions?.combinationKey)))\n }\n }\n }, [keys, cb, memoisedOptions, enabledScopes])\n\n return ref\n}\n"],"names":["reservedModifierKeywords","mappedKeys","esc","left","up","right","down","isHotkeyModifier","key","includes","parseKeysHookInput","keys","splitKey","split","parseHotkey","hotkey","combinationKey","toLocaleLowerCase","map","k","trim","modifiers","alt","shift","meta","mod","singleCharKeys","filter","currentlyPressedKeys","Set","isHotkeyPressed","hotkeyArray","Array","isArray","every","has","toLowerCase","pushToCurrentlyPressedKeys","forEach","add","removeFromCurrentlyPressedKeys","clear","document","addEventListener","e","undefined","maybePreventDefault","preventDefault","isHotkeyEnabled","enabled","isKeyboardEventTriggeredByInput","ev","isHotkeyEnabledOnTag","enabledOnTags","target","targetTagName","tagName","Boolean","some","tag","isScopeActive","activeScopes","scopes","length","console","warn","scope","isHotkeyMatchingKeyboardEvent","pressedKeyUppercase","code","altKey","shiftKey","metaKey","ctrlKey","keyCode","replace","pressedKey","BoundHotkeysProxyProvider","createContext","useBoundHotkeysProxy","useContext","BoundHotkeysProxyProviderProvider","addHotkey","removeHotkey","children","_jsx","deepEqual","x","y","Object","reduce","isEqual","HotkeysContext","hotkeys","enabledScopes","toggleScope","enableScope","disableScope","useHotkeysContext","HotkeysProvider","initiallyActiveScopes","useState","internalActiveScopes","setInternalActiveScopes","boundHotkeys","setBoundHotkeys","useCallback","prev","from","s","addBoundHotkey","removeBoundHotkey","h","useDeepEqualMemo","value","ref","useRef","current","stopPropagation","stopImmediatePropagation","useSafeLayoutEffect","window","useLayoutEffect","useEffect","useHotkeys","callback","options","dependencies","_options","_deps","cb","memoisedOptions","proxy","listener","enableOnFormTags","activeElement","contains","isContentEditable","enableOnContentEditable","handleKeyDown","event","keydown","keyup","handleKeyUp","removeEventListener"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";var e=require("react"),t=require("react/jsx-runtime");function n(){return(n=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function r(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function o(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(n)return(n=n.call(e)).next.bind(n);if(Array.isArray(e)||(n=function(e,t){if(e){if("string"==typeof e)return r(e,void 0);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?r(e,void 0):void 0}}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var o=0;return function(){return o>=e.length?{done:!0}:{done:!1,value:e[o++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i=["shift","alt","meta","mod"],u={esc:"escape",return:"enter",left:"arrowleft",up:"arrowup",right:"arrowright",down:"arrowdown",1:"digit1",2:"digit2",3:"digit3",4:"digit4",5:"digit5",6:"digit6",7:"digit7",8:"digit8",9:"digit9"};function a(e,t){return void 0===t&&(t=","),"string"==typeof e?e.split(t):e}function c(e,t){void 0===t&&(t="+");var r=e.toLocaleLowerCase().split(t).map((function(e){return e.trim()})).map((function(e){return u[e]||e}));return n({},{alt:r.includes("alt"),shift:r.includes("shift"),meta:r.includes("meta"),mod:r.includes("mod")},{keys:r.filter((function(e){return!i.includes(e)}))})}function l(e,t){var n=e.target;void 0===t&&(t=!1);var r=n&&n.tagName;return t instanceof Array?Boolean(r&&t&&t.some((function(e){return e.toLowerCase()===r.toLowerCase()}))):Boolean(r&&t&&!0===t)}var d=e.createContext(void 0);function s(e){return t.jsx(d.Provider,{value:{addHotkey:e.addHotkey,removeHotkey:e.removeHotkey},children:e.children})}function f(e,t){return e&&t&&"object"==typeof e&&"object"==typeof t?Object.keys(e).length===Object.keys(t).length&&Object.keys(e).reduce((function(n,r){return n&&f(e[r],t[r])}),!0):e===t}var y=e.createContext({hotkeys:[],enabledScopes:[],toggleScope:function(){},enableScope:function(){},disableScope:function(){}}),v=function(){return e.useContext(y)},p=function(e){e.stopPropagation(),e.preventDefault(),e.stopImmediatePropagation()},m="undefined"!=typeof window?e.useLayoutEffect:e.useEffect,k=new Set,b=new Set;"undefined"!=typeof window&&window.addEventListener("DOMContentLoaded",(function(){document.addEventListener("keydown",(function(e){var t;void 0!==e.key&&(t=e.key,(Array.isArray(t)?t:[t]).forEach((function(e){return b.add(c(e))})))})),document.addEventListener("keyup",(function(e){var t;void 0!==e.key&&(t=e.key,(Array.isArray(t)?t:[t]).forEach((function(e){for(var t,n=c(e),r=o(b);!(t=r()).done;){var i,u=t.value;null!=(i=u.keys)&&i.every((function(e){var t;return null==(t=n.keys)?void 0:t.includes(e)}))&&b.delete(u)}})))}))})),exports.HotkeysProvider=function(n){var r=n.initiallyActiveScopes,o=void 0===r?["*"]:r,i=n.children,u=e.useState((null==o?void 0:o.length)>0?o:["*"]),a=u[0],c=u[1],l=e.useState([]),d=l[0],v=l[1],p=e.useCallback((function(e){c((function(t){return t.includes("*")?[e]:Array.from(new Set([].concat(t,[e])))}))}),[]),m=e.useCallback((function(e){c((function(t){return 0===t.filter((function(t){return t!==e})).length?["*"]:t.filter((function(t){return t!==e}))}))}),[]),k=e.useCallback((function(e){c((function(t){return t.includes(e)?0===t.filter((function(t){return t!==e})).length?["*"]:t.filter((function(t){return t!==e})):t.includes("*")?[e]:Array.from(new Set([].concat(t,[e])))}))}),[]),b=e.useCallback((function(e){v((function(t){return[].concat(t,[e])}))}),[]),h=e.useCallback((function(e){v((function(t){return t.filter((function(t){return!f(t,e)}))}))}),[]);return t.jsx(y.Provider,{value:{enabledScopes:a,hotkeys:d,enableScope:p,disableScope:m,toggleScope:k},children:t.jsx(s,{addHotkey:b,removeHotkey:h,children:i})})},exports.isHotkeyPressed=function(e,t){return void 0===t&&(t=","),(Array.isArray(e)?e:e.split(t)).every((function(e){for(var t,n=c(e),r=o(b);!(t=r()).done;)if(f(n,t.value))return!0}))},exports.useHotkeys=function(t,n,r,o){var i=e.useRef(null),u=r instanceof Array?o instanceof Array?void 0:o:r,s=e.useCallback(n,[].concat(r instanceof Array?r:o instanceof Array?o:[])),y=function(t){var n=e.useRef(void 0);return f(n.current,t)||(n.current=t),n.current}(u),b=v().enabledScopes,h=e.useContext(d);return m((function(){if(!1!==(null==y?void 0:y.enabled)&&(n=null==y?void 0:y.scopes,0===(e=b).length&&n?(console.warn('A hotkey has the "scopes" option set, however no active scopes were found. If you want to use the global scopes feature, you need to wrap your app in a <HotkeysProvider>'),1):!n||e.some((function(e){return n.includes(e)}))||e.includes("*"))){var e,n,r=function(e){var n;l(e,["input","textarea","select"])&&!l(e,null==y?void 0:y.enableOnFormTags)||(null===i.current||document.activeElement===i.current||i.current.contains(document.activeElement)?(null==(n=e.target)||!n.isContentEditable||null!=y&&y.enableOnContentEditable)&&a(t,null==y?void 0:y.splitKey).forEach((function(t){var n,r=c(t,null==y?void 0:y.combinationKey);if(function(e,t,n){var r=t.alt,o=t.meta,i=t.mod,u=t.shift,a=t.keys,c=e.altKey,l=e.ctrlKey,d=e.metaKey,s=e.shiftKey,f=e.key,y=e.code.toLowerCase().replace("key",""),v=f.toLowerCase();if(c!==r&&"alt"!==v)return!1;if(s!==u&&"shift"!==v)return!1;if(i){if(!d&&!l)return!1}else if(d!==o&&l!==o&&"meta"!==y&&"ctrl"!==y)return!1;return!(!a||1!==a.length||!a.includes(v)&&!a.includes(y))||(a?a.every((function(e){return n.has(e)})):!a)}(e,r,k)||null!=(n=r.keys)&&n.includes("*")){if(function(e,t,n){("function"==typeof n&&n(e,t)||!0===n)&&e.preventDefault()}(e,r,null==y?void 0:y.preventDefault),!function(e,t,n){return"function"==typeof n?n(e,t):!0===n||void 0===n}(e,r,null==y?void 0:y.enabled))return void p(e);s(e,r)}})):p(e))},o=function(e){void 0!==e.key&&(k.add(e.key.toLowerCase()),(void 0===(null==y?void 0:y.keydown)&&!0!==(null==y?void 0:y.keyup)||null!=y&&y.keydown)&&r(e))},u=function(e){void 0!==e.key&&("meta"!==e.key.toLowerCase()?k.delete(e.key.toLowerCase()):k.clear(),null!=y&&y.keyup&&r(e))};return(i.current||document).addEventListener("keyup",u),(i.current||document).addEventListener("keydown",o),h&&a(t,null==y?void 0:y.splitKey).forEach((function(e){return h.addHotkey(c(e,null==y?void 0:y.combinationKey))})),function(){(i.current||document).removeEventListener("keyup",u),(i.current||document).removeEventListener("keydown",o),h&&a(t,null==y?void 0:y.splitKey).forEach((function(e){return h.removeHotkey(c(e,null==y?void 0:y.combinationKey))}))}}}),[t,s,y,b]),i},exports.useHotkeysContext=v;
1
+ "use strict";var e=require("react"),t=require("react/jsx-runtime");function n(){return(n=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}var r=["shift","alt","meta","mod"],o={esc:"escape",return:"enter",left:"arrowleft",up:"arrowup",right:"arrowright",down:"arrowdown",1:"digit1",2:"digit2",3:"digit3",4:"digit4",5:"digit5",6:"digit6",7:"digit7",8:"digit8",9:"digit9"};function i(e,t){return void 0===t&&(t=","),"string"==typeof e?e.split(t):e}function u(e,t){void 0===t&&(t="+");var i=e.toLocaleLowerCase().split(t).map((function(e){return e.trim()})).map((function(e){return o[e]||e}));return n({},{alt:i.includes("alt"),shift:i.includes("shift"),meta:i.includes("meta"),mod:i.includes("mod")},{keys:i.filter((function(e){return!r.includes(e)}))})}var c=new Set;function a(e,t){return void 0===t&&(t=","),(Array.isArray(e)?e:e.split(t)).every((function(e){return c.has(e.trim().toLowerCase())}))}function l(e,t){var n=e.target;void 0===t&&(t=!1);var r=n&&n.tagName;return t instanceof Array?Boolean(r&&t&&t.some((function(e){return e.toLowerCase()===r.toLowerCase()}))):Boolean(r&&t&&!0===t)}document.addEventListener("keydown",(function(e){var t,n;void 0!==e.key&&(t=e.key.toLowerCase(),n=Array.isArray(t)?t:[t],c.has("meta")&&c.forEach((function(e){return!function(e){return r.includes(e)}(e)&&c.delete(e)})),n.forEach((function(e){return c.add(e.toLowerCase())})))})),document.addEventListener("keyup",(function(e){var t;void 0!==e.key&&("meta"===(t=e.key.toLowerCase())?c.clear():c.delete(t))}));var s=e.createContext(void 0);function d(e){return t.jsx(s.Provider,{value:{addHotkey:e.addHotkey,removeHotkey:e.removeHotkey},children:e.children})}function f(e,t){return e&&t&&"object"==typeof e&&"object"==typeof t?Object.keys(e).length===Object.keys(t).length&&Object.keys(e).reduce((function(n,r){return n&&f(e[r],t[r])}),!0):e===t}var v=e.createContext({hotkeys:[],enabledScopes:[],toggleScope:function(){},enableScope:function(){},disableScope:function(){}}),y=function(){return e.useContext(v)},p=function(e){e.stopPropagation(),e.preventDefault(),e.stopImmediatePropagation()},k="undefined"!=typeof window?e.useLayoutEffect:e.useEffect;exports.HotkeysProvider=function(n){var r=n.initiallyActiveScopes,o=void 0===r?["*"]:r,i=n.children,u=e.useState((null==o?void 0:o.length)>0?o:["*"]),c=u[0],a=u[1],l=e.useState([]),s=l[0],y=l[1],p=e.useCallback((function(e){a((function(t){return t.includes("*")?[e]:Array.from(new Set([].concat(t,[e])))}))}),[]),k=e.useCallback((function(e){a((function(t){return 0===t.filter((function(t){return t!==e})).length?["*"]:t.filter((function(t){return t!==e}))}))}),[]),m=e.useCallback((function(e){a((function(t){return t.includes(e)?0===t.filter((function(t){return t!==e})).length?["*"]:t.filter((function(t){return t!==e})):t.includes("*")?[e]:Array.from(new Set([].concat(t,[e])))}))}),[]),h=e.useCallback((function(e){y((function(t){return[].concat(t,[e])}))}),[]),g=e.useCallback((function(e){y((function(t){return t.filter((function(t){return!f(t,e)}))}))}),[]);return t.jsx(v.Provider,{value:{enabledScopes:c,hotkeys:s,enableScope:p,disableScope:k,toggleScope:m},children:t.jsx(d,{addHotkey:h,removeHotkey:g,children:i})})},exports.isHotkeyPressed=a,exports.useHotkeys=function(t,n,r,o){var c=e.useRef(null),d=r instanceof Array?o instanceof Array?void 0:o:r,v=e.useCallback(n,[].concat(r instanceof Array?r:o instanceof Array?o:[])),m=function(t){var n=e.useRef(void 0);return f(n.current,t)||(n.current=t),n.current}(d),h=y().enabledScopes,g=e.useContext(s);return k((function(){if(!1!==(null==m?void 0:m.enabled)&&(n=null==m?void 0:m.scopes,0===(e=h).length&&n?(console.warn('A hotkey has the "scopes" option set, however no active scopes were found. If you want to use the global scopes feature, you need to wrap your app in a <HotkeysProvider>'),1):!n||e.some((function(e){return n.includes(e)}))||e.includes("*"))){var e,n,r=function(e){var n;l(e,["input","textarea","select"])&&!l(e,null==m?void 0:m.enableOnFormTags)||(null===c.current||document.activeElement===c.current||c.current.contains(document.activeElement)?(null==(n=e.target)||!n.isContentEditable||null!=m&&m.enableOnContentEditable)&&i(t,null==m?void 0:m.splitKey).forEach((function(t){var n,r=u(t,null==m?void 0:m.combinationKey);if(function(e,t){var n=t.alt,r=t.meta,o=t.mod,i=t.shift,u=t.keys,c=e.key,l=e.code,s=a("alt"),d=a("shift"),f=a("meta"),v=a("ctrl"),y=l.toLowerCase().replace("key",""),p=c.toLowerCase();if(s!==n&&"alt"!==p)return!1;if(d!==i&&"shift"!==p)return!1;if(o){if(!f&&!v)return!1}else if(f!==r&&v!==r&&"meta"!==y&&"ctrl"!==y)return!1;return!(!u||1!==u.length||!u.includes(p)&&!u.includes(y))||(u?a(u):!u)}(e,r)||null!=(n=r.keys)&&n.includes("*")){if(function(e,t,n){("function"==typeof n&&n(e,t)||!0===n)&&e.preventDefault()}(e,r,null==m?void 0:m.preventDefault),!function(e,t,n){return"function"==typeof n?n(e,t):!0===n||void 0===n}(e,r,null==m?void 0:m.enabled))return void p(e);v(e,r)}})):p(e))},o=function(e){void 0!==e.key&&(void 0===(null==m?void 0:m.keydown)&&!0!==(null==m?void 0:m.keyup)||null!=m&&m.keydown)&&r(e)},s=function(e){void 0!==e.key&&null!=m&&m.keyup&&r(e)};return(c.current||document).addEventListener("keyup",s),(c.current||document).addEventListener("keydown",o),g&&i(t,null==m?void 0:m.splitKey).forEach((function(e){return g.addHotkey(u(e,null==m?void 0:m.combinationKey))})),function(){(c.current||document).removeEventListener("keyup",s),(c.current||document).removeEventListener("keydown",o),g&&i(t,null==m?void 0:m.splitKey).forEach((function(e){return g.removeHotkey(u(e,null==m?void 0:m.combinationKey))}))}}}),[t,v,m,h]),c},exports.useHotkeysContext=y;
2
2
  //# sourceMappingURL=react-hotkeys-hook.cjs.production.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"react-hotkeys-hook.cjs.production.min.js","sources":["../src/parseHotkeys.ts","../src/validators.ts","../src/BoundHotkeysProxyProvider.tsx","../src/deepEqual.ts","../src/HotkeysProvider.tsx","../src/useHotkeys.ts","../src/isHotkeyPressed.ts","../src/useDeepEqualMemo.ts"],"sourcesContent":["import { Hotkey, KeyboardModifiers, Keys } from './types'\n\nconst reservedModifierKeywords = ['shift', 'alt', 'meta', 'mod']\n\nconst mappedKeys: Record<string, string> = {\n esc: 'escape',\n return: 'enter',\n left: 'arrowleft',\n up: 'arrowup',\n right: 'arrowright',\n down: 'arrowdown',\n '1': 'digit1',\n '2': 'digit2',\n '3': 'digit3',\n '4': 'digit4',\n '5': 'digit5',\n '6': 'digit6',\n '7': 'digit7',\n '8': 'digit8',\n '9': 'digit9',\n}\n\nexport function parseKeysHookInput(keys: Keys, splitKey: string = ','): string[] {\n if (typeof keys === 'string') {\n return keys.split(splitKey)\n }\n\n return keys\n}\n\nexport function parseHotkey(hotkey: string, combinationKey: string = '+'): Hotkey {\n const keys = hotkey\n .toLocaleLowerCase()\n .split(combinationKey)\n .map(k => k.trim())\n .map(k => mappedKeys[k] || k)\n\n const modifiers: KeyboardModifiers = {\n alt: keys.includes('alt'),\n shift: keys.includes('shift'),\n meta: keys.includes('meta'),\n mod: keys.includes('mod'),\n }\n\n const singleCharKeys = keys.filter((k) => !reservedModifierKeywords.includes(k))\n\n return {\n ...modifiers,\n keys: singleCharKeys,\n }\n}\n","import { FormTags, Hotkey, Scopes, Trigger } from './types'\n\nexport function maybePreventDefault(e: KeyboardEvent, hotkey: Hotkey, preventDefault?: Trigger): void {\n if ((typeof preventDefault === 'function' && preventDefault(e, hotkey)) || preventDefault === true) {\n e.preventDefault()\n }\n}\n\nexport function isHotkeyEnabled(e: KeyboardEvent, hotkey: Hotkey, enabled?: Trigger): boolean {\n if (typeof enabled === 'function') {\n return enabled(e, hotkey)\n }\n\n return enabled === true || enabled === undefined\n}\n\nexport function isKeyboardEventTriggeredByInput(ev: KeyboardEvent): boolean {\n return isHotkeyEnabledOnTag(ev, ['input', 'textarea', 'select'])\n}\n\nexport function isHotkeyEnabledOnTag({ target }: KeyboardEvent, enabledOnTags: FormTags[] | boolean = false): boolean {\n const targetTagName = target && (target as HTMLElement).tagName\n\n if (enabledOnTags instanceof Array) {\n return Boolean(targetTagName && enabledOnTags && enabledOnTags.some(tag => tag.toLowerCase() === targetTagName.toLowerCase()))\n }\n\n return Boolean(targetTagName && enabledOnTags && enabledOnTags === true)\n}\n\nexport function isScopeActive(activeScopes: string[], scopes?: Scopes): boolean {\n if (activeScopes.length === 0 && scopes) {\n console.warn(\n 'A hotkey has the \"scopes\" option set, however no active scopes were found. If you want to use the global scopes feature, you need to wrap your app in a <HotkeysProvider>'\n )\n\n return true\n }\n\n if (!scopes) {\n return true\n }\n\n return activeScopes.some(scope => scopes.includes(scope)) || activeScopes.includes('*')\n}\n\nexport const isHotkeyMatchingKeyboardEvent = (e: KeyboardEvent, hotkey: Hotkey, pressedDownKeys: Set<string>): boolean => {\n const { alt, meta, mod, shift, keys } = hotkey\n const { altKey, ctrlKey, metaKey, shiftKey, key: pressedKeyUppercase, code } = e\n\n const keyCode = code.toLowerCase().replace('key', '')\n const pressedKey = pressedKeyUppercase.toLowerCase()\n\n if (altKey !== alt && pressedKey !== 'alt') {\n return false\n }\n\n if (shiftKey !== shift && pressedKey !== 'shift') {\n return false\n }\n\n // Mod is a special key name that is checking for meta on macOS and ctrl on other platforms\n if (mod) {\n if (!metaKey && !ctrlKey) {\n return false\n }\n } else {\n if (metaKey !== meta && ctrlKey !== meta && keyCode !== 'meta' && keyCode !== 'ctrl') {\n return false\n }\n }\n\n // All modifiers are correct, now check the key\n // If the key is set we check for the key\n if (keys && keys.length === 1 && (keys.includes(pressedKey) || keys.includes(keyCode))) {\n return true\n } else if (keys) {\n // Check if all keys are present in pressedDownKeys set\n return keys.every(key => pressedDownKeys.has(key))\n }\n else if (!keys) {\n // If the key is not set, we only listen for modifiers, that check went alright, so we return true\n return true\n }\n\n // There is nothing that matches.\n return false\n}\n","import { createContext, ReactNode, useContext } from 'react'\nimport { Hotkey } from './types'\n\ntype BoundHotkeysProxyProviderType = {\n addHotkey: (hotkey: Hotkey) => void,\n removeHotkey: (hotkey: Hotkey) => void,\n}\n\nconst BoundHotkeysProxyProvider = createContext<BoundHotkeysProxyProviderType | undefined>(undefined)\n\nexport const useBoundHotkeysProxy = () => {\n return useContext(BoundHotkeysProxyProvider)\n}\n\ninterface Props {\n children: ReactNode\n addHotkey: (hotkey: Hotkey) => void\n removeHotkey: (hotkey: Hotkey) => void\n}\n\nexport default function BoundHotkeysProxyProviderProvider({ addHotkey, removeHotkey, children }: Props) {\n return <BoundHotkeysProxyProvider.Provider value={{addHotkey, removeHotkey}}>{children}</BoundHotkeysProxyProvider.Provider>\n}\n","export default function deepEqual(x: any, y: any): boolean {\n //@ts-ignore\n return (x && y && typeof x === 'object' && typeof y === 'object')\n //@ts-ignore\n ? (Object.keys(x).length === Object.keys(y).length) && Object.keys(x).reduce(function(isEqual, key) {\n return isEqual && deepEqual(x[key], y[key])\n }, true)\n : (x === y)\n}\n","import { Hotkey } from './types'\nimport { createContext, ReactNode, useState, useContext, useCallback } from 'react'\nimport BoundHotkeysProxyProviderProvider from './BoundHotkeysProxyProvider'\nimport deepEqual from './deepEqual'\n\nexport type HotkeysContextType = {\n hotkeys: ReadonlyArray<Hotkey>\n enabledScopes: string[]\n toggleScope: (scope: string) => void\n enableScope: (scope: string) => void\n disableScope: (scope: string) => void\n}\n\n// The context is only needed for special features like global scoping, so we use a graceful default fallback\nconst HotkeysContext = createContext<HotkeysContextType>({\n hotkeys: [],\n enabledScopes: [], // This array has to be empty instead of containing '*' as default, to check if the provider is set or not\n toggleScope: () => {},\n enableScope: () => {},\n disableScope: () => {},\n})\n\nexport const useHotkeysContext = () => {\n return useContext(HotkeysContext)\n}\n\ninterface Props {\n initiallyActiveScopes?: string[]\n children: ReactNode\n}\n\nexport const HotkeysProvider = ({initiallyActiveScopes = ['*'], children}: Props) => {\n const [internalActiveScopes, setInternalActiveScopes] = useState(initiallyActiveScopes?.length > 0 ? initiallyActiveScopes : ['*'])\n const [boundHotkeys, setBoundHotkeys] = useState<Hotkey[]>([]);\n\n const enableScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.includes('*')) {\n return [scope]\n }\n\n return Array.from(new Set([...prev, scope]))\n })\n }, [])\n\n const disableScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.filter(s => s !== scope).length === 0) {\n return ['*']\n } else {\n return prev.filter(s => s !== scope)\n }\n })\n }, [])\n\n const toggleScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.includes(scope)) {\n if (prev.filter(s => s !== scope).length === 0) {\n return ['*']\n } else {\n return prev.filter(s => s !== scope)\n }\n } else {\n if (prev.includes('*')) {\n return [scope]\n }\n\n return Array.from(new Set([...prev, scope]))\n }\n })\n }, [])\n\n const addBoundHotkey = useCallback((hotkey: Hotkey) => {\n setBoundHotkeys((prev) => [...prev, hotkey])\n }, [])\n\n const removeBoundHotkey = useCallback((hotkey: Hotkey) => {\n setBoundHotkeys((prev) => prev.filter(h => !deepEqual(h, hotkey)))\n }, [])\n\n return (\n <HotkeysContext.Provider value={{enabledScopes: internalActiveScopes, hotkeys: boundHotkeys, enableScope, disableScope, toggleScope}}>\n <BoundHotkeysProxyProviderProvider addHotkey={addBoundHotkey} removeHotkey={removeBoundHotkey}>\n {children}\n </BoundHotkeysProxyProviderProvider>\n </HotkeysContext.Provider>\n )\n}\n","import { HotkeyCallback, Keys, Options, OptionsOrDependencyArray, RefType } from './types'\nimport { DependencyList, useCallback, useEffect, useLayoutEffect, useRef } from 'react'\nimport { parseHotkey, parseKeysHookInput } from './parseHotkeys'\nimport {\n isHotkeyEnabled,\n isHotkeyEnabledOnTag,\n isHotkeyMatchingKeyboardEvent,\n isKeyboardEventTriggeredByInput,\n isScopeActive,\n maybePreventDefault,\n} from './validators'\nimport { useHotkeysContext } from './HotkeysProvider'\nimport { useBoundHotkeysProxy } from './BoundHotkeysProxyProvider'\nimport useDeepEqualMemo from './useDeepEqualMemo'\n\nconst stopPropagation = (e: KeyboardEvent): void => {\n e.stopPropagation()\n e.preventDefault()\n e.stopImmediatePropagation()\n}\n\nconst useSafeLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect\n\nconst pressedDownKeys = new Set<string>()\n\nexport default function useHotkeys<T extends HTMLElement>(\n keys: Keys,\n callback: HotkeyCallback,\n options?: OptionsOrDependencyArray,\n dependencies?: OptionsOrDependencyArray,\n) {\n const ref = useRef<RefType<T>>(null)\n\n const _options: Options | undefined = !(options instanceof Array) ? (options as Options) : !(dependencies instanceof Array) ? (dependencies as Options) : undefined\n const _deps: DependencyList = options instanceof Array ? options : dependencies instanceof Array ? dependencies : []\n\n const cb = useCallback(callback, [..._deps])\n const memoisedOptions = useDeepEqualMemo(_options)\n\n const { enabledScopes } = useHotkeysContext()\n const proxy = useBoundHotkeysProxy()\n\n useSafeLayoutEffect(() => {\n if (memoisedOptions?.enabled === false || !isScopeActive(enabledScopes, memoisedOptions?.scopes)) {\n return\n }\n\n const listener = (e: KeyboardEvent) => {\n if (isKeyboardEventTriggeredByInput(e) && !isHotkeyEnabledOnTag(e, memoisedOptions?.enableOnFormTags)) {\n return\n }\n\n // TODO: SINCE THE EVENT IS NOW ATTACHED TO THE REF, THE ACTIVE ELEMENT CAN NEVER BE INSIDE THE REF. THE HOTKEY ONLY TRIGGERS IF THE\n // REF IS THE ACTIVE ELEMENT. THIS IS A PROBLEM SINCE FOCUSED SUB COMPONENTS WON'T TRIGGER THE HOTKEY.\n if (ref.current !== null && document.activeElement !== ref.current && !ref.current.contains(document.activeElement)) {\n stopPropagation(e)\n\n return\n }\n\n if (((e.target as HTMLElement)?.isContentEditable && !memoisedOptions?.enableOnContentEditable)) {\n return\n }\n\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => {\n const hotkey = parseHotkey(key, memoisedOptions?.combinationKey)\n\n if (isHotkeyMatchingKeyboardEvent(e, hotkey, pressedDownKeys) || hotkey.keys?.includes('*')) {\n maybePreventDefault(e, hotkey, memoisedOptions?.preventDefault)\n\n if (!isHotkeyEnabled(e, hotkey, memoisedOptions?.enabled)) {\n stopPropagation(e)\n\n return\n }\n\n cb(e, hotkey)\n }\n })\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n pressedDownKeys.add(event.key.toLowerCase())\n\n if ((memoisedOptions?.keydown === undefined && memoisedOptions?.keyup !== true) || memoisedOptions?.keydown) {\n listener(event)\n }\n }\n\n const handleKeyUp = (event: KeyboardEvent) => {\n if (event.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n if (event.key.toLowerCase() !== 'meta') {\n pressedDownKeys.delete(event.key.toLowerCase())\n } else {\n // On macOS pressing down the meta key prevents triggering the keyup event for any other key https://stackoverflow.com/a/57153300/735226.\n pressedDownKeys.clear()\n }\n\n if (memoisedOptions?.keyup) {\n listener(event)\n }\n }\n\n // @ts-ignore\n (ref.current || document).addEventListener('keyup', handleKeyUp);\n // @ts-ignore\n (ref.current || document).addEventListener('keydown', handleKeyDown)\n\n if (proxy) {\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => proxy.addHotkey(parseHotkey(key, memoisedOptions?.combinationKey)))\n }\n\n return () => {\n // @ts-ignore\n (ref.current || document).removeEventListener('keyup', handleKeyUp);\n // @ts-ignore\n (ref.current || document).removeEventListener('keydown', handleKeyDown)\n\n if (proxy) {\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => proxy.removeHotkey(parseHotkey(key, memoisedOptions?.combinationKey)))\n }\n }\n }, [keys, cb, memoisedOptions, enabledScopes])\n\n return ref\n}\n","import { Hotkey } from './types'\nimport { parseHotkey } from './parseHotkeys'\nimport deepEqual from './deepEqual'\n\nconst currentlyPressedKeys: Set<Hotkey> = new Set<Hotkey>()\n\nexport function isHotkeyPressed(key: string | string[], splitKey: string = ','): boolean {\n const hotkeyArray = Array.isArray(key) ? key : key.split(splitKey)\n\n return hotkeyArray.every((hotkey) => {\n const parsedHotkey = parseHotkey(hotkey)\n\n for (const pressedHotkey of currentlyPressedKeys) {\n if (deepEqual(parsedHotkey, pressedHotkey)) {\n return true\n }\n }\n })\n}\n\nexport function pushToCurrentlyPressedKeys(key: string | string[]): void {\n const hotkeyArray = Array.isArray(key) ? key : [key]\n\n hotkeyArray.forEach(hotkey => currentlyPressedKeys.add(parseHotkey(hotkey)))\n}\n\nexport function removeFromCurrentlyPressedKeys(key: string | string[]): void {\n const hotkeyArray = Array.isArray(key) ? key : [key]\n\n hotkeyArray.forEach((hotkey) => {\n const parsedHotkey = parseHotkey(hotkey)\n\n for (const pressedHotkey of currentlyPressedKeys) {\n if (pressedHotkey.keys?.every((key) => parsedHotkey.keys?.includes(key))) {\n currentlyPressedKeys.delete(pressedHotkey)\n }\n }\n })\n}\n\n(() => {\n if (typeof window !== 'undefined') {\n window.addEventListener('DOMContentLoaded', () => {\n document.addEventListener('keydown', e => {\n if (e.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n pushToCurrentlyPressedKeys(e.key)\n })\n\n document.addEventListener('keyup', e => {\n if (e.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n removeFromCurrentlyPressedKeys(e.key)\n })\n })\n }\n})()\n","import { useRef } from 'react'\nimport deepEqual from './deepEqual'\n\nexport default function useDeepEqualMemo<T>(value: T) {\n const ref = useRef<T | undefined>(undefined)\n\n if (!deepEqual(ref.current, value)) {\n ref.current = value\n }\n\n return ref.current\n}\n"],"names":["reservedModifierKeywords","mappedKeys","esc","return","left","up","right","down","1","2","3","4","5","6","7","8","9","parseKeysHookInput","keys","splitKey","split","parseHotkey","hotkey","combinationKey","toLocaleLowerCase","map","k","trim","alt","includes","shift","meta","mod","filter","isHotkeyEnabledOnTag","enabledOnTags","target","targetTagName","tagName","Array","Boolean","some","tag","toLowerCase","BoundHotkeysProxyProvider","createContext","undefined","BoundHotkeysProxyProviderProvider","_jsx","Provider","value","addHotkey","removeHotkey","children","deepEqual","x","y","Object","length","reduce","isEqual","key","HotkeysContext","hotkeys","enabledScopes","toggleScope","enableScope","disableScope","useHotkeysContext","useContext","stopPropagation","e","preventDefault","stopImmediatePropagation","useSafeLayoutEffect","window","useLayoutEffect","useEffect","pressedDownKeys","Set","currentlyPressedKeys","addEventListener","document","isArray","forEach","add","parsedHotkey","pressedHotkey","_pressedHotkey$keys","every","_parsedHotkey$keys","initiallyActiveScopes","useState","internalActiveScopes","setInternalActiveScopes","boundHotkeys","setBoundHotkeys","useCallback","scope","prev","from","s","addBoundHotkey","removeBoundHotkey","h","callback","options","dependencies","ref","useRef","_options","cb","memoisedOptions","current","useDeepEqualMemo","proxy","enabled","scopes","activeScopes","console","warn","listener","enableOnFormTags","activeElement","contains","_e$target","isContentEditable","enableOnContentEditable","altKey","ctrlKey","metaKey","shiftKey","pressedKeyUppercase","keyCode","code","replace","pressedKey","has","isHotkeyMatchingKeyboardEvent","_hotkey$keys","maybePreventDefault","isHotkeyEnabled","handleKeyDown","event","keydown","keyup","handleKeyUp","clear","removeEventListener"],"mappings":"smCAEA,IAAMA,EAA2B,CAAC,QAAS,MAAO,OAAQ,OAEpDC,EAAqC,CACzCC,IAAK,SACLC,OAAQ,QACRC,KAAM,YACNC,GAAI,UACJC,MAAO,aACPC,KAAM,YACNC,EAAK,SACLC,EAAK,SACLC,EAAK,SACLC,EAAK,SACLC,EAAK,SACLC,EAAK,SACLC,EAAK,SACLC,EAAK,SACLC,EAAK,mBAGSC,EAAmBC,EAAYC,GAC7C,gBAD6CA,IAAAA,EAAmB,KAC5C,iBAATD,EACFA,EAAKE,MAAMD,GAGbD,WAGOG,EAAYC,EAAgBC,YAAAA,IAAAA,EAAyB,KACnE,IAAML,EAAOI,EACVE,oBACAJ,MAAMG,GACNE,KAAI,SAAAC,GAAC,OAAIA,EAAEC,UACXF,KAAI,SAAAC,GAAC,OAAIzB,EAAWyB,IAAMA,KAW7B,YATqC,CACnCE,IAAKV,EAAKW,SAAS,OACnBC,MAAOZ,EAAKW,SAAS,SACrBE,KAAMb,EAAKW,SAAS,QACpBG,IAAKd,EAAKW,SAAS,SAOnBX,KAJqBA,EAAKe,QAAO,SAACP,GAAC,OAAM1B,EAAyB6B,SAASH,iBCxB/DQ,IAAgDC,OAAzBC,IAAAA,gBAAyBD,IAAAA,GAAsC,GACpG,IAAME,EAAgBD,GAAWA,EAAuBE,QAExD,OAAIH,aAAyBI,MACpBC,QAAQH,GAAiBF,GAAiBA,EAAcM,MAAK,SAAAC,GAAG,OAAIA,EAAIC,gBAAkBN,EAAcM,kBAG1GH,QAAQH,GAAiBF,IAAmC,IAAlBA,GAmBnD,ICtCMS,EAA4BC,qBAAyDC,YAYnEC,KACtB,OAAOC,MAACJ,EAA0BK,UAASC,MAAO,CAACC,YADOA,UACIC,eADOA,cACOC,WADOA,oBCpB7DC,EAAUC,EAAQC,GAExC,OAAQD,GAAKC,GAAkB,iBAAND,GAA+B,iBAANC,EAE7CC,OAAOvC,KAAKqC,GAAGG,SAAWD,OAAOvC,KAAKsC,GAAGE,QAAWD,OAAOvC,KAAKqC,GAAGI,QAAO,SAASC,EAASC,GAC7F,OAAOD,GAAWN,EAAUC,EAAEM,GAAML,EAAEK,OACrC,GACAN,IAAMC,ECOb,IAAMM,EAAiBjB,gBAAkC,CACvDkB,QAAS,GACTC,cAAe,GACfC,YAAa,aACbC,YAAa,aACbC,aAAc,eAGHC,EAAoB,WAC/B,OAAOC,aAAWP,ICRdQ,EAAkB,SAACC,GACvBA,EAAED,kBACFC,EAAEC,iBACFD,EAAEE,4BAGEC,EAAwC,oBAAXC,OAAyBC,kBAAkBC,YAExEC,EAAkB,IAAIC,ICnBtBC,EAAoC,IAAID,IAqCtB,oBAAXJ,QACTA,OAAOM,iBAAiB,oBAAoB,WAC1CC,SAASD,iBAAiB,WAAW,SAAAV,OAvBAV,OAwBrBf,IAAVyB,EAAEV,MAxB6BA,EA6BRU,EAAEV,KA5BftB,MAAM4C,QAAQtB,GAAOA,EAAM,CAACA,IAEpCuB,SAAQ,SAAA9D,GAAM,OAAI0D,EAAqBK,IAAIhE,EAAYC,WA6B/D4D,SAASD,iBAAiB,SAAS,SAAAV,OA1BMV,OA2BzBf,IAAVyB,EAAEV,MA3BiCA,EAgCRU,EAAEV,KA/BnBtB,MAAM4C,QAAQtB,GAAOA,EAAM,CAACA,IAEpCuB,SAAQ,SAAC9D,GAGnB,IAFA,MAAMgE,EAAejE,EAAYC,OAEL0D,kBAAsB,CAAA,MAAvCO,mBACLA,EAAcrE,OAAdsE,EAAoBC,OAAM,SAAC5B,GAAG,MAAA,gBAAKyB,EAAapE,aAAbwE,EAAmB7D,SAASgC,OACjEmB,SAA4BO,sCFHL,oBAAEI,sBAAAA,aAAwB,CAAC,OAAMtC,IAAAA,WACNuC,kBAASD,SAAAA,EAAuBjC,QAAS,EAAIiC,EAAwB,CAAC,MAAvHE,OAAsBC,SACWF,WAAmB,IAApDG,OAAcC,OAEf9B,EAAc+B,eAAY,SAACC,GAC/BJ,GAAwB,SAACK,GACvB,OAAIA,EAAKtE,SAAS,KACT,CAACqE,GAGH3D,MAAM6D,KAAK,IAAIrB,cAAQoB,GAAMD,WAErC,IAEG/B,EAAe8B,eAAY,SAACC,GAChCJ,GAAwB,SAACK,GACvB,OAA6C,IAAzCA,EAAKlE,QAAO,SAAAoE,GAAC,OAAIA,IAAMH,KAAOxC,OACzB,CAAC,KAEDyC,EAAKlE,QAAO,SAAAoE,GAAC,OAAIA,IAAMH,UAGjC,IAEGjC,EAAcgC,eAAY,SAACC,GAC/BJ,GAAwB,SAACK,GACvB,OAAIA,EAAKtE,SAASqE,GAC6B,IAAzCC,EAAKlE,QAAO,SAAAoE,GAAC,OAAIA,IAAMH,KAAOxC,OACzB,CAAC,KAEDyC,EAAKlE,QAAO,SAAAoE,GAAC,OAAIA,IAAMH,KAG5BC,EAAKtE,SAAS,KACT,CAACqE,GAGH3D,MAAM6D,KAAK,IAAIrB,cAAQoB,GAAMD,WAGvC,IAEGI,EAAiBL,eAAY,SAAC3E,GAClC0E,GAAgB,SAACG,GAAI,gBAASA,GAAM7E,SACnC,IAEGiF,EAAoBN,eAAY,SAAC3E,GACrC0E,GAAgB,SAACG,GAAI,OAAKA,EAAKlE,QAAO,SAAAuE,GAAC,OAAKlD,EAAUkD,EAAGlF,WACxD,IAEH,OACE0B,MAACc,EAAeb,UAASC,MAAO,CAACc,cAAe6B,EAAsB9B,QAASgC,EAAc7B,YAAAA,EAAaC,aAAAA,EAAcF,YAAAA,GAAaZ,SACnIL,MAACD,GAAkCI,UAAWmD,EAAgBlD,aAAcmD,EAAkBlD,SAC3FA,wCE9EuBQ,EAAwB1C,GAGtD,gBAHsDA,IAAAA,EAAmB,MACrDoB,MAAM4C,QAAQtB,GAAOA,EAAMA,EAAIzC,MAAMD,IAEtCsE,OAAM,SAACnE,GAGxB,IAFA,MAAMgE,EAAejE,EAAYC,OAEL0D,kBAC1B,GAAI1B,EAAUgC,WACZ,OAAO,yBDWf,SACEpE,EACAuF,EACAC,EACAC,GAEA,IAAMC,EAAMC,SAAmB,MAEzBC,EAAkCJ,aAAmBnE,MAAkCoE,aAAwBpE,WAAqCO,EAA3B6D,EAA1DD,EAG/DK,EAAKd,cAAYQ,YAFOC,aAAmBnE,MAAQmE,EAAUC,aAAwBpE,MAAQoE,EAAe,KAG5GK,WElCoC9D,GAC1C,IAAM0D,EAAMC,cAAsB/D,GAMlC,OAJKQ,EAAUsD,EAAIK,QAAS/D,KAC1B0D,EAAIK,QAAU/D,GAGT0D,EAAIK,QF2BaC,CAAiBJ,GAEjC9C,EAAkBI,IAAlBJ,cACFmD,EH7BC9C,aAAWzB,GG0HlB,OA3FA8B,GAAoB,WAClB,IAAiC,WAA7BsC,SAAAA,EAAiBI,WJb6BC,QIasBL,SAAAA,EAAiBK,OJZ/D,KADAC,EIa+BtD,GJZ1CN,QAAgB2D,GAC/BE,QAAQC,KACN,6KAGK,IAGJH,GAIEC,EAAa7E,MAAK,SAAAyD,GAAK,OAAImB,EAAOxF,SAASqE,OAAWoB,EAAazF,SAAS,MIAjF,KJb0ByF,EAAwBD,EIiB5CI,EAAW,SAAClD,SJ9BbrC,EI+BiCqC,EJ/BR,CAAC,QAAS,WAAY,aI+BPrC,EAAqBqC,QAAGyC,SAAAA,EAAiBU,oBAMhE,OAAhBd,EAAIK,SAAoB/B,SAASyC,gBAAkBf,EAAIK,SAAYL,EAAIK,QAAQW,SAAS1C,SAASyC,yBAM/FpD,EAAEnC,UAAFyF,EAA0BC,yBAAsBd,GAAAA,EAAiBe,0BAIvE9G,EAAmBC,QAAM8F,SAAAA,EAAiB7F,UAAUiE,SAAQ,SAACvB,SACrDvC,EAASD,EAAYwC,QAAKmD,SAAAA,EAAiBzF,gBAEjD,GJrBqC,SAACgD,EAAkBjD,EAAgBwD,GAC9E,IAAQlD,EAAgCN,EAAhCM,IAAKG,EAA2BT,EAA3BS,KAAMC,EAAqBV,EAArBU,IAAKF,EAAgBR,EAAhBQ,MAAOZ,EAASI,EAATJ,KACvB8G,EAAuEzD,EAAvEyD,OAAQC,EAA+D1D,EAA/D0D,QAASC,EAAsD3D,EAAtD2D,QAASC,EAA6C5D,EAA7C4D,SAAeC,EAA8B7D,EAAnCV,IAEtCwE,EAFyE9D,EAAT+D,KAEjD3F,cAAc4F,QAAQ,MAAO,IAC5CC,EAAaJ,EAAoBzF,cAEvC,GAAIqF,IAAWpG,GAAsB,QAAf4G,EACpB,OAAO,EAGT,GAAIL,IAAarG,GAAwB,UAAf0G,EACxB,OAAO,EAIT,GAAIxG,GACF,IAAKkG,IAAYD,EACf,OAAO,OAGT,GAAIC,IAAYnG,GAAQkG,IAAYlG,GAAoB,SAAZsG,GAAkC,SAAZA,EAChE,OAAO,EAMX,SAAInH,GAAwB,IAAhBA,EAAKwC,SAAiBxC,EAAKW,SAAS2G,KAAetH,EAAKW,SAASwG,MAElEnH,EAEFA,EAAKuE,OAAM,SAAA5B,GAAG,OAAIiB,EAAgB2D,IAAI5E,OAErC3C,GIbAwH,CAA8BnE,EAAGjD,EAAQwD,aAAoBxD,EAAOJ,OAAPyH,EAAa9G,SAAS,KAAM,CAG3F,YJpE0B0C,EAAkBjD,EAAgBkD,IACrC,mBAAnBA,GAAiCA,EAAeD,EAAGjD,KAA+B,IAAnBkD,IACzED,EAAEC,iBIgEIoE,CAAoBrE,EAAGjD,QAAQ0F,SAAAA,EAAiBxC,iBJ5D1D,SAAgCD,EAAkBjD,EAAgB8F,GAChE,MAAuB,mBAAZA,EACFA,EAAQ7C,EAAGjD,IAGD,IAAZ8F,QAAgCtE,IAAZsE,EIyDdyB,CAAgBtE,EAAGjD,QAAQ0F,SAAAA,EAAiBI,SAG/C,YAFA9C,EAAgBC,GAKlBwC,EAAGxC,EAAGjD,OArBRgD,EAAgBC,KA0BduE,EAAgB,SAACC,QACHjG,IAAdiG,EAAMlF,MAKViB,EAAgBO,IAAI0D,EAAMlF,IAAIlB,qBAEIG,WAA7BkE,SAAAA,EAAiBgC,WAAoD,WAA3BhC,SAAAA,EAAiBiC,cAAmBjC,GAAAA,EAAiBgC,UAClGvB,EAASsB,KAIPG,EAAc,SAACH,QACDjG,IAAdiG,EAAMlF,MAKsB,SAA5BkF,EAAMlF,IAAIlB,cACZmC,SAAuBiE,EAAMlF,IAAIlB,eAGjCmC,EAAgBqE,cAGdnC,GAAAA,EAAiBiC,OACnBxB,EAASsB,KAab,OARCnC,EAAIK,SAAW/B,UAAUD,iBAAiB,QAASiE,IAEnDtC,EAAIK,SAAW/B,UAAUD,iBAAiB,UAAW6D,GAElD3B,GACFlG,EAAmBC,QAAM8F,SAAAA,EAAiB7F,UAAUiE,SAAQ,SAACvB,GAAG,OAAKsD,EAAMhE,UAAU9B,EAAYwC,QAAKmD,SAAAA,EAAiBzF,oBAGlH,YAEJqF,EAAIK,SAAW/B,UAAUkE,oBAAoB,QAASF,IAEtDtC,EAAIK,SAAW/B,UAAUkE,oBAAoB,UAAWN,GAErD3B,GACFlG,EAAmBC,QAAM8F,SAAAA,EAAiB7F,UAAUiE,SAAQ,SAACvB,GAAG,OAAKsD,EAAM/D,aAAa/B,EAAYwC,QAAKmD,SAAAA,EAAiBzF,wBAG7H,CAACL,EAAM6F,EAAIC,EAAiBhD,IAExB4C"}
1
+ {"version":3,"file":"react-hotkeys-hook.cjs.production.min.js","sources":["../src/parseHotkeys.ts","../src/isHotkeyPressed.ts","../src/validators.ts","../src/BoundHotkeysProxyProvider.tsx","../src/deepEqual.ts","../src/HotkeysProvider.tsx","../src/useHotkeys.ts","../src/useDeepEqualMemo.ts"],"sourcesContent":["import { Hotkey, KeyboardModifiers, Keys } from './types'\n\nconst reservedModifierKeywords = ['shift', 'alt', 'meta', 'mod']\n\nconst mappedKeys: Record<string, string> = {\n esc: 'escape',\n return: 'enter',\n left: 'arrowleft',\n up: 'arrowup',\n right: 'arrowright',\n down: 'arrowdown',\n '1': 'digit1',\n '2': 'digit2',\n '3': 'digit3',\n '4': 'digit4',\n '5': 'digit5',\n '6': 'digit6',\n '7': 'digit7',\n '8': 'digit8',\n '9': 'digit9',\n}\n\nexport function isHotkeyModifier(key: string) {\n return reservedModifierKeywords.includes(key)\n}\n\nexport function parseKeysHookInput(keys: Keys, splitKey: string = ','): string[] {\n if (typeof keys === 'string') {\n return keys.split(splitKey)\n }\n\n return keys\n}\n\nexport function parseHotkey(hotkey: string, combinationKey: string = '+'): Hotkey {\n const keys = hotkey\n .toLocaleLowerCase()\n .split(combinationKey)\n .map(k => k.trim())\n .map(k => mappedKeys[k] || k)\n\n const modifiers: KeyboardModifiers = {\n alt: keys.includes('alt'),\n shift: keys.includes('shift'),\n meta: keys.includes('meta'),\n mod: keys.includes('mod'),\n }\n\n const singleCharKeys = keys.filter((k) => !reservedModifierKeywords.includes(k))\n\n return {\n ...modifiers,\n keys: singleCharKeys,\n }\n}\n","import { isHotkeyModifier } from './parseHotkeys'\n\nconst currentlyPressedKeys: Set<string> = new Set<string>()\n\nexport function isHotkeyPressed(key: string | string[], splitKey: string = ','): boolean {\n const hotkeyArray = Array.isArray(key) ? key : key.split(splitKey)\n\n return hotkeyArray.every((hotkey) => currentlyPressedKeys.has(hotkey.trim().toLowerCase()))\n}\n\nfunction pushToCurrentlyPressedKeys(key: string | string[]): void {\n const hotkeyArray = Array.isArray(key) ? key : [key]\n\n /*\n Due to a weird behavior on macOS we need to clear the set if the user pressed down the meta key and presses another key.\n https://stackoverflow.com/questions/11818637/why-does-javascript-drop-keyup-events-when-the-metakey-is-pressed-on-mac-browser\n Otherwise the set will hold all ever pressed keys while the meta key is down which leads to wrong results.\n */\n if (currentlyPressedKeys.has('meta')) {\n currentlyPressedKeys.forEach(key => !isHotkeyModifier(key) && currentlyPressedKeys.delete(key))\n }\n\n hotkeyArray.forEach(hotkey => currentlyPressedKeys.add(hotkey.toLowerCase()))\n}\n\nfunction removeFromCurrentlyPressedKeys(key: string): void {\n /*\n Due to a weird behavior on macOS we need to clear the set if the user pressed down the meta key and presses another key.\n https://stackoverflow.com/questions/11818637/why-does-javascript-drop-keyup-events-when-the-metakey-is-pressed-on-mac-browser\n Otherwise the set will hold all ever pressed keys while the meta key is down which leads to wrong results.\n */\n if (key === 'meta') {\n currentlyPressedKeys.clear()\n } else {\n currentlyPressedKeys.delete(key)\n }\n}\n\n(() => {\n document.addEventListener('keydown', e => {\n if (e.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n pushToCurrentlyPressedKeys(e.key.toLowerCase())\n })\n\n document.addEventListener('keyup', e => {\n if (e.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n removeFromCurrentlyPressedKeys(e.key.toLowerCase())\n })\n})()\n","import { FormTags, Hotkey, Scopes, Trigger } from './types'\nimport { isHotkeyPressed } from './isHotkeyPressed'\n\nexport function maybePreventDefault(e: KeyboardEvent, hotkey: Hotkey, preventDefault?: Trigger): void {\n if ((typeof preventDefault === 'function' && preventDefault(e, hotkey)) || preventDefault === true) {\n e.preventDefault()\n }\n}\n\nexport function isHotkeyEnabled(e: KeyboardEvent, hotkey: Hotkey, enabled?: Trigger): boolean {\n if (typeof enabled === 'function') {\n return enabled(e, hotkey)\n }\n\n return enabled === true || enabled === undefined\n}\n\nexport function isKeyboardEventTriggeredByInput(ev: KeyboardEvent): boolean {\n return isHotkeyEnabledOnTag(ev, ['input', 'textarea', 'select'])\n}\n\nexport function isHotkeyEnabledOnTag({ target }: KeyboardEvent, enabledOnTags: FormTags[] | boolean = false): boolean {\n const targetTagName = target && (target as HTMLElement).tagName\n\n if (enabledOnTags instanceof Array) {\n return Boolean(targetTagName && enabledOnTags && enabledOnTags.some(tag => tag.toLowerCase() === targetTagName.toLowerCase()))\n }\n\n return Boolean(targetTagName && enabledOnTags && enabledOnTags === true)\n}\n\nexport function isScopeActive(activeScopes: string[], scopes?: Scopes): boolean {\n if (activeScopes.length === 0 && scopes) {\n console.warn(\n 'A hotkey has the \"scopes\" option set, however no active scopes were found. If you want to use the global scopes feature, you need to wrap your app in a <HotkeysProvider>'\n )\n\n return true\n }\n\n if (!scopes) {\n return true\n }\n\n return activeScopes.some(scope => scopes.includes(scope)) || activeScopes.includes('*')\n}\n\nexport const isHotkeyMatchingKeyboardEvent = (e: KeyboardEvent, hotkey: Hotkey): boolean => {\n const { alt, meta, mod, shift, keys } = hotkey\n const { key: pressedKeyUppercase, code } = e\n\n const altKey = isHotkeyPressed('alt')\n const shiftKey = isHotkeyPressed('shift')\n const metaKey = isHotkeyPressed('meta')\n const ctrlKey = isHotkeyPressed('ctrl')\n\n const keyCode = code.toLowerCase().replace('key', '')\n const pressedKey = pressedKeyUppercase.toLowerCase()\n\n if (altKey !== alt && pressedKey !== 'alt') {\n return false\n }\n\n if (shiftKey !== shift && pressedKey !== 'shift') {\n return false\n }\n\n // Mod is a special key name that is checking for meta on macOS and ctrl on other platforms\n if (mod) {\n if (!metaKey && !ctrlKey) {\n return false\n }\n } else {\n if (metaKey !== meta && ctrlKey !== meta && keyCode !== 'meta' && keyCode !== 'ctrl') {\n return false\n }\n }\n\n // All modifiers are correct, now check the key\n // If the key is set, we check for the key\n if (keys && keys.length === 1 && (keys.includes(pressedKey) || keys.includes(keyCode))) {\n return true\n } else if (keys) {\n // Check if all keys are present in pressedDownKeys set\n return isHotkeyPressed(keys)\n }\n else if (!keys) {\n // If the key is not set, we only listen for modifiers, that check went alright, so we return true\n return true\n }\n\n // There is nothing that matches.\n return false\n}\n","import { createContext, ReactNode, useContext } from 'react'\nimport { Hotkey } from './types'\n\ntype BoundHotkeysProxyProviderType = {\n addHotkey: (hotkey: Hotkey) => void,\n removeHotkey: (hotkey: Hotkey) => void,\n}\n\nconst BoundHotkeysProxyProvider = createContext<BoundHotkeysProxyProviderType | undefined>(undefined)\n\nexport const useBoundHotkeysProxy = () => {\n return useContext(BoundHotkeysProxyProvider)\n}\n\ninterface Props {\n children: ReactNode\n addHotkey: (hotkey: Hotkey) => void\n removeHotkey: (hotkey: Hotkey) => void\n}\n\nexport default function BoundHotkeysProxyProviderProvider({ addHotkey, removeHotkey, children }: Props) {\n return <BoundHotkeysProxyProvider.Provider value={{addHotkey, removeHotkey}}>{children}</BoundHotkeysProxyProvider.Provider>\n}\n","export default function deepEqual(x: any, y: any): boolean {\n //@ts-ignore\n return (x && y && typeof x === 'object' && typeof y === 'object')\n //@ts-ignore\n ? (Object.keys(x).length === Object.keys(y).length) && Object.keys(x).reduce(function(isEqual, key) {\n return isEqual && deepEqual(x[key], y[key])\n }, true)\n : (x === y)\n}\n","import { Hotkey } from './types'\nimport { createContext, ReactNode, useState, useContext, useCallback } from 'react'\nimport BoundHotkeysProxyProviderProvider from './BoundHotkeysProxyProvider'\nimport deepEqual from './deepEqual'\n\nexport type HotkeysContextType = {\n hotkeys: ReadonlyArray<Hotkey>\n enabledScopes: string[]\n toggleScope: (scope: string) => void\n enableScope: (scope: string) => void\n disableScope: (scope: string) => void\n}\n\n// The context is only needed for special features like global scoping, so we use a graceful default fallback\nconst HotkeysContext = createContext<HotkeysContextType>({\n hotkeys: [],\n enabledScopes: [], // This array has to be empty instead of containing '*' as default, to check if the provider is set or not\n toggleScope: () => {},\n enableScope: () => {},\n disableScope: () => {},\n})\n\nexport const useHotkeysContext = () => {\n return useContext(HotkeysContext)\n}\n\ninterface Props {\n initiallyActiveScopes?: string[]\n children: ReactNode\n}\n\nexport const HotkeysProvider = ({initiallyActiveScopes = ['*'], children}: Props) => {\n const [internalActiveScopes, setInternalActiveScopes] = useState(initiallyActiveScopes?.length > 0 ? initiallyActiveScopes : ['*'])\n const [boundHotkeys, setBoundHotkeys] = useState<Hotkey[]>([]);\n\n const enableScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.includes('*')) {\n return [scope]\n }\n\n return Array.from(new Set([...prev, scope]))\n })\n }, [])\n\n const disableScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.filter(s => s !== scope).length === 0) {\n return ['*']\n } else {\n return prev.filter(s => s !== scope)\n }\n })\n }, [])\n\n const toggleScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.includes(scope)) {\n if (prev.filter(s => s !== scope).length === 0) {\n return ['*']\n } else {\n return prev.filter(s => s !== scope)\n }\n } else {\n if (prev.includes('*')) {\n return [scope]\n }\n\n return Array.from(new Set([...prev, scope]))\n }\n })\n }, [])\n\n const addBoundHotkey = useCallback((hotkey: Hotkey) => {\n setBoundHotkeys((prev) => [...prev, hotkey])\n }, [])\n\n const removeBoundHotkey = useCallback((hotkey: Hotkey) => {\n setBoundHotkeys((prev) => prev.filter(h => !deepEqual(h, hotkey)))\n }, [])\n\n return (\n <HotkeysContext.Provider value={{enabledScopes: internalActiveScopes, hotkeys: boundHotkeys, enableScope, disableScope, toggleScope}}>\n <BoundHotkeysProxyProviderProvider addHotkey={addBoundHotkey} removeHotkey={removeBoundHotkey}>\n {children}\n </BoundHotkeysProxyProviderProvider>\n </HotkeysContext.Provider>\n )\n}\n","import { HotkeyCallback, Keys, Options, OptionsOrDependencyArray, RefType } from './types'\nimport { DependencyList, useCallback, useEffect, useLayoutEffect, useRef } from 'react'\nimport { parseHotkey, parseKeysHookInput } from './parseHotkeys'\nimport {\n isHotkeyEnabled,\n isHotkeyEnabledOnTag,\n isHotkeyMatchingKeyboardEvent,\n isKeyboardEventTriggeredByInput,\n isScopeActive,\n maybePreventDefault,\n} from './validators'\nimport { useHotkeysContext } from './HotkeysProvider'\nimport { useBoundHotkeysProxy } from './BoundHotkeysProxyProvider'\nimport useDeepEqualMemo from './useDeepEqualMemo'\n\nconst stopPropagation = (e: KeyboardEvent): void => {\n e.stopPropagation()\n e.preventDefault()\n e.stopImmediatePropagation()\n}\n\nconst useSafeLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect\n\nexport default function useHotkeys<T extends HTMLElement>(\n keys: Keys,\n callback: HotkeyCallback,\n options?: OptionsOrDependencyArray,\n dependencies?: OptionsOrDependencyArray,\n) {\n const ref = useRef<RefType<T>>(null)\n\n const _options: Options | undefined = !(options instanceof Array) ? (options as Options) : !(dependencies instanceof Array) ? (dependencies as Options) : undefined\n const _deps: DependencyList = options instanceof Array ? options : dependencies instanceof Array ? dependencies : []\n\n const cb = useCallback(callback, [..._deps])\n const memoisedOptions = useDeepEqualMemo(_options)\n\n const { enabledScopes } = useHotkeysContext()\n const proxy = useBoundHotkeysProxy()\n\n useSafeLayoutEffect(() => {\n if (memoisedOptions?.enabled === false || !isScopeActive(enabledScopes, memoisedOptions?.scopes)) {\n return\n }\n\n const listener = (e: KeyboardEvent) => {\n if (isKeyboardEventTriggeredByInput(e) && !isHotkeyEnabledOnTag(e, memoisedOptions?.enableOnFormTags)) {\n return\n }\n\n // TODO: SINCE THE EVENT IS NOW ATTACHED TO THE REF, THE ACTIVE ELEMENT CAN NEVER BE INSIDE THE REF. THE HOTKEY ONLY TRIGGERS IF THE\n // REF IS THE ACTIVE ELEMENT. THIS IS A PROBLEM SINCE FOCUSED SUB COMPONENTS WON'T TRIGGER THE HOTKEY.\n if (ref.current !== null && document.activeElement !== ref.current && !ref.current.contains(document.activeElement)) {\n stopPropagation(e)\n\n return\n }\n\n if (((e.target as HTMLElement)?.isContentEditable && !memoisedOptions?.enableOnContentEditable)) {\n return\n }\n\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => {\n const hotkey = parseHotkey(key, memoisedOptions?.combinationKey)\n\n if (isHotkeyMatchingKeyboardEvent(e, hotkey) || hotkey.keys?.includes('*')) {\n maybePreventDefault(e, hotkey, memoisedOptions?.preventDefault)\n\n if (!isHotkeyEnabled(e, hotkey, memoisedOptions?.enabled)) {\n stopPropagation(e)\n\n return\n }\n\n // Execute the user callback for that hotkey\n cb(e, hotkey)\n }\n })\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n if ((memoisedOptions?.keydown === undefined && memoisedOptions?.keyup !== true) || memoisedOptions?.keydown) {\n listener(event)\n }\n }\n\n const handleKeyUp = (event: KeyboardEvent) => {\n if (event.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n if (memoisedOptions?.keyup) {\n listener(event)\n }\n }\n\n // @ts-ignore\n (ref.current || document).addEventListener('keyup', handleKeyUp);\n // @ts-ignore\n (ref.current || document).addEventListener('keydown', handleKeyDown)\n\n if (proxy) {\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => proxy.addHotkey(parseHotkey(key, memoisedOptions?.combinationKey)))\n }\n\n return () => {\n // @ts-ignore\n (ref.current || document).removeEventListener('keyup', handleKeyUp);\n // @ts-ignore\n (ref.current || document).removeEventListener('keydown', handleKeyDown)\n\n if (proxy) {\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => proxy.removeHotkey(parseHotkey(key, memoisedOptions?.combinationKey)))\n }\n }\n }, [keys, cb, memoisedOptions, enabledScopes])\n\n return ref\n}\n","import { useRef } from 'react'\nimport deepEqual from './deepEqual'\n\nexport default function useDeepEqualMemo<T>(value: T) {\n const ref = useRef<T | undefined>(undefined)\n\n if (!deepEqual(ref.current, value)) {\n ref.current = value\n }\n\n return ref.current\n}\n"],"names":["reservedModifierKeywords","mappedKeys","esc","return","left","up","right","down","1","2","3","4","5","6","7","8","9","parseKeysHookInput","keys","splitKey","split","parseHotkey","hotkey","combinationKey","toLocaleLowerCase","map","k","trim","alt","includes","shift","meta","mod","filter","currentlyPressedKeys","Set","isHotkeyPressed","key","Array","isArray","every","has","toLowerCase","isHotkeyEnabledOnTag","enabledOnTags","target","targetTagName","tagName","Boolean","some","tag","document","addEventListener","e","hotkeyArray","undefined","forEach","isHotkeyModifier","add","clear","BoundHotkeysProxyProvider","createContext","BoundHotkeysProxyProviderProvider","_jsx","Provider","value","addHotkey","removeHotkey","children","deepEqual","x","y","Object","length","reduce","isEqual","HotkeysContext","hotkeys","enabledScopes","toggleScope","enableScope","disableScope","useHotkeysContext","useContext","stopPropagation","preventDefault","stopImmediatePropagation","useSafeLayoutEffect","window","useLayoutEffect","useEffect","initiallyActiveScopes","useState","internalActiveScopes","setInternalActiveScopes","boundHotkeys","setBoundHotkeys","useCallback","scope","prev","from","s","addBoundHotkey","removeBoundHotkey","h","callback","options","dependencies","ref","useRef","_options","cb","memoisedOptions","current","useDeepEqualMemo","proxy","enabled","scopes","activeScopes","console","warn","listener","enableOnFormTags","activeElement","contains","_e$target","isContentEditable","enableOnContentEditable","pressedKeyUppercase","code","altKey","shiftKey","metaKey","ctrlKey","keyCode","replace","pressedKey","isHotkeyMatchingKeyboardEvent","_hotkey$keys","maybePreventDefault","isHotkeyEnabled","handleKeyDown","event","keydown","keyup","handleKeyUp","removeEventListener"],"mappings":"sSAEA,IAAMA,EAA2B,CAAC,QAAS,MAAO,OAAQ,OAEpDC,EAAqC,CACzCC,IAAK,SACLC,OAAQ,QACRC,KAAM,YACNC,GAAI,UACJC,MAAO,aACPC,KAAM,YACNC,EAAK,SACLC,EAAK,SACLC,EAAK,SACLC,EAAK,SACLC,EAAK,SACLC,EAAK,SACLC,EAAK,SACLC,EAAK,SACLC,EAAK,mBAOSC,EAAmBC,EAAYC,GAC7C,gBAD6CA,IAAAA,EAAmB,KAC5C,iBAATD,EACFA,EAAKE,MAAMD,GAGbD,WAGOG,EAAYC,EAAgBC,YAAAA,IAAAA,EAAyB,KACnE,IAAML,EAAOI,EACVE,oBACAJ,MAAMG,GACNE,KAAI,SAAAC,GAAC,OAAIA,EAAEC,UACXF,KAAI,SAAAC,GAAC,OAAIzB,EAAWyB,IAAMA,KAW7B,YATqC,CACnCE,IAAKV,EAAKW,SAAS,OACnBC,MAAOZ,EAAKW,SAAS,SACrBE,KAAMb,EAAKW,SAAS,QACpBG,IAAKd,EAAKW,SAAS,SAOnBX,KAJqBA,EAAKe,QAAO,SAACP,GAAC,OAAM1B,EAAyB6B,SAASH,QC9C/E,IAAMQ,EAAoC,IAAIC,aAE9BC,EAAgBC,EAAwBlB,GAGtD,gBAHsDA,IAAAA,EAAmB,MACrDmB,MAAMC,QAAQF,GAAOA,EAAMA,EAAIjB,MAAMD,IAEtCqB,OAAM,SAAClB,GAAM,OAAKY,EAAqBO,IAAInB,EAAOK,OAAOe,2BCc9DC,IAAgDC,OAAzBC,IAAAA,gBAAyBD,IAAAA,GAAsC,GACpG,IAAME,EAAgBD,GAAWA,EAAuBE,QAExD,OAAIH,aAAyBN,MACpBU,QAAQF,GAAiBF,GAAiBA,EAAcK,MAAK,SAAAC,GAAG,OAAIA,EAAIR,gBAAkBI,EAAcJ,kBAG1GM,QAAQF,GAAiBF,IAAmC,IAAlBA,GDWjDO,SAASC,iBAAiB,WAAW,SAAAC,GA7BvC,IAAoChB,EAC5BiB,OA6BUC,IAAVF,EAAEhB,MA9B0BA,EAmCLgB,EAAEhB,IAAIK,cAlC7BY,EAAchB,MAAMC,QAAQF,GAAOA,EAAM,CAACA,GAO5CH,EAAqBO,IAAI,SAC3BP,EAAqBsB,SAAQ,SAAAnB,GAAG,gBDGHA,GAC/B,OAAOrC,EAAyB6B,SAASQ,GCJFoB,CAAiBpB,IAAQH,SAA4BG,MAG5FiB,EAAYE,SAAQ,SAAAlC,GAAM,OAAIY,EAAqBwB,IAAIpC,EAAOoB,sBA0B9DS,SAASC,iBAAiB,SAAS,SAAAC,GAvBrC,IAAwChB,OAwBtBkB,IAAVF,EAAEhB,MAlBI,UAN0BA,EA6BLgB,EAAEhB,IAAIK,eAtBrCR,EAAqByB,QAErBzB,SAA4BG,OCahC,ICvCMuB,EAA4BC,qBAAyDN,YAYnEO,KACtB,OAAOC,MAACH,EAA0BI,UAASC,MAAO,CAACC,YADOA,UACIC,eADOA,cACOC,WADOA,oBCpB7DC,EAAUC,EAAQC,GAExC,OAAQD,GAAKC,GAAkB,iBAAND,GAA+B,iBAANC,EAE7CC,OAAOtD,KAAKoD,GAAGG,SAAWD,OAAOtD,KAAKqD,GAAGE,QAAWD,OAAOtD,KAAKoD,GAAGI,QAAO,SAASC,EAAStC,GAC7F,OAAOsC,GAAWN,EAAUC,EAAEjC,GAAMkC,EAAElC,OACrC,GACAiC,IAAMC,ECOb,IAAMK,EAAiBf,gBAAkC,CACvDgB,QAAS,GACTC,cAAe,GACfC,YAAa,aACbC,YAAa,aACbC,aAAc,eAGHC,EAAoB,WAC/B,OAAOC,aAAWP,ICRdQ,EAAkB,SAAC/B,GACvBA,EAAE+B,kBACF/B,EAAEgC,iBACFhC,EAAEiC,4BAGEC,EAAwC,oBAAXC,OAAyBC,kBAAkBC,oCDU/C,oBAAEC,sBAAAA,aAAwB,CAAC,OAAMvB,IAAAA,WACNwB,kBAASD,SAAAA,EAAuBlB,QAAS,EAAIkB,EAAwB,CAAC,MAAvHE,OAAsBC,SACWF,WAAmB,IAApDG,OAAcC,OAEfhB,EAAciB,eAAY,SAACC,GAC/BJ,GAAwB,SAACK,GACvB,OAAIA,EAAKtE,SAAS,KACT,CAACqE,GAGH5D,MAAM8D,KAAK,IAAIjE,cAAQgE,GAAMD,WAErC,IAEGjB,EAAegB,eAAY,SAACC,GAChCJ,GAAwB,SAACK,GACvB,OAA6C,IAAzCA,EAAKlE,QAAO,SAAAoE,GAAC,OAAIA,IAAMH,KAAOzB,OACzB,CAAC,KAED0B,EAAKlE,QAAO,SAAAoE,GAAC,OAAIA,IAAMH,UAGjC,IAEGnB,EAAckB,eAAY,SAACC,GAC/BJ,GAAwB,SAACK,GACvB,OAAIA,EAAKtE,SAASqE,GAC6B,IAAzCC,EAAKlE,QAAO,SAAAoE,GAAC,OAAIA,IAAMH,KAAOzB,OACzB,CAAC,KAED0B,EAAKlE,QAAO,SAAAoE,GAAC,OAAIA,IAAMH,KAG5BC,EAAKtE,SAAS,KACT,CAACqE,GAGH5D,MAAM8D,KAAK,IAAIjE,cAAQgE,GAAMD,WAGvC,IAEGI,EAAiBL,eAAY,SAAC3E,GAClC0E,GAAgB,SAACG,GAAI,gBAASA,GAAM7E,SACnC,IAEGiF,EAAoBN,eAAY,SAAC3E,GACrC0E,GAAgB,SAACG,GAAI,OAAKA,EAAKlE,QAAO,SAAAuE,GAAC,OAAKnC,EAAUmC,EAAGlF,WACxD,IAEH,OACEyC,MAACa,EAAeZ,UAASC,MAAO,CAACa,cAAee,EAAsBhB,QAASkB,EAAcf,YAAAA,EAAaC,aAAAA,EAAcF,YAAAA,GAAaX,SACnIL,MAACD,GAAkCI,UAAWoC,EAAgBnC,aAAcoC,EAAkBnC,SAC3FA,oDC7DT,SACElD,EACAuF,EACAC,EACAC,GAEA,IAAMC,EAAMC,SAAmB,MAEzBC,EAAkCJ,aAAmBpE,MAAkCqE,aAAwBrE,WAAqCiB,EAA3BoD,EAA1DD,EAG/DK,EAAKd,cAAYQ,YAFOC,aAAmBpE,MAAQoE,EAAUC,aAAwBrE,MAAQqE,EAAe,KAG5GK,WChCoC/C,GAC1C,IAAM2C,EAAMC,cAAsBtD,GAMlC,OAJKc,EAAUuC,EAAIK,QAAShD,KAC1B2C,EAAIK,QAAUhD,GAGT2C,EAAIK,QDyBaC,CAAiBJ,GAEjChC,EAAkBI,IAAlBJ,cACFqC,EH3BChC,aAAWvB,GGgHlB,OAnFA2B,GAAoB,WAClB,IAAiC,WAA7ByB,SAAAA,EAAiBI,WJV6BC,QIUsBL,SAAAA,EAAiBK,OJT/D,KADAC,EIU+BxC,GJT1CL,QAAgB4C,GAC/BE,QAAQC,KACN,6KAGK,IAGJH,GAIEC,EAAarE,MAAK,SAAAiD,GAAK,OAAImB,EAAOxF,SAASqE,OAAWoB,EAAazF,SAAS,MIHjF,KJV0ByF,EAAwBD,EIc5CI,EAAW,SAACpE,SJ3BbV,EI4BiCU,EJ5BR,CAAC,QAAS,WAAY,aI4BPV,EAAqBU,QAAG2D,SAAAA,EAAiBU,oBAMhE,OAAhBd,EAAIK,SAAoB9D,SAASwE,gBAAkBf,EAAIK,SAAYL,EAAIK,QAAQW,SAASzE,SAASwE,yBAM/FtE,EAAER,UAAFgF,EAA0BC,yBAAsBd,GAAAA,EAAiBe,0BAIvE9G,EAAmBC,QAAM8F,SAAAA,EAAiB7F,UAAUqC,SAAQ,SAACnB,SACrDf,EAASD,EAAYgB,QAAK2E,SAAAA,EAAiBzF,gBAEjD,GJlBqC,SAAC8B,EAAkB/B,GAC9D,IAAQM,EAAgCN,EAAhCM,IAAKG,EAA2BT,EAA3BS,KAAMC,EAAqBV,EAArBU,IAAKF,EAAgBR,EAAhBQ,MAAOZ,EAASI,EAATJ,KAClB8G,EAA8B3E,EAAnChB,IAA0B4F,EAAS5E,EAAT4E,KAE5BC,EAAS9F,EAAgB,OACzB+F,EAAW/F,EAAgB,SAC3BgG,EAAUhG,EAAgB,QAC1BiG,EAAUjG,EAAgB,QAE1BkG,EAAUL,EAAKvF,cAAc6F,QAAQ,MAAO,IAC5CC,EAAaR,EAAoBtF,cAEvC,GAAIwF,IAAWtG,GAAsB,QAAf4G,EACpB,OAAO,EAGT,GAAIL,IAAarG,GAAwB,UAAf0G,EACxB,OAAO,EAIT,GAAIxG,GACF,IAAKoG,IAAYC,EACf,OAAO,OAGT,GAAID,IAAYrG,GAAQsG,IAAYtG,GAAoB,SAAZuG,GAAkC,SAAZA,EAChE,OAAO,EAMX,SAAIpH,GAAwB,IAAhBA,EAAKuD,SAAiBvD,EAAKW,SAAS2G,KAAetH,EAAKW,SAASyG,MAElEpH,EAEFkB,EAAgBlB,IAEfA,GIrBAuH,CAA8BpF,EAAG/B,aAAWA,EAAOJ,OAAPwH,EAAa7G,SAAS,KAAM,CAG1E,YJjE0BwB,EAAkB/B,EAAgB+D,IACrC,mBAAnBA,GAAiCA,EAAehC,EAAG/B,KAA+B,IAAnB+D,IACzEhC,EAAEgC,iBI6DIsD,CAAoBtF,EAAG/B,QAAQ0F,SAAAA,EAAiB3B,iBJzD1D,SAAgChC,EAAkB/B,EAAgB8F,GAChE,MAAuB,mBAAZA,EACFA,EAAQ/D,EAAG/B,IAGD,IAAZ8F,QAAgC7D,IAAZ6D,EIsDdwB,CAAgBvF,EAAG/B,QAAQ0F,SAAAA,EAAiBI,SAG/C,YAFAhC,EAAgB/B,GAMlB0D,EAAG1D,EAAG/B,OAtBR8D,EAAgB/B,KA2BdwF,EAAgB,SAACC,QACHvF,IAAduF,EAAMzG,WAKwBkB,WAA7ByD,SAAAA,EAAiB+B,WAAoD,WAA3B/B,SAAAA,EAAiBgC,cAAmBhC,GAAAA,EAAiB+B,UAClGtB,EAASqB,IAIPG,EAAc,SAACH,QACDvF,IAAduF,EAAMzG,WAKN2E,GAAAA,EAAiBgC,OACnBvB,EAASqB,IAab,OARClC,EAAIK,SAAW9D,UAAUC,iBAAiB,QAAS6F,IAEnDrC,EAAIK,SAAW9D,UAAUC,iBAAiB,UAAWyF,GAElD1B,GACFlG,EAAmBC,QAAM8F,SAAAA,EAAiB7F,UAAUqC,SAAQ,SAACnB,GAAG,OAAK8E,EAAMjD,UAAU7C,EAAYgB,QAAK2E,SAAAA,EAAiBzF,oBAGlH,YAEJqF,EAAIK,SAAW9D,UAAU+F,oBAAoB,QAASD,IAEtDrC,EAAIK,SAAW9D,UAAU+F,oBAAoB,UAAWL,GAErD1B,GACFlG,EAAmBC,QAAM8F,SAAAA,EAAiB7F,UAAUqC,SAAQ,SAACnB,GAAG,OAAK8E,EAAMhD,aAAa9C,EAAYgB,QAAK2E,SAAAA,EAAiBzF,wBAG7H,CAACL,EAAM6F,EAAIC,EAAiBlC,IAExB8B"}
@@ -15,37 +15,6 @@ function _extends() {
15
15
  };
16
16
  return _extends.apply(this, arguments);
17
17
  }
18
- function _unsupportedIterableToArray(o, minLen) {
19
- if (!o) return;
20
- if (typeof o === "string") return _arrayLikeToArray(o, minLen);
21
- var n = Object.prototype.toString.call(o).slice(8, -1);
22
- if (n === "Object" && o.constructor) n = o.constructor.name;
23
- if (n === "Map" || n === "Set") return Array.from(o);
24
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
25
- }
26
- function _arrayLikeToArray(arr, len) {
27
- if (len == null || len > arr.length) len = arr.length;
28
- for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
29
- return arr2;
30
- }
31
- function _createForOfIteratorHelperLoose(o, allowArrayLike) {
32
- var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
33
- if (it) return (it = it.call(o)).next.bind(it);
34
- if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
35
- if (it) o = it;
36
- var i = 0;
37
- return function () {
38
- if (i >= o.length) return {
39
- done: true
40
- };
41
- return {
42
- done: false,
43
- value: o[i++]
44
- };
45
- };
46
- }
47
- throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
48
- }
49
18
 
50
19
  var reservedModifierKeywords = ['shift', 'alt', 'meta', 'mod'];
51
20
  var mappedKeys = {
@@ -65,6 +34,9 @@ var mappedKeys = {
65
34
  '8': 'digit8',
66
35
  '9': 'digit9'
67
36
  };
37
+ function isHotkeyModifier(key) {
38
+ return reservedModifierKeywords.includes(key);
39
+ }
68
40
  function parseKeysHookInput(keys, splitKey) {
69
41
  if (splitKey === void 0) {
70
42
  splitKey = ',';
@@ -97,6 +69,61 @@ function parseHotkey(hotkey, combinationKey) {
97
69
  });
98
70
  }
99
71
 
72
+ var currentlyPressedKeys = /*#__PURE__*/new Set();
73
+ function isHotkeyPressed(key, splitKey) {
74
+ if (splitKey === void 0) {
75
+ splitKey = ',';
76
+ }
77
+ var hotkeyArray = Array.isArray(key) ? key : key.split(splitKey);
78
+ return hotkeyArray.every(function (hotkey) {
79
+ return currentlyPressedKeys.has(hotkey.trim().toLowerCase());
80
+ });
81
+ }
82
+ function pushToCurrentlyPressedKeys(key) {
83
+ var hotkeyArray = Array.isArray(key) ? key : [key];
84
+ /*
85
+ Due to a weird behavior on macOS we need to clear the set if the user pressed down the meta key and presses another key.
86
+ https://stackoverflow.com/questions/11818637/why-does-javascript-drop-keyup-events-when-the-metakey-is-pressed-on-mac-browser
87
+ Otherwise the set will hold all ever pressed keys while the meta key is down which leads to wrong results.
88
+ */
89
+ if (currentlyPressedKeys.has('meta')) {
90
+ currentlyPressedKeys.forEach(function (key) {
91
+ return !isHotkeyModifier(key) && currentlyPressedKeys["delete"](key);
92
+ });
93
+ }
94
+ hotkeyArray.forEach(function (hotkey) {
95
+ return currentlyPressedKeys.add(hotkey.toLowerCase());
96
+ });
97
+ }
98
+ function removeFromCurrentlyPressedKeys(key) {
99
+ /*
100
+ Due to a weird behavior on macOS we need to clear the set if the user pressed down the meta key and presses another key.
101
+ https://stackoverflow.com/questions/11818637/why-does-javascript-drop-keyup-events-when-the-metakey-is-pressed-on-mac-browser
102
+ Otherwise the set will hold all ever pressed keys while the meta key is down which leads to wrong results.
103
+ */
104
+ if (key === 'meta') {
105
+ currentlyPressedKeys.clear();
106
+ } else {
107
+ currentlyPressedKeys["delete"](key);
108
+ }
109
+ }
110
+ (function () {
111
+ document.addEventListener('keydown', function (e) {
112
+ if (e.key === undefined) {
113
+ // Synthetic event (e.g., Chrome autofill). Ignore.
114
+ return;
115
+ }
116
+ pushToCurrentlyPressedKeys(e.key.toLowerCase());
117
+ });
118
+ document.addEventListener('keyup', function (e) {
119
+ if (e.key === undefined) {
120
+ // Synthetic event (e.g., Chrome autofill). Ignore.
121
+ return;
122
+ }
123
+ removeFromCurrentlyPressedKeys(e.key.toLowerCase());
124
+ });
125
+ })();
126
+
100
127
  function maybePreventDefault(e, hotkey, preventDefault) {
101
128
  if (typeof preventDefault === 'function' && preventDefault(e, hotkey) || preventDefault === true) {
102
129
  e.preventDefault();
@@ -136,18 +163,18 @@ function isScopeActive(activeScopes, scopes) {
136
163
  return scopes.includes(scope);
137
164
  }) || activeScopes.includes('*');
138
165
  }
139
- var isHotkeyMatchingKeyboardEvent = function isHotkeyMatchingKeyboardEvent(e, hotkey, pressedDownKeys) {
166
+ var isHotkeyMatchingKeyboardEvent = function isHotkeyMatchingKeyboardEvent(e, hotkey) {
140
167
  var alt = hotkey.alt,
141
168
  meta = hotkey.meta,
142
169
  mod = hotkey.mod,
143
170
  shift = hotkey.shift,
144
171
  keys = hotkey.keys;
145
- var altKey = e.altKey,
146
- ctrlKey = e.ctrlKey,
147
- metaKey = e.metaKey,
148
- shiftKey = e.shiftKey,
149
- pressedKeyUppercase = e.key,
172
+ var pressedKeyUppercase = e.key,
150
173
  code = e.code;
174
+ var altKey = isHotkeyPressed('alt');
175
+ var shiftKey = isHotkeyPressed('shift');
176
+ var metaKey = isHotkeyPressed('meta');
177
+ var ctrlKey = isHotkeyPressed('ctrl');
151
178
  var keyCode = code.toLowerCase().replace('key', '');
152
179
  var pressedKey = pressedKeyUppercase.toLowerCase();
153
180
  if (altKey !== alt && pressedKey !== 'alt') {
@@ -167,14 +194,12 @@ var isHotkeyMatchingKeyboardEvent = function isHotkeyMatchingKeyboardEvent(e, ho
167
194
  }
168
195
  }
169
196
  // All modifiers are correct, now check the key
170
- // If the key is set we check for the key
197
+ // If the key is set, we check for the key
171
198
  if (keys && keys.length === 1 && (keys.includes(pressedKey) || keys.includes(keyCode))) {
172
199
  return true;
173
200
  } else if (keys) {
174
201
  // Check if all keys are present in pressedDownKeys set
175
- return keys.every(function (key) {
176
- return pressedDownKeys.has(key);
177
- });
202
+ return isHotkeyPressed(keys);
178
203
  } else if (!keys) {
179
204
  // If the key is not set, we only listen for modifiers, that check went alright, so we return true
180
205
  return true;
@@ -312,7 +337,6 @@ var stopPropagation = function stopPropagation(e) {
312
337
  e.stopImmediatePropagation();
313
338
  };
314
339
  var useSafeLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
315
- var pressedDownKeys = /*#__PURE__*/new Set();
316
340
  function useHotkeys(keys, callback, options, dependencies) {
317
341
  var ref = useRef(null);
318
342
  var _options = !(options instanceof Array) ? options : !(dependencies instanceof Array) ? dependencies : undefined;
@@ -343,12 +367,13 @@ function useHotkeys(keys, callback, options, dependencies) {
343
367
  parseKeysHookInput(keys, memoisedOptions == null ? void 0 : memoisedOptions.splitKey).forEach(function (key) {
344
368
  var _hotkey$keys;
345
369
  var hotkey = parseHotkey(key, memoisedOptions == null ? void 0 : memoisedOptions.combinationKey);
346
- if (isHotkeyMatchingKeyboardEvent(e, hotkey, pressedDownKeys) || (_hotkey$keys = hotkey.keys) != null && _hotkey$keys.includes('*')) {
370
+ if (isHotkeyMatchingKeyboardEvent(e, hotkey) || (_hotkey$keys = hotkey.keys) != null && _hotkey$keys.includes('*')) {
347
371
  maybePreventDefault(e, hotkey, memoisedOptions == null ? void 0 : memoisedOptions.preventDefault);
348
372
  if (!isHotkeyEnabled(e, hotkey, memoisedOptions == null ? void 0 : memoisedOptions.enabled)) {
349
373
  stopPropagation(e);
350
374
  return;
351
375
  }
376
+ // Execute the user callback for that hotkey
352
377
  cb(e, hotkey);
353
378
  }
354
379
  });
@@ -358,7 +383,6 @@ function useHotkeys(keys, callback, options, dependencies) {
358
383
  // Synthetic event (e.g., Chrome autofill). Ignore.
359
384
  return;
360
385
  }
361
- pressedDownKeys.add(event.key.toLowerCase());
362
386
  if ((memoisedOptions == null ? void 0 : memoisedOptions.keydown) === undefined && (memoisedOptions == null ? void 0 : memoisedOptions.keyup) !== true || memoisedOptions != null && memoisedOptions.keydown) {
363
387
  listener(event);
364
388
  }
@@ -368,12 +392,6 @@ function useHotkeys(keys, callback, options, dependencies) {
368
392
  // Synthetic event (e.g., Chrome autofill). Ignore.
369
393
  return;
370
394
  }
371
- if (event.key.toLowerCase() !== 'meta') {
372
- pressedDownKeys["delete"](event.key.toLowerCase());
373
- } else {
374
- // On macOS pressing down the meta key prevents triggering the keyup event for any other key https://stackoverflow.com/a/57153300/735226.
375
- pressedDownKeys.clear();
376
- }
377
395
  if (memoisedOptions != null && memoisedOptions.keyup) {
378
396
  listener(event);
379
397
  }
@@ -402,64 +420,5 @@ function useHotkeys(keys, callback, options, dependencies) {
402
420
  return ref;
403
421
  }
404
422
 
405
- var currentlyPressedKeys = /*#__PURE__*/new Set();
406
- function isHotkeyPressed(key, splitKey) {
407
- if (splitKey === void 0) {
408
- splitKey = ',';
409
- }
410
- var hotkeyArray = Array.isArray(key) ? key : key.split(splitKey);
411
- return hotkeyArray.every(function (hotkey) {
412
- var parsedHotkey = parseHotkey(hotkey);
413
- for (var _iterator = _createForOfIteratorHelperLoose(currentlyPressedKeys), _step; !(_step = _iterator()).done;) {
414
- var pressedHotkey = _step.value;
415
- if (deepEqual(parsedHotkey, pressedHotkey)) {
416
- return true;
417
- }
418
- }
419
- });
420
- }
421
- function pushToCurrentlyPressedKeys(key) {
422
- var hotkeyArray = Array.isArray(key) ? key : [key];
423
- hotkeyArray.forEach(function (hotkey) {
424
- return currentlyPressedKeys.add(parseHotkey(hotkey));
425
- });
426
- }
427
- function removeFromCurrentlyPressedKeys(key) {
428
- var hotkeyArray = Array.isArray(key) ? key : [key];
429
- hotkeyArray.forEach(function (hotkey) {
430
- var parsedHotkey = parseHotkey(hotkey);
431
- for (var _iterator2 = _createForOfIteratorHelperLoose(currentlyPressedKeys), _step2; !(_step2 = _iterator2()).done;) {
432
- var _pressedHotkey$keys;
433
- var pressedHotkey = _step2.value;
434
- if ((_pressedHotkey$keys = pressedHotkey.keys) != null && _pressedHotkey$keys.every(function (key) {
435
- var _parsedHotkey$keys;
436
- return (_parsedHotkey$keys = parsedHotkey.keys) == null ? void 0 : _parsedHotkey$keys.includes(key);
437
- })) {
438
- currentlyPressedKeys["delete"](pressedHotkey);
439
- }
440
- }
441
- });
442
- }
443
- (function () {
444
- if (typeof window !== 'undefined') {
445
- window.addEventListener('DOMContentLoaded', function () {
446
- document.addEventListener('keydown', function (e) {
447
- if (e.key === undefined) {
448
- // Synthetic event (e.g., Chrome autofill). Ignore.
449
- return;
450
- }
451
- pushToCurrentlyPressedKeys(e.key);
452
- });
453
- document.addEventListener('keyup', function (e) {
454
- if (e.key === undefined) {
455
- // Synthetic event (e.g., Chrome autofill). Ignore.
456
- return;
457
- }
458
- removeFromCurrentlyPressedKeys(e.key);
459
- });
460
- });
461
- }
462
- })();
463
-
464
423
  export { HotkeysProvider, isHotkeyPressed, useHotkeys, useHotkeysContext };
465
424
  //# sourceMappingURL=react-hotkeys-hook.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"react-hotkeys-hook.esm.js","sources":["../src/parseHotkeys.ts","../src/validators.ts","../src/BoundHotkeysProxyProvider.tsx","../src/deepEqual.ts","../src/HotkeysProvider.tsx","../src/useDeepEqualMemo.ts","../src/useHotkeys.ts","../src/isHotkeyPressed.ts"],"sourcesContent":["import { Hotkey, KeyboardModifiers, Keys } from './types'\n\nconst reservedModifierKeywords = ['shift', 'alt', 'meta', 'mod']\n\nconst mappedKeys: Record<string, string> = {\n esc: 'escape',\n return: 'enter',\n left: 'arrowleft',\n up: 'arrowup',\n right: 'arrowright',\n down: 'arrowdown',\n '1': 'digit1',\n '2': 'digit2',\n '3': 'digit3',\n '4': 'digit4',\n '5': 'digit5',\n '6': 'digit6',\n '7': 'digit7',\n '8': 'digit8',\n '9': 'digit9',\n}\n\nexport function parseKeysHookInput(keys: Keys, splitKey: string = ','): string[] {\n if (typeof keys === 'string') {\n return keys.split(splitKey)\n }\n\n return keys\n}\n\nexport function parseHotkey(hotkey: string, combinationKey: string = '+'): Hotkey {\n const keys = hotkey\n .toLocaleLowerCase()\n .split(combinationKey)\n .map(k => k.trim())\n .map(k => mappedKeys[k] || k)\n\n const modifiers: KeyboardModifiers = {\n alt: keys.includes('alt'),\n shift: keys.includes('shift'),\n meta: keys.includes('meta'),\n mod: keys.includes('mod'),\n }\n\n const singleCharKeys = keys.filter((k) => !reservedModifierKeywords.includes(k))\n\n return {\n ...modifiers,\n keys: singleCharKeys,\n }\n}\n","import { FormTags, Hotkey, Scopes, Trigger } from './types'\n\nexport function maybePreventDefault(e: KeyboardEvent, hotkey: Hotkey, preventDefault?: Trigger): void {\n if ((typeof preventDefault === 'function' && preventDefault(e, hotkey)) || preventDefault === true) {\n e.preventDefault()\n }\n}\n\nexport function isHotkeyEnabled(e: KeyboardEvent, hotkey: Hotkey, enabled?: Trigger): boolean {\n if (typeof enabled === 'function') {\n return enabled(e, hotkey)\n }\n\n return enabled === true || enabled === undefined\n}\n\nexport function isKeyboardEventTriggeredByInput(ev: KeyboardEvent): boolean {\n return isHotkeyEnabledOnTag(ev, ['input', 'textarea', 'select'])\n}\n\nexport function isHotkeyEnabledOnTag({ target }: KeyboardEvent, enabledOnTags: FormTags[] | boolean = false): boolean {\n const targetTagName = target && (target as HTMLElement).tagName\n\n if (enabledOnTags instanceof Array) {\n return Boolean(targetTagName && enabledOnTags && enabledOnTags.some(tag => tag.toLowerCase() === targetTagName.toLowerCase()))\n }\n\n return Boolean(targetTagName && enabledOnTags && enabledOnTags === true)\n}\n\nexport function isScopeActive(activeScopes: string[], scopes?: Scopes): boolean {\n if (activeScopes.length === 0 && scopes) {\n console.warn(\n 'A hotkey has the \"scopes\" option set, however no active scopes were found. If you want to use the global scopes feature, you need to wrap your app in a <HotkeysProvider>'\n )\n\n return true\n }\n\n if (!scopes) {\n return true\n }\n\n return activeScopes.some(scope => scopes.includes(scope)) || activeScopes.includes('*')\n}\n\nexport const isHotkeyMatchingKeyboardEvent = (e: KeyboardEvent, hotkey: Hotkey, pressedDownKeys: Set<string>): boolean => {\n const { alt, meta, mod, shift, keys } = hotkey\n const { altKey, ctrlKey, metaKey, shiftKey, key: pressedKeyUppercase, code } = e\n\n const keyCode = code.toLowerCase().replace('key', '')\n const pressedKey = pressedKeyUppercase.toLowerCase()\n\n if (altKey !== alt && pressedKey !== 'alt') {\n return false\n }\n\n if (shiftKey !== shift && pressedKey !== 'shift') {\n return false\n }\n\n // Mod is a special key name that is checking for meta on macOS and ctrl on other platforms\n if (mod) {\n if (!metaKey && !ctrlKey) {\n return false\n }\n } else {\n if (metaKey !== meta && ctrlKey !== meta && keyCode !== 'meta' && keyCode !== 'ctrl') {\n return false\n }\n }\n\n // All modifiers are correct, now check the key\n // If the key is set we check for the key\n if (keys && keys.length === 1 && (keys.includes(pressedKey) || keys.includes(keyCode))) {\n return true\n } else if (keys) {\n // Check if all keys are present in pressedDownKeys set\n return keys.every(key => pressedDownKeys.has(key))\n }\n else if (!keys) {\n // If the key is not set, we only listen for modifiers, that check went alright, so we return true\n return true\n }\n\n // There is nothing that matches.\n return false\n}\n","import { createContext, ReactNode, useContext } from 'react'\nimport { Hotkey } from './types'\n\ntype BoundHotkeysProxyProviderType = {\n addHotkey: (hotkey: Hotkey) => void,\n removeHotkey: (hotkey: Hotkey) => void,\n}\n\nconst BoundHotkeysProxyProvider = createContext<BoundHotkeysProxyProviderType | undefined>(undefined)\n\nexport const useBoundHotkeysProxy = () => {\n return useContext(BoundHotkeysProxyProvider)\n}\n\ninterface Props {\n children: ReactNode\n addHotkey: (hotkey: Hotkey) => void\n removeHotkey: (hotkey: Hotkey) => void\n}\n\nexport default function BoundHotkeysProxyProviderProvider({ addHotkey, removeHotkey, children }: Props) {\n return <BoundHotkeysProxyProvider.Provider value={{addHotkey, removeHotkey}}>{children}</BoundHotkeysProxyProvider.Provider>\n}\n","export default function deepEqual(x: any, y: any): boolean {\n //@ts-ignore\n return (x && y && typeof x === 'object' && typeof y === 'object')\n //@ts-ignore\n ? (Object.keys(x).length === Object.keys(y).length) && Object.keys(x).reduce(function(isEqual, key) {\n return isEqual && deepEqual(x[key], y[key])\n }, true)\n : (x === y)\n}\n","import { Hotkey } from './types'\nimport { createContext, ReactNode, useState, useContext, useCallback } from 'react'\nimport BoundHotkeysProxyProviderProvider from './BoundHotkeysProxyProvider'\nimport deepEqual from './deepEqual'\n\nexport type HotkeysContextType = {\n hotkeys: ReadonlyArray<Hotkey>\n enabledScopes: string[]\n toggleScope: (scope: string) => void\n enableScope: (scope: string) => void\n disableScope: (scope: string) => void\n}\n\n// The context is only needed for special features like global scoping, so we use a graceful default fallback\nconst HotkeysContext = createContext<HotkeysContextType>({\n hotkeys: [],\n enabledScopes: [], // This array has to be empty instead of containing '*' as default, to check if the provider is set or not\n toggleScope: () => {},\n enableScope: () => {},\n disableScope: () => {},\n})\n\nexport const useHotkeysContext = () => {\n return useContext(HotkeysContext)\n}\n\ninterface Props {\n initiallyActiveScopes?: string[]\n children: ReactNode\n}\n\nexport const HotkeysProvider = ({initiallyActiveScopes = ['*'], children}: Props) => {\n const [internalActiveScopes, setInternalActiveScopes] = useState(initiallyActiveScopes?.length > 0 ? initiallyActiveScopes : ['*'])\n const [boundHotkeys, setBoundHotkeys] = useState<Hotkey[]>([]);\n\n const enableScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.includes('*')) {\n return [scope]\n }\n\n return Array.from(new Set([...prev, scope]))\n })\n }, [])\n\n const disableScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.filter(s => s !== scope).length === 0) {\n return ['*']\n } else {\n return prev.filter(s => s !== scope)\n }\n })\n }, [])\n\n const toggleScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.includes(scope)) {\n if (prev.filter(s => s !== scope).length === 0) {\n return ['*']\n } else {\n return prev.filter(s => s !== scope)\n }\n } else {\n if (prev.includes('*')) {\n return [scope]\n }\n\n return Array.from(new Set([...prev, scope]))\n }\n })\n }, [])\n\n const addBoundHotkey = useCallback((hotkey: Hotkey) => {\n setBoundHotkeys((prev) => [...prev, hotkey])\n }, [])\n\n const removeBoundHotkey = useCallback((hotkey: Hotkey) => {\n setBoundHotkeys((prev) => prev.filter(h => !deepEqual(h, hotkey)))\n }, [])\n\n return (\n <HotkeysContext.Provider value={{enabledScopes: internalActiveScopes, hotkeys: boundHotkeys, enableScope, disableScope, toggleScope}}>\n <BoundHotkeysProxyProviderProvider addHotkey={addBoundHotkey} removeHotkey={removeBoundHotkey}>\n {children}\n </BoundHotkeysProxyProviderProvider>\n </HotkeysContext.Provider>\n )\n}\n","import { useRef } from 'react'\nimport deepEqual from './deepEqual'\n\nexport default function useDeepEqualMemo<T>(value: T) {\n const ref = useRef<T | undefined>(undefined)\n\n if (!deepEqual(ref.current, value)) {\n ref.current = value\n }\n\n return ref.current\n}\n","import { HotkeyCallback, Keys, Options, OptionsOrDependencyArray, RefType } from './types'\nimport { DependencyList, useCallback, useEffect, useLayoutEffect, useRef } from 'react'\nimport { parseHotkey, parseKeysHookInput } from './parseHotkeys'\nimport {\n isHotkeyEnabled,\n isHotkeyEnabledOnTag,\n isHotkeyMatchingKeyboardEvent,\n isKeyboardEventTriggeredByInput,\n isScopeActive,\n maybePreventDefault,\n} from './validators'\nimport { useHotkeysContext } from './HotkeysProvider'\nimport { useBoundHotkeysProxy } from './BoundHotkeysProxyProvider'\nimport useDeepEqualMemo from './useDeepEqualMemo'\n\nconst stopPropagation = (e: KeyboardEvent): void => {\n e.stopPropagation()\n e.preventDefault()\n e.stopImmediatePropagation()\n}\n\nconst useSafeLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect\n\nconst pressedDownKeys = new Set<string>()\n\nexport default function useHotkeys<T extends HTMLElement>(\n keys: Keys,\n callback: HotkeyCallback,\n options?: OptionsOrDependencyArray,\n dependencies?: OptionsOrDependencyArray,\n) {\n const ref = useRef<RefType<T>>(null)\n\n const _options: Options | undefined = !(options instanceof Array) ? (options as Options) : !(dependencies instanceof Array) ? (dependencies as Options) : undefined\n const _deps: DependencyList = options instanceof Array ? options : dependencies instanceof Array ? dependencies : []\n\n const cb = useCallback(callback, [..._deps])\n const memoisedOptions = useDeepEqualMemo(_options)\n\n const { enabledScopes } = useHotkeysContext()\n const proxy = useBoundHotkeysProxy()\n\n useSafeLayoutEffect(() => {\n if (memoisedOptions?.enabled === false || !isScopeActive(enabledScopes, memoisedOptions?.scopes)) {\n return\n }\n\n const listener = (e: KeyboardEvent) => {\n if (isKeyboardEventTriggeredByInput(e) && !isHotkeyEnabledOnTag(e, memoisedOptions?.enableOnFormTags)) {\n return\n }\n\n // TODO: SINCE THE EVENT IS NOW ATTACHED TO THE REF, THE ACTIVE ELEMENT CAN NEVER BE INSIDE THE REF. THE HOTKEY ONLY TRIGGERS IF THE\n // REF IS THE ACTIVE ELEMENT. THIS IS A PROBLEM SINCE FOCUSED SUB COMPONENTS WON'T TRIGGER THE HOTKEY.\n if (ref.current !== null && document.activeElement !== ref.current && !ref.current.contains(document.activeElement)) {\n stopPropagation(e)\n\n return\n }\n\n if (((e.target as HTMLElement)?.isContentEditable && !memoisedOptions?.enableOnContentEditable)) {\n return\n }\n\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => {\n const hotkey = parseHotkey(key, memoisedOptions?.combinationKey)\n\n if (isHotkeyMatchingKeyboardEvent(e, hotkey, pressedDownKeys) || hotkey.keys?.includes('*')) {\n maybePreventDefault(e, hotkey, memoisedOptions?.preventDefault)\n\n if (!isHotkeyEnabled(e, hotkey, memoisedOptions?.enabled)) {\n stopPropagation(e)\n\n return\n }\n\n cb(e, hotkey)\n }\n })\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n pressedDownKeys.add(event.key.toLowerCase())\n\n if ((memoisedOptions?.keydown === undefined && memoisedOptions?.keyup !== true) || memoisedOptions?.keydown) {\n listener(event)\n }\n }\n\n const handleKeyUp = (event: KeyboardEvent) => {\n if (event.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n if (event.key.toLowerCase() !== 'meta') {\n pressedDownKeys.delete(event.key.toLowerCase())\n } else {\n // On macOS pressing down the meta key prevents triggering the keyup event for any other key https://stackoverflow.com/a/57153300/735226.\n pressedDownKeys.clear()\n }\n\n if (memoisedOptions?.keyup) {\n listener(event)\n }\n }\n\n // @ts-ignore\n (ref.current || document).addEventListener('keyup', handleKeyUp);\n // @ts-ignore\n (ref.current || document).addEventListener('keydown', handleKeyDown)\n\n if (proxy) {\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => proxy.addHotkey(parseHotkey(key, memoisedOptions?.combinationKey)))\n }\n\n return () => {\n // @ts-ignore\n (ref.current || document).removeEventListener('keyup', handleKeyUp);\n // @ts-ignore\n (ref.current || document).removeEventListener('keydown', handleKeyDown)\n\n if (proxy) {\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => proxy.removeHotkey(parseHotkey(key, memoisedOptions?.combinationKey)))\n }\n }\n }, [keys, cb, memoisedOptions, enabledScopes])\n\n return ref\n}\n","import { Hotkey } from './types'\nimport { parseHotkey } from './parseHotkeys'\nimport deepEqual from './deepEqual'\n\nconst currentlyPressedKeys: Set<Hotkey> = new Set<Hotkey>()\n\nexport function isHotkeyPressed(key: string | string[], splitKey: string = ','): boolean {\n const hotkeyArray = Array.isArray(key) ? key : key.split(splitKey)\n\n return hotkeyArray.every((hotkey) => {\n const parsedHotkey = parseHotkey(hotkey)\n\n for (const pressedHotkey of currentlyPressedKeys) {\n if (deepEqual(parsedHotkey, pressedHotkey)) {\n return true\n }\n }\n })\n}\n\nexport function pushToCurrentlyPressedKeys(key: string | string[]): void {\n const hotkeyArray = Array.isArray(key) ? key : [key]\n\n hotkeyArray.forEach(hotkey => currentlyPressedKeys.add(parseHotkey(hotkey)))\n}\n\nexport function removeFromCurrentlyPressedKeys(key: string | string[]): void {\n const hotkeyArray = Array.isArray(key) ? key : [key]\n\n hotkeyArray.forEach((hotkey) => {\n const parsedHotkey = parseHotkey(hotkey)\n\n for (const pressedHotkey of currentlyPressedKeys) {\n if (pressedHotkey.keys?.every((key) => parsedHotkey.keys?.includes(key))) {\n currentlyPressedKeys.delete(pressedHotkey)\n }\n }\n })\n}\n\n(() => {\n if (typeof window !== 'undefined') {\n window.addEventListener('DOMContentLoaded', () => {\n document.addEventListener('keydown', e => {\n if (e.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n pushToCurrentlyPressedKeys(e.key)\n })\n\n document.addEventListener('keyup', e => {\n if (e.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n removeFromCurrentlyPressedKeys(e.key)\n })\n })\n }\n})()\n"],"names":["reservedModifierKeywords","mappedKeys","esc","left","up","right","down","parseKeysHookInput","keys","splitKey","split","parseHotkey","hotkey","combinationKey","toLocaleLowerCase","map","k","trim","modifiers","alt","includes","shift","meta","mod","singleCharKeys","filter","maybePreventDefault","e","preventDefault","isHotkeyEnabled","enabled","undefined","isKeyboardEventTriggeredByInput","ev","isHotkeyEnabledOnTag","enabledOnTags","target","targetTagName","tagName","Array","Boolean","some","tag","toLowerCase","isScopeActive","activeScopes","scopes","length","console","warn","scope","isHotkeyMatchingKeyboardEvent","pressedDownKeys","altKey","ctrlKey","metaKey","shiftKey","pressedKeyUppercase","key","code","keyCode","replace","pressedKey","every","has","BoundHotkeysProxyProvider","createContext","useBoundHotkeysProxy","useContext","BoundHotkeysProxyProviderProvider","addHotkey","removeHotkey","children","_jsx","deepEqual","x","y","Object","reduce","isEqual","HotkeysContext","hotkeys","enabledScopes","toggleScope","enableScope","disableScope","useHotkeysContext","HotkeysProvider","initiallyActiveScopes","useState","internalActiveScopes","setInternalActiveScopes","boundHotkeys","setBoundHotkeys","useCallback","prev","from","Set","s","addBoundHotkey","removeBoundHotkey","h","useDeepEqualMemo","value","ref","useRef","current","stopPropagation","stopImmediatePropagation","useSafeLayoutEffect","window","useLayoutEffect","useEffect","useHotkeys","callback","options","dependencies","_options","_deps","cb","memoisedOptions","proxy","listener","enableOnFormTags","document","activeElement","contains","isContentEditable","enableOnContentEditable","forEach","handleKeyDown","event","add","keydown","keyup","handleKeyUp","clear","addEventListener","removeEventListener","currentlyPressedKeys","isHotkeyPressed","hotkeyArray","isArray","parsedHotkey","pressedHotkey","pushToCurrentlyPressedKeys","removeFromCurrentlyPressedKeys"],"mappings":"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"}
1
+ {"version":3,"file":"react-hotkeys-hook.esm.js","sources":["../src/parseHotkeys.ts","../src/isHotkeyPressed.ts","../src/validators.ts","../src/BoundHotkeysProxyProvider.tsx","../src/deepEqual.ts","../src/HotkeysProvider.tsx","../src/useDeepEqualMemo.ts","../src/useHotkeys.ts"],"sourcesContent":["import { Hotkey, KeyboardModifiers, Keys } from './types'\n\nconst reservedModifierKeywords = ['shift', 'alt', 'meta', 'mod']\n\nconst mappedKeys: Record<string, string> = {\n esc: 'escape',\n return: 'enter',\n left: 'arrowleft',\n up: 'arrowup',\n right: 'arrowright',\n down: 'arrowdown',\n '1': 'digit1',\n '2': 'digit2',\n '3': 'digit3',\n '4': 'digit4',\n '5': 'digit5',\n '6': 'digit6',\n '7': 'digit7',\n '8': 'digit8',\n '9': 'digit9',\n}\n\nexport function isHotkeyModifier(key: string) {\n return reservedModifierKeywords.includes(key)\n}\n\nexport function parseKeysHookInput(keys: Keys, splitKey: string = ','): string[] {\n if (typeof keys === 'string') {\n return keys.split(splitKey)\n }\n\n return keys\n}\n\nexport function parseHotkey(hotkey: string, combinationKey: string = '+'): Hotkey {\n const keys = hotkey\n .toLocaleLowerCase()\n .split(combinationKey)\n .map(k => k.trim())\n .map(k => mappedKeys[k] || k)\n\n const modifiers: KeyboardModifiers = {\n alt: keys.includes('alt'),\n shift: keys.includes('shift'),\n meta: keys.includes('meta'),\n mod: keys.includes('mod'),\n }\n\n const singleCharKeys = keys.filter((k) => !reservedModifierKeywords.includes(k))\n\n return {\n ...modifiers,\n keys: singleCharKeys,\n }\n}\n","import { isHotkeyModifier } from './parseHotkeys'\n\nconst currentlyPressedKeys: Set<string> = new Set<string>()\n\nexport function isHotkeyPressed(key: string | string[], splitKey: string = ','): boolean {\n const hotkeyArray = Array.isArray(key) ? key : key.split(splitKey)\n\n return hotkeyArray.every((hotkey) => currentlyPressedKeys.has(hotkey.trim().toLowerCase()))\n}\n\nfunction pushToCurrentlyPressedKeys(key: string | string[]): void {\n const hotkeyArray = Array.isArray(key) ? key : [key]\n\n /*\n Due to a weird behavior on macOS we need to clear the set if the user pressed down the meta key and presses another key.\n https://stackoverflow.com/questions/11818637/why-does-javascript-drop-keyup-events-when-the-metakey-is-pressed-on-mac-browser\n Otherwise the set will hold all ever pressed keys while the meta key is down which leads to wrong results.\n */\n if (currentlyPressedKeys.has('meta')) {\n currentlyPressedKeys.forEach(key => !isHotkeyModifier(key) && currentlyPressedKeys.delete(key))\n }\n\n hotkeyArray.forEach(hotkey => currentlyPressedKeys.add(hotkey.toLowerCase()))\n}\n\nfunction removeFromCurrentlyPressedKeys(key: string): void {\n /*\n Due to a weird behavior on macOS we need to clear the set if the user pressed down the meta key and presses another key.\n https://stackoverflow.com/questions/11818637/why-does-javascript-drop-keyup-events-when-the-metakey-is-pressed-on-mac-browser\n Otherwise the set will hold all ever pressed keys while the meta key is down which leads to wrong results.\n */\n if (key === 'meta') {\n currentlyPressedKeys.clear()\n } else {\n currentlyPressedKeys.delete(key)\n }\n}\n\n(() => {\n document.addEventListener('keydown', e => {\n if (e.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n pushToCurrentlyPressedKeys(e.key.toLowerCase())\n })\n\n document.addEventListener('keyup', e => {\n if (e.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n removeFromCurrentlyPressedKeys(e.key.toLowerCase())\n })\n})()\n","import { FormTags, Hotkey, Scopes, Trigger } from './types'\nimport { isHotkeyPressed } from './isHotkeyPressed'\n\nexport function maybePreventDefault(e: KeyboardEvent, hotkey: Hotkey, preventDefault?: Trigger): void {\n if ((typeof preventDefault === 'function' && preventDefault(e, hotkey)) || preventDefault === true) {\n e.preventDefault()\n }\n}\n\nexport function isHotkeyEnabled(e: KeyboardEvent, hotkey: Hotkey, enabled?: Trigger): boolean {\n if (typeof enabled === 'function') {\n return enabled(e, hotkey)\n }\n\n return enabled === true || enabled === undefined\n}\n\nexport function isKeyboardEventTriggeredByInput(ev: KeyboardEvent): boolean {\n return isHotkeyEnabledOnTag(ev, ['input', 'textarea', 'select'])\n}\n\nexport function isHotkeyEnabledOnTag({ target }: KeyboardEvent, enabledOnTags: FormTags[] | boolean = false): boolean {\n const targetTagName = target && (target as HTMLElement).tagName\n\n if (enabledOnTags instanceof Array) {\n return Boolean(targetTagName && enabledOnTags && enabledOnTags.some(tag => tag.toLowerCase() === targetTagName.toLowerCase()))\n }\n\n return Boolean(targetTagName && enabledOnTags && enabledOnTags === true)\n}\n\nexport function isScopeActive(activeScopes: string[], scopes?: Scopes): boolean {\n if (activeScopes.length === 0 && scopes) {\n console.warn(\n 'A hotkey has the \"scopes\" option set, however no active scopes were found. If you want to use the global scopes feature, you need to wrap your app in a <HotkeysProvider>'\n )\n\n return true\n }\n\n if (!scopes) {\n return true\n }\n\n return activeScopes.some(scope => scopes.includes(scope)) || activeScopes.includes('*')\n}\n\nexport const isHotkeyMatchingKeyboardEvent = (e: KeyboardEvent, hotkey: Hotkey): boolean => {\n const { alt, meta, mod, shift, keys } = hotkey\n const { key: pressedKeyUppercase, code } = e\n\n const altKey = isHotkeyPressed('alt')\n const shiftKey = isHotkeyPressed('shift')\n const metaKey = isHotkeyPressed('meta')\n const ctrlKey = isHotkeyPressed('ctrl')\n\n const keyCode = code.toLowerCase().replace('key', '')\n const pressedKey = pressedKeyUppercase.toLowerCase()\n\n if (altKey !== alt && pressedKey !== 'alt') {\n return false\n }\n\n if (shiftKey !== shift && pressedKey !== 'shift') {\n return false\n }\n\n // Mod is a special key name that is checking for meta on macOS and ctrl on other platforms\n if (mod) {\n if (!metaKey && !ctrlKey) {\n return false\n }\n } else {\n if (metaKey !== meta && ctrlKey !== meta && keyCode !== 'meta' && keyCode !== 'ctrl') {\n return false\n }\n }\n\n // All modifiers are correct, now check the key\n // If the key is set, we check for the key\n if (keys && keys.length === 1 && (keys.includes(pressedKey) || keys.includes(keyCode))) {\n return true\n } else if (keys) {\n // Check if all keys are present in pressedDownKeys set\n return isHotkeyPressed(keys)\n }\n else if (!keys) {\n // If the key is not set, we only listen for modifiers, that check went alright, so we return true\n return true\n }\n\n // There is nothing that matches.\n return false\n}\n","import { createContext, ReactNode, useContext } from 'react'\nimport { Hotkey } from './types'\n\ntype BoundHotkeysProxyProviderType = {\n addHotkey: (hotkey: Hotkey) => void,\n removeHotkey: (hotkey: Hotkey) => void,\n}\n\nconst BoundHotkeysProxyProvider = createContext<BoundHotkeysProxyProviderType | undefined>(undefined)\n\nexport const useBoundHotkeysProxy = () => {\n return useContext(BoundHotkeysProxyProvider)\n}\n\ninterface Props {\n children: ReactNode\n addHotkey: (hotkey: Hotkey) => void\n removeHotkey: (hotkey: Hotkey) => void\n}\n\nexport default function BoundHotkeysProxyProviderProvider({ addHotkey, removeHotkey, children }: Props) {\n return <BoundHotkeysProxyProvider.Provider value={{addHotkey, removeHotkey}}>{children}</BoundHotkeysProxyProvider.Provider>\n}\n","export default function deepEqual(x: any, y: any): boolean {\n //@ts-ignore\n return (x && y && typeof x === 'object' && typeof y === 'object')\n //@ts-ignore\n ? (Object.keys(x).length === Object.keys(y).length) && Object.keys(x).reduce(function(isEqual, key) {\n return isEqual && deepEqual(x[key], y[key])\n }, true)\n : (x === y)\n}\n","import { Hotkey } from './types'\nimport { createContext, ReactNode, useState, useContext, useCallback } from 'react'\nimport BoundHotkeysProxyProviderProvider from './BoundHotkeysProxyProvider'\nimport deepEqual from './deepEqual'\n\nexport type HotkeysContextType = {\n hotkeys: ReadonlyArray<Hotkey>\n enabledScopes: string[]\n toggleScope: (scope: string) => void\n enableScope: (scope: string) => void\n disableScope: (scope: string) => void\n}\n\n// The context is only needed for special features like global scoping, so we use a graceful default fallback\nconst HotkeysContext = createContext<HotkeysContextType>({\n hotkeys: [],\n enabledScopes: [], // This array has to be empty instead of containing '*' as default, to check if the provider is set or not\n toggleScope: () => {},\n enableScope: () => {},\n disableScope: () => {},\n})\n\nexport const useHotkeysContext = () => {\n return useContext(HotkeysContext)\n}\n\ninterface Props {\n initiallyActiveScopes?: string[]\n children: ReactNode\n}\n\nexport const HotkeysProvider = ({initiallyActiveScopes = ['*'], children}: Props) => {\n const [internalActiveScopes, setInternalActiveScopes] = useState(initiallyActiveScopes?.length > 0 ? initiallyActiveScopes : ['*'])\n const [boundHotkeys, setBoundHotkeys] = useState<Hotkey[]>([]);\n\n const enableScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.includes('*')) {\n return [scope]\n }\n\n return Array.from(new Set([...prev, scope]))\n })\n }, [])\n\n const disableScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.filter(s => s !== scope).length === 0) {\n return ['*']\n } else {\n return prev.filter(s => s !== scope)\n }\n })\n }, [])\n\n const toggleScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.includes(scope)) {\n if (prev.filter(s => s !== scope).length === 0) {\n return ['*']\n } else {\n return prev.filter(s => s !== scope)\n }\n } else {\n if (prev.includes('*')) {\n return [scope]\n }\n\n return Array.from(new Set([...prev, scope]))\n }\n })\n }, [])\n\n const addBoundHotkey = useCallback((hotkey: Hotkey) => {\n setBoundHotkeys((prev) => [...prev, hotkey])\n }, [])\n\n const removeBoundHotkey = useCallback((hotkey: Hotkey) => {\n setBoundHotkeys((prev) => prev.filter(h => !deepEqual(h, hotkey)))\n }, [])\n\n return (\n <HotkeysContext.Provider value={{enabledScopes: internalActiveScopes, hotkeys: boundHotkeys, enableScope, disableScope, toggleScope}}>\n <BoundHotkeysProxyProviderProvider addHotkey={addBoundHotkey} removeHotkey={removeBoundHotkey}>\n {children}\n </BoundHotkeysProxyProviderProvider>\n </HotkeysContext.Provider>\n )\n}\n","import { useRef } from 'react'\nimport deepEqual from './deepEqual'\n\nexport default function useDeepEqualMemo<T>(value: T) {\n const ref = useRef<T | undefined>(undefined)\n\n if (!deepEqual(ref.current, value)) {\n ref.current = value\n }\n\n return ref.current\n}\n","import { HotkeyCallback, Keys, Options, OptionsOrDependencyArray, RefType } from './types'\nimport { DependencyList, useCallback, useEffect, useLayoutEffect, useRef } from 'react'\nimport { parseHotkey, parseKeysHookInput } from './parseHotkeys'\nimport {\n isHotkeyEnabled,\n isHotkeyEnabledOnTag,\n isHotkeyMatchingKeyboardEvent,\n isKeyboardEventTriggeredByInput,\n isScopeActive,\n maybePreventDefault,\n} from './validators'\nimport { useHotkeysContext } from './HotkeysProvider'\nimport { useBoundHotkeysProxy } from './BoundHotkeysProxyProvider'\nimport useDeepEqualMemo from './useDeepEqualMemo'\n\nconst stopPropagation = (e: KeyboardEvent): void => {\n e.stopPropagation()\n e.preventDefault()\n e.stopImmediatePropagation()\n}\n\nconst useSafeLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect\n\nexport default function useHotkeys<T extends HTMLElement>(\n keys: Keys,\n callback: HotkeyCallback,\n options?: OptionsOrDependencyArray,\n dependencies?: OptionsOrDependencyArray,\n) {\n const ref = useRef<RefType<T>>(null)\n\n const _options: Options | undefined = !(options instanceof Array) ? (options as Options) : !(dependencies instanceof Array) ? (dependencies as Options) : undefined\n const _deps: DependencyList = options instanceof Array ? options : dependencies instanceof Array ? dependencies : []\n\n const cb = useCallback(callback, [..._deps])\n const memoisedOptions = useDeepEqualMemo(_options)\n\n const { enabledScopes } = useHotkeysContext()\n const proxy = useBoundHotkeysProxy()\n\n useSafeLayoutEffect(() => {\n if (memoisedOptions?.enabled === false || !isScopeActive(enabledScopes, memoisedOptions?.scopes)) {\n return\n }\n\n const listener = (e: KeyboardEvent) => {\n if (isKeyboardEventTriggeredByInput(e) && !isHotkeyEnabledOnTag(e, memoisedOptions?.enableOnFormTags)) {\n return\n }\n\n // TODO: SINCE THE EVENT IS NOW ATTACHED TO THE REF, THE ACTIVE ELEMENT CAN NEVER BE INSIDE THE REF. THE HOTKEY ONLY TRIGGERS IF THE\n // REF IS THE ACTIVE ELEMENT. THIS IS A PROBLEM SINCE FOCUSED SUB COMPONENTS WON'T TRIGGER THE HOTKEY.\n if (ref.current !== null && document.activeElement !== ref.current && !ref.current.contains(document.activeElement)) {\n stopPropagation(e)\n\n return\n }\n\n if (((e.target as HTMLElement)?.isContentEditable && !memoisedOptions?.enableOnContentEditable)) {\n return\n }\n\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => {\n const hotkey = parseHotkey(key, memoisedOptions?.combinationKey)\n\n if (isHotkeyMatchingKeyboardEvent(e, hotkey) || hotkey.keys?.includes('*')) {\n maybePreventDefault(e, hotkey, memoisedOptions?.preventDefault)\n\n if (!isHotkeyEnabled(e, hotkey, memoisedOptions?.enabled)) {\n stopPropagation(e)\n\n return\n }\n\n // Execute the user callback for that hotkey\n cb(e, hotkey)\n }\n })\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n if ((memoisedOptions?.keydown === undefined && memoisedOptions?.keyup !== true) || memoisedOptions?.keydown) {\n listener(event)\n }\n }\n\n const handleKeyUp = (event: KeyboardEvent) => {\n if (event.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n if (memoisedOptions?.keyup) {\n listener(event)\n }\n }\n\n // @ts-ignore\n (ref.current || document).addEventListener('keyup', handleKeyUp);\n // @ts-ignore\n (ref.current || document).addEventListener('keydown', handleKeyDown)\n\n if (proxy) {\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => proxy.addHotkey(parseHotkey(key, memoisedOptions?.combinationKey)))\n }\n\n return () => {\n // @ts-ignore\n (ref.current || document).removeEventListener('keyup', handleKeyUp);\n // @ts-ignore\n (ref.current || document).removeEventListener('keydown', handleKeyDown)\n\n if (proxy) {\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => proxy.removeHotkey(parseHotkey(key, memoisedOptions?.combinationKey)))\n }\n }\n }, [keys, cb, memoisedOptions, enabledScopes])\n\n return ref\n}\n"],"names":["reservedModifierKeywords","mappedKeys","esc","left","up","right","down","isHotkeyModifier","key","includes","parseKeysHookInput","keys","splitKey","split","parseHotkey","hotkey","combinationKey","toLocaleLowerCase","map","k","trim","modifiers","alt","shift","meta","mod","singleCharKeys","filter","currentlyPressedKeys","Set","isHotkeyPressed","hotkeyArray","Array","isArray","every","has","toLowerCase","pushToCurrentlyPressedKeys","forEach","add","removeFromCurrentlyPressedKeys","clear","document","addEventListener","e","undefined","maybePreventDefault","preventDefault","isHotkeyEnabled","enabled","isKeyboardEventTriggeredByInput","ev","isHotkeyEnabledOnTag","enabledOnTags","target","targetTagName","tagName","Boolean","some","tag","isScopeActive","activeScopes","scopes","length","console","warn","scope","isHotkeyMatchingKeyboardEvent","pressedKeyUppercase","code","altKey","shiftKey","metaKey","ctrlKey","keyCode","replace","pressedKey","BoundHotkeysProxyProvider","createContext","useBoundHotkeysProxy","useContext","BoundHotkeysProxyProviderProvider","addHotkey","removeHotkey","children","_jsx","deepEqual","x","y","Object","reduce","isEqual","HotkeysContext","hotkeys","enabledScopes","toggleScope","enableScope","disableScope","useHotkeysContext","HotkeysProvider","initiallyActiveScopes","useState","internalActiveScopes","setInternalActiveScopes","boundHotkeys","setBoundHotkeys","useCallback","prev","from","s","addBoundHotkey","removeBoundHotkey","h","useDeepEqualMemo","value","ref","useRef","current","stopPropagation","stopImmediatePropagation","useSafeLayoutEffect","window","useLayoutEffect","useEffect","useHotkeys","callback","options","dependencies","_options","_deps","cb","memoisedOptions","proxy","listener","enableOnFormTags","activeElement","contains","isContentEditable","enableOnContentEditable","handleKeyDown","event","keydown","keyup","handleKeyUp","removeEventListener"],"mappings":"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"}
@@ -4,4 +4,4 @@ export declare function isHotkeyEnabled(e: KeyboardEvent, hotkey: Hotkey, enable
4
4
  export declare function isKeyboardEventTriggeredByInput(ev: KeyboardEvent): boolean;
5
5
  export declare function isHotkeyEnabledOnTag({ target }: KeyboardEvent, enabledOnTags?: FormTags[] | boolean): boolean;
6
6
  export declare function isScopeActive(activeScopes: string[], scopes?: Scopes): boolean;
7
- export declare const isHotkeyMatchingKeyboardEvent: (e: KeyboardEvent, hotkey: Hotkey, pressedDownKeys: Set<string>) => boolean;
7
+ export declare const isHotkeyMatchingKeyboardEvent: (e: KeyboardEvent, hotkey: Hotkey) => boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-hotkeys-hook",
3
- "version": "4.0.8",
3
+ "version": "4.1.0-1",
4
4
  "repository": "https://JohannesKlauss@github.com/JohannesKlauss/react-keymap-hook.git",
5
5
  "homepage": "https://johannesklauss.github.io/react-hotkeys-hook/",
6
6
  "author": "Johannes Klauss",
@@ -1,63 +1,57 @@
1
- import { Hotkey } from './types'
2
- import { parseHotkey } from './parseHotkeys'
3
- import deepEqual from './deepEqual'
1
+ import { isHotkeyModifier } from './parseHotkeys'
4
2
 
5
- const currentlyPressedKeys: Set<Hotkey> = new Set<Hotkey>()
3
+ const currentlyPressedKeys: Set<string> = new Set<string>()
6
4
 
7
5
  export function isHotkeyPressed(key: string | string[], splitKey: string = ','): boolean {
8
6
  const hotkeyArray = Array.isArray(key) ? key : key.split(splitKey)
9
7
 
10
- return hotkeyArray.every((hotkey) => {
11
- const parsedHotkey = parseHotkey(hotkey)
12
-
13
- for (const pressedHotkey of currentlyPressedKeys) {
14
- if (deepEqual(parsedHotkey, pressedHotkey)) {
15
- return true
16
- }
17
- }
18
- })
8
+ return hotkeyArray.every((hotkey) => currentlyPressedKeys.has(hotkey.trim().toLowerCase()))
19
9
  }
20
10
 
21
- export function pushToCurrentlyPressedKeys(key: string | string[]): void {
11
+ function pushToCurrentlyPressedKeys(key: string | string[]): void {
22
12
  const hotkeyArray = Array.isArray(key) ? key : [key]
23
13
 
24
- hotkeyArray.forEach(hotkey => currentlyPressedKeys.add(parseHotkey(hotkey)))
25
- }
14
+ /*
15
+ Due to a weird behavior on macOS we need to clear the set if the user pressed down the meta key and presses another key.
16
+ https://stackoverflow.com/questions/11818637/why-does-javascript-drop-keyup-events-when-the-metakey-is-pressed-on-mac-browser
17
+ Otherwise the set will hold all ever pressed keys while the meta key is down which leads to wrong results.
18
+ */
19
+ if (currentlyPressedKeys.has('meta')) {
20
+ currentlyPressedKeys.forEach(key => !isHotkeyModifier(key) && currentlyPressedKeys.delete(key))
21
+ }
26
22
 
27
- export function removeFromCurrentlyPressedKeys(key: string | string[]): void {
28
- const hotkeyArray = Array.isArray(key) ? key : [key]
23
+ hotkeyArray.forEach(hotkey => currentlyPressedKeys.add(hotkey.toLowerCase()))
24
+ }
29
25
 
30
- hotkeyArray.forEach((hotkey) => {
31
- const parsedHotkey = parseHotkey(hotkey)
26
+ function removeFromCurrentlyPressedKeys(key: string): void {
27
+ /*
28
+ Due to a weird behavior on macOS we need to clear the set if the user pressed down the meta key and presses another key.
29
+ https://stackoverflow.com/questions/11818637/why-does-javascript-drop-keyup-events-when-the-metakey-is-pressed-on-mac-browser
30
+ Otherwise the set will hold all ever pressed keys while the meta key is down which leads to wrong results.
31
+ */
32
+ if (key === 'meta') {
33
+ currentlyPressedKeys.clear()
34
+ } else {
35
+ currentlyPressedKeys.delete(key)
36
+ }
37
+ }
32
38
 
33
- for (const pressedHotkey of currentlyPressedKeys) {
34
- if (pressedHotkey.keys?.every((key) => parsedHotkey.keys?.includes(key))) {
35
- currentlyPressedKeys.delete(pressedHotkey)
36
- }
39
+ (() => {
40
+ document.addEventListener('keydown', e => {
41
+ if (e.key === undefined) {
42
+ // Synthetic event (e.g., Chrome autofill). Ignore.
43
+ return
37
44
  }
45
+
46
+ pushToCurrentlyPressedKeys(e.key.toLowerCase())
38
47
  })
39
- }
40
48
 
41
- (() => {
42
- if (typeof window !== 'undefined') {
43
- window.addEventListener('DOMContentLoaded', () => {
44
- document.addEventListener('keydown', e => {
45
- if (e.key === undefined) {
46
- // Synthetic event (e.g., Chrome autofill). Ignore.
47
- return
48
- }
49
-
50
- pushToCurrentlyPressedKeys(e.key)
51
- })
52
-
53
- document.addEventListener('keyup', e => {
54
- if (e.key === undefined) {
55
- // Synthetic event (e.g., Chrome autofill). Ignore.
56
- return
57
- }
58
-
59
- removeFromCurrentlyPressedKeys(e.key)
60
- })
61
- })
62
- }
49
+ document.addEventListener('keyup', e => {
50
+ if (e.key === undefined) {
51
+ // Synthetic event (e.g., Chrome autofill). Ignore.
52
+ return
53
+ }
54
+
55
+ removeFromCurrentlyPressedKeys(e.key.toLowerCase())
56
+ })
63
57
  })()
@@ -20,6 +20,10 @@ const mappedKeys: Record<string, string> = {
20
20
  '9': 'digit9',
21
21
  }
22
22
 
23
+ export function isHotkeyModifier(key: string) {
24
+ return reservedModifierKeywords.includes(key)
25
+ }
26
+
23
27
  export function parseKeysHookInput(keys: Keys, splitKey: string = ','): string[] {
24
28
  if (typeof keys === 'string') {
25
29
  return keys.split(splitKey)
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,
@@ -65,7 +63,7 @@ export default function useHotkeys<T extends HTMLElement>(
65
63
  parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => {
66
64
  const hotkey = parseHotkey(key, memoisedOptions?.combinationKey)
67
65
 
68
- if (isHotkeyMatchingKeyboardEvent(e, hotkey, pressedDownKeys) || hotkey.keys?.includes('*')) {
66
+ if (isHotkeyMatchingKeyboardEvent(e, hotkey) || hotkey.keys?.includes('*')) {
69
67
  maybePreventDefault(e, hotkey, memoisedOptions?.preventDefault)
70
68
 
71
69
  if (!isHotkeyEnabled(e, hotkey, memoisedOptions?.enabled)) {
@@ -74,6 +72,7 @@ export default function useHotkeys<T extends HTMLElement>(
74
72
  return
75
73
  }
76
74
 
75
+ // Execute the user callback for that hotkey
77
76
  cb(e, hotkey)
78
77
  }
79
78
  })
@@ -85,8 +84,6 @@ export default function useHotkeys<T extends HTMLElement>(
85
84
  return
86
85
  }
87
86
 
88
- pressedDownKeys.add(event.key.toLowerCase())
89
-
90
87
  if ((memoisedOptions?.keydown === undefined && memoisedOptions?.keyup !== true) || memoisedOptions?.keydown) {
91
88
  listener(event)
92
89
  }
@@ -98,13 +95,6 @@ export default function useHotkeys<T extends HTMLElement>(
98
95
  return
99
96
  }
100
97
 
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
- }
107
-
108
98
  if (memoisedOptions?.keyup) {
109
99
  listener(event)
110
100
  }
package/src/validators.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { FormTags, Hotkey, Scopes, Trigger } from './types'
2
+ import { isHotkeyPressed } from './isHotkeyPressed'
2
3
 
3
4
  export function maybePreventDefault(e: KeyboardEvent, hotkey: Hotkey, preventDefault?: Trigger): void {
4
5
  if ((typeof preventDefault === 'function' && preventDefault(e, hotkey)) || preventDefault === true) {
@@ -44,9 +45,14 @@ export function isScopeActive(activeScopes: string[], scopes?: Scopes): boolean
44
45
  return activeScopes.some(scope => scopes.includes(scope)) || activeScopes.includes('*')
45
46
  }
46
47
 
47
- export const isHotkeyMatchingKeyboardEvent = (e: KeyboardEvent, hotkey: Hotkey, pressedDownKeys: Set<string>): boolean => {
48
+ export const isHotkeyMatchingKeyboardEvent = (e: KeyboardEvent, hotkey: Hotkey): boolean => {
48
49
  const { alt, meta, mod, shift, keys } = hotkey
49
- const { altKey, ctrlKey, metaKey, shiftKey, key: pressedKeyUppercase, code } = e
50
+ const { key: pressedKeyUppercase, code } = e
51
+
52
+ const altKey = isHotkeyPressed('alt')
53
+ const shiftKey = isHotkeyPressed('shift')
54
+ const metaKey = isHotkeyPressed('meta')
55
+ const ctrlKey = isHotkeyPressed('ctrl')
50
56
 
51
57
  const keyCode = code.toLowerCase().replace('key', '')
52
58
  const pressedKey = pressedKeyUppercase.toLowerCase()
@@ -71,12 +77,12 @@ export const isHotkeyMatchingKeyboardEvent = (e: KeyboardEvent, hotkey: Hotkey,
71
77
  }
72
78
 
73
79
  // All modifiers are correct, now check the key
74
- // If the key is set we check for the key
80
+ // If the key is set, we check for the key
75
81
  if (keys && keys.length === 1 && (keys.includes(pressedKey) || keys.includes(keyCode))) {
76
82
  return true
77
83
  } else if (keys) {
78
84
  // Check if all keys are present in pressedDownKeys set
79
- return keys.every(key => pressedDownKeys.has(key))
85
+ return isHotkeyPressed(keys)
80
86
  }
81
87
  else if (!keys) {
82
88
  // If the key is not set, we only listen for modifiers, that check went alright, so we return true