react-hotkeys-hook 4.5.0 → 5.0.0-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/HotkeysProvider.d.ts +1 -1
- package/dist/isHotkeyPressed.d.ts +1 -1
- package/dist/parseHotkeys.d.ts +2 -2
- package/dist/react-hotkeys-hook.cjs.development.js +64 -72
- package/dist/react-hotkeys-hook.cjs.development.js.map +1 -1
- package/dist/react-hotkeys-hook.cjs.production.min.js +1 -1
- package/dist/react-hotkeys-hook.cjs.production.min.js.map +1 -1
- package/dist/react-hotkeys-hook.esm.js +64 -72
- package/dist/react-hotkeys-hook.esm.js.map +1 -1
- package/dist/types.d.ts +3 -1
- package/package.json +1 -1
- package/src/HotkeysProvider.tsx +6 -18
- package/src/isHotkeyPressed.ts +8 -8
- package/src/parseHotkeys.ts +11 -16
- package/src/types.ts +29 -13
- package/src/useHotkeys.ts +17 -12
- package/src/useRecordHotkeys.ts +1 -1
- package/src/validators.ts +17 -11
|
@@ -1 +1 @@
|
|
|
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 '.': 'period',\n ',': 'comma',\n '-': 'slash',\n ' ': 'space',\n '`': 'backquote',\n '#': 'backslash',\n '+': 'bracketright',\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] || key)\n .trim()\n .toLowerCase()\n .replace(/key|digit|numpad|arrow/, '')\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 pushToCurrentlyPressedKeys([mapKey(e.key), mapKey(e.code)])\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), mapKey(e.code)])\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'\nimport { mapKey } from './parseHotkeys'\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, code, ctrlKey, metaKey, shiftKey, altKey } = e\n\n const keyCode = mapKey(code)\n const pressedKey = pressedKeyUppercase.toLowerCase()\n\n if (!keys?.includes(keyCode) && !keys?.includes(pressedKey) && !['ctrl', 'control', 'unknown', 'meta', 'alt', 'shift', 'os'].includes(keyCode)) {\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) || keys.includes(keyCode))) {\n return true\n } else if (keys) {\n // Check if all keys are present in pressedDownKeys set\n return isHotkeyPressed(keys)\n } 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 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(\n initiallyActiveScopes?.length > 0 ? initiallyActiveScopes : ['*']\n )\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\n value={{ enabledScopes: 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 { 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, 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 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.code))\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.code))\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, enabledScopes])\n\n return ref\n}\n","import { useRef } from 'react'\nimport deepEqual from './deepEqual'\n\nexport default function useDeepEqualMemo<T>(value: T) {\n const ref = useRef<T | undefined>(undefined)\n\n if (!deepEqual(ref.current, value)) {\n ref.current = value\n }\n\n return ref.current\n}\n","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.code))\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 const resetKeys = useCallback(() => {\n setKeys(new Set<string>())\n }, [])\n\n return [keys, { start, stop, resetKeys, isRecording }] as const\n}\n"],"names":["reservedModifierKeywords","mappedKeys","esc","return",".",",","-"," ","`","#","+","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","pushToCurrentlyPressedKeys","code","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","length","reduce","isEqual","HotkeysContext","hotkeys","enabledScopes","toggleScope","enableScope","disableScope","useHotkeysContext","useContext","stopPropagation","preventDefault","stopImmediatePropagation","useSafeLayoutEffect","useLayoutEffect","useEffect","initiallyActiveScopes","_ref$initiallyActiveS","_useState","useState","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","activeScopes","console","warn","listener","isKeyUp","enableOnFormTags","rootNode","getRootNode","Document","ShadowRoot","activeElement","contains","_e$target","isContentEditable","enableOnContentEditable","ignoreModifiers","pressedKeyUppercase","ctrlKey","metaKey","shiftKey","altKey","keyCode","pressedKey","isHotkeyMatchingKeyboardEvent","_hotkey$keys","ignoreEventWhen","maybePreventDefault","isHotkeyEnabled","handleKeyDown","event","keydown","keyup","handleKeyUp","domNode","removeEventListener","setKeys","isRecording","setIsRecording","handler","newKeys","stop","start","resetKeys"],"mappings":"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"}
|
|
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', 'control']\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 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, delimiter = ','): string[] {\n return keys.toLowerCase().split(delimiter)\n}\n\nexport function parseHotkey(hotkey: string, splitKey = '+', useKey = false, description?: string): Hotkey {\n const keys = hotkey\n .toLocaleLowerCase()\n .split(splitKey)\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 useKey,\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.code === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n pushToCurrentlyPressedKeys([mapKey(e.code)])\n })\n\n document.addEventListener('keyup', (e) => {\n if (e.code === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n removeFromCurrentlyPressedKeys([mapKey(e.code)])\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[], delimiter = ','): boolean {\n const hotkeyArray = isReadonlyArray(key) ? key : key.split(delimiter)\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'\nimport { mapKey } from './parseHotkeys'\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)\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, useKey } = hotkey\n const { code, key: producedKey, ctrlKey, metaKey, shiftKey, altKey } = e\n\n const mappedCode = mapKey(code)\n\n if (useKey && keys?.length === 1 && keys.includes(producedKey)) {\n return true\n }\n\n if (\n !keys?.includes(mappedCode) &&\n !['ctrl', 'control', 'unknown', 'meta', 'alt', 'shift', 'os'].includes(mappedCode)\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 && mappedCode !== 'alt') {\n return false\n }\n\n if (shift !== shiftKey && mappedCode !== '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 && mappedCode !== 'meta' && mappedCode !== 'os') {\n return false\n }\n\n if (ctrl !== ctrlKey && mappedCode !== 'ctrl' && mappedCode !== '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(mappedCode)) {\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?.delimiter) : 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?.delimiter).forEach((key) => {\n const hotkey = parseHotkey(key, memoisedOptions?.splitKey, memoisedOptions?.useKey)\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.code === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n pushToCurrentlyPressedKeys(mapKey(event.code))\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.code === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n removeFromCurrentlyPressedKeys(mapKey(event.code))\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?.delimiter).forEach((key) =>\n proxy.addHotkey(\n parseHotkey(key, memoisedOptions?.splitKey, memoisedOptions?.useKey, memoisedOptions?.description)\n )\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?.delimiter).forEach((key) =>\n proxy.removeHotkey(\n parseHotkey(key, memoisedOptions?.splitKey, memoisedOptions?.useKey, memoisedOptions?.description)\n )\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.code === 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.code))\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 const resetKeys = useCallback(() => {\n setKeys(new Set<string>())\n }, [])\n\n return [keys, { start, stop, resetKeys, isRecording }] as const\n}\n"],"names":["reservedModifierKeywords","mappedKeys","esc","return","left","right","up","down","ShiftLeft","ShiftRight","AltLeft","AltRight","MetaLeft","MetaRight","OSLeft","OSRight","ControlLeft","ControlRight","mapKey","key","trim","toLowerCase","replace","parseKeysHookInput","keys","delimiter","split","parseHotkey","hotkey","splitKey","useKey","description","toLocaleLowerCase","map","k","_extends","alt","includes","ctrl","shift","meta","mod","filter","document","addEventListener","e","undefined","code","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","length","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","console","warn","isScopeActive","listener","isKeyUp","enableOnFormTags","rootNode","getRootNode","Document","ShadowRoot","activeElement","contains","_e$target","isContentEditable","enableOnContentEditable","ignoreModifiers","producedKey","ctrlKey","metaKey","shiftKey","altKey","mappedCode","isHotkeyMatchingKeyboardEvent","_hotkey$keys","ignoreEventWhen","maybePreventDefault","isHotkeyEnabled","handleKeyDown","event","keydown","keyup","handleKeyUp","domNode","removeEventListener","setKeys","isRecording","setIsRecording","handler","newKeys","stop","start","resetKeys"],"mappings":"sSAEA,IAAMA,EAA2B,CAAC,QAAS,MAAO,OAAQ,MAAO,OAAQ,WAEnEC,EAAqC,CACzCC,IAAK,SACLC,OAAQ,QACRC,KAAM,YACNC,MAAO,aACPC,GAAI,UACJC,KAAM,YACNC,UAAW,QACXC,WAAY,QACZC,QAAS,MACTC,SAAU,MACVC,SAAU,OACVC,UAAW,OACXC,OAAQ,OACRC,QAAS,OACTC,YAAa,OACbC,aAAc,iBAGAC,EAAOC,GACrB,OAAQlB,EAAWkB,EAAIC,SAAWD,EAAIC,QAAQC,cAAcC,QAAQ,mBAAoB,aAO1EC,EAAmBC,EAAcC,GAC/C,gBAD+CA,IAAAA,EAAY,KACpDD,EAAKH,cAAcK,MAAMD,YAGlBE,EAAYC,EAAgBC,EAAgBC,EAAgBC,YAAhCF,IAAAA,EAAW,cAAKC,IAAAA,GAAS,GACnE,IAAMN,EAAOI,EACVI,oBACAN,MAAMG,GACNI,KAAI,SAACC,GAAC,OAAKhB,EAAOgB,MAarB,OAAAC,KAXqC,CACnCC,IAAKZ,EAAKa,SAAS,OACnBC,KAAMd,EAAKa,SAAS,SAAWb,EAAKa,SAAS,WAC7CE,MAAOf,EAAKa,SAAS,SACrBG,KAAMhB,EAAKa,SAAS,QACpBI,IAAKjB,EAAKa,SAAS,OACnBP,OAAAA,IAOAN,KAJqBA,EAAKkB,QAAO,SAACR,GAAC,OAAMlC,EAAyBqC,SAASH,MAK3EH,YAAAA,ICrDsB,oBAAbY,WACTA,SAASC,iBAAiB,WAAW,SAACC,QACrBC,IAAXD,EAAEE,MAKNC,EAA2B,CAAC9B,EAAO2B,EAAEE,WAGvCJ,SAASC,iBAAiB,SAAS,SAACC,QACnBC,IAAXD,EAAEE,MAKNE,EAA+B,CAAC/B,EAAO2B,EAAEE,YAIvB,oBAAXG,QACTA,OAAON,iBAAiB,QAAQ,WAC9BO,EAAqBC,WAK3B,IAAMD,EAAoC,IAAIE,aAG9BC,EAAgBC,GAC9B,OAAOC,MAAMC,QAAQF,YAGPG,EAAgBvC,EAAiCM,GAG/D,gBAH+DA,IAAAA,EAAY,MACvD6B,EAAgBnC,GAAOA,EAAMA,EAAIO,MAAMD,IAExCkC,OAAM,SAAC/B,GAAM,OAAKuB,EAAqBS,IAAIhC,EAAOR,OAAOC,2BAG9D2B,EAA2B7B,GACzC,IAAM0C,EAAcL,MAAMC,QAAQtC,GAAOA,EAAM,CAACA,GAO5CgC,EAAqBS,IAAI,SAC3BT,EAAqBW,SAAQ,SAAC3C,GAAG,gBDxBJA,GAC/B,OAAOnB,EAAyBqC,SAASlB,GCuBA4C,CAAiB5C,IAAQgC,SAA4BhC,EAAIE,kBAGlGwC,EAAYC,SAAQ,SAAClC,GAAM,OAAKuB,EAAqBa,IAAIpC,EAAOP,2BAGlD4B,EAA+B9B,GAC7C,IAAM0C,EAAcL,MAAMC,QAAQtC,GAAOA,EAAM,CAACA,GAOpC,SAARA,EACFgC,EAAqBC,QAErBS,EAAYC,SAAQ,SAAClC,GAAM,OAAKuB,SAA4BvB,EAAOP,2BC9CvD4C,EAAoBC,EAElCC,OADEC,EAAMF,EAANE,gBACFD,IAAAA,GAA+C,GAE/C,IAAME,EAAgBD,GAAWA,EAAuBE,QAExD,OAAIhB,EAAgBa,GACXI,QACLF,GAAiBF,GAAiBA,EAAcK,MAAK,SAACC,GAAG,OAAKA,EAAIpD,gBAAkBgD,EAAchD,kBAI/FkD,QAAQF,GAAiBF,GAAiBA,GAmBnD,IC7CMO,EAA4BC,qBAAyD7B,YAYnE8B,EAAiCV,GACvD,OACEW,MAACH,EAA0BI,UAASvB,MAAO,CAAEwB,UAFoBb,EAATa,UAEAC,aAFuBd,EAAZc,cAEIC,SAFkBf,EAARe,oBCpB7DC,EAAUC,EAAQC,GAExC,OAAOD,GAAKC,GAAkB,iBAAND,GAA+B,iBAANC,EAC7CC,OAAO7D,KAAK2D,GAAGG,SAAWD,OAAO7D,KAAK4D,GAAGE,QAEvCD,OAAO7D,KAAK2D,GAAGI,QAAO,SAACC,EAASrE,GAAG,OAAKqE,GAAWN,EAAUC,EAAEhE,GAAMiE,EAAEjE,OAAO,GAChFgE,IAAMC,ECQZ,IAAMK,EAAiBd,gBAAkC,CACvDe,QAAS,GACTC,aAAc,GACdC,YAAa,aACbC,YAAa,aACbC,aAAc,eAGHC,EAAoB,WAC/B,OAAOC,aAAWP,ICPdQ,EAAkB,SAACpD,GACvBA,EAAEoD,kBACFpD,EAAEqD,iBACFrD,EAAEsD,4BAGEC,EAAwC,oBAAXlD,OAAyBmD,kBAAkBC,oCDS/C,SAAHpC,WAAMqC,sBAA+BtB,EAAQf,EAARe,SAC/DuB,EAAwDC,oBADHC,EAAG,CAAC,KAAIA,GACtDC,EAAoBH,KAAEI,EAAuBJ,KACpDK,EAAwCJ,WAAmB,IAApDK,EAAYD,KAAEE,EAAeF,KAE9BhB,EAAcmB,eAAY,SAACC,GAC/BL,GAAwB,SAACM,GACvB,OAAIA,EAAK7E,SAAS,KACT,CAAC4E,GAEHzD,MAAM2D,KAAK,IAAI9D,OAAG+D,OAAKF,GAAMD,WAErC,IAEGnB,EAAekB,eAAY,SAACC,GAChCL,GAAwB,SAACM,GACvB,OAAOA,EAAKxE,QAAO,SAAC2E,GAAC,OAAKA,IAAMJ,UAEjC,IAEGrB,EAAcoB,eAAY,SAACC,GAC/BL,GAAwB,SAACM,GACvB,OAAIA,EAAK7E,SAAS4E,GACTC,EAAKxE,QAAO,SAAC2E,GAAC,OAAKA,IAAMJ,KAE5BC,EAAK7E,SAAS,KACT,CAAC4E,GAEHzD,MAAM2D,KAAK,IAAI9D,OAAG+D,OAAKF,GAAMD,WAGvC,IAEGK,EAAiBN,eAAY,SAACpF,GAClCmF,GAAgB,SAACG,GAAI,SAAAE,OAASF,GAAMtF,SACnC,IAEG2F,EAAoBP,eAAY,SAACpF,GACrCmF,GAAgB,SAACG,GAAI,OAAKA,EAAKxE,QAAO,SAAC8E,GAAC,OAAMtC,EAAUsC,EAAG5F,WAC1D,IAEH,OACEiD,MAACY,EAAeX,UACdvB,MAAO,CAAEoC,aAAcgB,EAAsBjB,QAASoB,EAAcjB,YAAAA,EAAaC,aAAAA,EAAcF,YAAAA,GAAcX,SAE7GJ,MAACD,GAAkCG,UAAWuC,EAAgBtC,aAAcuC,EAAkBtC,SAC3FA,oDCpDT,SACEzD,EACAiG,EACAC,EACAC,GAEA,IAAMC,EAAMC,SAAmB,MACzBC,EAAkBD,UAAO,GAEzBE,EAAkCL,aAAmBlE,MAErDmE,aAAwBnE,WAE1BV,EADC6E,EAFAD,EAICM,EAAgB1E,EAAgB9B,GAAQA,EAAKyG,WAAKF,SAAAA,EAAUtG,WAAaD,EACzE0G,EACJR,aAAmBlE,MAAQkE,EAAUC,aAAwBnE,MAAQmE,OAAe7E,EAEhFqF,EAAanB,cAAYS,QAAUS,EAAAA,EAAS,IAC5CE,EAAQP,SAAuBM,GAGnCC,EAAMC,QADJH,EACcC,EAEAV,EAGlB,IAAMa,WChDoC/E,GAC1C,IAAMqE,EAAMC,cAAsB/E,GAMlC,OAJKoC,EAAU0C,EAAIS,QAAS9E,KAC1BqE,EAAIS,QAAU9E,GAGTqE,EAAIS,QDyCaE,CAAiBR,GAEjCpC,EAAiBI,IAAjBJ,aACF6C,EH3CCxC,aAAWtB,GGmKlB,OAtHA0B,GAAoB,WAClB,IAAiC,WAA7BkC,SAAAA,EAAiBG,mBJpBK9C,EAAwB+C,GACpD,OAA4B,IAAxB/C,EAAaL,QAAgBoD,GAC/BC,QAAQC,KACN,8KAGK,IAGJF,GAIE/C,EAAanB,MAAK,SAACyC,GAAK,OAAKyB,EAAOrG,SAAS4E,OAAWtB,EAAatD,SAAS,KIOxCwG,CAAclD,QAAc2C,SAAAA,EAAiBI,QAAxF,CAIA,IAAMI,EAAW,SAACjG,EAAkBkG,SAClC,YADkCA,IAAAA,GAAU,IJ1CzC9E,EI2CiCpB,EJ3CR,CAAC,QAAS,WAAY,YI2CPoB,EAAqBpB,QAAGyF,SAAAA,EAAiBU,kBAApF,CAMA,GAAoB,OAAhBpB,EAAIS,QAAkB,CACxB,IAAMY,EAAWrB,EAAIS,QAAQa,cAE7B,IACGD,aAAoBE,UAAYF,aAAoBG,aACrDH,EAASI,gBAAkBzB,EAAIS,UAC9BT,EAAIS,QAAQiB,SAASL,EAASI,eAG/B,YADApD,EAAgBpD,WAKf0G,EAAA1G,EAAEuB,UAAFmF,EAA0BC,yBAAsBlB,GAAAA,EAAiBmB,0BAItElI,EAAmByG,QAAOM,SAAAA,EAAiB7G,WAAWqC,SAAQ,SAAC3C,SACvDS,EAASD,EAAYR,QAAKmH,SAAAA,EAAiBzG,eAAUyG,SAAAA,EAAiBxG,QAE5E,GJnCqC,SAACe,EAAkBjB,EAAgB8H,YAAAA,IAAAA,GAAkB,GAChG,IAAQtH,EAA8CR,EAA9CQ,IAAKI,EAAyCZ,EAAzCY,KAAMC,EAAmCb,EAAnCa,IAAKF,EAA8BX,EAA9BW,MAAOD,EAAuBV,EAAvBU,KAAMd,EAAiBI,EAAjBJ,KAAMM,EAAWF,EAAXE,OACxB6H,EAAoD9G,EAAzD1B,IAAkByI,EAAuC/G,EAAvC+G,QAASC,EAA8BhH,EAA9BgH,QAASC,EAAqBjH,EAArBiH,SAAUC,EAAWlH,EAAXkH,OAEtDC,EAAa9I,EAFoD2B,EAA/DE,MAIR,GAAIjB,GAA2B,WAAjBN,SAAAA,EAAM8D,SAAgB9D,EAAKa,SAASsH,GAChD,OAAO,EAGT,WACGnI,GAAAA,EAAMa,SAAS2H,IACf,CAAC,OAAQ,UAAW,UAAW,OAAQ,MAAO,QAAS,MAAM3H,SAAS2H,IAEvE,OAAO,EAGT,IAAKN,EAAiB,CAEpB,GAAItH,IAAQ2H,GAAyB,QAAfC,EACpB,OAAO,EAGT,GAAIzH,IAAUuH,GAA2B,UAAfE,EACxB,OAAO,EAIT,GAAIvH,GACF,IAAKoH,IAAYD,EACf,OAAO,MAEJ,CACL,GAAIpH,IAASqH,GAA0B,SAAfG,GAAwC,OAAfA,EAC/C,OAAO,EAGT,GAAI1H,IAASsH,GAA0B,SAAfI,GAAwC,YAAfA,EAC/C,OAAO,GAOb,SAAIxI,GAAwB,IAAhBA,EAAK8D,SAAgB9D,EAAKa,SAAS2H,MAEpCxI,EAEFkC,EAAgBlC,IACbA,GIfFyI,CAA8BpH,EAAGjB,QAAQ0G,SAAAA,EAAiBoB,yBAAgBQ,EAAItI,EAAOJ,OAAP0I,EAAa7H,SAAS,KAAM,CAC5G,SAAIiG,SAAAA,EAAiB6B,iBAAjB7B,EAAiB6B,gBAAkBtH,GACrC,OAGF,GAAIkG,GAAWjB,EAAgBO,QAC7B,OAKF,YJ/F0BxF,EAAkBjB,EAAgBsE,IACrC,mBAAnBA,GAAiCA,EAAerD,EAAGjB,KAA+B,IAAnBsE,IACzErD,EAAEqD,iBI2FIkE,CAAoBvH,EAAGjB,QAAQ0G,SAAAA,EAAiBpC,iBJvF1D,SAAgCrD,EAAkBjB,EAAgB6G,GAChE,MAAuB,mBAAZA,EACFA,EAAQ5F,EAAGjB,IAGD,IAAZ6G,QAAgC3F,IAAZ2F,EIoFd4B,CAAgBxH,EAAGjB,QAAQ0G,SAAAA,EAAiBG,SAG/C,YAFAxC,EAAgBpD,GAMlBuF,EAAMC,QAAQxF,EAAGjB,GAEZmH,IACHjB,EAAgBO,SAAU,SAM5BiC,EAAgB,SAACC,QACFzH,IAAfyH,EAAMxH,OAKVC,EAA2B9B,EAAOqJ,EAAMxH,aAEND,WAA7BwF,SAAAA,EAAiBkC,WAAoD,WAA3BlC,SAAAA,EAAiBmC,cAAmBnC,GAAAA,EAAiBkC,UAClG1B,EAASyB,KAIPG,EAAc,SAACH,QACAzH,IAAfyH,EAAMxH,OAKVE,EAA+B/B,EAAOqJ,EAAMxH,OAE5C+E,EAAgBO,SAAU,QAEtBC,GAAAA,EAAiBmC,OACnB3B,EAASyB,GAAO,KAIdI,EAAU/C,EAAIS,gBAAWN,SAAAA,EAAUpF,WAAYA,SAerD,OAZAgI,EAAQ/H,iBAAiB,QAAS8H,GAElCC,EAAQ/H,iBAAiB,UAAW0H,GAEhC9B,GACFjH,EAAmByG,QAAOM,SAAAA,EAAiB7G,WAAWqC,SAAQ,SAAC3C,GAAG,OAChEqH,EAAMzD,UACJpD,EAAYR,QAAKmH,SAAAA,EAAiBzG,eAAUyG,SAAAA,EAAiBxG,aAAQwG,SAAAA,EAAiBvG,iBAKrF,WAEL4I,EAAQC,oBAAoB,QAASF,GAErCC,EAAQC,oBAAoB,UAAWN,GAEnC9B,GACFjH,EAAmByG,QAAOM,SAAAA,EAAiB7G,WAAWqC,SAAQ,SAAC3C,GAAG,OAChEqH,EAAMxD,aACJrD,EAAYR,QAAKmH,SAAAA,EAAiBzG,eAAUyG,SAAAA,EAAiBxG,aAAQwG,SAAAA,EAAiBvG,qBAK7F,CAACiG,EAAOM,EAAiB3C,IAErBiC,mEE1KP,IAAApB,EAAwBC,WAAS,IAAIpD,KAA9B7B,EAAIgF,KAAEqE,EAAOrE,KACpBK,EAAsCJ,YAAS,GAAxCqE,EAAWjE,KAAEkE,EAAclE,KAE5BmE,EAAUhE,eAAY,SAACuD,QACRzH,IAAfyH,EAAMxH,OAKVwH,EAAMrE,iBACNqE,EAAMtE,kBAEN4E,GAAQ,SAAC3D,GACP,IAAM+D,EAAU,IAAI5H,IAAI6D,GAIxB,OAFA+D,EAAQjH,IAAI9C,EAAOqJ,EAAMxH,OAElBkI,QAER,IAEGC,EAAOlE,eAAY,WACC,oBAAbrE,WACTA,SAASiI,oBAAoB,UAAWI,GAExCD,GAAe,MAEhB,CAACC,IAEEG,EAAQnE,eAAY,WACxB6D,EAAQ,IAAIxH,KAEY,oBAAbV,WACTuI,IAEAvI,SAASC,iBAAiB,UAAWoI,GAErCD,GAAe,MAEhB,CAACC,EAASE,IAEPE,EAAYpE,eAAY,WAC5B6D,EAAQ,IAAIxH,OACX,IAEH,MAAO,CAAC7B,EAAM,CAAE2J,MAAAA,EAAOD,KAAAA,EAAME,UAAAA,EAAWN,YAAAA"}
|
|
@@ -16,17 +16,14 @@ function _extends() {
|
|
|
16
16
|
return _extends.apply(this, arguments);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
var reservedModifierKeywords = ['shift', 'alt', 'meta', 'mod', 'ctrl'];
|
|
19
|
+
var reservedModifierKeywords = ['shift', 'alt', 'meta', 'mod', 'ctrl', 'control'];
|
|
20
20
|
var mappedKeys = {
|
|
21
21
|
esc: 'escape',
|
|
22
22
|
"return": 'enter',
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
'`': 'backquote',
|
|
28
|
-
'#': 'backslash',
|
|
29
|
-
'+': 'bracketright',
|
|
23
|
+
left: 'arrowleft',
|
|
24
|
+
right: 'arrowright',
|
|
25
|
+
up: 'arrowup',
|
|
26
|
+
down: 'arrowdown',
|
|
30
27
|
ShiftLeft: 'shift',
|
|
31
28
|
ShiftRight: 'shift',
|
|
32
29
|
AltLeft: 'alt',
|
|
@@ -39,22 +36,25 @@ var mappedKeys = {
|
|
|
39
36
|
ControlRight: 'ctrl'
|
|
40
37
|
};
|
|
41
38
|
function mapKey(key) {
|
|
42
|
-
return (mappedKeys[key] || key
|
|
39
|
+
return (mappedKeys[key.trim()] || key.trim()).toLowerCase().replace(/key|digit|numpad/, '');
|
|
43
40
|
}
|
|
44
41
|
function isHotkeyModifier(key) {
|
|
45
42
|
return reservedModifierKeywords.includes(key);
|
|
46
43
|
}
|
|
47
|
-
function parseKeysHookInput(keys,
|
|
48
|
-
if (
|
|
49
|
-
|
|
44
|
+
function parseKeysHookInput(keys, delimiter) {
|
|
45
|
+
if (delimiter === void 0) {
|
|
46
|
+
delimiter = ',';
|
|
50
47
|
}
|
|
51
|
-
return keys.split(
|
|
48
|
+
return keys.toLowerCase().split(delimiter);
|
|
52
49
|
}
|
|
53
|
-
function parseHotkey(hotkey,
|
|
54
|
-
if (
|
|
55
|
-
|
|
50
|
+
function parseHotkey(hotkey, splitKey, useKey, description) {
|
|
51
|
+
if (splitKey === void 0) {
|
|
52
|
+
splitKey = '+';
|
|
53
|
+
}
|
|
54
|
+
if (useKey === void 0) {
|
|
55
|
+
useKey = false;
|
|
56
56
|
}
|
|
57
|
-
var keys = hotkey.toLocaleLowerCase().split(
|
|
57
|
+
var keys = hotkey.toLocaleLowerCase().split(splitKey).map(function (k) {
|
|
58
58
|
return mapKey(k);
|
|
59
59
|
});
|
|
60
60
|
var modifiers = {
|
|
@@ -62,7 +62,8 @@ function parseHotkey(hotkey, combinationKey, description) {
|
|
|
62
62
|
ctrl: keys.includes('ctrl') || keys.includes('control'),
|
|
63
63
|
shift: keys.includes('shift'),
|
|
64
64
|
meta: keys.includes('meta'),
|
|
65
|
-
mod: keys.includes('mod')
|
|
65
|
+
mod: keys.includes('mod'),
|
|
66
|
+
useKey: useKey
|
|
66
67
|
};
|
|
67
68
|
var singleCharKeys = keys.filter(function (k) {
|
|
68
69
|
return !reservedModifierKeywords.includes(k);
|
|
@@ -76,18 +77,18 @@ function parseHotkey(hotkey, combinationKey, description) {
|
|
|
76
77
|
(function () {
|
|
77
78
|
if (typeof document !== 'undefined') {
|
|
78
79
|
document.addEventListener('keydown', function (e) {
|
|
79
|
-
if (e.
|
|
80
|
-
// Synthetic event (e.g., Chrome autofill).
|
|
80
|
+
if (e.code === undefined) {
|
|
81
|
+
// Synthetic event (e.g., Chrome autofill). Ignore.
|
|
81
82
|
return;
|
|
82
83
|
}
|
|
83
|
-
pushToCurrentlyPressedKeys([mapKey(e.
|
|
84
|
+
pushToCurrentlyPressedKeys([mapKey(e.code)]);
|
|
84
85
|
});
|
|
85
86
|
document.addEventListener('keyup', function (e) {
|
|
86
|
-
if (e.
|
|
87
|
-
// Synthetic event (e.g., Chrome autofill).
|
|
87
|
+
if (e.code === undefined) {
|
|
88
|
+
// Synthetic event (e.g., Chrome autofill). Ignore.
|
|
88
89
|
return;
|
|
89
90
|
}
|
|
90
|
-
removeFromCurrentlyPressedKeys([mapKey(e.
|
|
91
|
+
removeFromCurrentlyPressedKeys([mapKey(e.code)]);
|
|
91
92
|
});
|
|
92
93
|
}
|
|
93
94
|
if (typeof window !== 'undefined') {
|
|
@@ -101,11 +102,11 @@ var currentlyPressedKeys = /*#__PURE__*/new Set();
|
|
|
101
102
|
function isReadonlyArray(value) {
|
|
102
103
|
return Array.isArray(value);
|
|
103
104
|
}
|
|
104
|
-
function isHotkeyPressed(key,
|
|
105
|
-
if (
|
|
106
|
-
|
|
105
|
+
function isHotkeyPressed(key, delimiter) {
|
|
106
|
+
if (delimiter === void 0) {
|
|
107
|
+
delimiter = ',';
|
|
107
108
|
}
|
|
108
|
-
var hotkeyArray = isReadonlyArray(key) ? key : key.split(
|
|
109
|
+
var hotkeyArray = isReadonlyArray(key) ? key : key.split(delimiter);
|
|
109
110
|
return hotkeyArray.every(function (hotkey) {
|
|
110
111
|
return currentlyPressedKeys.has(hotkey.trim().toLowerCase());
|
|
111
112
|
});
|
|
@@ -167,7 +168,7 @@ function isHotkeyEnabledOnTag(_ref, enabledOnTags) {
|
|
|
167
168
|
return tag.toLowerCase() === targetTagName.toLowerCase();
|
|
168
169
|
}));
|
|
169
170
|
}
|
|
170
|
-
return Boolean(targetTagName && enabledOnTags && enabledOnTags
|
|
171
|
+
return Boolean(targetTagName && enabledOnTags && enabledOnTags);
|
|
171
172
|
}
|
|
172
173
|
function isScopeActive(activeScopes, scopes) {
|
|
173
174
|
if (activeScopes.length === 0 && scopes) {
|
|
@@ -190,24 +191,27 @@ var isHotkeyMatchingKeyboardEvent = function isHotkeyMatchingKeyboardEvent(e, ho
|
|
|
190
191
|
mod = hotkey.mod,
|
|
191
192
|
shift = hotkey.shift,
|
|
192
193
|
ctrl = hotkey.ctrl,
|
|
193
|
-
keys = hotkey.keys
|
|
194
|
-
|
|
195
|
-
|
|
194
|
+
keys = hotkey.keys,
|
|
195
|
+
useKey = hotkey.useKey;
|
|
196
|
+
var code = e.code,
|
|
197
|
+
producedKey = e.key,
|
|
196
198
|
ctrlKey = e.ctrlKey,
|
|
197
199
|
metaKey = e.metaKey,
|
|
198
200
|
shiftKey = e.shiftKey,
|
|
199
201
|
altKey = e.altKey;
|
|
200
|
-
var
|
|
201
|
-
|
|
202
|
-
|
|
202
|
+
var mappedCode = mapKey(code);
|
|
203
|
+
if (useKey && (keys == null ? void 0 : keys.length) === 1 && keys.includes(producedKey)) {
|
|
204
|
+
return true;
|
|
205
|
+
}
|
|
206
|
+
if (!(keys != null && keys.includes(mappedCode)) && !['ctrl', 'control', 'unknown', 'meta', 'alt', 'shift', 'os'].includes(mappedCode)) {
|
|
203
207
|
return false;
|
|
204
208
|
}
|
|
205
209
|
if (!ignoreModifiers) {
|
|
206
210
|
// We check the pressed keys for compatibility with the keyup event. In keyup events the modifier flags are not set.
|
|
207
|
-
if (alt
|
|
211
|
+
if (alt !== altKey && mappedCode !== 'alt') {
|
|
208
212
|
return false;
|
|
209
213
|
}
|
|
210
|
-
if (shift
|
|
214
|
+
if (shift !== shiftKey && mappedCode !== 'shift') {
|
|
211
215
|
return false;
|
|
212
216
|
}
|
|
213
217
|
// Mod is a special key name that is checking for meta on macOS and ctrl on other platforms
|
|
@@ -216,17 +220,17 @@ var isHotkeyMatchingKeyboardEvent = function isHotkeyMatchingKeyboardEvent(e, ho
|
|
|
216
220
|
return false;
|
|
217
221
|
}
|
|
218
222
|
} else {
|
|
219
|
-
if (meta
|
|
223
|
+
if (meta !== metaKey && mappedCode !== 'meta' && mappedCode !== 'os') {
|
|
220
224
|
return false;
|
|
221
225
|
}
|
|
222
|
-
if (ctrl
|
|
226
|
+
if (ctrl !== ctrlKey && mappedCode !== 'ctrl' && mappedCode !== 'control') {
|
|
223
227
|
return false;
|
|
224
228
|
}
|
|
225
229
|
}
|
|
226
230
|
}
|
|
227
231
|
// All modifiers are correct, now check the key
|
|
228
232
|
// If the key is set, we check for the key
|
|
229
|
-
if (keys && keys.length === 1 &&
|
|
233
|
+
if (keys && keys.length === 1 && keys.includes(mappedCode)) {
|
|
230
234
|
return true;
|
|
231
235
|
} else if (keys) {
|
|
232
236
|
// Check if all keys are present in pressedDownKeys set
|
|
@@ -267,7 +271,7 @@ function deepEqual(x, y) {
|
|
|
267
271
|
|
|
268
272
|
var HotkeysContext = /*#__PURE__*/createContext({
|
|
269
273
|
hotkeys: [],
|
|
270
|
-
|
|
274
|
+
activeScopes: [],
|
|
271
275
|
toggleScope: function toggleScope() {},
|
|
272
276
|
enableScope: function enableScope() {},
|
|
273
277
|
disableScope: function disableScope() {}
|
|
@@ -279,7 +283,7 @@ var HotkeysProvider = function HotkeysProvider(_ref) {
|
|
|
279
283
|
var _ref$initiallyActiveS = _ref.initiallyActiveScopes,
|
|
280
284
|
initiallyActiveScopes = _ref$initiallyActiveS === void 0 ? ['*'] : _ref$initiallyActiveS,
|
|
281
285
|
children = _ref.children;
|
|
282
|
-
var _useState = useState(
|
|
286
|
+
var _useState = useState(initiallyActiveScopes),
|
|
283
287
|
internalActiveScopes = _useState[0],
|
|
284
288
|
setInternalActiveScopes = _useState[1];
|
|
285
289
|
var _useState2 = useState([]),
|
|
@@ -295,29 +299,17 @@ var HotkeysProvider = function HotkeysProvider(_ref) {
|
|
|
295
299
|
}, []);
|
|
296
300
|
var disableScope = useCallback(function (scope) {
|
|
297
301
|
setInternalActiveScopes(function (prev) {
|
|
298
|
-
|
|
302
|
+
return prev.filter(function (s) {
|
|
299
303
|
return s !== scope;
|
|
300
|
-
})
|
|
301
|
-
return ['*'];
|
|
302
|
-
} else {
|
|
303
|
-
return prev.filter(function (s) {
|
|
304
|
-
return s !== scope;
|
|
305
|
-
});
|
|
306
|
-
}
|
|
304
|
+
});
|
|
307
305
|
});
|
|
308
306
|
}, []);
|
|
309
307
|
var toggleScope = useCallback(function (scope) {
|
|
310
308
|
setInternalActiveScopes(function (prev) {
|
|
311
309
|
if (prev.includes(scope)) {
|
|
312
|
-
|
|
310
|
+
return prev.filter(function (s) {
|
|
313
311
|
return s !== scope;
|
|
314
|
-
})
|
|
315
|
-
return ['*'];
|
|
316
|
-
} else {
|
|
317
|
-
return prev.filter(function (s) {
|
|
318
|
-
return s !== scope;
|
|
319
|
-
});
|
|
320
|
-
}
|
|
312
|
+
});
|
|
321
313
|
} else {
|
|
322
314
|
if (prev.includes('*')) {
|
|
323
315
|
return [scope];
|
|
@@ -340,7 +332,7 @@ var HotkeysProvider = function HotkeysProvider(_ref) {
|
|
|
340
332
|
}, []);
|
|
341
333
|
return /*#__PURE__*/jsx(HotkeysContext.Provider, {
|
|
342
334
|
value: {
|
|
343
|
-
|
|
335
|
+
activeScopes: internalActiveScopes,
|
|
344
336
|
hotkeys: boundHotkeys,
|
|
345
337
|
enableScope: enableScope,
|
|
346
338
|
disableScope: disableScope,
|
|
@@ -372,7 +364,7 @@ function useHotkeys(keys, callback, options, dependencies) {
|
|
|
372
364
|
var ref = useRef(null);
|
|
373
365
|
var hasTriggeredRef = useRef(false);
|
|
374
366
|
var _options = !(options instanceof Array) ? options : !(dependencies instanceof Array) ? dependencies : undefined;
|
|
375
|
-
var _keys = isReadonlyArray(keys) ? keys.join(_options == null ? void 0 : _options.
|
|
367
|
+
var _keys = isReadonlyArray(keys) ? keys.join(_options == null ? void 0 : _options.delimiter) : keys;
|
|
376
368
|
var _deps = options instanceof Array ? options : dependencies instanceof Array ? dependencies : undefined;
|
|
377
369
|
var memoisedCB = useCallback(callback, _deps != null ? _deps : []);
|
|
378
370
|
var cbRef = useRef(memoisedCB);
|
|
@@ -383,10 +375,10 @@ function useHotkeys(keys, callback, options, dependencies) {
|
|
|
383
375
|
}
|
|
384
376
|
var memoisedOptions = useDeepEqualMemo(_options);
|
|
385
377
|
var _useHotkeysContext = useHotkeysContext(),
|
|
386
|
-
|
|
378
|
+
activeScopes = _useHotkeysContext.activeScopes;
|
|
387
379
|
var proxy = useBoundHotkeysProxy();
|
|
388
380
|
useSafeLayoutEffect(function () {
|
|
389
|
-
if ((memoisedOptions == null ? void 0 : memoisedOptions.enabled) === false || !isScopeActive(
|
|
381
|
+
if ((memoisedOptions == null ? void 0 : memoisedOptions.enabled) === false || !isScopeActive(activeScopes, memoisedOptions == null ? void 0 : memoisedOptions.scopes)) {
|
|
390
382
|
return;
|
|
391
383
|
}
|
|
392
384
|
var listener = function listener(e, isKeyUp) {
|
|
@@ -409,9 +401,9 @@ function useHotkeys(keys, callback, options, dependencies) {
|
|
|
409
401
|
if ((_e$target = e.target) != null && _e$target.isContentEditable && !(memoisedOptions != null && memoisedOptions.enableOnContentEditable)) {
|
|
410
402
|
return;
|
|
411
403
|
}
|
|
412
|
-
parseKeysHookInput(_keys, memoisedOptions == null ? void 0 : memoisedOptions.
|
|
404
|
+
parseKeysHookInput(_keys, memoisedOptions == null ? void 0 : memoisedOptions.delimiter).forEach(function (key) {
|
|
413
405
|
var _hotkey$keys;
|
|
414
|
-
var hotkey = parseHotkey(key, memoisedOptions == null ? void 0 : memoisedOptions.
|
|
406
|
+
var hotkey = parseHotkey(key, memoisedOptions == null ? void 0 : memoisedOptions.splitKey, memoisedOptions == null ? void 0 : memoisedOptions.useKey);
|
|
415
407
|
if (isHotkeyMatchingKeyboardEvent(e, hotkey, memoisedOptions == null ? void 0 : memoisedOptions.ignoreModifiers) || (_hotkey$keys = hotkey.keys) != null && _hotkey$keys.includes('*')) {
|
|
416
408
|
if (memoisedOptions != null && memoisedOptions.ignoreEventWhen != null && memoisedOptions.ignoreEventWhen(e)) {
|
|
417
409
|
return;
|
|
@@ -433,7 +425,7 @@ function useHotkeys(keys, callback, options, dependencies) {
|
|
|
433
425
|
});
|
|
434
426
|
};
|
|
435
427
|
var handleKeyDown = function handleKeyDown(event) {
|
|
436
|
-
if (event.
|
|
428
|
+
if (event.code === undefined) {
|
|
437
429
|
// Synthetic event (e.g., Chrome autofill). Ignore.
|
|
438
430
|
return;
|
|
439
431
|
}
|
|
@@ -443,7 +435,7 @@ function useHotkeys(keys, callback, options, dependencies) {
|
|
|
443
435
|
}
|
|
444
436
|
};
|
|
445
437
|
var handleKeyUp = function handleKeyUp(event) {
|
|
446
|
-
if (event.
|
|
438
|
+
if (event.code === undefined) {
|
|
447
439
|
// Synthetic event (e.g., Chrome autofill). Ignore.
|
|
448
440
|
return;
|
|
449
441
|
}
|
|
@@ -459,8 +451,8 @@ function useHotkeys(keys, callback, options, dependencies) {
|
|
|
459
451
|
// @ts-ignore
|
|
460
452
|
domNode.addEventListener('keydown', handleKeyDown);
|
|
461
453
|
if (proxy) {
|
|
462
|
-
parseKeysHookInput(_keys, memoisedOptions == null ? void 0 : memoisedOptions.
|
|
463
|
-
return proxy.addHotkey(parseHotkey(key, memoisedOptions == null ? void 0 : memoisedOptions.
|
|
454
|
+
parseKeysHookInput(_keys, memoisedOptions == null ? void 0 : memoisedOptions.delimiter).forEach(function (key) {
|
|
455
|
+
return proxy.addHotkey(parseHotkey(key, memoisedOptions == null ? void 0 : memoisedOptions.splitKey, memoisedOptions == null ? void 0 : memoisedOptions.useKey, memoisedOptions == null ? void 0 : memoisedOptions.description));
|
|
464
456
|
});
|
|
465
457
|
}
|
|
466
458
|
return function () {
|
|
@@ -469,12 +461,12 @@ function useHotkeys(keys, callback, options, dependencies) {
|
|
|
469
461
|
// @ts-ignore
|
|
470
462
|
domNode.removeEventListener('keydown', handleKeyDown);
|
|
471
463
|
if (proxy) {
|
|
472
|
-
parseKeysHookInput(_keys, memoisedOptions == null ? void 0 : memoisedOptions.
|
|
473
|
-
return proxy.removeHotkey(parseHotkey(key, memoisedOptions == null ? void 0 : memoisedOptions.
|
|
464
|
+
parseKeysHookInput(_keys, memoisedOptions == null ? void 0 : memoisedOptions.delimiter).forEach(function (key) {
|
|
465
|
+
return proxy.removeHotkey(parseHotkey(key, memoisedOptions == null ? void 0 : memoisedOptions.splitKey, memoisedOptions == null ? void 0 : memoisedOptions.useKey, memoisedOptions == null ? void 0 : memoisedOptions.description));
|
|
474
466
|
});
|
|
475
467
|
}
|
|
476
468
|
};
|
|
477
|
-
}, [_keys, memoisedOptions,
|
|
469
|
+
}, [_keys, memoisedOptions, activeScopes]);
|
|
478
470
|
return ref;
|
|
479
471
|
}
|
|
480
472
|
|
|
@@ -486,7 +478,7 @@ function useRecordHotkeys() {
|
|
|
486
478
|
isRecording = _useState2[0],
|
|
487
479
|
setIsRecording = _useState2[1];
|
|
488
480
|
var handler = useCallback(function (event) {
|
|
489
|
-
if (event.
|
|
481
|
+
if (event.code === undefined) {
|
|
490
482
|
// Synthetic event (e.g., Chrome autofill). Ignore.
|
|
491
483
|
return;
|
|
492
484
|
}
|