react-hotkeys-hook 5.0.0-0 → 5.0.0-2

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.
Files changed (35) hide show
  1. package/package.json +13 -85
  2. package/{dist → packages/react-hotkeys-hook/dist}/BoundHotkeysProxyProvider.d.ts +14 -14
  3. package/{dist → packages/react-hotkeys-hook/dist}/HotkeysProvider.d.ts +16 -16
  4. package/packages/react-hotkeys-hook/dist/deepEqual.d.ts +1 -0
  5. package/{dist → packages/react-hotkeys-hook/dist}/index.d.ts +6 -6
  6. package/packages/react-hotkeys-hook/dist/index.js +220 -0
  7. package/{dist → packages/react-hotkeys-hook/dist}/isHotkeyPressed.d.ts +4 -4
  8. package/packages/react-hotkeys-hook/dist/parseHotkeys.d.ts +5 -0
  9. package/packages/react-hotkeys-hook/dist/types.d.ts +45 -0
  10. package/{dist → packages/react-hotkeys-hook/dist}/useDeepEqualMemo.d.ts +1 -1
  11. package/{dist → packages/react-hotkeys-hook/dist}/useHotkeys.d.ts +2 -3
  12. package/{dist → packages/react-hotkeys-hook/dist}/useRecordHotkeys.d.ts +6 -5
  13. package/{dist → packages/react-hotkeys-hook/dist}/validators.d.ts +8 -7
  14. package/dist/deepEqual.d.ts +0 -1
  15. package/dist/index.js +0 -8
  16. package/dist/parseHotkeys.d.ts +0 -5
  17. package/dist/react-hotkeys-hook.cjs.development.js +0 -514
  18. package/dist/react-hotkeys-hook.cjs.development.js.map +0 -1
  19. package/dist/react-hotkeys-hook.cjs.production.min.js +0 -2
  20. package/dist/react-hotkeys-hook.cjs.production.min.js.map +0 -1
  21. package/dist/react-hotkeys-hook.esm.js +0 -508
  22. package/dist/react-hotkeys-hook.esm.js.map +0 -1
  23. package/dist/setupTests.d.ts +0 -1
  24. package/dist/types.d.ts +0 -36
  25. package/src/BoundHotkeysProxyProvider.tsx +0 -27
  26. package/src/HotkeysProvider.tsx +0 -81
  27. package/src/deepEqual.ts +0 -8
  28. package/src/index.ts +0 -16
  29. package/src/isHotkeyPressed.ts +0 -73
  30. package/src/parseHotkeys.ts +0 -58
  31. package/src/types.ts +0 -45
  32. package/src/useDeepEqualMemo.ts +0 -12
  33. package/src/useHotkeys.ts +0 -172
  34. package/src/useRecordHotkeys.ts +0 -47
  35. package/src/validators.ts +0 -106
@@ -1 +0,0 @@
1
- {"version":3,"file":"react-hotkeys-hook.cjs.production.min.js","sources":["../src/parseHotkeys.ts","../src/isHotkeyPressed.ts","../src/validators.ts","../src/BoundHotkeysProxyProvider.tsx","../src/deepEqual.ts","../src/HotkeysProvider.tsx","../src/useHotkeys.ts","../src/useDeepEqualMemo.ts","../src/useRecordHotkeys.ts"],"sourcesContent":["import { Hotkey, KeyboardModifiers } from './types'\n\nconst reservedModifierKeywords = ['shift', 'alt', 'meta', 'mod', 'ctrl']\n\nconst mappedKeys: Record<string, string> = {\n esc: 'escape',\n return: 'enter',\n left: 'arrowleft',\n right: 'arrowright',\n up: 'arrowup',\n down: 'arrowdown',\n space: ' ',\n ShiftLeft: 'shift',\n ShiftRight: 'shift',\n AltLeft: 'alt',\n AltRight: 'alt',\n MetaLeft: 'meta',\n MetaRight: 'meta',\n OSLeft: 'meta',\n OSRight: 'meta',\n ControlLeft: 'ctrl',\n ControlRight: 'ctrl',\n}\n\nexport function mapKey(key: string): string {\n return (mappedKeys[key.trim()] || key.trim()).toLowerCase().replace(/key|digit|numpad/, '')\n}\n\nexport function isHotkeyModifier(key: string) {\n return reservedModifierKeywords.includes(key)\n}\n\nexport function parseKeysHookInput(keys: string, splitKey = ','): string[] {\n return keys.split(splitKey)\n}\n\nexport function parseHotkey(hotkey: string, combinationKey = '+', description?: string): Hotkey {\n const keys = hotkey\n .toLocaleLowerCase()\n .split(combinationKey)\n .map((k) => mapKey(k))\n\n const modifiers: KeyboardModifiers = {\n alt: keys.includes('alt'),\n ctrl: keys.includes('ctrl') || keys.includes('control'),\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 description,\n }\n}\n","import { isHotkeyModifier, mapKey } from './parseHotkeys'\n;(() => {\n if (typeof document !== 'undefined') {\n document.addEventListener('keydown', (e) => {\n if (e.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n console.log('keydown', e.key, mapKey(e.key), e.key.length)\n\n pushToCurrentlyPressedKeys([mapKey(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([mapKey(e.key)])\n })\n }\n\n if (typeof window !== 'undefined') {\n window.addEventListener('blur', () => {\n currentlyPressedKeys.clear()\n })\n }\n})()\n\nconst currentlyPressedKeys: Set<string> = new Set<string>()\n\n// https://github.com/microsoft/TypeScript/issues/17002\nexport function isReadonlyArray(value: unknown): value is readonly unknown[] {\n return Array.isArray(value)\n}\n\nexport function isHotkeyPressed(key: string | readonly string[], splitKey = ','): boolean {\n const hotkeyArray = isReadonlyArray(key) ? key : key.split(splitKey)\n\n return hotkeyArray.every((hotkey) => currentlyPressedKeys.has(hotkey.trim().toLowerCase()))\n}\n\nexport function pushToCurrentlyPressedKeys(key: string | string[]): void {\n const hotkeyArray = Array.isArray(key) ? key : [key]\n\n /*\n Due to a weird behavior on macOS we need to clear the set if the user pressed down the meta key and presses another key.\n https://stackoverflow.com/questions/11818637/why-does-javascript-drop-keyup-events-when-the-metakey-is-pressed-on-mac-browser\n Otherwise the set will hold all ever pressed keys while the meta key is down which leads to wrong results.\n */\n if (currentlyPressedKeys.has('meta')) {\n currentlyPressedKeys.forEach((key) => !isHotkeyModifier(key) && currentlyPressedKeys.delete(key.toLowerCase()))\n }\n\n hotkeyArray.forEach((hotkey) => currentlyPressedKeys.add(hotkey.toLowerCase()))\n}\n\nexport function removeFromCurrentlyPressedKeys(key: string | string[]): void {\n const hotkeyArray = Array.isArray(key) ? key : [key]\n\n /*\n Due to a weird behavior on macOS we need to clear the set if the user pressed down the meta key and presses another key.\n https://stackoverflow.com/questions/11818637/why-does-javascript-drop-keyup-events-when-the-metakey-is-pressed-on-mac-browser\n Otherwise the set will hold all ever pressed keys while the meta key is down which leads to wrong results.\n */\n if (key === 'meta') {\n currentlyPressedKeys.clear()\n } else {\n hotkeyArray.forEach((hotkey) => currentlyPressedKeys.delete(hotkey.toLowerCase()))\n }\n}\n","import { FormTags, Hotkey, Scopes, Trigger } from './types'\nimport { isHotkeyPressed, isReadonlyArray } from './isHotkeyPressed'\n\nexport function maybePreventDefault(e: KeyboardEvent, hotkey: Hotkey, preventDefault?: Trigger): void {\n if ((typeof preventDefault === 'function' && preventDefault(e, hotkey)) || preventDefault === true) {\n e.preventDefault()\n }\n}\n\nexport function isHotkeyEnabled(e: KeyboardEvent, hotkey: Hotkey, enabled?: Trigger): boolean {\n if (typeof enabled === 'function') {\n return enabled(e, hotkey)\n }\n\n return enabled === true || enabled === undefined\n}\n\nexport function isKeyboardEventTriggeredByInput(ev: KeyboardEvent): boolean {\n return isHotkeyEnabledOnTag(ev, ['input', 'textarea', 'select'])\n}\n\nexport function isHotkeyEnabledOnTag(\n { target }: KeyboardEvent,\n enabledOnTags: readonly FormTags[] | boolean = false\n): boolean {\n const targetTagName = target && (target as HTMLElement).tagName\n\n if (isReadonlyArray(enabledOnTags)) {\n return Boolean(\n targetTagName && enabledOnTags && enabledOnTags.some((tag) => tag.toLowerCase() === targetTagName.toLowerCase())\n )\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, ignoreModifiers = false): boolean => {\n const { alt, meta, mod, shift, ctrl, keys } = hotkey\n const { key: pressedKeyUppercase, ctrlKey, metaKey, shiftKey, altKey } = e\n\n const pressedKey = pressedKeyUppercase.toLowerCase()\n\n if (\n !keys?.includes(pressedKey) &&\n !['ctrl', 'control', 'unknown', 'meta', 'alt', 'shift', 'os'].includes(pressedKey)\n ) {\n return false\n }\n\n if (!ignoreModifiers) {\n // We check the pressed keys for compatibility with the keyup event. In keyup events the modifier flags are not set.\n if (alt === !altKey && pressedKey !== 'alt') {\n return false\n }\n\n if (shift === !shiftKey && 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 (meta === !metaKey && pressedKey !== 'meta' && pressedKey !== 'os') {\n return false\n }\n\n if (ctrl === !ctrlKey && pressedKey !== 'ctrl' && pressedKey !== 'control') {\n return false\n }\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)) {\n return true\n } else if (keys) {\n // Check if all keys are present in pressedDownKeys set\n return isHotkeyPressed(keys)\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 (\n <BoundHotkeysProxyProvider.Provider value={{ addHotkey, removeHotkey }}>\n {children}\n </BoundHotkeysProxyProvider.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 ? Object.keys(x).length === Object.keys(y).length &&\n //@ts-ignore\n Object.keys(x).reduce((isEqual, key) => isEqual && deepEqual(x[key], y[key]), 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 activeScopes: 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 activeScopes: [], // 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)\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 return Array.from(new Set([...prev, scope]))\n })\n }, [])\n\n const disableScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n return prev.filter((s) => s !== scope)\n })\n }, [])\n\n const toggleScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.includes(scope)) {\n return prev.filter((s) => s !== scope)\n } else {\n if (prev.includes('*')) {\n return [scope]\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\n value={{ activeScopes: internalActiveScopes, hotkeys: boundHotkeys, enableScope, disableScope, toggleScope }}\n >\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 { mapKey, 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'\nimport { isReadonlyArray, pushToCurrentlyPressedKeys, removeFromCurrentlyPressedKeys } from './isHotkeyPressed'\n\nconst stopPropagation = (e: KeyboardEvent): void => {\n e.stopPropagation()\n e.preventDefault()\n e.stopImmediatePropagation()\n}\n\nconst useSafeLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect\n\nexport default function useHotkeys<T extends HTMLElement>(\n keys: Keys,\n callback: HotkeyCallback,\n options?: OptionsOrDependencyArray,\n dependencies?: OptionsOrDependencyArray\n) {\n const ref = useRef<RefType<T>>(null)\n const hasTriggeredRef = useRef(false)\n\n const _options: Options | undefined = !(options instanceof Array)\n ? (options as Options)\n : !(dependencies instanceof Array)\n ? (dependencies as Options)\n : undefined\n const _keys: string = isReadonlyArray(keys) ? keys.join(_options?.splitKey) : keys\n const _deps: DependencyList | undefined =\n options instanceof Array ? options : dependencies instanceof Array ? dependencies : undefined\n\n const memoisedCB = useCallback(callback, _deps ?? [])\n const cbRef = useRef<HotkeyCallback>(memoisedCB)\n\n if (_deps) {\n cbRef.current = memoisedCB\n } else {\n cbRef.current = callback\n }\n\n const memoisedOptions = useDeepEqualMemo(_options)\n\n const { activeScopes } = useHotkeysContext()\n const proxy = useBoundHotkeysProxy()\n\n useSafeLayoutEffect(() => {\n if (memoisedOptions?.enabled === false || !isScopeActive(activeScopes, memoisedOptions?.scopes)) {\n return\n }\n\n const listener = (e: KeyboardEvent, isKeyUp = false) => {\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) {\n const rootNode = ref.current.getRootNode()\n\n if (\n (rootNode instanceof Document || rootNode instanceof ShadowRoot) &&\n rootNode.activeElement !== ref.current &&\n !ref.current.contains(rootNode.activeElement)\n ) {\n stopPropagation(e)\n return\n }\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, memoisedOptions?.ignoreModifiers) || hotkey.keys?.includes('*')) {\n if (memoisedOptions?.ignoreEventWhen?.(e)) {\n return\n }\n\n if (isKeyUp && hasTriggeredRef.current) {\n return\n }\n\n maybePreventDefault(e, hotkey, memoisedOptions?.preventDefault)\n\n if (!isHotkeyEnabled(e, hotkey, memoisedOptions?.enabled)) {\n stopPropagation(e)\n\n return\n }\n\n // Execute the user callback for that hotkey\n cbRef.current(e, hotkey)\n\n if (!isKeyUp) {\n hasTriggeredRef.current = true\n }\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 pushToCurrentlyPressedKeys(mapKey(event.key))\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 removeFromCurrentlyPressedKeys(mapKey(event.key))\n\n hasTriggeredRef.current = false\n\n if (memoisedOptions?.keyup) {\n listener(event, true)\n }\n }\n\n const domNode = ref.current || _options?.document || document\n\n // @ts-ignore\n domNode.addEventListener('keyup', handleKeyUp)\n // @ts-ignore\n domNode.addEventListener('keydown', handleKeyDown)\n\n if (proxy) {\n parseKeysHookInput(_keys, memoisedOptions?.splitKey).forEach((key) =>\n proxy.addHotkey(parseHotkey(key, memoisedOptions?.combinationKey, memoisedOptions?.description))\n )\n }\n\n return () => {\n // @ts-ignore\n domNode.removeEventListener('keyup', handleKeyUp)\n // @ts-ignore\n domNode.removeEventListener('keydown', handleKeyDown)\n\n if (proxy) {\n parseKeysHookInput(_keys, memoisedOptions?.splitKey).forEach((key) =>\n proxy.removeHotkey(parseHotkey(key, memoisedOptions?.combinationKey, memoisedOptions?.description))\n )\n }\n }\n }, [_keys, memoisedOptions, activeScopes])\n\n return ref\n}\n","import { useRef } from 'react'\nimport deepEqual from './deepEqual'\n\nexport default function useDeepEqualMemo<T>(value: T) {\n const ref = useRef<T | undefined>(undefined)\n\n if (!deepEqual(ref.current, value)) {\n ref.current = value\n }\n\n return ref.current\n}\n","import { useCallback, useState } from 'react'\nimport { mapKey } from './parseHotkeys'\n\nexport default function useRecordHotkeys() {\n const [keys, setKeys] = useState(new Set<string>())\n const [isRecording, setIsRecording] = useState(false)\n\n const handler = useCallback((event: KeyboardEvent) => {\n if (event.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n event.preventDefault()\n event.stopPropagation()\n\n setKeys((prev) => {\n const newKeys = new Set(prev)\n\n newKeys.add(mapKey(event.key))\n\n return newKeys\n })\n }, [])\n\n const stop = useCallback(() => {\n if (typeof document !== 'undefined') {\n document.removeEventListener('keydown', handler)\n\n setIsRecording(false)\n }\n }, [handler])\n\n const start = useCallback(() => {\n setKeys(new Set<string>())\n\n if (typeof document !== 'undefined') {\n stop()\n\n document.addEventListener('keydown', handler)\n\n setIsRecording(true)\n }\n }, [handler, stop])\n\n return [keys, { start, stop, isRecording }] as const\n}\n"],"names":["reservedModifierKeywords","mappedKeys","esc","return","left","right","up","down","space","ShiftLeft","ShiftRight","AltLeft","AltRight","MetaLeft","MetaRight","OSLeft","OSRight","ControlLeft","ControlRight","mapKey","key","trim","toLowerCase","replace","parseKeysHookInput","keys","splitKey","split","parseHotkey","hotkey","combinationKey","description","toLocaleLowerCase","map","k","_extends","alt","includes","ctrl","shift","meta","mod","filter","document","addEventListener","e","undefined","console","log","length","pushToCurrentlyPressedKeys","removeFromCurrentlyPressedKeys","window","currentlyPressedKeys","clear","Set","isReadonlyArray","value","Array","isArray","isHotkeyPressed","every","has","hotkeyArray","forEach","isHotkeyModifier","add","isHotkeyEnabledOnTag","_ref","enabledOnTags","target","targetTagName","tagName","Boolean","some","tag","BoundHotkeysProxyProvider","createContext","BoundHotkeysProxyProviderProvider","_jsx","Provider","addHotkey","removeHotkey","children","deepEqual","x","y","Object","reduce","isEqual","HotkeysContext","hotkeys","activeScopes","toggleScope","enableScope","disableScope","useHotkeysContext","useContext","stopPropagation","preventDefault","stopImmediatePropagation","useSafeLayoutEffect","useLayoutEffect","useEffect","initiallyActiveScopes","_useState","useState","_ref$initiallyActiveS","internalActiveScopes","setInternalActiveScopes","_useState2","boundHotkeys","setBoundHotkeys","useCallback","scope","prev","from","concat","s","addBoundHotkey","removeBoundHotkey","h","callback","options","dependencies","ref","useRef","hasTriggeredRef","_options","_keys","join","_deps","memoisedCB","cbRef","current","memoisedOptions","useDeepEqualMemo","proxy","enabled","scopes","warn","isScopeActive","listener","isKeyUp","enableOnFormTags","rootNode","getRootNode","Document","ShadowRoot","activeElement","contains","_e$target","isContentEditable","enableOnContentEditable","ignoreModifiers","ctrlKey","metaKey","shiftKey","altKey","pressedKey","isHotkeyMatchingKeyboardEvent","_hotkey$keys","ignoreEventWhen","maybePreventDefault","isHotkeyEnabled","handleKeyDown","event","keydown","keyup","handleKeyUp","domNode","removeEventListener","setKeys","isRecording","setIsRecording","handler","newKeys","stop","start"],"mappings":"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"}
@@ -1,508 +0,0 @@
1
- import { useContext, createContext, useState, useCallback, useRef, useLayoutEffect, useEffect } from 'react';
2
- import { jsx } from 'react/jsx-runtime';
3
-
4
- function _extends() {
5
- _extends = Object.assign ? Object.assign.bind() : function (target) {
6
- for (var i = 1; i < arguments.length; i++) {
7
- var source = arguments[i];
8
- for (var key in source) {
9
- if (Object.prototype.hasOwnProperty.call(source, key)) {
10
- target[key] = source[key];
11
- }
12
- }
13
- }
14
- return target;
15
- };
16
- return _extends.apply(this, arguments);
17
- }
18
-
19
- var reservedModifierKeywords = ['shift', 'alt', 'meta', 'mod', 'ctrl'];
20
- var mappedKeys = {
21
- esc: 'escape',
22
- "return": 'enter',
23
- left: 'arrowleft',
24
- right: 'arrowright',
25
- up: 'arrowup',
26
- down: 'arrowdown',
27
- space: ' ',
28
- ShiftLeft: 'shift',
29
- ShiftRight: 'shift',
30
- AltLeft: 'alt',
31
- AltRight: 'alt',
32
- MetaLeft: 'meta',
33
- MetaRight: 'meta',
34
- OSLeft: 'meta',
35
- OSRight: 'meta',
36
- ControlLeft: 'ctrl',
37
- ControlRight: 'ctrl'
38
- };
39
- function mapKey(key) {
40
- return (mappedKeys[key.trim()] || key.trim()).toLowerCase().replace(/key|digit|numpad/, '');
41
- }
42
- function isHotkeyModifier(key) {
43
- return reservedModifierKeywords.includes(key);
44
- }
45
- function parseKeysHookInput(keys, splitKey) {
46
- if (splitKey === void 0) {
47
- splitKey = ',';
48
- }
49
- return keys.split(splitKey);
50
- }
51
- function parseHotkey(hotkey, combinationKey, description) {
52
- if (combinationKey === void 0) {
53
- combinationKey = '+';
54
- }
55
- var keys = hotkey.toLocaleLowerCase().split(combinationKey).map(function (k) {
56
- return mapKey(k);
57
- });
58
- var modifiers = {
59
- alt: keys.includes('alt'),
60
- ctrl: keys.includes('ctrl') || keys.includes('control'),
61
- shift: keys.includes('shift'),
62
- meta: keys.includes('meta'),
63
- mod: keys.includes('mod')
64
- };
65
- var singleCharKeys = keys.filter(function (k) {
66
- return !reservedModifierKeywords.includes(k);
67
- });
68
- return _extends({}, modifiers, {
69
- keys: singleCharKeys,
70
- description: description
71
- });
72
- }
73
-
74
- (function () {
75
- if (typeof document !== 'undefined') {
76
- document.addEventListener('keydown', function (e) {
77
- if (e.key === undefined) {
78
- // Synthetic event (e.g., Chrome autofill). Ignore.
79
- return;
80
- }
81
- console.log('keydown', e.key, mapKey(e.key), e.key.length);
82
- pushToCurrentlyPressedKeys([mapKey(e.key)]);
83
- });
84
- document.addEventListener('keyup', function (e) {
85
- if (e.key === undefined) {
86
- // Synthetic event (e.g., Chrome autofill). Ignore.
87
- return;
88
- }
89
- removeFromCurrentlyPressedKeys([mapKey(e.key)]);
90
- });
91
- }
92
- if (typeof window !== 'undefined') {
93
- window.addEventListener('blur', function () {
94
- currentlyPressedKeys.clear();
95
- });
96
- }
97
- })();
98
- var currentlyPressedKeys = /*#__PURE__*/new Set();
99
- // https://github.com/microsoft/TypeScript/issues/17002
100
- function isReadonlyArray(value) {
101
- return Array.isArray(value);
102
- }
103
- function isHotkeyPressed(key, splitKey) {
104
- if (splitKey === void 0) {
105
- splitKey = ',';
106
- }
107
- var hotkeyArray = isReadonlyArray(key) ? key : key.split(splitKey);
108
- return hotkeyArray.every(function (hotkey) {
109
- return currentlyPressedKeys.has(hotkey.trim().toLowerCase());
110
- });
111
- }
112
- function pushToCurrentlyPressedKeys(key) {
113
- var hotkeyArray = Array.isArray(key) ? key : [key];
114
- /*
115
- Due to a weird behavior on macOS we need to clear the set if the user pressed down the meta key and presses another key.
116
- https://stackoverflow.com/questions/11818637/why-does-javascript-drop-keyup-events-when-the-metakey-is-pressed-on-mac-browser
117
- Otherwise the set will hold all ever pressed keys while the meta key is down which leads to wrong results.
118
- */
119
- if (currentlyPressedKeys.has('meta')) {
120
- currentlyPressedKeys.forEach(function (key) {
121
- return !isHotkeyModifier(key) && currentlyPressedKeys["delete"](key.toLowerCase());
122
- });
123
- }
124
- hotkeyArray.forEach(function (hotkey) {
125
- return currentlyPressedKeys.add(hotkey.toLowerCase());
126
- });
127
- }
128
- function removeFromCurrentlyPressedKeys(key) {
129
- var hotkeyArray = Array.isArray(key) ? key : [key];
130
- /*
131
- Due to a weird behavior on macOS we need to clear the set if the user pressed down the meta key and presses another key.
132
- https://stackoverflow.com/questions/11818637/why-does-javascript-drop-keyup-events-when-the-metakey-is-pressed-on-mac-browser
133
- Otherwise the set will hold all ever pressed keys while the meta key is down which leads to wrong results.
134
- */
135
- if (key === 'meta') {
136
- currentlyPressedKeys.clear();
137
- } else {
138
- hotkeyArray.forEach(function (hotkey) {
139
- return currentlyPressedKeys["delete"](hotkey.toLowerCase());
140
- });
141
- }
142
- }
143
-
144
- function maybePreventDefault(e, hotkey, preventDefault) {
145
- if (typeof preventDefault === 'function' && preventDefault(e, hotkey) || preventDefault === true) {
146
- e.preventDefault();
147
- }
148
- }
149
- function isHotkeyEnabled(e, hotkey, enabled) {
150
- if (typeof enabled === 'function') {
151
- return enabled(e, hotkey);
152
- }
153
- return enabled === true || enabled === undefined;
154
- }
155
- function isKeyboardEventTriggeredByInput(ev) {
156
- return isHotkeyEnabledOnTag(ev, ['input', 'textarea', 'select']);
157
- }
158
- function isHotkeyEnabledOnTag(_ref, enabledOnTags) {
159
- var target = _ref.target;
160
- if (enabledOnTags === void 0) {
161
- enabledOnTags = false;
162
- }
163
- var targetTagName = target && target.tagName;
164
- if (isReadonlyArray(enabledOnTags)) {
165
- return Boolean(targetTagName && enabledOnTags && enabledOnTags.some(function (tag) {
166
- return tag.toLowerCase() === targetTagName.toLowerCase();
167
- }));
168
- }
169
- return Boolean(targetTagName && enabledOnTags && enabledOnTags === true);
170
- }
171
- function isScopeActive(activeScopes, scopes) {
172
- if (activeScopes.length === 0 && scopes) {
173
- 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>');
174
- return true;
175
- }
176
- if (!scopes) {
177
- return true;
178
- }
179
- return activeScopes.some(function (scope) {
180
- return scopes.includes(scope);
181
- }) || activeScopes.includes('*');
182
- }
183
- var isHotkeyMatchingKeyboardEvent = function isHotkeyMatchingKeyboardEvent(e, hotkey, ignoreModifiers) {
184
- if (ignoreModifiers === void 0) {
185
- ignoreModifiers = false;
186
- }
187
- var alt = hotkey.alt,
188
- meta = hotkey.meta,
189
- mod = hotkey.mod,
190
- shift = hotkey.shift,
191
- ctrl = hotkey.ctrl,
192
- keys = hotkey.keys;
193
- var pressedKeyUppercase = e.key,
194
- ctrlKey = e.ctrlKey,
195
- metaKey = e.metaKey,
196
- shiftKey = e.shiftKey,
197
- altKey = e.altKey;
198
- var pressedKey = pressedKeyUppercase.toLowerCase();
199
- if (!(keys != null && keys.includes(pressedKey)) && !['ctrl', 'control', 'unknown', 'meta', 'alt', 'shift', 'os'].includes(pressedKey)) {
200
- return false;
201
- }
202
- if (!ignoreModifiers) {
203
- // We check the pressed keys for compatibility with the keyup event. In keyup events the modifier flags are not set.
204
- if (alt === !altKey && pressedKey !== 'alt') {
205
- return false;
206
- }
207
- if (shift === !shiftKey && pressedKey !== 'shift') {
208
- return false;
209
- }
210
- // Mod is a special key name that is checking for meta on macOS and ctrl on other platforms
211
- if (mod) {
212
- if (!metaKey && !ctrlKey) {
213
- return false;
214
- }
215
- } else {
216
- if (meta === !metaKey && pressedKey !== 'meta' && pressedKey !== 'os') {
217
- return false;
218
- }
219
- if (ctrl === !ctrlKey && pressedKey !== 'ctrl' && pressedKey !== 'control') {
220
- return false;
221
- }
222
- }
223
- }
224
- // All modifiers are correct, now check the key
225
- // If the key is set, we check for the key
226
- if (keys && keys.length === 1 && keys.includes(pressedKey)) {
227
- return true;
228
- } else if (keys) {
229
- // Check if all keys are present in pressedDownKeys set
230
- return isHotkeyPressed(keys);
231
- } else if (!keys) {
232
- // If the key is not set, we only listen for modifiers, that check went alright, so we return true
233
- return true;
234
- }
235
- // There is nothing that matches.
236
- return false;
237
- };
238
-
239
- var BoundHotkeysProxyProvider = /*#__PURE__*/createContext(undefined);
240
- var useBoundHotkeysProxy = function useBoundHotkeysProxy() {
241
- return useContext(BoundHotkeysProxyProvider);
242
- };
243
- function BoundHotkeysProxyProviderProvider(_ref) {
244
- var addHotkey = _ref.addHotkey,
245
- removeHotkey = _ref.removeHotkey,
246
- children = _ref.children;
247
- return /*#__PURE__*/jsx(BoundHotkeysProxyProvider.Provider, {
248
- value: {
249
- addHotkey: addHotkey,
250
- removeHotkey: removeHotkey
251
- },
252
- children: children
253
- });
254
- }
255
-
256
- function deepEqual(x, y) {
257
- //@ts-ignore
258
- return x && y && typeof x === 'object' && typeof y === 'object' ? Object.keys(x).length === Object.keys(y).length &&
259
- //@ts-ignore
260
- Object.keys(x).reduce(function (isEqual, key) {
261
- return isEqual && deepEqual(x[key], y[key]);
262
- }, true) : x === y;
263
- }
264
-
265
- var HotkeysContext = /*#__PURE__*/createContext({
266
- hotkeys: [],
267
- activeScopes: [],
268
- toggleScope: function toggleScope() {},
269
- enableScope: function enableScope() {},
270
- disableScope: function disableScope() {}
271
- });
272
- var useHotkeysContext = function useHotkeysContext() {
273
- return useContext(HotkeysContext);
274
- };
275
- var HotkeysProvider = function HotkeysProvider(_ref) {
276
- var _ref$initiallyActiveS = _ref.initiallyActiveScopes,
277
- initiallyActiveScopes = _ref$initiallyActiveS === void 0 ? ['*'] : _ref$initiallyActiveS,
278
- children = _ref.children;
279
- var _useState = useState(initiallyActiveScopes),
280
- internalActiveScopes = _useState[0],
281
- setInternalActiveScopes = _useState[1];
282
- var _useState2 = useState([]),
283
- boundHotkeys = _useState2[0],
284
- setBoundHotkeys = _useState2[1];
285
- var enableScope = useCallback(function (scope) {
286
- setInternalActiveScopes(function (prev) {
287
- if (prev.includes('*')) {
288
- return [scope];
289
- }
290
- return Array.from(new Set([].concat(prev, [scope])));
291
- });
292
- }, []);
293
- var disableScope = useCallback(function (scope) {
294
- setInternalActiveScopes(function (prev) {
295
- return prev.filter(function (s) {
296
- return s !== scope;
297
- });
298
- });
299
- }, []);
300
- var toggleScope = useCallback(function (scope) {
301
- setInternalActiveScopes(function (prev) {
302
- if (prev.includes(scope)) {
303
- return prev.filter(function (s) {
304
- return s !== scope;
305
- });
306
- } else {
307
- if (prev.includes('*')) {
308
- return [scope];
309
- }
310
- return Array.from(new Set([].concat(prev, [scope])));
311
- }
312
- });
313
- }, []);
314
- var addBoundHotkey = useCallback(function (hotkey) {
315
- setBoundHotkeys(function (prev) {
316
- return [].concat(prev, [hotkey]);
317
- });
318
- }, []);
319
- var removeBoundHotkey = useCallback(function (hotkey) {
320
- setBoundHotkeys(function (prev) {
321
- return prev.filter(function (h) {
322
- return !deepEqual(h, hotkey);
323
- });
324
- });
325
- }, []);
326
- return /*#__PURE__*/jsx(HotkeysContext.Provider, {
327
- value: {
328
- activeScopes: internalActiveScopes,
329
- hotkeys: boundHotkeys,
330
- enableScope: enableScope,
331
- disableScope: disableScope,
332
- toggleScope: toggleScope
333
- },
334
- children: /*#__PURE__*/jsx(BoundHotkeysProxyProviderProvider, {
335
- addHotkey: addBoundHotkey,
336
- removeHotkey: removeBoundHotkey,
337
- children: children
338
- })
339
- });
340
- };
341
-
342
- function useDeepEqualMemo(value) {
343
- var ref = useRef(undefined);
344
- if (!deepEqual(ref.current, value)) {
345
- ref.current = value;
346
- }
347
- return ref.current;
348
- }
349
-
350
- var stopPropagation = function stopPropagation(e) {
351
- e.stopPropagation();
352
- e.preventDefault();
353
- e.stopImmediatePropagation();
354
- };
355
- var useSafeLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
356
- function useHotkeys(keys, callback, options, dependencies) {
357
- var ref = useRef(null);
358
- var hasTriggeredRef = useRef(false);
359
- var _options = !(options instanceof Array) ? options : !(dependencies instanceof Array) ? dependencies : undefined;
360
- var _keys = isReadonlyArray(keys) ? keys.join(_options == null ? void 0 : _options.splitKey) : keys;
361
- var _deps = options instanceof Array ? options : dependencies instanceof Array ? dependencies : undefined;
362
- var memoisedCB = useCallback(callback, _deps != null ? _deps : []);
363
- var cbRef = useRef(memoisedCB);
364
- if (_deps) {
365
- cbRef.current = memoisedCB;
366
- } else {
367
- cbRef.current = callback;
368
- }
369
- var memoisedOptions = useDeepEqualMemo(_options);
370
- var _useHotkeysContext = useHotkeysContext(),
371
- activeScopes = _useHotkeysContext.activeScopes;
372
- var proxy = useBoundHotkeysProxy();
373
- useSafeLayoutEffect(function () {
374
- if ((memoisedOptions == null ? void 0 : memoisedOptions.enabled) === false || !isScopeActive(activeScopes, memoisedOptions == null ? void 0 : memoisedOptions.scopes)) {
375
- return;
376
- }
377
- var listener = function listener(e, isKeyUp) {
378
- var _e$target;
379
- if (isKeyUp === void 0) {
380
- isKeyUp = false;
381
- }
382
- if (isKeyboardEventTriggeredByInput(e) && !isHotkeyEnabledOnTag(e, memoisedOptions == null ? void 0 : memoisedOptions.enableOnFormTags)) {
383
- return;
384
- }
385
- // 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
386
- // REF IS THE ACTIVE ELEMENT. THIS IS A PROBLEM SINCE FOCUSED SUB COMPONENTS WON'T TRIGGER THE HOTKEY.
387
- if (ref.current !== null) {
388
- var rootNode = ref.current.getRootNode();
389
- if ((rootNode instanceof Document || rootNode instanceof ShadowRoot) && rootNode.activeElement !== ref.current && !ref.current.contains(rootNode.activeElement)) {
390
- stopPropagation(e);
391
- return;
392
- }
393
- }
394
- if ((_e$target = e.target) != null && _e$target.isContentEditable && !(memoisedOptions != null && memoisedOptions.enableOnContentEditable)) {
395
- return;
396
- }
397
- parseKeysHookInput(_keys, memoisedOptions == null ? void 0 : memoisedOptions.splitKey).forEach(function (key) {
398
- var _hotkey$keys;
399
- var hotkey = parseHotkey(key, memoisedOptions == null ? void 0 : memoisedOptions.combinationKey);
400
- if (isHotkeyMatchingKeyboardEvent(e, hotkey, memoisedOptions == null ? void 0 : memoisedOptions.ignoreModifiers) || (_hotkey$keys = hotkey.keys) != null && _hotkey$keys.includes('*')) {
401
- if (memoisedOptions != null && memoisedOptions.ignoreEventWhen != null && memoisedOptions.ignoreEventWhen(e)) {
402
- return;
403
- }
404
- if (isKeyUp && hasTriggeredRef.current) {
405
- return;
406
- }
407
- maybePreventDefault(e, hotkey, memoisedOptions == null ? void 0 : memoisedOptions.preventDefault);
408
- if (!isHotkeyEnabled(e, hotkey, memoisedOptions == null ? void 0 : memoisedOptions.enabled)) {
409
- stopPropagation(e);
410
- return;
411
- }
412
- // Execute the user callback for that hotkey
413
- cbRef.current(e, hotkey);
414
- if (!isKeyUp) {
415
- hasTriggeredRef.current = true;
416
- }
417
- }
418
- });
419
- };
420
- var handleKeyDown = function handleKeyDown(event) {
421
- if (event.key === undefined) {
422
- // Synthetic event (e.g., Chrome autofill). Ignore.
423
- return;
424
- }
425
- pushToCurrentlyPressedKeys(mapKey(event.key));
426
- if ((memoisedOptions == null ? void 0 : memoisedOptions.keydown) === undefined && (memoisedOptions == null ? void 0 : memoisedOptions.keyup) !== true || memoisedOptions != null && memoisedOptions.keydown) {
427
- listener(event);
428
- }
429
- };
430
- var handleKeyUp = function handleKeyUp(event) {
431
- if (event.key === undefined) {
432
- // Synthetic event (e.g., Chrome autofill). Ignore.
433
- return;
434
- }
435
- removeFromCurrentlyPressedKeys(mapKey(event.key));
436
- hasTriggeredRef.current = false;
437
- if (memoisedOptions != null && memoisedOptions.keyup) {
438
- listener(event, true);
439
- }
440
- };
441
- var domNode = ref.current || (_options == null ? void 0 : _options.document) || document;
442
- // @ts-ignore
443
- domNode.addEventListener('keyup', handleKeyUp);
444
- // @ts-ignore
445
- domNode.addEventListener('keydown', handleKeyDown);
446
- if (proxy) {
447
- parseKeysHookInput(_keys, memoisedOptions == null ? void 0 : memoisedOptions.splitKey).forEach(function (key) {
448
- return proxy.addHotkey(parseHotkey(key, memoisedOptions == null ? void 0 : memoisedOptions.combinationKey, memoisedOptions == null ? void 0 : memoisedOptions.description));
449
- });
450
- }
451
- return function () {
452
- // @ts-ignore
453
- domNode.removeEventListener('keyup', handleKeyUp);
454
- // @ts-ignore
455
- domNode.removeEventListener('keydown', handleKeyDown);
456
- if (proxy) {
457
- parseKeysHookInput(_keys, memoisedOptions == null ? void 0 : memoisedOptions.splitKey).forEach(function (key) {
458
- return proxy.removeHotkey(parseHotkey(key, memoisedOptions == null ? void 0 : memoisedOptions.combinationKey, memoisedOptions == null ? void 0 : memoisedOptions.description));
459
- });
460
- }
461
- };
462
- }, [_keys, memoisedOptions, activeScopes]);
463
- return ref;
464
- }
465
-
466
- function useRecordHotkeys() {
467
- var _useState = useState(new Set()),
468
- keys = _useState[0],
469
- setKeys = _useState[1];
470
- var _useState2 = useState(false),
471
- isRecording = _useState2[0],
472
- setIsRecording = _useState2[1];
473
- var handler = useCallback(function (event) {
474
- if (event.key === undefined) {
475
- // Synthetic event (e.g., Chrome autofill). Ignore.
476
- return;
477
- }
478
- event.preventDefault();
479
- event.stopPropagation();
480
- setKeys(function (prev) {
481
- var newKeys = new Set(prev);
482
- newKeys.add(mapKey(event.key));
483
- return newKeys;
484
- });
485
- }, []);
486
- var stop = useCallback(function () {
487
- if (typeof document !== 'undefined') {
488
- document.removeEventListener('keydown', handler);
489
- setIsRecording(false);
490
- }
491
- }, [handler]);
492
- var start = useCallback(function () {
493
- setKeys(new Set());
494
- if (typeof document !== 'undefined') {
495
- stop();
496
- document.addEventListener('keydown', handler);
497
- setIsRecording(true);
498
- }
499
- }, [handler, stop]);
500
- return [keys, {
501
- start: start,
502
- stop: stop,
503
- isRecording: isRecording
504
- }];
505
- }
506
-
507
- export { HotkeysProvider, isHotkeyPressed, useHotkeys, useHotkeysContext, useRecordHotkeys };
508
- //# sourceMappingURL=react-hotkeys-hook.esm.js.map