react-hotkeys-hook 4.0.7 → 4.0.8

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.
@@ -202,6 +202,15 @@ function BoundHotkeysProxyProviderProvider(_ref) {
202
202
  });
203
203
  }
204
204
 
205
+ function deepEqual(x, y) {
206
+ //@ts-ignore
207
+ return x && y && typeof x === 'object' && typeof y === 'object'
208
+ //@ts-ignore
209
+ ? Object.keys(x).length === Object.keys(y).length && Object.keys(x).reduce(function (isEqual, key) {
210
+ return isEqual && deepEqual(x[key], y[key]);
211
+ }, true) : x === y;
212
+ }
213
+
205
214
  var HotkeysContext = /*#__PURE__*/react.createContext({
206
215
  hotkeys: [],
207
216
  enabledScopes: [],
@@ -222,41 +231,59 @@ var HotkeysProvider = function HotkeysProvider(_ref) {
222
231
  var _useState2 = react.useState([]),
223
232
  boundHotkeys = _useState2[0],
224
233
  setBoundHotkeys = _useState2[1];
225
- var isAllActive = react.useMemo(function () {
226
- return internalActiveScopes.includes('*');
227
- }, [internalActiveScopes]);
228
- var enableScope = function enableScope(scope) {
229
- if (isAllActive) {
230
- setInternalActiveScopes([scope]);
231
- } else {
232
- setInternalActiveScopes(Array.from(new Set([].concat(internalActiveScopes, [scope]))));
233
- }
234
- };
235
- var disableScope = function disableScope(scope) {
236
- var scopes = internalActiveScopes.filter(function (s) {
237
- return s !== scope;
234
+ var enableScope = react.useCallback(function (scope) {
235
+ setInternalActiveScopes(function (prev) {
236
+ if (prev.includes('*')) {
237
+ return [scope];
238
+ }
239
+ return Array.from(new Set([].concat(prev, [scope])));
238
240
  });
239
- if (scopes.length === 0) {
240
- setInternalActiveScopes(['*']);
241
- } else {
242
- setInternalActiveScopes(scopes);
243
- }
244
- };
245
- var toggleScope = function toggleScope(scope) {
246
- if (internalActiveScopes.includes(scope)) {
247
- disableScope(scope);
248
- } else {
249
- enableScope(scope);
250
- }
251
- };
252
- var addBoundHotkey = function addBoundHotkey(hotkey) {
253
- setBoundHotkeys([].concat(boundHotkeys, [hotkey]));
254
- };
255
- var removeBoundHotkey = function removeBoundHotkey(hotkey) {
256
- setBoundHotkeys(boundHotkeys.filter(function (h) {
257
- return h.keys !== hotkey.keys;
258
- }));
259
- };
241
+ }, []);
242
+ var disableScope = react.useCallback(function (scope) {
243
+ setInternalActiveScopes(function (prev) {
244
+ if (prev.filter(function (s) {
245
+ return s !== scope;
246
+ }).length === 0) {
247
+ return ['*'];
248
+ } else {
249
+ return prev.filter(function (s) {
250
+ return s !== scope;
251
+ });
252
+ }
253
+ });
254
+ }, []);
255
+ var toggleScope = react.useCallback(function (scope) {
256
+ setInternalActiveScopes(function (prev) {
257
+ if (prev.includes(scope)) {
258
+ if (prev.filter(function (s) {
259
+ return s !== scope;
260
+ }).length === 0) {
261
+ return ['*'];
262
+ } else {
263
+ return prev.filter(function (s) {
264
+ return s !== scope;
265
+ });
266
+ }
267
+ } else {
268
+ if (prev.includes('*')) {
269
+ return [scope];
270
+ }
271
+ return Array.from(new Set([].concat(prev, [scope])));
272
+ }
273
+ });
274
+ }, []);
275
+ var addBoundHotkey = react.useCallback(function (hotkey) {
276
+ setBoundHotkeys(function (prev) {
277
+ return [].concat(prev, [hotkey]);
278
+ });
279
+ }, []);
280
+ var removeBoundHotkey = react.useCallback(function (hotkey) {
281
+ setBoundHotkeys(function (prev) {
282
+ return prev.filter(function (h) {
283
+ return !deepEqual(h, hotkey);
284
+ });
285
+ });
286
+ }, []);
260
287
  return /*#__PURE__*/jsxRuntime.jsx(HotkeysContext.Provider, {
261
288
  value: {
262
289
  enabledScopes: internalActiveScopes,
@@ -273,15 +300,6 @@ var HotkeysProvider = function HotkeysProvider(_ref) {
273
300
  });
274
301
  };
275
302
 
276
- function deepEqual(x, y) {
277
- //@ts-ignore
278
- return x && y && typeof x === 'object' && typeof y === 'object'
279
- //@ts-ignore
280
- ? Object.keys(x).length === Object.keys(y).length && Object.keys(x).reduce(function (isEqual, key) {
281
- return isEqual && deepEqual(x[key], y[key]);
282
- }, true) : x === y;
283
- }
284
-
285
303
  function useDeepEqualMemo(value) {
286
304
  var ref = react.useRef(undefined);
287
305
  if (!deepEqual(ref.current, value)) {
@@ -316,7 +334,7 @@ function useHotkeys(keys, callback, options, dependencies) {
316
334
  return;
317
335
  }
318
336
  // 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
319
- // REF IS THE ACTIVE ELEMENT. THIS IS A PROBLEM SINCE FOCUSED SUB COMPONENTS WONT TRIGGER THE HOTKEY.
337
+ // REF IS THE ACTIVE ELEMENT. THIS IS A PROBLEM SINCE FOCUSED SUB COMPONENTS WON'T TRIGGER THE HOTKEY.
320
338
  if (ref.current !== null && document.activeElement !== ref.current && !ref.current.contains(document.activeElement)) {
321
339
  stopPropagation(e);
322
340
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"react-hotkeys-hook.cjs.development.js","sources":["../src/parseHotkeys.ts","../src/validators.ts","../src/BoundHotkeysProxyProvider.tsx","../src/HotkeysProvider.tsx","../src/deepEqual.ts","../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","import { Hotkey } from './types'\nimport { createContext, ReactNode, useMemo, useState, useContext } from 'react'\nimport BoundHotkeysProxyProviderProvider from './BoundHotkeysProxyProvider'\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 isAllActive = useMemo(() => internalActiveScopes.includes('*'), [internalActiveScopes])\n\n const enableScope = (scope: string) => {\n if (isAllActive) {\n setInternalActiveScopes([scope])\n } else {\n setInternalActiveScopes(Array.from(new Set([...internalActiveScopes, scope])))\n }\n }\n\n const disableScope = (scope: string) => {\n const scopes = internalActiveScopes.filter(s => s !== scope)\n\n if (scopes.length === 0) {\n setInternalActiveScopes(['*'])\n } else {\n setInternalActiveScopes(scopes)\n }\n }\n\n const toggleScope = (scope: string) => {\n if (internalActiveScopes.includes(scope)) {\n disableScope(scope)\n } else {\n enableScope(scope)\n }\n }\n\n const addBoundHotkey = (hotkey: Hotkey) => {\n setBoundHotkeys([...boundHotkeys, hotkey])\n }\n\n const removeBoundHotkey = (hotkey: Hotkey) => {\n setBoundHotkeys(boundHotkeys.filter(h => h.keys !== hotkey.keys))\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","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 { 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 WONT 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","HotkeysContext","hotkeys","enabledScopes","toggleScope","enableScope","disableScope","useHotkeysContext","HotkeysProvider","initiallyActiveScopes","useState","internalActiveScopes","setInternalActiveScopes","boundHotkeys","setBoundHotkeys","isAllActive","useMemo","from","Set","s","addBoundHotkey","removeBoundHotkey","h","deepEqual","x","y","Object","reduce","isEqual","useDeepEqualMemo","value","ref","useRef","current","stopPropagation","stopImmediatePropagation","useSafeLayoutEffect","window","useLayoutEffect","useEffect","useHotkeys","callback","options","dependencies","_options","_deps","cb","useCallback","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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,IAAMA,wBAAwB,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC;AAEhE,IAAMC,UAAU,GAA2B;EACzCC,GAAG,EAAE,QAAQ;EACb,UAAQ,OAAO;EACfC,IAAI,EAAE,WAAW;EACjBC,EAAE,EAAE,SAAS;EACbC,KAAK,EAAE,YAAY;EACnBC,IAAI,EAAE,WAAW;EACjB,GAAG,EAAE,QAAQ;EACb,GAAG,EAAE,QAAQ;EACb,GAAG,EAAE,QAAQ;EACb,GAAG,EAAE,QAAQ;EACb,GAAG,EAAE,QAAQ;EACb,GAAG,EAAE,QAAQ;EACb,GAAG,EAAE,QAAQ;EACb,GAAG,EAAE,QAAQ;EACb,GAAG,EAAE;CACN;SAEeC,kBAAkB,CAACC,IAAU,EAAEC;MAAAA;IAAAA,WAAmB,GAAG;;EACnE,IAAI,OAAOD,IAAI,KAAK,QAAQ,EAAE;IAC5B,OAAOA,IAAI,CAACE,KAAK,CAACD,QAAQ,CAAC;;EAG7B,OAAOD,IAAI;AACb;SAEgBG,WAAW,CAACC,MAAc,EAAEC;MAAAA;IAAAA,iBAAyB,GAAG;;EACtE,IAAML,IAAI,GAAGI,MAAM,CAChBE,iBAAiB,EAAE,CACnBJ,KAAK,CAACG,cAAc,CAAC,CACrBE,GAAG,CAAC,UAAAC,CAAC;IAAA,OAAIA,CAAC,CAACC,IAAI,EAAE;IAAC,CAClBF,GAAG,CAAC,UAAAC,CAAC;IAAA,OAAIf,UAAU,CAACe,CAAC,CAAC,IAAIA,CAAC;IAAC;EAE/B,IAAME,SAAS,GAAsB;IACnCC,GAAG,EAAEX,IAAI,CAACY,QAAQ,CAAC,KAAK,CAAC;IACzBC,KAAK,EAAEb,IAAI,CAACY,QAAQ,CAAC,OAAO,CAAC;IAC7BE,IAAI,EAAEd,IAAI,CAACY,QAAQ,CAAC,MAAM,CAAC;IAC3BG,GAAG,EAAEf,IAAI,CAACY,QAAQ,CAAC,KAAK;GACzB;EAED,IAAMI,cAAc,GAAGhB,IAAI,CAACiB,MAAM,CAAC,UAACT,CAAC;IAAA,OAAK,CAAChB,wBAAwB,CAACoB,QAAQ,CAACJ,CAAC,CAAC;IAAC;EAEhF,oBACKE,SAAS;IACZV,IAAI,EAAEgB;;AAEV;;SChDgBE,mBAAmB,CAACC,CAAgB,EAAEf,MAAc,EAAEgB,cAAwB;EAC5F,IAAK,OAAOA,cAAc,KAAK,UAAU,IAAIA,cAAc,CAACD,CAAC,EAAEf,MAAM,CAAC,IAAKgB,cAAc,KAAK,IAAI,EAAE;IAClGD,CAAC,CAACC,cAAc,EAAE;;AAEtB;AAEA,SAAgBC,eAAe,CAACF,CAAgB,EAAEf,MAAc,EAAEkB,OAAiB;EACjF,IAAI,OAAOA,OAAO,KAAK,UAAU,EAAE;IACjC,OAAOA,OAAO,CAACH,CAAC,EAAEf,MAAM,CAAC;;EAG3B,OAAOkB,OAAO,KAAK,IAAI,IAAIA,OAAO,KAAKC,SAAS;AAClD;AAEA,SAAgBC,+BAA+B,CAACC,EAAiB;EAC/D,OAAOC,oBAAoB,CAACD,EAAE,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;AAClE;AAEA,SAAgBC,oBAAoB,OAA4BC;MAAzBC,MAAM,QAANA,MAAM;EAAA,IAAmBD;IAAAA,gBAAsC,KAAK;;EACzG,IAAME,aAAa,GAAGD,MAAM,IAAKA,MAAsB,CAACE,OAAO;EAE/D,IAAIH,aAAa,YAAYI,KAAK,EAAE;IAClC,OAAOC,OAAO,CAACH,aAAa,IAAIF,aAAa,IAAIA,aAAa,CAACM,IAAI,CAAC,UAAAC,GAAG;MAAA,OAAIA,GAAG,CAACC,WAAW,EAAE,KAAKN,aAAa,CAACM,WAAW,EAAE;MAAC,CAAC;;EAGhI,OAAOH,OAAO,CAACH,aAAa,IAAIF,aAAa,IAAIA,aAAa,KAAK,IAAI,CAAC;AAC1E;AAEA,SAAgBS,aAAa,CAACC,YAAsB,EAAEC,MAAe;EACnE,IAAID,YAAY,CAACE,MAAM,KAAK,CAAC,IAAID,MAAM,EAAE;IACvCE,OAAO,CAACC,IAAI,CACV,2KAA2K,CAC5K;IAED,OAAO,IAAI;;EAGb,IAAI,CAACH,MAAM,EAAE;IACX,OAAO,IAAI;;EAGb,OAAOD,YAAY,CAACJ,IAAI,CAAC,UAAAS,KAAK;IAAA,OAAIJ,MAAM,CAAC1B,QAAQ,CAAC8B,KAAK,CAAC;IAAC,IAAIL,YAAY,CAACzB,QAAQ,CAAC,GAAG,CAAC;AACzF;AAEA,AAAO,IAAM+B,6BAA6B,GAAG,SAAhCA,6BAA6B,CAAIxB,CAAgB,EAAEf,MAAc,EAAEwC,eAA4B;EAC1G,IAAQjC,GAAG,GAA6BP,MAAM,CAAtCO,GAAG;IAAEG,IAAI,GAAuBV,MAAM,CAAjCU,IAAI;IAAEC,GAAG,GAAkBX,MAAM,CAA3BW,GAAG;IAAEF,KAAK,GAAWT,MAAM,CAAtBS,KAAK;IAAEb,IAAI,GAAKI,MAAM,CAAfJ,IAAI;EACnC,IAAQ6C,MAAM,GAAiE1B,CAAC,CAAxE0B,MAAM;IAAEC,OAAO,GAAwD3B,CAAC,CAAhE2B,OAAO;IAAEC,OAAO,GAA+C5B,CAAC,CAAvD4B,OAAO;IAAEC,QAAQ,GAAqC7B,CAAC,CAA9C6B,QAAQ;IAAOC,mBAAmB,GAAW9B,CAAC,CAApC+B,GAAG;IAAuBC,IAAI,GAAKhC,CAAC,CAAVgC,IAAI;EAE1E,IAAMC,OAAO,GAAGD,IAAI,CAAChB,WAAW,EAAE,CAACkB,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;EACrD,IAAMC,UAAU,GAAGL,mBAAmB,CAACd,WAAW,EAAE;EAEpD,IAAIU,MAAM,KAAKlC,GAAG,IAAI2C,UAAU,KAAK,KAAK,EAAE;IAC1C,OAAO,KAAK;;EAGd,IAAIN,QAAQ,KAAKnC,KAAK,IAAIyC,UAAU,KAAK,OAAO,EAAE;IAChD,OAAO,KAAK;;;EAId,IAAIvC,GAAG,EAAE;IACP,IAAI,CAACgC,OAAO,IAAI,CAACD,OAAO,EAAE;MACxB,OAAO,KAAK;;GAEf,MAAM;IACL,IAAIC,OAAO,KAAKjC,IAAI,IAAIgC,OAAO,KAAKhC,IAAI,IAAIsC,OAAO,KAAK,MAAM,IAAIA,OAAO,KAAK,MAAM,EAAE;MACpF,OAAO,KAAK;;;;;EAMhB,IAAIpD,IAAI,IAAIA,IAAI,CAACuC,MAAM,KAAK,CAAC,KAAKvC,IAAI,CAACY,QAAQ,CAAC0C,UAAU,CAAC,IAAItD,IAAI,CAACY,QAAQ,CAACwC,OAAO,CAAC,CAAC,EAAE;IACtF,OAAO,IAAI;GACZ,MAAM,IAAIpD,IAAI,EAAE;;IAEf,OAAOA,IAAI,CAACuD,KAAK,CAAC,UAAAL,GAAG;MAAA,OAAIN,eAAe,CAACY,GAAG,CAACN,GAAG,CAAC;MAAC;GACnD,MACI,IAAI,CAAClD,IAAI,EAAE;;IAEd,OAAO,IAAI;;;EAIb,OAAO,KAAK;AACd,CAAC;;AC/ED,IAAMyD,yBAAyB,gBAAGC,mBAAa,CAA4CnC,SAAS,CAAC;AAErG,AAAO,IAAMoC,oBAAoB,GAAG,SAAvBA,oBAAoB;EAC/B,OAAOC,gBAAU,CAACH,yBAAyB,CAAC;AAC9C,CAAC;AAQD,SAAwBI,iCAAiC;MAAGC,SAAS,QAATA,SAAS;IAAEC,YAAY,QAAZA,YAAY;IAAEC,QAAQ,QAARA,QAAQ;EAC3F,oBAAOC,eAAC,yBAAyB,CAAC,QAAQ;IAAC,KAAK,EAAE;MAACH,SAAS,EAATA,SAAS;MAAEC,YAAY,EAAZA;KAAc;IAAA,UAAEC;IAA8C;AAC9H;;ACTA,IAAME,cAAc,gBAAGR,mBAAa,CAAqB;EACvDS,OAAO,EAAE,EAAE;EACXC,aAAa,EAAE,EAAE;EACjBC,WAAW,EAAE,yBAAQ;EACrBC,WAAW,EAAE,yBAAQ;EACrBC,YAAY,EAAE;CACf,CAAC;AAEF,IAAaC,iBAAiB,GAAG,SAApBA,iBAAiB;EAC5B,OAAOZ,gBAAU,CAACM,cAAc,CAAC;AACnC,CAAC;AAOD,IAAaO,eAAe,GAAG,SAAlBA,eAAe;mCAAKC,qBAAqB;IAArBA,qBAAqB,sCAAG,CAAC,GAAG,CAAC;IAAEV,QAAQ,QAARA,QAAQ;EACtE,gBAAwDW,cAAQ,CAAC,CAAAD,qBAAqB,oBAArBA,qBAAqB,CAAEnC,MAAM,IAAG,CAAC,GAAGmC,qBAAqB,GAAG,CAAC,GAAG,CAAC,CAAC;IAA5HE,oBAAoB;IAAEC,uBAAuB;EACpD,iBAAwCF,cAAQ,CAAW,EAAE,CAAC;IAAvDG,YAAY;IAAEC,eAAe;EAEpC,IAAMC,WAAW,GAAGC,aAAO,CAAC;IAAA,OAAML,oBAAoB,CAAChE,QAAQ,CAAC,GAAG,CAAC;KAAE,CAACgE,oBAAoB,CAAC,CAAC;EAE7F,IAAMN,WAAW,GAAG,SAAdA,WAAW,CAAI5B,KAAa;IAChC,IAAIsC,WAAW,EAAE;MACfH,uBAAuB,CAAC,CAACnC,KAAK,CAAC,CAAC;KACjC,MAAM;MACLmC,uBAAuB,CAAC9C,KAAK,CAACmD,IAAI,CAAC,IAAIC,GAAG,WAAKP,oBAAoB,GAAElC,KAAK,GAAE,CAAC,CAAC;;GAEjF;EAED,IAAM6B,YAAY,GAAG,SAAfA,YAAY,CAAI7B,KAAa;IACjC,IAAMJ,MAAM,GAAGsC,oBAAoB,CAAC3D,MAAM,CAAC,UAAAmE,CAAC;MAAA,OAAIA,CAAC,KAAK1C,KAAK;MAAC;IAE5D,IAAIJ,MAAM,CAACC,MAAM,KAAK,CAAC,EAAE;MACvBsC,uBAAuB,CAAC,CAAC,GAAG,CAAC,CAAC;KAC/B,MAAM;MACLA,uBAAuB,CAACvC,MAAM,CAAC;;GAElC;EAED,IAAM+B,WAAW,GAAG,SAAdA,WAAW,CAAI3B,KAAa;IAChC,IAAIkC,oBAAoB,CAAChE,QAAQ,CAAC8B,KAAK,CAAC,EAAE;MACxC6B,YAAY,CAAC7B,KAAK,CAAC;KACpB,MAAM;MACL4B,WAAW,CAAC5B,KAAK,CAAC;;GAErB;EAED,IAAM2C,cAAc,GAAG,SAAjBA,cAAc,CAAIjF,MAAc;IACpC2E,eAAe,WAAKD,YAAY,GAAE1E,MAAM,GAAE;GAC3C;EAED,IAAMkF,iBAAiB,GAAG,SAApBA,iBAAiB,CAAIlF,MAAc;IACvC2E,eAAe,CAACD,YAAY,CAAC7D,MAAM,CAAC,UAAAsE,CAAC;MAAA,OAAIA,CAAC,CAACvF,IAAI,KAAKI,MAAM,CAACJ,IAAI;MAAC,CAAC;GAClE;EAED,oBACEiE,eAAC,cAAc,CAAC,QAAQ;IAAC,KAAK,EAAE;MAACG,aAAa,EAAEQ,oBAAoB;MAAET,OAAO,EAAEW,YAAY;MAAER,WAAW,EAAXA,WAAW;MAAEC,YAAY,EAAZA,YAAY;MAAEF,WAAW,EAAXA;KAAa;IAAA,uBACnIJ,eAAC,iCAAiC;MAAC,SAAS,EAAEoB,cAAe;MAAC,YAAY,EAAEC,iBAAkB;MAAA,UAC3FtB;;IAEqB;AAE9B,CAAC;;SC7EuBwB,SAAS,CAACC,CAAM,EAAEC,CAAM;;EAE9C,OAAQD,CAAC,IAAIC,CAAC,IAAI,OAAOD,CAAC,KAAK,QAAQ,IAAI,OAAOC,CAAC,KAAK;;IAEnDC,MAAM,CAAC3F,IAAI,CAACyF,CAAC,CAAC,CAAClD,MAAM,KAAKoD,MAAM,CAAC3F,IAAI,CAAC0F,CAAC,CAAC,CAACnD,MAAM,IAAKoD,MAAM,CAAC3F,IAAI,CAACyF,CAAC,CAAC,CAACG,MAAM,CAAC,UAASC,OAAO,EAAE3C,GAAG;IAChG,OAAO2C,OAAO,IAAIL,SAAS,CAACC,CAAC,CAACvC,GAAG,CAAC,EAAEwC,CAAC,CAACxC,GAAG,CAAC,CAAC;GAC5C,EAAE,IAAI,CAAC,GACLuC,CAAC,KAAKC,CAAE;AACf;;SCLwBI,gBAAgB,CAAIC,KAAQ;EAClD,IAAMC,GAAG,GAAGC,YAAM,CAAgB1E,SAAS,CAAC;EAE5C,IAAI,CAACiE,SAAS,CAACQ,GAAG,CAACE,OAAO,EAAEH,KAAK,CAAC,EAAE;IAClCC,GAAG,CAACE,OAAO,GAAGH,KAAK;;EAGrB,OAAOC,GAAG,CAACE,OAAO;AACpB;;ACIA,IAAMC,eAAe,GAAG,SAAlBA,eAAe,CAAIhF,CAAgB;EACvCA,CAAC,CAACgF,eAAe,EAAE;EACnBhF,CAAC,CAACC,cAAc,EAAE;EAClBD,CAAC,CAACiF,wBAAwB,EAAE;AAC9B,CAAC;AAED,IAAMC,mBAAmB,GAAG,OAAOC,MAAM,KAAK,WAAW,GAAGC,qBAAe,GAAGC,eAAS;AAEvF,IAAM5D,eAAe,gBAAG,IAAIuC,GAAG,EAAU;AAEzC,SAAwBsB,UAAU,CAChCzG,IAAU,EACV0G,QAAwB,EACxBC,OAAkC,EAClCC,YAAuC;EAEvC,IAAMZ,GAAG,GAAGC,YAAM,CAAa,IAAI,CAAC;EAEpC,IAAMY,QAAQ,GAAwB,EAAEF,OAAO,YAAY5E,KAAK,CAAC,GAAI4E,OAAmB,GAAG,EAAEC,YAAY,YAAY7E,KAAK,CAAC,GAAI6E,YAAwB,GAAGrF,SAAS;EACnK,IAAMuF,KAAK,GAAmBH,OAAO,YAAY5E,KAAK,GAAG4E,OAAO,GAAGC,YAAY,YAAY7E,KAAK,GAAG6E,YAAY,GAAG,EAAE;EAEpH,IAAMG,EAAE,GAAGC,iBAAW,CAACN,QAAQ,YAAMI,KAAK,EAAE;EAC5C,IAAMG,eAAe,GAAGnB,gBAAgB,CAACe,QAAQ,CAAC;EAElD,yBAA0BrC,iBAAiB,EAAE;IAArCJ,aAAa,sBAAbA,aAAa;EACrB,IAAM8C,KAAK,GAAGvD,oBAAoB,EAAE;EAEpC0C,mBAAmB,CAAC;IAClB,IAAI,CAAAY,eAAe,oBAAfA,eAAe,CAAE3F,OAAO,MAAK,KAAK,IAAI,CAACc,aAAa,CAACgC,aAAa,EAAE6C,eAAe,oBAAfA,eAAe,CAAE3E,MAAM,CAAC,EAAE;MAChG;;IAGF,IAAM6E,QAAQ,GAAG,SAAXA,QAAQ,CAAIhG,CAAgB;;MAChC,IAAIK,+BAA+B,CAACL,CAAC,CAAC,IAAI,CAACO,oBAAoB,CAACP,CAAC,EAAE8F,eAAe,oBAAfA,eAAe,CAAEG,gBAAgB,CAAC,EAAE;QACrG;;;;MAKF,IAAIpB,GAAG,CAACE,OAAO,KAAK,IAAI,IAAImB,QAAQ,CAACC,aAAa,KAAKtB,GAAG,CAACE,OAAO,IAAI,CAACF,GAAG,CAACE,OAAO,CAACqB,QAAQ,CAACF,QAAQ,CAACC,aAAa,CAAC,EAAE;QACnHnB,eAAe,CAAChF,CAAC,CAAC;QAElB;;MAGF,IAAM,aAAAA,CAAC,CAACS,MAAsB,aAAxB,UAA0B4F,iBAAiB,IAAI,EAACP,eAAe,YAAfA,eAAe,CAAEQ,uBAAuB,GAAG;QAC/F;;MAGF1H,kBAAkB,CAACC,IAAI,EAAEiH,eAAe,oBAAfA,eAAe,CAAEhH,QAAQ,CAAC,CAACyH,OAAO,CAAC,UAACxE,GAAG;;QAC9D,IAAM9C,MAAM,GAAGD,WAAW,CAAC+C,GAAG,EAAE+D,eAAe,oBAAfA,eAAe,CAAE5G,cAAc,CAAC;QAEhE,IAAIsC,6BAA6B,CAACxB,CAAC,EAAEf,MAAM,EAAEwC,eAAe,CAAC,oBAAIxC,MAAM,CAACJ,IAAI,aAAX,aAAaY,QAAQ,CAAC,GAAG,CAAC,EAAE;UAC3FM,mBAAmB,CAACC,CAAC,EAAEf,MAAM,EAAE6G,eAAe,oBAAfA,eAAe,CAAE7F,cAAc,CAAC;UAE/D,IAAI,CAACC,eAAe,CAACF,CAAC,EAAEf,MAAM,EAAE6G,eAAe,oBAAfA,eAAe,CAAE3F,OAAO,CAAC,EAAE;YACzD6E,eAAe,CAAChF,CAAC,CAAC;YAElB;;UAGF4F,EAAE,CAAC5F,CAAC,EAAEf,MAAM,CAAC;;OAEhB,CAAC;KACH;IAED,IAAMuH,aAAa,GAAG,SAAhBA,aAAa,CAAIC,KAAoB;MACzC,IAAIA,KAAK,CAAC1E,GAAG,KAAK3B,SAAS,EAAE;;QAE3B;;MAGFqB,eAAe,CAACiF,GAAG,CAACD,KAAK,CAAC1E,GAAG,CAACf,WAAW,EAAE,CAAC;MAE5C,IAAK,CAAA8E,eAAe,oBAAfA,eAAe,CAAEa,OAAO,MAAKvG,SAAS,IAAI,CAAA0F,eAAe,oBAAfA,eAAe,CAAEc,KAAK,MAAK,IAAI,IAAKd,eAAe,YAAfA,eAAe,CAAEa,OAAO,EAAE;QAC3GX,QAAQ,CAACS,KAAK,CAAC;;KAElB;IAED,IAAMI,WAAW,GAAG,SAAdA,WAAW,CAAIJ,KAAoB;MACvC,IAAIA,KAAK,CAAC1E,GAAG,KAAK3B,SAAS,EAAE;;QAE3B;;MAGF,IAAIqG,KAAK,CAAC1E,GAAG,CAACf,WAAW,EAAE,KAAK,MAAM,EAAE;QACtCS,eAAe,UAAO,CAACgF,KAAK,CAAC1E,GAAG,CAACf,WAAW,EAAE,CAAC;OAChD,MAAM;;QAELS,eAAe,CAACqF,KAAK,EAAE;;MAGzB,IAAIhB,eAAe,YAAfA,eAAe,CAAEc,KAAK,EAAE;QAC1BZ,QAAQ,CAACS,KAAK,CAAC;;KAElB;;IAGD,CAAC5B,GAAG,CAACE,OAAO,IAAImB,QAAQ,EAAEa,gBAAgB,CAAC,OAAO,EAAEF,WAAW,CAAC;;IAEhE,CAAChC,GAAG,CAACE,OAAO,IAAImB,QAAQ,EAAEa,gBAAgB,CAAC,SAAS,EAAEP,aAAa,CAAC;IAEpE,IAAIT,KAAK,EAAE;MACTnH,kBAAkB,CAACC,IAAI,EAAEiH,eAAe,oBAAfA,eAAe,CAAEhH,QAAQ,CAAC,CAACyH,OAAO,CAAC,UAACxE,GAAG;QAAA,OAAKgE,KAAK,CAACpD,SAAS,CAAC3D,WAAW,CAAC+C,GAAG,EAAE+D,eAAe,oBAAfA,eAAe,CAAE5G,cAAc,CAAC,CAAC;QAAC;;IAG1I,OAAO;;MAEL,CAAC2F,GAAG,CAACE,OAAO,IAAImB,QAAQ,EAAEc,mBAAmB,CAAC,OAAO,EAAEH,WAAW,CAAC;;MAEnE,CAAChC,GAAG,CAACE,OAAO,IAAImB,QAAQ,EAAEc,mBAAmB,CAAC,SAAS,EAAER,aAAa,CAAC;MAEvE,IAAIT,KAAK,EAAE;QACTnH,kBAAkB,CAACC,IAAI,EAAEiH,eAAe,oBAAfA,eAAe,CAAEhH,QAAQ,CAAC,CAACyH,OAAO,CAAC,UAACxE,GAAG;UAAA,OAAKgE,KAAK,CAACnD,YAAY,CAAC5D,WAAW,CAAC+C,GAAG,EAAE+D,eAAe,oBAAfA,eAAe,CAAE5G,cAAc,CAAC,CAAC;UAAC;;KAE9I;GACF,EAAE,CAACL,IAAI,EAAE+G,EAAE,EAAEE,eAAe,EAAE7C,aAAa,CAAC,CAAC;EAE9C,OAAO4B,GAAG;AACZ;;AClIA,IAAMoC,oBAAoB,gBAAgB,IAAIjD,GAAG,EAAU;AAE3D,SAAgBkD,eAAe,CAACnF,GAAsB,EAAEjD;MAAAA;IAAAA,WAAmB,GAAG;;EAC5E,IAAMqI,WAAW,GAAGvG,KAAK,CAACwG,OAAO,CAACrF,GAAG,CAAC,GAAGA,GAAG,GAAGA,GAAG,CAAChD,KAAK,CAACD,QAAQ,CAAC;EAElE,OAAOqI,WAAW,CAAC/E,KAAK,CAAC,UAACnD,MAAM;IAC9B,IAAMoI,YAAY,GAAGrI,WAAW,CAACC,MAAM,CAAC;IAExC,qDAA4BgI,oBAAoB,wCAAE;MAAA,IAAvCK,aAAa;MACtB,IAAIjD,SAAS,CAACgD,YAAY,EAAEC,aAAa,CAAC,EAAE;QAC1C,OAAO,IAAI;;;GAGhB,CAAC;AACJ;AAEA,SAAgBC,0BAA0B,CAACxF,GAAsB;EAC/D,IAAMoF,WAAW,GAAGvG,KAAK,CAACwG,OAAO,CAACrF,GAAG,CAAC,GAAGA,GAAG,GAAG,CAACA,GAAG,CAAC;EAEpDoF,WAAW,CAACZ,OAAO,CAAC,UAAAtH,MAAM;IAAA,OAAIgI,oBAAoB,CAACP,GAAG,CAAC1H,WAAW,CAACC,MAAM,CAAC,CAAC;IAAC;AAC9E;AAEA,SAAgBuI,8BAA8B,CAACzF,GAAsB;EACnE,IAAMoF,WAAW,GAAGvG,KAAK,CAACwG,OAAO,CAACrF,GAAG,CAAC,GAAGA,GAAG,GAAG,CAACA,GAAG,CAAC;EAEpDoF,WAAW,CAACZ,OAAO,CAAC,UAACtH,MAAM;IACzB,IAAMoI,YAAY,GAAGrI,WAAW,CAACC,MAAM,CAAC;IAExC,sDAA4BgI,oBAAoB,2CAAE;MAAA;MAAA,IAAvCK,aAAa;MACtB,2BAAIA,aAAa,CAACzI,IAAI,aAAlB,oBAAoBuD,KAAK,CAAC,UAACL,GAAG;QAAA;QAAA,6BAAKsF,YAAY,CAACxI,IAAI,qBAAjB,mBAAmBY,QAAQ,CAACsC,GAAG,CAAC;QAAC,EAAE;QACxEkF,oBAAoB,UAAO,CAACK,aAAa,CAAC;;;GAG/C,CAAC;AACJ;AAEA,CAAC;EACC,IAAI,OAAOnC,MAAM,KAAK,WAAW,EAAE;IACjCA,MAAM,CAAC4B,gBAAgB,CAAC,kBAAkB,EAAE;MAC1Cb,QAAQ,CAACa,gBAAgB,CAAC,SAAS,EAAE,UAAA/G,CAAC;QACpC,IAAIA,CAAC,CAAC+B,GAAG,KAAK3B,SAAS,EAAE;;UAEvB;;QAGFmH,0BAA0B,CAACvH,CAAC,CAAC+B,GAAG,CAAC;OAClC,CAAC;MAEFmE,QAAQ,CAACa,gBAAgB,CAAC,OAAO,EAAE,UAAA/G,CAAC;QAClC,IAAIA,CAAC,CAAC+B,GAAG,KAAK3B,SAAS,EAAE;;UAEvB;;QAGFoH,8BAA8B,CAACxH,CAAC,CAAC+B,GAAG,CAAC;OACtC,CAAC;KACH,CAAC;;AAEN,CAAC,GAAG;;;;;;;"}
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,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})}var f=e.createContext({hotkeys:[],enabledScopes:[],toggleScope:function(){},enableScope:function(){},disableScope:function(){}}),y=function(){return e.useContext(f)};function v(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&&v(e[r],t[r])}),!0):e===t}var p=function(e){e.stopPropagation(),e.preventDefault(),e.stopImmediatePropagation()},m="undefined"!=typeof window?e.useLayoutEffect:e.useEffect,k=new Set,h=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 h.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(h);!(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)}))&&h.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],y=l[1],v=e.useMemo((function(){return a.includes("*")}),[a]),p=function(e){c(v?[e]:Array.from(new Set([].concat(a,[e]))))},m=function(e){var t=a.filter((function(t){return t!==e}));c(0===t.length?["*"]:t)};return t.jsx(f.Provider,{value:{enabledScopes:a,hotkeys:d,enableScope:p,disableScope:m,toggleScope:function(e){a.includes(e)?m(e):p(e)}},children:t.jsx(s,{addHotkey:function(e){y([].concat(d,[e]))},removeHotkey:function(e){y(d.filter((function(t){return t.keys!==e.keys})))},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(h);!(t=r()).done;)if(v(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:[])),f=function(t){var n=e.useRef(void 0);return v(n.current,t)||(n.current=t),n.current}(u),h=y().enabledScopes,g=e.useContext(d);return m((function(){if(!1!==(null==f?void 0:f.enabled)&&(n=null==f?void 0:f.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==f?void 0:f.enableOnFormTags)||(null===i.current||document.activeElement===i.current||i.current.contains(document.activeElement)?(null==(n=e.target)||!n.isContentEditable||null!=f&&f.enableOnContentEditable)&&a(t,null==f?void 0:f.splitKey).forEach((function(t){var n,r=c(t,null==f?void 0:f.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==f?void 0:f.preventDefault),!function(e,t,n){return"function"==typeof n?n(e,t):!0===n||void 0===n}(e,r,null==f?void 0:f.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==f?void 0:f.keydown)&&!0!==(null==f?void 0:f.keyup)||null!=f&&f.keydown)&&r(e))},u=function(e){void 0!==e.key&&("meta"!==e.key.toLowerCase()?k.delete(e.key.toLowerCase()):k.clear(),null!=f&&f.keyup&&r(e))};return(i.current||document).addEventListener("keyup",u),(i.current||document).addEventListener("keydown",o),g&&a(t,null==f?void 0:f.splitKey).forEach((function(e){return g.addHotkey(c(e,null==f?void 0:f.combinationKey))})),function(){(i.current||document).removeEventListener("keyup",u),(i.current||document).removeEventListener("keydown",o),g&&a(t,null==f?void 0:f.splitKey).forEach((function(e){return g.removeHotkey(c(e,null==f?void 0:f.combinationKey))}))}}}),[t,s,f,h]),i},exports.useHotkeysContext=y;
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;
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/HotkeysProvider.tsx","../src/deepEqual.ts","../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","import { Hotkey } from './types'\nimport { createContext, ReactNode, useMemo, useState, useContext } from 'react'\nimport BoundHotkeysProxyProviderProvider from './BoundHotkeysProxyProvider'\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 isAllActive = useMemo(() => internalActiveScopes.includes('*'), [internalActiveScopes])\n\n const enableScope = (scope: string) => {\n if (isAllActive) {\n setInternalActiveScopes([scope])\n } else {\n setInternalActiveScopes(Array.from(new Set([...internalActiveScopes, scope])))\n }\n }\n\n const disableScope = (scope: string) => {\n const scopes = internalActiveScopes.filter(s => s !== scope)\n\n if (scopes.length === 0) {\n setInternalActiveScopes(['*'])\n } else {\n setInternalActiveScopes(scopes)\n }\n }\n\n const toggleScope = (scope: string) => {\n if (internalActiveScopes.includes(scope)) {\n disableScope(scope)\n } else {\n enableScope(scope)\n }\n }\n\n const addBoundHotkey = (hotkey: Hotkey) => {\n setBoundHotkeys([...boundHotkeys, hotkey])\n }\n\n const removeBoundHotkey = (hotkey: Hotkey) => {\n setBoundHotkeys(boundHotkeys.filter(h => h.keys !== hotkey.keys))\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","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 { 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 WONT 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","HotkeysContext","hotkeys","enabledScopes","toggleScope","enableScope","disableScope","useHotkeysContext","useContext","deepEqual","x","y","Object","length","reduce","isEqual","key","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","isAllActive","useMemo","scope","from","scopes","s","h","callback","options","dependencies","ref","useRef","_options","cb","useCallback","memoisedOptions","current","useDeepEqualMemo","proxy","enabled","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":"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"}
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":"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"}
@@ -1,4 +1,4 @@
1
- import { useContext, createContext, useState, useMemo, useRef, useCallback, useLayoutEffect, useEffect } from 'react';
1
+ import { useContext, createContext, useState, useCallback, useRef, useLayoutEffect, useEffect } from 'react';
2
2
  import { jsx } from 'react/jsx-runtime';
3
3
 
4
4
  function _extends() {
@@ -200,6 +200,15 @@ function BoundHotkeysProxyProviderProvider(_ref) {
200
200
  });
201
201
  }
202
202
 
203
+ function deepEqual(x, y) {
204
+ //@ts-ignore
205
+ return x && y && typeof x === 'object' && typeof y === 'object'
206
+ //@ts-ignore
207
+ ? Object.keys(x).length === Object.keys(y).length && Object.keys(x).reduce(function (isEqual, key) {
208
+ return isEqual && deepEqual(x[key], y[key]);
209
+ }, true) : x === y;
210
+ }
211
+
203
212
  var HotkeysContext = /*#__PURE__*/createContext({
204
213
  hotkeys: [],
205
214
  enabledScopes: [],
@@ -220,41 +229,59 @@ var HotkeysProvider = function HotkeysProvider(_ref) {
220
229
  var _useState2 = useState([]),
221
230
  boundHotkeys = _useState2[0],
222
231
  setBoundHotkeys = _useState2[1];
223
- var isAllActive = useMemo(function () {
224
- return internalActiveScopes.includes('*');
225
- }, [internalActiveScopes]);
226
- var enableScope = function enableScope(scope) {
227
- if (isAllActive) {
228
- setInternalActiveScopes([scope]);
229
- } else {
230
- setInternalActiveScopes(Array.from(new Set([].concat(internalActiveScopes, [scope]))));
231
- }
232
- };
233
- var disableScope = function disableScope(scope) {
234
- var scopes = internalActiveScopes.filter(function (s) {
235
- return s !== scope;
232
+ var enableScope = useCallback(function (scope) {
233
+ setInternalActiveScopes(function (prev) {
234
+ if (prev.includes('*')) {
235
+ return [scope];
236
+ }
237
+ return Array.from(new Set([].concat(prev, [scope])));
236
238
  });
237
- if (scopes.length === 0) {
238
- setInternalActiveScopes(['*']);
239
- } else {
240
- setInternalActiveScopes(scopes);
241
- }
242
- };
243
- var toggleScope = function toggleScope(scope) {
244
- if (internalActiveScopes.includes(scope)) {
245
- disableScope(scope);
246
- } else {
247
- enableScope(scope);
248
- }
249
- };
250
- var addBoundHotkey = function addBoundHotkey(hotkey) {
251
- setBoundHotkeys([].concat(boundHotkeys, [hotkey]));
252
- };
253
- var removeBoundHotkey = function removeBoundHotkey(hotkey) {
254
- setBoundHotkeys(boundHotkeys.filter(function (h) {
255
- return h.keys !== hotkey.keys;
256
- }));
257
- };
239
+ }, []);
240
+ var disableScope = useCallback(function (scope) {
241
+ setInternalActiveScopes(function (prev) {
242
+ if (prev.filter(function (s) {
243
+ return s !== scope;
244
+ }).length === 0) {
245
+ return ['*'];
246
+ } else {
247
+ return prev.filter(function (s) {
248
+ return s !== scope;
249
+ });
250
+ }
251
+ });
252
+ }, []);
253
+ var toggleScope = useCallback(function (scope) {
254
+ setInternalActiveScopes(function (prev) {
255
+ if (prev.includes(scope)) {
256
+ if (prev.filter(function (s) {
257
+ return s !== scope;
258
+ }).length === 0) {
259
+ return ['*'];
260
+ } else {
261
+ return prev.filter(function (s) {
262
+ return s !== scope;
263
+ });
264
+ }
265
+ } else {
266
+ if (prev.includes('*')) {
267
+ return [scope];
268
+ }
269
+ return Array.from(new Set([].concat(prev, [scope])));
270
+ }
271
+ });
272
+ }, []);
273
+ var addBoundHotkey = useCallback(function (hotkey) {
274
+ setBoundHotkeys(function (prev) {
275
+ return [].concat(prev, [hotkey]);
276
+ });
277
+ }, []);
278
+ var removeBoundHotkey = useCallback(function (hotkey) {
279
+ setBoundHotkeys(function (prev) {
280
+ return prev.filter(function (h) {
281
+ return !deepEqual(h, hotkey);
282
+ });
283
+ });
284
+ }, []);
258
285
  return /*#__PURE__*/jsx(HotkeysContext.Provider, {
259
286
  value: {
260
287
  enabledScopes: internalActiveScopes,
@@ -271,15 +298,6 @@ var HotkeysProvider = function HotkeysProvider(_ref) {
271
298
  });
272
299
  };
273
300
 
274
- function deepEqual(x, y) {
275
- //@ts-ignore
276
- return x && y && typeof x === 'object' && typeof y === 'object'
277
- //@ts-ignore
278
- ? Object.keys(x).length === Object.keys(y).length && Object.keys(x).reduce(function (isEqual, key) {
279
- return isEqual && deepEqual(x[key], y[key]);
280
- }, true) : x === y;
281
- }
282
-
283
301
  function useDeepEqualMemo(value) {
284
302
  var ref = useRef(undefined);
285
303
  if (!deepEqual(ref.current, value)) {
@@ -314,7 +332,7 @@ function useHotkeys(keys, callback, options, dependencies) {
314
332
  return;
315
333
  }
316
334
  // 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
317
- // REF IS THE ACTIVE ELEMENT. THIS IS A PROBLEM SINCE FOCUSED SUB COMPONENTS WONT TRIGGER THE HOTKEY.
335
+ // REF IS THE ACTIVE ELEMENT. THIS IS A PROBLEM SINCE FOCUSED SUB COMPONENTS WON'T TRIGGER THE HOTKEY.
318
336
  if (ref.current !== null && document.activeElement !== ref.current && !ref.current.contains(document.activeElement)) {
319
337
  stopPropagation(e);
320
338
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"react-hotkeys-hook.esm.js","sources":["../src/parseHotkeys.ts","../src/validators.ts","../src/BoundHotkeysProxyProvider.tsx","../src/HotkeysProvider.tsx","../src/deepEqual.ts","../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","import { Hotkey } from './types'\nimport { createContext, ReactNode, useMemo, useState, useContext } from 'react'\nimport BoundHotkeysProxyProviderProvider from './BoundHotkeysProxyProvider'\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 isAllActive = useMemo(() => internalActiveScopes.includes('*'), [internalActiveScopes])\n\n const enableScope = (scope: string) => {\n if (isAllActive) {\n setInternalActiveScopes([scope])\n } else {\n setInternalActiveScopes(Array.from(new Set([...internalActiveScopes, scope])))\n }\n }\n\n const disableScope = (scope: string) => {\n const scopes = internalActiveScopes.filter(s => s !== scope)\n\n if (scopes.length === 0) {\n setInternalActiveScopes(['*'])\n } else {\n setInternalActiveScopes(scopes)\n }\n }\n\n const toggleScope = (scope: string) => {\n if (internalActiveScopes.includes(scope)) {\n disableScope(scope)\n } else {\n enableScope(scope)\n }\n }\n\n const addBoundHotkey = (hotkey: Hotkey) => {\n setBoundHotkeys([...boundHotkeys, hotkey])\n }\n\n const removeBoundHotkey = (hotkey: Hotkey) => {\n setBoundHotkeys(boundHotkeys.filter(h => h.keys !== hotkey.keys))\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","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 { 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 WONT 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","HotkeysContext","hotkeys","enabledScopes","toggleScope","enableScope","disableScope","useHotkeysContext","HotkeysProvider","initiallyActiveScopes","useState","internalActiveScopes","setInternalActiveScopes","boundHotkeys","setBoundHotkeys","isAllActive","useMemo","from","Set","s","addBoundHotkey","removeBoundHotkey","h","deepEqual","x","y","Object","reduce","isEqual","useDeepEqualMemo","value","ref","useRef","current","stopPropagation","stopImmediatePropagation","useSafeLayoutEffect","window","useLayoutEffect","useEffect","useHotkeys","callback","options","dependencies","_options","_deps","cb","useCallback","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/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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-hotkeys-hook",
3
- "version": "4.0.7",
3
+ "version": "4.0.8",
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,6 +1,7 @@
1
1
  import { Hotkey } from './types'
2
- import { createContext, ReactNode, useMemo, useState, useContext } from 'react'
2
+ import { createContext, ReactNode, useState, useContext, useCallback } from 'react'
3
3
  import BoundHotkeysProxyProviderProvider from './BoundHotkeysProxyProvider'
4
+ import deepEqual from './deepEqual'
4
5
 
5
6
  export type HotkeysContextType = {
6
7
  hotkeys: ReadonlyArray<Hotkey>
@@ -32,41 +33,51 @@ export const HotkeysProvider = ({initiallyActiveScopes = ['*'], children}: Props
32
33
  const [internalActiveScopes, setInternalActiveScopes] = useState(initiallyActiveScopes?.length > 0 ? initiallyActiveScopes : ['*'])
33
34
  const [boundHotkeys, setBoundHotkeys] = useState<Hotkey[]>([]);
34
35
 
35
- const isAllActive = useMemo(() => internalActiveScopes.includes('*'), [internalActiveScopes])
36
+ const enableScope = useCallback((scope: string) => {
37
+ setInternalActiveScopes((prev) => {
38
+ if (prev.includes('*')) {
39
+ return [scope]
40
+ }
36
41
 
37
- const enableScope = (scope: string) => {
38
- if (isAllActive) {
39
- setInternalActiveScopes([scope])
40
- } else {
41
- setInternalActiveScopes(Array.from(new Set([...internalActiveScopes, scope])))
42
- }
43
- }
42
+ return Array.from(new Set([...prev, scope]))
43
+ })
44
+ }, [])
44
45
 
45
- const disableScope = (scope: string) => {
46
- const scopes = internalActiveScopes.filter(s => s !== scope)
46
+ const disableScope = useCallback((scope: string) => {
47
+ setInternalActiveScopes((prev) => {
48
+ if (prev.filter(s => s !== scope).length === 0) {
49
+ return ['*']
50
+ } else {
51
+ return prev.filter(s => s !== scope)
52
+ }
53
+ })
54
+ }, [])
47
55
 
48
- if (scopes.length === 0) {
49
- setInternalActiveScopes(['*'])
50
- } else {
51
- setInternalActiveScopes(scopes)
52
- }
53
- }
56
+ const toggleScope = useCallback((scope: string) => {
57
+ setInternalActiveScopes((prev) => {
58
+ if (prev.includes(scope)) {
59
+ if (prev.filter(s => s !== scope).length === 0) {
60
+ return ['*']
61
+ } else {
62
+ return prev.filter(s => s !== scope)
63
+ }
64
+ } else {
65
+ if (prev.includes('*')) {
66
+ return [scope]
67
+ }
54
68
 
55
- const toggleScope = (scope: string) => {
56
- if (internalActiveScopes.includes(scope)) {
57
- disableScope(scope)
58
- } else {
59
- enableScope(scope)
60
- }
61
- }
69
+ return Array.from(new Set([...prev, scope]))
70
+ }
71
+ })
72
+ }, [])
62
73
 
63
- const addBoundHotkey = (hotkey: Hotkey) => {
64
- setBoundHotkeys([...boundHotkeys, hotkey])
65
- }
74
+ const addBoundHotkey = useCallback((hotkey: Hotkey) => {
75
+ setBoundHotkeys((prev) => [...prev, hotkey])
76
+ }, [])
66
77
 
67
- const removeBoundHotkey = (hotkey: Hotkey) => {
68
- setBoundHotkeys(boundHotkeys.filter(h => h.keys !== hotkey.keys))
69
- }
78
+ const removeBoundHotkey = useCallback((hotkey: Hotkey) => {
79
+ setBoundHotkeys((prev) => prev.filter(h => !deepEqual(h, hotkey)))
80
+ }, [])
70
81
 
71
82
  return (
72
83
  <HotkeysContext.Provider value={{enabledScopes: internalActiveScopes, hotkeys: boundHotkeys, enableScope, disableScope, toggleScope}}>
package/src/useHotkeys.ts CHANGED
@@ -51,7 +51,7 @@ export default function useHotkeys<T extends HTMLElement>(
51
51
  }
52
52
 
53
53
  // 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
54
- // REF IS THE ACTIVE ELEMENT. THIS IS A PROBLEM SINCE FOCUSED SUB COMPONENTS WONT TRIGGER THE HOTKEY.
54
+ // REF IS THE ACTIVE ELEMENT. THIS IS A PROBLEM SINCE FOCUSED SUB COMPONENTS WON'T TRIGGER THE HOTKEY.
55
55
  if (ref.current !== null && document.activeElement !== ref.current && !ref.current.contains(document.activeElement)) {
56
56
  stopPropagation(e)
57
57