react-hotkeys-hook 4.0.7 → 4.1.0-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/isHotkeyPressed.d.ts +0 -2
- package/dist/react-hotkeys-hook.cjs.development.js +123 -109
- 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 +124 -110
- package/dist/react-hotkeys-hook.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/HotkeysProvider.tsx +41 -30
- package/src/isHotkeyPressed.ts +3 -3
- package/src/useHotkeys.ts +1 -1
- package/src/validators.ts +8 -2
|
@@ -99,6 +99,70 @@ function parseHotkey(hotkey, combinationKey) {
|
|
|
99
99
|
});
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
function deepEqual(x, y) {
|
|
103
|
+
//@ts-ignore
|
|
104
|
+
return x && y && typeof x === 'object' && typeof y === 'object'
|
|
105
|
+
//@ts-ignore
|
|
106
|
+
? Object.keys(x).length === Object.keys(y).length && Object.keys(x).reduce(function (isEqual, key) {
|
|
107
|
+
return isEqual && deepEqual(x[key], y[key]);
|
|
108
|
+
}, true) : x === y;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
var currentlyPressedKeys = /*#__PURE__*/new Set();
|
|
112
|
+
function isHotkeyPressed(key, splitKey) {
|
|
113
|
+
if (splitKey === void 0) {
|
|
114
|
+
splitKey = ',';
|
|
115
|
+
}
|
|
116
|
+
var hotkeyArray = Array.isArray(key) ? key : key.split(splitKey);
|
|
117
|
+
return hotkeyArray.every(function (hotkey) {
|
|
118
|
+
var parsedHotkey = parseHotkey(hotkey);
|
|
119
|
+
for (var _iterator = _createForOfIteratorHelperLoose(currentlyPressedKeys), _step; !(_step = _iterator()).done;) {
|
|
120
|
+
var pressedHotkey = _step.value;
|
|
121
|
+
if (deepEqual(parsedHotkey, pressedHotkey)) {
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
function pushToCurrentlyPressedKeys(key) {
|
|
128
|
+
var hotkeyArray = Array.isArray(key) ? key : [key];
|
|
129
|
+
hotkeyArray.forEach(function (hotkey) {
|
|
130
|
+
return currentlyPressedKeys.add(parseHotkey(hotkey));
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
function removeFromCurrentlyPressedKeys(key) {
|
|
134
|
+
var hotkeyArray = Array.isArray(key) ? key : [key];
|
|
135
|
+
hotkeyArray.forEach(function (hotkey) {
|
|
136
|
+
var parsedHotkey = parseHotkey(hotkey);
|
|
137
|
+
for (var _iterator2 = _createForOfIteratorHelperLoose(currentlyPressedKeys), _step2; !(_step2 = _iterator2()).done;) {
|
|
138
|
+
var pressedHotkey = _step2.value;
|
|
139
|
+
if (deepEqual(parsedHotkey, pressedHotkey)) {
|
|
140
|
+
currentlyPressedKeys["delete"](pressedHotkey);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
(function () {
|
|
146
|
+
if (typeof window !== 'undefined') {
|
|
147
|
+
window.addEventListener('DOMContentLoaded', function () {
|
|
148
|
+
document.addEventListener('keydown', function (e) {
|
|
149
|
+
if (e.key === undefined) {
|
|
150
|
+
// Synthetic event (e.g., Chrome autofill). Ignore.
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
pushToCurrentlyPressedKeys(e.key);
|
|
154
|
+
});
|
|
155
|
+
document.addEventListener('keyup', function (e) {
|
|
156
|
+
if (e.key === undefined) {
|
|
157
|
+
// Synthetic event (e.g., Chrome autofill). Ignore.
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
removeFromCurrentlyPressedKeys(e.key);
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
})();
|
|
165
|
+
|
|
102
166
|
function maybePreventDefault(e, hotkey, preventDefault) {
|
|
103
167
|
if (typeof preventDefault === 'function' && preventDefault(e, hotkey) || preventDefault === true) {
|
|
104
168
|
e.preventDefault();
|
|
@@ -144,12 +208,12 @@ var isHotkeyMatchingKeyboardEvent = function isHotkeyMatchingKeyboardEvent(e, ho
|
|
|
144
208
|
mod = hotkey.mod,
|
|
145
209
|
shift = hotkey.shift,
|
|
146
210
|
keys = hotkey.keys;
|
|
147
|
-
var
|
|
148
|
-
ctrlKey = e.ctrlKey,
|
|
149
|
-
metaKey = e.metaKey,
|
|
150
|
-
shiftKey = e.shiftKey,
|
|
151
|
-
pressedKeyUppercase = e.key,
|
|
211
|
+
var pressedKeyUppercase = e.key,
|
|
152
212
|
code = e.code;
|
|
213
|
+
var altKey = isHotkeyPressed('alt');
|
|
214
|
+
var shiftKey = isHotkeyPressed('shift');
|
|
215
|
+
var metaKey = isHotkeyPressed('meta');
|
|
216
|
+
var ctrlKey = isHotkeyPressed('ctrl');
|
|
153
217
|
var keyCode = code.toLowerCase().replace('key', '');
|
|
154
218
|
var pressedKey = pressedKeyUppercase.toLowerCase();
|
|
155
219
|
if (altKey !== alt && pressedKey !== 'alt') {
|
|
@@ -169,7 +233,7 @@ var isHotkeyMatchingKeyboardEvent = function isHotkeyMatchingKeyboardEvent(e, ho
|
|
|
169
233
|
}
|
|
170
234
|
}
|
|
171
235
|
// All modifiers are correct, now check the key
|
|
172
|
-
// If the key is set we check for the key
|
|
236
|
+
// If the key is set, we check for the key
|
|
173
237
|
if (keys && keys.length === 1 && (keys.includes(pressedKey) || keys.includes(keyCode))) {
|
|
174
238
|
return true;
|
|
175
239
|
} else if (keys) {
|
|
@@ -222,41 +286,59 @@ var HotkeysProvider = function HotkeysProvider(_ref) {
|
|
|
222
286
|
var _useState2 = react.useState([]),
|
|
223
287
|
boundHotkeys = _useState2[0],
|
|
224
288
|
setBoundHotkeys = _useState2[1];
|
|
225
|
-
var
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
} else {
|
|
232
|
-
setInternalActiveScopes(Array.from(new Set([].concat(internalActiveScopes, [scope]))));
|
|
233
|
-
}
|
|
234
|
-
};
|
|
235
|
-
var disableScope = function disableScope(scope) {
|
|
236
|
-
var scopes = internalActiveScopes.filter(function (s) {
|
|
237
|
-
return s !== scope;
|
|
289
|
+
var enableScope = react.useCallback(function (scope) {
|
|
290
|
+
setInternalActiveScopes(function (prev) {
|
|
291
|
+
if (prev.includes('*')) {
|
|
292
|
+
return [scope];
|
|
293
|
+
}
|
|
294
|
+
return Array.from(new Set([].concat(prev, [scope])));
|
|
238
295
|
});
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
296
|
+
}, []);
|
|
297
|
+
var disableScope = react.useCallback(function (scope) {
|
|
298
|
+
setInternalActiveScopes(function (prev) {
|
|
299
|
+
if (prev.filter(function (s) {
|
|
300
|
+
return s !== scope;
|
|
301
|
+
}).length === 0) {
|
|
302
|
+
return ['*'];
|
|
303
|
+
} else {
|
|
304
|
+
return prev.filter(function (s) {
|
|
305
|
+
return s !== scope;
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
}, []);
|
|
310
|
+
var toggleScope = react.useCallback(function (scope) {
|
|
311
|
+
setInternalActiveScopes(function (prev) {
|
|
312
|
+
if (prev.includes(scope)) {
|
|
313
|
+
if (prev.filter(function (s) {
|
|
314
|
+
return s !== scope;
|
|
315
|
+
}).length === 0) {
|
|
316
|
+
return ['*'];
|
|
317
|
+
} else {
|
|
318
|
+
return prev.filter(function (s) {
|
|
319
|
+
return s !== scope;
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
} else {
|
|
323
|
+
if (prev.includes('*')) {
|
|
324
|
+
return [scope];
|
|
325
|
+
}
|
|
326
|
+
return Array.from(new Set([].concat(prev, [scope])));
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
}, []);
|
|
330
|
+
var addBoundHotkey = react.useCallback(function (hotkey) {
|
|
331
|
+
setBoundHotkeys(function (prev) {
|
|
332
|
+
return [].concat(prev, [hotkey]);
|
|
333
|
+
});
|
|
334
|
+
}, []);
|
|
335
|
+
var removeBoundHotkey = react.useCallback(function (hotkey) {
|
|
336
|
+
setBoundHotkeys(function (prev) {
|
|
337
|
+
return prev.filter(function (h) {
|
|
338
|
+
return !deepEqual(h, hotkey);
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
}, []);
|
|
260
342
|
return /*#__PURE__*/jsxRuntime.jsx(HotkeysContext.Provider, {
|
|
261
343
|
value: {
|
|
262
344
|
enabledScopes: internalActiveScopes,
|
|
@@ -273,15 +355,6 @@ var HotkeysProvider = function HotkeysProvider(_ref) {
|
|
|
273
355
|
});
|
|
274
356
|
};
|
|
275
357
|
|
|
276
|
-
function deepEqual(x, y) {
|
|
277
|
-
//@ts-ignore
|
|
278
|
-
return x && y && typeof x === 'object' && typeof y === 'object'
|
|
279
|
-
//@ts-ignore
|
|
280
|
-
? Object.keys(x).length === Object.keys(y).length && Object.keys(x).reduce(function (isEqual, key) {
|
|
281
|
-
return isEqual && deepEqual(x[key], y[key]);
|
|
282
|
-
}, true) : x === y;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
358
|
function useDeepEqualMemo(value) {
|
|
286
359
|
var ref = react.useRef(undefined);
|
|
287
360
|
if (!deepEqual(ref.current, value)) {
|
|
@@ -316,7 +389,7 @@ function useHotkeys(keys, callback, options, dependencies) {
|
|
|
316
389
|
return;
|
|
317
390
|
}
|
|
318
391
|
// TODO: SINCE THE EVENT IS NOW ATTACHED TO THE REF, THE ACTIVE ELEMENT CAN NEVER BE INSIDE THE REF. THE HOTKEY ONLY TRIGGERS IF THE
|
|
319
|
-
// REF IS THE ACTIVE ELEMENT. THIS IS A PROBLEM SINCE FOCUSED SUB COMPONENTS
|
|
392
|
+
// REF IS THE ACTIVE ELEMENT. THIS IS A PROBLEM SINCE FOCUSED SUB COMPONENTS WON'T TRIGGER THE HOTKEY.
|
|
320
393
|
if (ref.current !== null && document.activeElement !== ref.current && !ref.current.contains(document.activeElement)) {
|
|
321
394
|
stopPropagation(e);
|
|
322
395
|
return;
|
|
@@ -386,65 +459,6 @@ function useHotkeys(keys, callback, options, dependencies) {
|
|
|
386
459
|
return ref;
|
|
387
460
|
}
|
|
388
461
|
|
|
389
|
-
var currentlyPressedKeys = /*#__PURE__*/new Set();
|
|
390
|
-
function isHotkeyPressed(key, splitKey) {
|
|
391
|
-
if (splitKey === void 0) {
|
|
392
|
-
splitKey = ',';
|
|
393
|
-
}
|
|
394
|
-
var hotkeyArray = Array.isArray(key) ? key : key.split(splitKey);
|
|
395
|
-
return hotkeyArray.every(function (hotkey) {
|
|
396
|
-
var parsedHotkey = parseHotkey(hotkey);
|
|
397
|
-
for (var _iterator = _createForOfIteratorHelperLoose(currentlyPressedKeys), _step; !(_step = _iterator()).done;) {
|
|
398
|
-
var pressedHotkey = _step.value;
|
|
399
|
-
if (deepEqual(parsedHotkey, pressedHotkey)) {
|
|
400
|
-
return true;
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
});
|
|
404
|
-
}
|
|
405
|
-
function pushToCurrentlyPressedKeys(key) {
|
|
406
|
-
var hotkeyArray = Array.isArray(key) ? key : [key];
|
|
407
|
-
hotkeyArray.forEach(function (hotkey) {
|
|
408
|
-
return currentlyPressedKeys.add(parseHotkey(hotkey));
|
|
409
|
-
});
|
|
410
|
-
}
|
|
411
|
-
function removeFromCurrentlyPressedKeys(key) {
|
|
412
|
-
var hotkeyArray = Array.isArray(key) ? key : [key];
|
|
413
|
-
hotkeyArray.forEach(function (hotkey) {
|
|
414
|
-
var parsedHotkey = parseHotkey(hotkey);
|
|
415
|
-
for (var _iterator2 = _createForOfIteratorHelperLoose(currentlyPressedKeys), _step2; !(_step2 = _iterator2()).done;) {
|
|
416
|
-
var _pressedHotkey$keys;
|
|
417
|
-
var pressedHotkey = _step2.value;
|
|
418
|
-
if ((_pressedHotkey$keys = pressedHotkey.keys) != null && _pressedHotkey$keys.every(function (key) {
|
|
419
|
-
var _parsedHotkey$keys;
|
|
420
|
-
return (_parsedHotkey$keys = parsedHotkey.keys) == null ? void 0 : _parsedHotkey$keys.includes(key);
|
|
421
|
-
})) {
|
|
422
|
-
currentlyPressedKeys["delete"](pressedHotkey);
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
});
|
|
426
|
-
}
|
|
427
|
-
(function () {
|
|
428
|
-
if (typeof window !== 'undefined') {
|
|
429
|
-
window.addEventListener('DOMContentLoaded', function () {
|
|
430
|
-
document.addEventListener('keydown', function (e) {
|
|
431
|
-
if (e.key === undefined) {
|
|
432
|
-
// Synthetic event (e.g., Chrome autofill). Ignore.
|
|
433
|
-
return;
|
|
434
|
-
}
|
|
435
|
-
pushToCurrentlyPressedKeys(e.key);
|
|
436
|
-
});
|
|
437
|
-
document.addEventListener('keyup', function (e) {
|
|
438
|
-
if (e.key === undefined) {
|
|
439
|
-
// Synthetic event (e.g., Chrome autofill). Ignore.
|
|
440
|
-
return;
|
|
441
|
-
}
|
|
442
|
-
removeFromCurrentlyPressedKeys(e.key);
|
|
443
|
-
});
|
|
444
|
-
});
|
|
445
|
-
}
|
|
446
|
-
})();
|
|
447
|
-
|
|
448
462
|
exports.HotkeysProvider = HotkeysProvider;
|
|
449
463
|
exports.isHotkeyPressed = isHotkeyPressed;
|
|
450
464
|
exports.useHotkeys = useHotkeys;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react-hotkeys-hook.cjs.development.js","sources":["../src/parseHotkeys.ts","../src/validators.ts","../src/BoundHotkeysProxyProvider.tsx","../src/HotkeysProvider.tsx","../src/deepEqual.ts","../src/useDeepEqualMemo.ts","../src/useHotkeys.ts","../src/isHotkeyPressed.ts"],"sourcesContent":["import { Hotkey, KeyboardModifiers, Keys } from './types'\n\nconst reservedModifierKeywords = ['shift', 'alt', 'meta', 'mod']\n\nconst mappedKeys: Record<string, string> = {\n esc: 'escape',\n return: 'enter',\n left: 'arrowleft',\n up: 'arrowup',\n right: 'arrowright',\n down: 'arrowdown',\n '1': 'digit1',\n '2': 'digit2',\n '3': 'digit3',\n '4': 'digit4',\n '5': 'digit5',\n '6': 'digit6',\n '7': 'digit7',\n '8': 'digit8',\n '9': 'digit9',\n}\n\nexport function parseKeysHookInput(keys: Keys, splitKey: string = ','): string[] {\n if (typeof keys === 'string') {\n return keys.split(splitKey)\n }\n\n return keys\n}\n\nexport function parseHotkey(hotkey: string, combinationKey: string = '+'): Hotkey {\n const keys = hotkey\n .toLocaleLowerCase()\n .split(combinationKey)\n .map(k => k.trim())\n .map(k => mappedKeys[k] || k)\n\n const modifiers: KeyboardModifiers = {\n alt: keys.includes('alt'),\n shift: keys.includes('shift'),\n meta: keys.includes('meta'),\n mod: keys.includes('mod'),\n }\n\n const singleCharKeys = keys.filter((k) => !reservedModifierKeywords.includes(k))\n\n return {\n ...modifiers,\n keys: singleCharKeys,\n }\n}\n","import { FormTags, Hotkey, Scopes, Trigger } from './types'\n\nexport function maybePreventDefault(e: KeyboardEvent, hotkey: Hotkey, preventDefault?: Trigger): void {\n if ((typeof preventDefault === 'function' && preventDefault(e, hotkey)) || preventDefault === true) {\n e.preventDefault()\n }\n}\n\nexport function isHotkeyEnabled(e: KeyboardEvent, hotkey: Hotkey, enabled?: Trigger): boolean {\n if (typeof enabled === 'function') {\n return enabled(e, hotkey)\n }\n\n return enabled === true || enabled === undefined\n}\n\nexport function isKeyboardEventTriggeredByInput(ev: KeyboardEvent): boolean {\n return isHotkeyEnabledOnTag(ev, ['input', 'textarea', 'select'])\n}\n\nexport function isHotkeyEnabledOnTag({ target }: KeyboardEvent, enabledOnTags: FormTags[] | boolean = false): boolean {\n const targetTagName = target && (target as HTMLElement).tagName\n\n if (enabledOnTags instanceof Array) {\n return Boolean(targetTagName && enabledOnTags && enabledOnTags.some(tag => tag.toLowerCase() === targetTagName.toLowerCase()))\n }\n\n return Boolean(targetTagName && enabledOnTags && enabledOnTags === true)\n}\n\nexport function isScopeActive(activeScopes: string[], scopes?: Scopes): boolean {\n if (activeScopes.length === 0 && scopes) {\n console.warn(\n 'A hotkey has the \"scopes\" option set, however no active scopes were found. If you want to use the global scopes feature, you need to wrap your app in a <HotkeysProvider>'\n )\n\n return true\n }\n\n if (!scopes) {\n return true\n }\n\n return activeScopes.some(scope => scopes.includes(scope)) || activeScopes.includes('*')\n}\n\nexport const isHotkeyMatchingKeyboardEvent = (e: KeyboardEvent, hotkey: Hotkey, pressedDownKeys: Set<string>): boolean => {\n const { alt, meta, mod, shift, keys } = hotkey\n const { altKey, ctrlKey, metaKey, shiftKey, key: pressedKeyUppercase, code } = e\n\n const keyCode = code.toLowerCase().replace('key', '')\n const pressedKey = pressedKeyUppercase.toLowerCase()\n\n if (altKey !== alt && pressedKey !== 'alt') {\n return false\n }\n\n if (shiftKey !== shift && pressedKey !== 'shift') {\n return false\n }\n\n // Mod is a special key name that is checking for meta on macOS and ctrl on other platforms\n if (mod) {\n if (!metaKey && !ctrlKey) {\n return false\n }\n } else {\n if (metaKey !== meta && ctrlKey !== meta && keyCode !== 'meta' && keyCode !== 'ctrl') {\n return false\n }\n }\n\n // All modifiers are correct, now check the key\n // If the key is set we check for the key\n if (keys && keys.length === 1 && (keys.includes(pressedKey) || keys.includes(keyCode))) {\n return true\n } else if (keys) {\n // Check if all keys are present in pressedDownKeys set\n return keys.every(key => pressedDownKeys.has(key))\n }\n else if (!keys) {\n // If the key is not set, we only listen for modifiers, that check went alright, so we return true\n return true\n }\n\n // There is nothing that matches.\n return false\n}\n","import { createContext, ReactNode, useContext } from 'react'\nimport { Hotkey } from './types'\n\ntype BoundHotkeysProxyProviderType = {\n addHotkey: (hotkey: Hotkey) => void,\n removeHotkey: (hotkey: Hotkey) => void,\n}\n\nconst BoundHotkeysProxyProvider = createContext<BoundHotkeysProxyProviderType | undefined>(undefined)\n\nexport const useBoundHotkeysProxy = () => {\n return useContext(BoundHotkeysProxyProvider)\n}\n\ninterface Props {\n children: ReactNode\n addHotkey: (hotkey: Hotkey) => void\n removeHotkey: (hotkey: Hotkey) => void\n}\n\nexport default function BoundHotkeysProxyProviderProvider({ addHotkey, removeHotkey, children }: Props) {\n return <BoundHotkeysProxyProvider.Provider value={{addHotkey, removeHotkey}}>{children}</BoundHotkeysProxyProvider.Provider>\n}\n","import { Hotkey } from './types'\nimport { createContext, ReactNode, useMemo, useState, useContext } from 'react'\nimport BoundHotkeysProxyProviderProvider from './BoundHotkeysProxyProvider'\n\nexport type HotkeysContextType = {\n hotkeys: ReadonlyArray<Hotkey>\n enabledScopes: string[]\n toggleScope: (scope: string) => void\n enableScope: (scope: string) => void\n disableScope: (scope: string) => void\n}\n\n// The context is only needed for special features like global scoping, so we use a graceful default fallback\nconst HotkeysContext = createContext<HotkeysContextType>({\n hotkeys: [],\n enabledScopes: [], // This array has to be empty instead of containing '*' as default, to check if the provider is set or not\n toggleScope: () => {},\n enableScope: () => {},\n disableScope: () => {},\n})\n\nexport const useHotkeysContext = () => {\n return useContext(HotkeysContext)\n}\n\ninterface Props {\n initiallyActiveScopes?: string[]\n children: ReactNode\n}\n\nexport const HotkeysProvider = ({initiallyActiveScopes = ['*'], children}: Props) => {\n const [internalActiveScopes, setInternalActiveScopes] = useState(initiallyActiveScopes?.length > 0 ? initiallyActiveScopes : ['*'])\n const [boundHotkeys, setBoundHotkeys] = useState<Hotkey[]>([]);\n\n const isAllActive = useMemo(() => internalActiveScopes.includes('*'), [internalActiveScopes])\n\n const enableScope = (scope: string) => {\n if (isAllActive) {\n setInternalActiveScopes([scope])\n } else {\n setInternalActiveScopes(Array.from(new Set([...internalActiveScopes, scope])))\n }\n }\n\n const disableScope = (scope: string) => {\n const scopes = internalActiveScopes.filter(s => s !== scope)\n\n if (scopes.length === 0) {\n setInternalActiveScopes(['*'])\n } else {\n setInternalActiveScopes(scopes)\n }\n }\n\n const toggleScope = (scope: string) => {\n if (internalActiveScopes.includes(scope)) {\n disableScope(scope)\n } else {\n enableScope(scope)\n }\n }\n\n const addBoundHotkey = (hotkey: Hotkey) => {\n setBoundHotkeys([...boundHotkeys, hotkey])\n }\n\n const removeBoundHotkey = (hotkey: Hotkey) => {\n setBoundHotkeys(boundHotkeys.filter(h => h.keys !== hotkey.keys))\n }\n\n return (\n <HotkeysContext.Provider value={{enabledScopes: internalActiveScopes, hotkeys: boundHotkeys, enableScope, disableScope, toggleScope}}>\n <BoundHotkeysProxyProviderProvider addHotkey={addBoundHotkey} removeHotkey={removeBoundHotkey}>\n {children}\n </BoundHotkeysProxyProviderProvider>\n </HotkeysContext.Provider>\n )\n}\n","export default function deepEqual(x: any, y: any): boolean {\n //@ts-ignore\n return (x && y && typeof x === 'object' && typeof y === 'object')\n //@ts-ignore\n ? (Object.keys(x).length === Object.keys(y).length) && Object.keys(x).reduce(function(isEqual, key) {\n return isEqual && deepEqual(x[key], y[key])\n }, true)\n : (x === y)\n}\n","import { useRef } from 'react'\nimport deepEqual from './deepEqual'\n\nexport default function useDeepEqualMemo<T>(value: T) {\n const ref = useRef<T | undefined>(undefined)\n\n if (!deepEqual(ref.current, value)) {\n ref.current = value\n }\n\n return ref.current\n}\n","import { HotkeyCallback, Keys, Options, OptionsOrDependencyArray, RefType } from './types'\nimport { DependencyList, useCallback, useEffect, useLayoutEffect, useRef } from 'react'\nimport { parseHotkey, parseKeysHookInput } from './parseHotkeys'\nimport {\n isHotkeyEnabled,\n isHotkeyEnabledOnTag,\n isHotkeyMatchingKeyboardEvent,\n isKeyboardEventTriggeredByInput,\n isScopeActive,\n maybePreventDefault,\n} from './validators'\nimport { useHotkeysContext } from './HotkeysProvider'\nimport { useBoundHotkeysProxy } from './BoundHotkeysProxyProvider'\nimport useDeepEqualMemo from './useDeepEqualMemo'\n\nconst stopPropagation = (e: KeyboardEvent): void => {\n e.stopPropagation()\n e.preventDefault()\n e.stopImmediatePropagation()\n}\n\nconst useSafeLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect\n\nconst pressedDownKeys = new Set<string>()\n\nexport default function useHotkeys<T extends HTMLElement>(\n keys: Keys,\n callback: HotkeyCallback,\n options?: OptionsOrDependencyArray,\n dependencies?: OptionsOrDependencyArray,\n) {\n const ref = useRef<RefType<T>>(null)\n\n const _options: Options | undefined = !(options instanceof Array) ? (options as Options) : !(dependencies instanceof Array) ? (dependencies as Options) : undefined\n const _deps: DependencyList = options instanceof Array ? options : dependencies instanceof Array ? dependencies : []\n\n const cb = useCallback(callback, [..._deps])\n const memoisedOptions = useDeepEqualMemo(_options)\n\n const { enabledScopes } = useHotkeysContext()\n const proxy = useBoundHotkeysProxy()\n\n useSafeLayoutEffect(() => {\n if (memoisedOptions?.enabled === false || !isScopeActive(enabledScopes, memoisedOptions?.scopes)) {\n return\n }\n\n const listener = (e: KeyboardEvent) => {\n if (isKeyboardEventTriggeredByInput(e) && !isHotkeyEnabledOnTag(e, memoisedOptions?.enableOnFormTags)) {\n return\n }\n\n // TODO: SINCE THE EVENT IS NOW ATTACHED TO THE REF, THE ACTIVE ELEMENT CAN NEVER BE INSIDE THE REF. THE HOTKEY ONLY TRIGGERS IF THE\n // REF IS THE ACTIVE ELEMENT. THIS IS A PROBLEM SINCE FOCUSED SUB COMPONENTS WONT TRIGGER THE HOTKEY.\n if (ref.current !== null && document.activeElement !== ref.current && !ref.current.contains(document.activeElement)) {\n stopPropagation(e)\n\n return\n }\n\n if (((e.target as HTMLElement)?.isContentEditable && !memoisedOptions?.enableOnContentEditable)) {\n return\n }\n\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => {\n const hotkey = parseHotkey(key, memoisedOptions?.combinationKey)\n\n if (isHotkeyMatchingKeyboardEvent(e, hotkey, pressedDownKeys) || hotkey.keys?.includes('*')) {\n maybePreventDefault(e, hotkey, memoisedOptions?.preventDefault)\n\n if (!isHotkeyEnabled(e, hotkey, memoisedOptions?.enabled)) {\n stopPropagation(e)\n\n return\n }\n\n cb(e, hotkey)\n }\n })\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n pressedDownKeys.add(event.key.toLowerCase())\n\n if ((memoisedOptions?.keydown === undefined && memoisedOptions?.keyup !== true) || memoisedOptions?.keydown) {\n listener(event)\n }\n }\n\n const handleKeyUp = (event: KeyboardEvent) => {\n if (event.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n if (event.key.toLowerCase() !== 'meta') {\n pressedDownKeys.delete(event.key.toLowerCase())\n } else {\n // On macOS pressing down the meta key prevents triggering the keyup event for any other key https://stackoverflow.com/a/57153300/735226.\n pressedDownKeys.clear()\n }\n\n if (memoisedOptions?.keyup) {\n listener(event)\n }\n }\n\n // @ts-ignore\n (ref.current || document).addEventListener('keyup', handleKeyUp);\n // @ts-ignore\n (ref.current || document).addEventListener('keydown', handleKeyDown)\n\n if (proxy) {\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => proxy.addHotkey(parseHotkey(key, memoisedOptions?.combinationKey)))\n }\n\n return () => {\n // @ts-ignore\n (ref.current || document).removeEventListener('keyup', handleKeyUp);\n // @ts-ignore\n (ref.current || document).removeEventListener('keydown', handleKeyDown)\n\n if (proxy) {\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => proxy.removeHotkey(parseHotkey(key, memoisedOptions?.combinationKey)))\n }\n }\n }, [keys, cb, memoisedOptions, enabledScopes])\n\n return ref\n}\n","import { Hotkey } from './types'\nimport { parseHotkey } from './parseHotkeys'\nimport deepEqual from './deepEqual'\n\nconst currentlyPressedKeys: Set<Hotkey> = new Set<Hotkey>()\n\nexport function isHotkeyPressed(key: string | string[], splitKey: string = ','): boolean {\n const hotkeyArray = Array.isArray(key) ? key : key.split(splitKey)\n\n return hotkeyArray.every((hotkey) => {\n const parsedHotkey = parseHotkey(hotkey)\n\n for (const pressedHotkey of currentlyPressedKeys) {\n if (deepEqual(parsedHotkey, pressedHotkey)) {\n return true\n }\n }\n })\n}\n\nexport function pushToCurrentlyPressedKeys(key: string | string[]): void {\n const hotkeyArray = Array.isArray(key) ? key : [key]\n\n hotkeyArray.forEach(hotkey => currentlyPressedKeys.add(parseHotkey(hotkey)))\n}\n\nexport function removeFromCurrentlyPressedKeys(key: string | string[]): void {\n const hotkeyArray = Array.isArray(key) ? key : [key]\n\n hotkeyArray.forEach((hotkey) => {\n const parsedHotkey = parseHotkey(hotkey)\n\n for (const pressedHotkey of currentlyPressedKeys) {\n if (pressedHotkey.keys?.every((key) => parsedHotkey.keys?.includes(key))) {\n currentlyPressedKeys.delete(pressedHotkey)\n }\n }\n })\n}\n\n(() => {\n if (typeof window !== 'undefined') {\n window.addEventListener('DOMContentLoaded', () => {\n document.addEventListener('keydown', e => {\n if (e.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n pushToCurrentlyPressedKeys(e.key)\n })\n\n document.addEventListener('keyup', e => {\n if (e.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n removeFromCurrentlyPressedKeys(e.key)\n })\n })\n }\n})()\n"],"names":["reservedModifierKeywords","mappedKeys","esc","left","up","right","down","parseKeysHookInput","keys","splitKey","split","parseHotkey","hotkey","combinationKey","toLocaleLowerCase","map","k","trim","modifiers","alt","includes","shift","meta","mod","singleCharKeys","filter","maybePreventDefault","e","preventDefault","isHotkeyEnabled","enabled","undefined","isKeyboardEventTriggeredByInput","ev","isHotkeyEnabledOnTag","enabledOnTags","target","targetTagName","tagName","Array","Boolean","some","tag","toLowerCase","isScopeActive","activeScopes","scopes","length","console","warn","scope","isHotkeyMatchingKeyboardEvent","pressedDownKeys","altKey","ctrlKey","metaKey","shiftKey","pressedKeyUppercase","key","code","keyCode","replace","pressedKey","every","has","BoundHotkeysProxyProvider","createContext","useBoundHotkeysProxy","useContext","BoundHotkeysProxyProviderProvider","addHotkey","removeHotkey","children","_jsx","HotkeysContext","hotkeys","enabledScopes","toggleScope","enableScope","disableScope","useHotkeysContext","HotkeysProvider","initiallyActiveScopes","useState","internalActiveScopes","setInternalActiveScopes","boundHotkeys","setBoundHotkeys","isAllActive","useMemo","from","Set","s","addBoundHotkey","removeBoundHotkey","h","deepEqual","x","y","Object","reduce","isEqual","useDeepEqualMemo","value","ref","useRef","current","stopPropagation","stopImmediatePropagation","useSafeLayoutEffect","window","useLayoutEffect","useEffect","useHotkeys","callback","options","dependencies","_options","_deps","cb","useCallback","memoisedOptions","proxy","listener","enableOnFormTags","document","activeElement","contains","isContentEditable","enableOnContentEditable","forEach","handleKeyDown","event","add","keydown","keyup","handleKeyUp","clear","addEventListener","removeEventListener","currentlyPressedKeys","isHotkeyPressed","hotkeyArray","isArray","parsedHotkey","pressedHotkey","pushToCurrentlyPressedKeys","removeFromCurrentlyPressedKeys"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,IAAMA,wBAAwB,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC;AAEhE,IAAMC,UAAU,GAA2B;EACzCC,GAAG,EAAE,QAAQ;EACb,UAAQ,OAAO;EACfC,IAAI,EAAE,WAAW;EACjBC,EAAE,EAAE,SAAS;EACbC,KAAK,EAAE,YAAY;EACnBC,IAAI,EAAE,WAAW;EACjB,GAAG,EAAE,QAAQ;EACb,GAAG,EAAE,QAAQ;EACb,GAAG,EAAE,QAAQ;EACb,GAAG,EAAE,QAAQ;EACb,GAAG,EAAE,QAAQ;EACb,GAAG,EAAE,QAAQ;EACb,GAAG,EAAE,QAAQ;EACb,GAAG,EAAE,QAAQ;EACb,GAAG,EAAE;CACN;SAEeC,kBAAkB,CAACC,IAAU,EAAEC;MAAAA;IAAAA,WAAmB,GAAG;;EACnE,IAAI,OAAOD,IAAI,KAAK,QAAQ,EAAE;IAC5B,OAAOA,IAAI,CAACE,KAAK,CAACD,QAAQ,CAAC;;EAG7B,OAAOD,IAAI;AACb;SAEgBG,WAAW,CAACC,MAAc,EAAEC;MAAAA;IAAAA,iBAAyB,GAAG;;EACtE,IAAML,IAAI,GAAGI,MAAM,CAChBE,iBAAiB,EAAE,CACnBJ,KAAK,CAACG,cAAc,CAAC,CACrBE,GAAG,CAAC,UAAAC,CAAC;IAAA,OAAIA,CAAC,CAACC,IAAI,EAAE;IAAC,CAClBF,GAAG,CAAC,UAAAC,CAAC;IAAA,OAAIf,UAAU,CAACe,CAAC,CAAC,IAAIA,CAAC;IAAC;EAE/B,IAAME,SAAS,GAAsB;IACnCC,GAAG,EAAEX,IAAI,CAACY,QAAQ,CAAC,KAAK,CAAC;IACzBC,KAAK,EAAEb,IAAI,CAACY,QAAQ,CAAC,OAAO,CAAC;IAC7BE,IAAI,EAAEd,IAAI,CAACY,QAAQ,CAAC,MAAM,CAAC;IAC3BG,GAAG,EAAEf,IAAI,CAACY,QAAQ,CAAC,KAAK;GACzB;EAED,IAAMI,cAAc,GAAGhB,IAAI,CAACiB,MAAM,CAAC,UAACT,CAAC;IAAA,OAAK,CAAChB,wBAAwB,CAACoB,QAAQ,CAACJ,CAAC,CAAC;IAAC;EAEhF,oBACKE,SAAS;IACZV,IAAI,EAAEgB;;AAEV;;SChDgBE,mBAAmB,CAACC,CAAgB,EAAEf,MAAc,EAAEgB,cAAwB;EAC5F,IAAK,OAAOA,cAAc,KAAK,UAAU,IAAIA,cAAc,CAACD,CAAC,EAAEf,MAAM,CAAC,IAAKgB,cAAc,KAAK,IAAI,EAAE;IAClGD,CAAC,CAACC,cAAc,EAAE;;AAEtB;AAEA,SAAgBC,eAAe,CAACF,CAAgB,EAAEf,MAAc,EAAEkB,OAAiB;EACjF,IAAI,OAAOA,OAAO,KAAK,UAAU,EAAE;IACjC,OAAOA,OAAO,CAACH,CAAC,EAAEf,MAAM,CAAC;;EAG3B,OAAOkB,OAAO,KAAK,IAAI,IAAIA,OAAO,KAAKC,SAAS;AAClD;AAEA,SAAgBC,+BAA+B,CAACC,EAAiB;EAC/D,OAAOC,oBAAoB,CAACD,EAAE,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;AAClE;AAEA,SAAgBC,oBAAoB,OAA4BC;MAAzBC,MAAM,QAANA,MAAM;EAAA,IAAmBD;IAAAA,gBAAsC,KAAK;;EACzG,IAAME,aAAa,GAAGD,MAAM,IAAKA,MAAsB,CAACE,OAAO;EAE/D,IAAIH,aAAa,YAAYI,KAAK,EAAE;IAClC,OAAOC,OAAO,CAACH,aAAa,IAAIF,aAAa,IAAIA,aAAa,CAACM,IAAI,CAAC,UAAAC,GAAG;MAAA,OAAIA,GAAG,CAACC,WAAW,EAAE,KAAKN,aAAa,CAACM,WAAW,EAAE;MAAC,CAAC;;EAGhI,OAAOH,OAAO,CAACH,aAAa,IAAIF,aAAa,IAAIA,aAAa,KAAK,IAAI,CAAC;AAC1E;AAEA,SAAgBS,aAAa,CAACC,YAAsB,EAAEC,MAAe;EACnE,IAAID,YAAY,CAACE,MAAM,KAAK,CAAC,IAAID,MAAM,EAAE;IACvCE,OAAO,CAACC,IAAI,CACV,2KAA2K,CAC5K;IAED,OAAO,IAAI;;EAGb,IAAI,CAACH,MAAM,EAAE;IACX,OAAO,IAAI;;EAGb,OAAOD,YAAY,CAACJ,IAAI,CAAC,UAAAS,KAAK;IAAA,OAAIJ,MAAM,CAAC1B,QAAQ,CAAC8B,KAAK,CAAC;IAAC,IAAIL,YAAY,CAACzB,QAAQ,CAAC,GAAG,CAAC;AACzF;AAEA,AAAO,IAAM+B,6BAA6B,GAAG,SAAhCA,6BAA6B,CAAIxB,CAAgB,EAAEf,MAAc,EAAEwC,eAA4B;EAC1G,IAAQjC,GAAG,GAA6BP,MAAM,CAAtCO,GAAG;IAAEG,IAAI,GAAuBV,MAAM,CAAjCU,IAAI;IAAEC,GAAG,GAAkBX,MAAM,CAA3BW,GAAG;IAAEF,KAAK,GAAWT,MAAM,CAAtBS,KAAK;IAAEb,IAAI,GAAKI,MAAM,CAAfJ,IAAI;EACnC,IAAQ6C,MAAM,GAAiE1B,CAAC,CAAxE0B,MAAM;IAAEC,OAAO,GAAwD3B,CAAC,CAAhE2B,OAAO;IAAEC,OAAO,GAA+C5B,CAAC,CAAvD4B,OAAO;IAAEC,QAAQ,GAAqC7B,CAAC,CAA9C6B,QAAQ;IAAOC,mBAAmB,GAAW9B,CAAC,CAApC+B,GAAG;IAAuBC,IAAI,GAAKhC,CAAC,CAAVgC,IAAI;EAE1E,IAAMC,OAAO,GAAGD,IAAI,CAAChB,WAAW,EAAE,CAACkB,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;EACrD,IAAMC,UAAU,GAAGL,mBAAmB,CAACd,WAAW,EAAE;EAEpD,IAAIU,MAAM,KAAKlC,GAAG,IAAI2C,UAAU,KAAK,KAAK,EAAE;IAC1C,OAAO,KAAK;;EAGd,IAAIN,QAAQ,KAAKnC,KAAK,IAAIyC,UAAU,KAAK,OAAO,EAAE;IAChD,OAAO,KAAK;;;EAId,IAAIvC,GAAG,EAAE;IACP,IAAI,CAACgC,OAAO,IAAI,CAACD,OAAO,EAAE;MACxB,OAAO,KAAK;;GAEf,MAAM;IACL,IAAIC,OAAO,KAAKjC,IAAI,IAAIgC,OAAO,KAAKhC,IAAI,IAAIsC,OAAO,KAAK,MAAM,IAAIA,OAAO,KAAK,MAAM,EAAE;MACpF,OAAO,KAAK;;;;;EAMhB,IAAIpD,IAAI,IAAIA,IAAI,CAACuC,MAAM,KAAK,CAAC,KAAKvC,IAAI,CAACY,QAAQ,CAAC0C,UAAU,CAAC,IAAItD,IAAI,CAACY,QAAQ,CAACwC,OAAO,CAAC,CAAC,EAAE;IACtF,OAAO,IAAI;GACZ,MAAM,IAAIpD,IAAI,EAAE;;IAEf,OAAOA,IAAI,CAACuD,KAAK,CAAC,UAAAL,GAAG;MAAA,OAAIN,eAAe,CAACY,GAAG,CAACN,GAAG,CAAC;MAAC;GACnD,MACI,IAAI,CAAClD,IAAI,EAAE;;IAEd,OAAO,IAAI;;;EAIb,OAAO,KAAK;AACd,CAAC;;AC/ED,IAAMyD,yBAAyB,gBAAGC,mBAAa,CAA4CnC,SAAS,CAAC;AAErG,AAAO,IAAMoC,oBAAoB,GAAG,SAAvBA,oBAAoB;EAC/B,OAAOC,gBAAU,CAACH,yBAAyB,CAAC;AAC9C,CAAC;AAQD,SAAwBI,iCAAiC;MAAGC,SAAS,QAATA,SAAS;IAAEC,YAAY,QAAZA,YAAY;IAAEC,QAAQ,QAARA,QAAQ;EAC3F,oBAAOC,eAAC,yBAAyB,CAAC,QAAQ;IAAC,KAAK,EAAE;MAACH,SAAS,EAATA,SAAS;MAAEC,YAAY,EAAZA;KAAc;IAAA,UAAEC;IAA8C;AAC9H;;ACTA,IAAME,cAAc,gBAAGR,mBAAa,CAAqB;EACvDS,OAAO,EAAE,EAAE;EACXC,aAAa,EAAE,EAAE;EACjBC,WAAW,EAAE,yBAAQ;EACrBC,WAAW,EAAE,yBAAQ;EACrBC,YAAY,EAAE;CACf,CAAC;AAEF,IAAaC,iBAAiB,GAAG,SAApBA,iBAAiB;EAC5B,OAAOZ,gBAAU,CAACM,cAAc,CAAC;AACnC,CAAC;AAOD,IAAaO,eAAe,GAAG,SAAlBA,eAAe;mCAAKC,qBAAqB;IAArBA,qBAAqB,sCAAG,CAAC,GAAG,CAAC;IAAEV,QAAQ,QAARA,QAAQ;EACtE,gBAAwDW,cAAQ,CAAC,CAAAD,qBAAqB,oBAArBA,qBAAqB,CAAEnC,MAAM,IAAG,CAAC,GAAGmC,qBAAqB,GAAG,CAAC,GAAG,CAAC,CAAC;IAA5HE,oBAAoB;IAAEC,uBAAuB;EACpD,iBAAwCF,cAAQ,CAAW,EAAE,CAAC;IAAvDG,YAAY;IAAEC,eAAe;EAEpC,IAAMC,WAAW,GAAGC,aAAO,CAAC;IAAA,OAAML,oBAAoB,CAAChE,QAAQ,CAAC,GAAG,CAAC;KAAE,CAACgE,oBAAoB,CAAC,CAAC;EAE7F,IAAMN,WAAW,GAAG,SAAdA,WAAW,CAAI5B,KAAa;IAChC,IAAIsC,WAAW,EAAE;MACfH,uBAAuB,CAAC,CAACnC,KAAK,CAAC,CAAC;KACjC,MAAM;MACLmC,uBAAuB,CAAC9C,KAAK,CAACmD,IAAI,CAAC,IAAIC,GAAG,WAAKP,oBAAoB,GAAElC,KAAK,GAAE,CAAC,CAAC;;GAEjF;EAED,IAAM6B,YAAY,GAAG,SAAfA,YAAY,CAAI7B,KAAa;IACjC,IAAMJ,MAAM,GAAGsC,oBAAoB,CAAC3D,MAAM,CAAC,UAAAmE,CAAC;MAAA,OAAIA,CAAC,KAAK1C,KAAK;MAAC;IAE5D,IAAIJ,MAAM,CAACC,MAAM,KAAK,CAAC,EAAE;MACvBsC,uBAAuB,CAAC,CAAC,GAAG,CAAC,CAAC;KAC/B,MAAM;MACLA,uBAAuB,CAACvC,MAAM,CAAC;;GAElC;EAED,IAAM+B,WAAW,GAAG,SAAdA,WAAW,CAAI3B,KAAa;IAChC,IAAIkC,oBAAoB,CAAChE,QAAQ,CAAC8B,KAAK,CAAC,EAAE;MACxC6B,YAAY,CAAC7B,KAAK,CAAC;KACpB,MAAM;MACL4B,WAAW,CAAC5B,KAAK,CAAC;;GAErB;EAED,IAAM2C,cAAc,GAAG,SAAjBA,cAAc,CAAIjF,MAAc;IACpC2E,eAAe,WAAKD,YAAY,GAAE1E,MAAM,GAAE;GAC3C;EAED,IAAMkF,iBAAiB,GAAG,SAApBA,iBAAiB,CAAIlF,MAAc;IACvC2E,eAAe,CAACD,YAAY,CAAC7D,MAAM,CAAC,UAAAsE,CAAC;MAAA,OAAIA,CAAC,CAACvF,IAAI,KAAKI,MAAM,CAACJ,IAAI;MAAC,CAAC;GAClE;EAED,oBACEiE,eAAC,cAAc,CAAC,QAAQ;IAAC,KAAK,EAAE;MAACG,aAAa,EAAEQ,oBAAoB;MAAET,OAAO,EAAEW,YAAY;MAAER,WAAW,EAAXA,WAAW;MAAEC,YAAY,EAAZA,YAAY;MAAEF,WAAW,EAAXA;KAAa;IAAA,uBACnIJ,eAAC,iCAAiC;MAAC,SAAS,EAAEoB,cAAe;MAAC,YAAY,EAAEC,iBAAkB;MAAA,UAC3FtB;;IAEqB;AAE9B,CAAC;;SC7EuBwB,SAAS,CAACC,CAAM,EAAEC,CAAM;;EAE9C,OAAQD,CAAC,IAAIC,CAAC,IAAI,OAAOD,CAAC,KAAK,QAAQ,IAAI,OAAOC,CAAC,KAAK;;IAEnDC,MAAM,CAAC3F,IAAI,CAACyF,CAAC,CAAC,CAAClD,MAAM,KAAKoD,MAAM,CAAC3F,IAAI,CAAC0F,CAAC,CAAC,CAACnD,MAAM,IAAKoD,MAAM,CAAC3F,IAAI,CAACyF,CAAC,CAAC,CAACG,MAAM,CAAC,UAASC,OAAO,EAAE3C,GAAG;IAChG,OAAO2C,OAAO,IAAIL,SAAS,CAACC,CAAC,CAACvC,GAAG,CAAC,EAAEwC,CAAC,CAACxC,GAAG,CAAC,CAAC;GAC5C,EAAE,IAAI,CAAC,GACLuC,CAAC,KAAKC,CAAE;AACf;;SCLwBI,gBAAgB,CAAIC,KAAQ;EAClD,IAAMC,GAAG,GAAGC,YAAM,CAAgB1E,SAAS,CAAC;EAE5C,IAAI,CAACiE,SAAS,CAACQ,GAAG,CAACE,OAAO,EAAEH,KAAK,CAAC,EAAE;IAClCC,GAAG,CAACE,OAAO,GAAGH,KAAK;;EAGrB,OAAOC,GAAG,CAACE,OAAO;AACpB;;ACIA,IAAMC,eAAe,GAAG,SAAlBA,eAAe,CAAIhF,CAAgB;EACvCA,CAAC,CAACgF,eAAe,EAAE;EACnBhF,CAAC,CAACC,cAAc,EAAE;EAClBD,CAAC,CAACiF,wBAAwB,EAAE;AAC9B,CAAC;AAED,IAAMC,mBAAmB,GAAG,OAAOC,MAAM,KAAK,WAAW,GAAGC,qBAAe,GAAGC,eAAS;AAEvF,IAAM5D,eAAe,gBAAG,IAAIuC,GAAG,EAAU;AAEzC,SAAwBsB,UAAU,CAChCzG,IAAU,EACV0G,QAAwB,EACxBC,OAAkC,EAClCC,YAAuC;EAEvC,IAAMZ,GAAG,GAAGC,YAAM,CAAa,IAAI,CAAC;EAEpC,IAAMY,QAAQ,GAAwB,EAAEF,OAAO,YAAY5E,KAAK,CAAC,GAAI4E,OAAmB,GAAG,EAAEC,YAAY,YAAY7E,KAAK,CAAC,GAAI6E,YAAwB,GAAGrF,SAAS;EACnK,IAAMuF,KAAK,GAAmBH,OAAO,YAAY5E,KAAK,GAAG4E,OAAO,GAAGC,YAAY,YAAY7E,KAAK,GAAG6E,YAAY,GAAG,EAAE;EAEpH,IAAMG,EAAE,GAAGC,iBAAW,CAACN,QAAQ,YAAMI,KAAK,EAAE;EAC5C,IAAMG,eAAe,GAAGnB,gBAAgB,CAACe,QAAQ,CAAC;EAElD,yBAA0BrC,iBAAiB,EAAE;IAArCJ,aAAa,sBAAbA,aAAa;EACrB,IAAM8C,KAAK,GAAGvD,oBAAoB,EAAE;EAEpC0C,mBAAmB,CAAC;IAClB,IAAI,CAAAY,eAAe,oBAAfA,eAAe,CAAE3F,OAAO,MAAK,KAAK,IAAI,CAACc,aAAa,CAACgC,aAAa,EAAE6C,eAAe,oBAAfA,eAAe,CAAE3E,MAAM,CAAC,EAAE;MAChG;;IAGF,IAAM6E,QAAQ,GAAG,SAAXA,QAAQ,CAAIhG,CAAgB;;MAChC,IAAIK,+BAA+B,CAACL,CAAC,CAAC,IAAI,CAACO,oBAAoB,CAACP,CAAC,EAAE8F,eAAe,oBAAfA,eAAe,CAAEG,gBAAgB,CAAC,EAAE;QACrG;;;;MAKF,IAAIpB,GAAG,CAACE,OAAO,KAAK,IAAI,IAAImB,QAAQ,CAACC,aAAa,KAAKtB,GAAG,CAACE,OAAO,IAAI,CAACF,GAAG,CAACE,OAAO,CAACqB,QAAQ,CAACF,QAAQ,CAACC,aAAa,CAAC,EAAE;QACnHnB,eAAe,CAAChF,CAAC,CAAC;QAElB;;MAGF,IAAM,aAAAA,CAAC,CAACS,MAAsB,aAAxB,UAA0B4F,iBAAiB,IAAI,EAACP,eAAe,YAAfA,eAAe,CAAEQ,uBAAuB,GAAG;QAC/F;;MAGF1H,kBAAkB,CAACC,IAAI,EAAEiH,eAAe,oBAAfA,eAAe,CAAEhH,QAAQ,CAAC,CAACyH,OAAO,CAAC,UAACxE,GAAG;;QAC9D,IAAM9C,MAAM,GAAGD,WAAW,CAAC+C,GAAG,EAAE+D,eAAe,oBAAfA,eAAe,CAAE5G,cAAc,CAAC;QAEhE,IAAIsC,6BAA6B,CAACxB,CAAC,EAAEf,MAAM,EAAEwC,eAAe,CAAC,oBAAIxC,MAAM,CAACJ,IAAI,aAAX,aAAaY,QAAQ,CAAC,GAAG,CAAC,EAAE;UAC3FM,mBAAmB,CAACC,CAAC,EAAEf,MAAM,EAAE6G,eAAe,oBAAfA,eAAe,CAAE7F,cAAc,CAAC;UAE/D,IAAI,CAACC,eAAe,CAACF,CAAC,EAAEf,MAAM,EAAE6G,eAAe,oBAAfA,eAAe,CAAE3F,OAAO,CAAC,EAAE;YACzD6E,eAAe,CAAChF,CAAC,CAAC;YAElB;;UAGF4F,EAAE,CAAC5F,CAAC,EAAEf,MAAM,CAAC;;OAEhB,CAAC;KACH;IAED,IAAMuH,aAAa,GAAG,SAAhBA,aAAa,CAAIC,KAAoB;MACzC,IAAIA,KAAK,CAAC1E,GAAG,KAAK3B,SAAS,EAAE;;QAE3B;;MAGFqB,eAAe,CAACiF,GAAG,CAACD,KAAK,CAAC1E,GAAG,CAACf,WAAW,EAAE,CAAC;MAE5C,IAAK,CAAA8E,eAAe,oBAAfA,eAAe,CAAEa,OAAO,MAAKvG,SAAS,IAAI,CAAA0F,eAAe,oBAAfA,eAAe,CAAEc,KAAK,MAAK,IAAI,IAAKd,eAAe,YAAfA,eAAe,CAAEa,OAAO,EAAE;QAC3GX,QAAQ,CAACS,KAAK,CAAC;;KAElB;IAED,IAAMI,WAAW,GAAG,SAAdA,WAAW,CAAIJ,KAAoB;MACvC,IAAIA,KAAK,CAAC1E,GAAG,KAAK3B,SAAS,EAAE;;QAE3B;;MAGF,IAAIqG,KAAK,CAAC1E,GAAG,CAACf,WAAW,EAAE,KAAK,MAAM,EAAE;QACtCS,eAAe,UAAO,CAACgF,KAAK,CAAC1E,GAAG,CAACf,WAAW,EAAE,CAAC;OAChD,MAAM;;QAELS,eAAe,CAACqF,KAAK,EAAE;;MAGzB,IAAIhB,eAAe,YAAfA,eAAe,CAAEc,KAAK,EAAE;QAC1BZ,QAAQ,CAACS,KAAK,CAAC;;KAElB;;IAGD,CAAC5B,GAAG,CAACE,OAAO,IAAImB,QAAQ,EAAEa,gBAAgB,CAAC,OAAO,EAAEF,WAAW,CAAC;;IAEhE,CAAChC,GAAG,CAACE,OAAO,IAAImB,QAAQ,EAAEa,gBAAgB,CAAC,SAAS,EAAEP,aAAa,CAAC;IAEpE,IAAIT,KAAK,EAAE;MACTnH,kBAAkB,CAACC,IAAI,EAAEiH,eAAe,oBAAfA,eAAe,CAAEhH,QAAQ,CAAC,CAACyH,OAAO,CAAC,UAACxE,GAAG;QAAA,OAAKgE,KAAK,CAACpD,SAAS,CAAC3D,WAAW,CAAC+C,GAAG,EAAE+D,eAAe,oBAAfA,eAAe,CAAE5G,cAAc,CAAC,CAAC;QAAC;;IAG1I,OAAO;;MAEL,CAAC2F,GAAG,CAACE,OAAO,IAAImB,QAAQ,EAAEc,mBAAmB,CAAC,OAAO,EAAEH,WAAW,CAAC;;MAEnE,CAAChC,GAAG,CAACE,OAAO,IAAImB,QAAQ,EAAEc,mBAAmB,CAAC,SAAS,EAAER,aAAa,CAAC;MAEvE,IAAIT,KAAK,EAAE;QACTnH,kBAAkB,CAACC,IAAI,EAAEiH,eAAe,oBAAfA,eAAe,CAAEhH,QAAQ,CAAC,CAACyH,OAAO,CAAC,UAACxE,GAAG;UAAA,OAAKgE,KAAK,CAACnD,YAAY,CAAC5D,WAAW,CAAC+C,GAAG,EAAE+D,eAAe,oBAAfA,eAAe,CAAE5G,cAAc,CAAC,CAAC;UAAC;;KAE9I;GACF,EAAE,CAACL,IAAI,EAAE+G,EAAE,EAAEE,eAAe,EAAE7C,aAAa,CAAC,CAAC;EAE9C,OAAO4B,GAAG;AACZ;;AClIA,IAAMoC,oBAAoB,gBAAgB,IAAIjD,GAAG,EAAU;AAE3D,SAAgBkD,eAAe,CAACnF,GAAsB,EAAEjD;MAAAA;IAAAA,WAAmB,GAAG;;EAC5E,IAAMqI,WAAW,GAAGvG,KAAK,CAACwG,OAAO,CAACrF,GAAG,CAAC,GAAGA,GAAG,GAAGA,GAAG,CAAChD,KAAK,CAACD,QAAQ,CAAC;EAElE,OAAOqI,WAAW,CAAC/E,KAAK,CAAC,UAACnD,MAAM;IAC9B,IAAMoI,YAAY,GAAGrI,WAAW,CAACC,MAAM,CAAC;IAExC,qDAA4BgI,oBAAoB,wCAAE;MAAA,IAAvCK,aAAa;MACtB,IAAIjD,SAAS,CAACgD,YAAY,EAAEC,aAAa,CAAC,EAAE;QAC1C,OAAO,IAAI;;;GAGhB,CAAC;AACJ;AAEA,SAAgBC,0BAA0B,CAACxF,GAAsB;EAC/D,IAAMoF,WAAW,GAAGvG,KAAK,CAACwG,OAAO,CAACrF,GAAG,CAAC,GAAGA,GAAG,GAAG,CAACA,GAAG,CAAC;EAEpDoF,WAAW,CAACZ,OAAO,CAAC,UAAAtH,MAAM;IAAA,OAAIgI,oBAAoB,CAACP,GAAG,CAAC1H,WAAW,CAACC,MAAM,CAAC,CAAC;IAAC;AAC9E;AAEA,SAAgBuI,8BAA8B,CAACzF,GAAsB;EACnE,IAAMoF,WAAW,GAAGvG,KAAK,CAACwG,OAAO,CAACrF,GAAG,CAAC,GAAGA,GAAG,GAAG,CAACA,GAAG,CAAC;EAEpDoF,WAAW,CAACZ,OAAO,CAAC,UAACtH,MAAM;IACzB,IAAMoI,YAAY,GAAGrI,WAAW,CAACC,MAAM,CAAC;IAExC,sDAA4BgI,oBAAoB,2CAAE;MAAA;MAAA,IAAvCK,aAAa;MACtB,2BAAIA,aAAa,CAACzI,IAAI,aAAlB,oBAAoBuD,KAAK,CAAC,UAACL,GAAG;QAAA;QAAA,6BAAKsF,YAAY,CAACxI,IAAI,qBAAjB,mBAAmBY,QAAQ,CAACsC,GAAG,CAAC;QAAC,EAAE;QACxEkF,oBAAoB,UAAO,CAACK,aAAa,CAAC;;;GAG/C,CAAC;AACJ;AAEA,CAAC;EACC,IAAI,OAAOnC,MAAM,KAAK,WAAW,EAAE;IACjCA,MAAM,CAAC4B,gBAAgB,CAAC,kBAAkB,EAAE;MAC1Cb,QAAQ,CAACa,gBAAgB,CAAC,SAAS,EAAE,UAAA/G,CAAC;QACpC,IAAIA,CAAC,CAAC+B,GAAG,KAAK3B,SAAS,EAAE;;UAEvB;;QAGFmH,0BAA0B,CAACvH,CAAC,CAAC+B,GAAG,CAAC;OAClC,CAAC;MAEFmE,QAAQ,CAACa,gBAAgB,CAAC,OAAO,EAAE,UAAA/G,CAAC;QAClC,IAAIA,CAAC,CAAC+B,GAAG,KAAK3B,SAAS,EAAE;;UAEvB;;QAGFoH,8BAA8B,CAACxH,CAAC,CAAC+B,GAAG,CAAC;OACtC,CAAC;KACH,CAAC;;AAEN,CAAC,GAAG;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"react-hotkeys-hook.cjs.development.js","sources":["../src/parseHotkeys.ts","../src/deepEqual.ts","../src/isHotkeyPressed.ts","../src/validators.ts","../src/BoundHotkeysProxyProvider.tsx","../src/HotkeysProvider.tsx","../src/useDeepEqualMemo.ts","../src/useHotkeys.ts"],"sourcesContent":["import { Hotkey, KeyboardModifiers, Keys } from './types'\n\nconst reservedModifierKeywords = ['shift', 'alt', 'meta', 'mod']\n\nconst mappedKeys: Record<string, string> = {\n esc: 'escape',\n return: 'enter',\n left: 'arrowleft',\n up: 'arrowup',\n right: 'arrowright',\n down: 'arrowdown',\n '1': 'digit1',\n '2': 'digit2',\n '3': 'digit3',\n '4': 'digit4',\n '5': 'digit5',\n '6': 'digit6',\n '7': 'digit7',\n '8': 'digit8',\n '9': 'digit9',\n}\n\nexport function parseKeysHookInput(keys: Keys, splitKey: string = ','): string[] {\n if (typeof keys === 'string') {\n return keys.split(splitKey)\n }\n\n return keys\n}\n\nexport function parseHotkey(hotkey: string, combinationKey: string = '+'): Hotkey {\n const keys = hotkey\n .toLocaleLowerCase()\n .split(combinationKey)\n .map(k => k.trim())\n .map(k => mappedKeys[k] || k)\n\n const modifiers: KeyboardModifiers = {\n alt: keys.includes('alt'),\n shift: keys.includes('shift'),\n meta: keys.includes('meta'),\n mod: keys.includes('mod'),\n }\n\n const singleCharKeys = keys.filter((k) => !reservedModifierKeywords.includes(k))\n\n return {\n ...modifiers,\n keys: singleCharKeys,\n }\n}\n","export default function deepEqual(x: any, y: any): boolean {\n //@ts-ignore\n return (x && y && typeof x === 'object' && typeof y === 'object')\n //@ts-ignore\n ? (Object.keys(x).length === Object.keys(y).length) && Object.keys(x).reduce(function(isEqual, key) {\n return isEqual && deepEqual(x[key], y[key])\n }, true)\n : (x === y)\n}\n","import { Hotkey } from './types'\nimport { parseHotkey } from './parseHotkeys'\nimport deepEqual from './deepEqual'\n\nconst currentlyPressedKeys: Set<Hotkey> = new Set<Hotkey>()\n\nexport function isHotkeyPressed(key: string | string[], splitKey: string = ','): boolean {\n const hotkeyArray = Array.isArray(key) ? key : key.split(splitKey)\n\n return hotkeyArray.every((hotkey) => {\n const parsedHotkey = parseHotkey(hotkey)\n\n for (const pressedHotkey of currentlyPressedKeys) {\n if (deepEqual(parsedHotkey, pressedHotkey)) {\n return true\n }\n }\n })\n}\n\nfunction pushToCurrentlyPressedKeys(key: string | string[]): void {\n const hotkeyArray = Array.isArray(key) ? key : [key]\n\n hotkeyArray.forEach(hotkey => currentlyPressedKeys.add(parseHotkey(hotkey)))\n}\n\nfunction removeFromCurrentlyPressedKeys(key: string | string[]): void {\n const hotkeyArray = Array.isArray(key) ? key : [key]\n\n hotkeyArray.forEach((hotkey) => {\n const parsedHotkey = parseHotkey(hotkey)\n\n for (const pressedHotkey of currentlyPressedKeys) {\n if (deepEqual(parsedHotkey, pressedHotkey)) {\n currentlyPressedKeys.delete(pressedHotkey)\n }\n }\n })\n}\n\n(() => {\n if (typeof window !== 'undefined') {\n window.addEventListener('DOMContentLoaded', () => {\n document.addEventListener('keydown', e => {\n if (e.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n pushToCurrentlyPressedKeys(e.key)\n })\n\n document.addEventListener('keyup', e => {\n if (e.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n removeFromCurrentlyPressedKeys(e.key)\n })\n })\n }\n})()\n","import { FormTags, Hotkey, Scopes, Trigger } from './types'\nimport { isHotkeyPressed } from './isHotkeyPressed'\n\nexport function maybePreventDefault(e: KeyboardEvent, hotkey: Hotkey, preventDefault?: Trigger): void {\n if ((typeof preventDefault === 'function' && preventDefault(e, hotkey)) || preventDefault === true) {\n e.preventDefault()\n }\n}\n\nexport function isHotkeyEnabled(e: KeyboardEvent, hotkey: Hotkey, enabled?: Trigger): boolean {\n if (typeof enabled === 'function') {\n return enabled(e, hotkey)\n }\n\n return enabled === true || enabled === undefined\n}\n\nexport function isKeyboardEventTriggeredByInput(ev: KeyboardEvent): boolean {\n return isHotkeyEnabledOnTag(ev, ['input', 'textarea', 'select'])\n}\n\nexport function isHotkeyEnabledOnTag({ target }: KeyboardEvent, enabledOnTags: FormTags[] | boolean = false): boolean {\n const targetTagName = target && (target as HTMLElement).tagName\n\n if (enabledOnTags instanceof Array) {\n return Boolean(targetTagName && enabledOnTags && enabledOnTags.some(tag => tag.toLowerCase() === targetTagName.toLowerCase()))\n }\n\n return Boolean(targetTagName && enabledOnTags && enabledOnTags === true)\n}\n\nexport function isScopeActive(activeScopes: string[], scopes?: Scopes): boolean {\n if (activeScopes.length === 0 && scopes) {\n console.warn(\n 'A hotkey has the \"scopes\" option set, however no active scopes were found. If you want to use the global scopes feature, you need to wrap your app in a <HotkeysProvider>'\n )\n\n return true\n }\n\n if (!scopes) {\n return true\n }\n\n return activeScopes.some(scope => scopes.includes(scope)) || activeScopes.includes('*')\n}\n\nexport const isHotkeyMatchingKeyboardEvent = (e: KeyboardEvent, hotkey: Hotkey, pressedDownKeys: Set<string>): boolean => {\n const { alt, meta, mod, shift, keys } = hotkey\n const { key: pressedKeyUppercase, code } = e\n\n const altKey = isHotkeyPressed('alt')\n const shiftKey = isHotkeyPressed('shift')\n const metaKey = isHotkeyPressed('meta')\n const ctrlKey = isHotkeyPressed('ctrl')\n\n const keyCode = code.toLowerCase().replace('key', '')\n const pressedKey = pressedKeyUppercase.toLowerCase()\n\n if (altKey !== alt && pressedKey !== 'alt') {\n return false\n }\n\n if (shiftKey !== shift && pressedKey !== 'shift') {\n return false\n }\n\n // Mod is a special key name that is checking for meta on macOS and ctrl on other platforms\n if (mod) {\n if (!metaKey && !ctrlKey) {\n return false\n }\n } else {\n if (metaKey !== meta && ctrlKey !== meta && keyCode !== 'meta' && keyCode !== 'ctrl') {\n return false\n }\n }\n\n // All modifiers are correct, now check the key\n // If the key is set, we check for the key\n if (keys && keys.length === 1 && (keys.includes(pressedKey) || keys.includes(keyCode))) {\n return true\n } else if (keys) {\n // Check if all keys are present in pressedDownKeys set\n return keys.every(key => pressedDownKeys.has(key))\n }\n else if (!keys) {\n // If the key is not set, we only listen for modifiers, that check went alright, so we return true\n return true\n }\n\n // There is nothing that matches.\n return false\n}\n","import { createContext, ReactNode, useContext } from 'react'\nimport { Hotkey } from './types'\n\ntype BoundHotkeysProxyProviderType = {\n addHotkey: (hotkey: Hotkey) => void,\n removeHotkey: (hotkey: Hotkey) => void,\n}\n\nconst BoundHotkeysProxyProvider = createContext<BoundHotkeysProxyProviderType | undefined>(undefined)\n\nexport const useBoundHotkeysProxy = () => {\n return useContext(BoundHotkeysProxyProvider)\n}\n\ninterface Props {\n children: ReactNode\n addHotkey: (hotkey: Hotkey) => void\n removeHotkey: (hotkey: Hotkey) => void\n}\n\nexport default function BoundHotkeysProxyProviderProvider({ addHotkey, removeHotkey, children }: Props) {\n return <BoundHotkeysProxyProvider.Provider value={{addHotkey, removeHotkey}}>{children}</BoundHotkeysProxyProvider.Provider>\n}\n","import { Hotkey } from './types'\nimport { createContext, ReactNode, useState, useContext, useCallback } from 'react'\nimport BoundHotkeysProxyProviderProvider from './BoundHotkeysProxyProvider'\nimport deepEqual from './deepEqual'\n\nexport type HotkeysContextType = {\n hotkeys: ReadonlyArray<Hotkey>\n enabledScopes: string[]\n toggleScope: (scope: string) => void\n enableScope: (scope: string) => void\n disableScope: (scope: string) => void\n}\n\n// The context is only needed for special features like global scoping, so we use a graceful default fallback\nconst HotkeysContext = createContext<HotkeysContextType>({\n hotkeys: [],\n enabledScopes: [], // This array has to be empty instead of containing '*' as default, to check if the provider is set or not\n toggleScope: () => {},\n enableScope: () => {},\n disableScope: () => {},\n})\n\nexport const useHotkeysContext = () => {\n return useContext(HotkeysContext)\n}\n\ninterface Props {\n initiallyActiveScopes?: string[]\n children: ReactNode\n}\n\nexport const HotkeysProvider = ({initiallyActiveScopes = ['*'], children}: Props) => {\n const [internalActiveScopes, setInternalActiveScopes] = useState(initiallyActiveScopes?.length > 0 ? initiallyActiveScopes : ['*'])\n const [boundHotkeys, setBoundHotkeys] = useState<Hotkey[]>([]);\n\n const enableScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.includes('*')) {\n return [scope]\n }\n\n return Array.from(new Set([...prev, scope]))\n })\n }, [])\n\n const disableScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.filter(s => s !== scope).length === 0) {\n return ['*']\n } else {\n return prev.filter(s => s !== scope)\n }\n })\n }, [])\n\n const toggleScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.includes(scope)) {\n if (prev.filter(s => s !== scope).length === 0) {\n return ['*']\n } else {\n return prev.filter(s => s !== scope)\n }\n } else {\n if (prev.includes('*')) {\n return [scope]\n }\n\n return Array.from(new Set([...prev, scope]))\n }\n })\n }, [])\n\n const addBoundHotkey = useCallback((hotkey: Hotkey) => {\n setBoundHotkeys((prev) => [...prev, hotkey])\n }, [])\n\n const removeBoundHotkey = useCallback((hotkey: Hotkey) => {\n setBoundHotkeys((prev) => prev.filter(h => !deepEqual(h, hotkey)))\n }, [])\n\n return (\n <HotkeysContext.Provider value={{enabledScopes: internalActiveScopes, hotkeys: boundHotkeys, enableScope, disableScope, toggleScope}}>\n <BoundHotkeysProxyProviderProvider addHotkey={addBoundHotkey} removeHotkey={removeBoundHotkey}>\n {children}\n </BoundHotkeysProxyProviderProvider>\n </HotkeysContext.Provider>\n )\n}\n","import { useRef } from 'react'\nimport deepEqual from './deepEqual'\n\nexport default function useDeepEqualMemo<T>(value: T) {\n const ref = useRef<T | undefined>(undefined)\n\n if (!deepEqual(ref.current, value)) {\n ref.current = value\n }\n\n return ref.current\n}\n","import { HotkeyCallback, Keys, Options, OptionsOrDependencyArray, RefType } from './types'\nimport { DependencyList, useCallback, useEffect, useLayoutEffect, useRef } from 'react'\nimport { parseHotkey, parseKeysHookInput } from './parseHotkeys'\nimport {\n isHotkeyEnabled,\n isHotkeyEnabledOnTag,\n isHotkeyMatchingKeyboardEvent,\n isKeyboardEventTriggeredByInput,\n isScopeActive,\n maybePreventDefault,\n} from './validators'\nimport { useHotkeysContext } from './HotkeysProvider'\nimport { useBoundHotkeysProxy } from './BoundHotkeysProxyProvider'\nimport useDeepEqualMemo from './useDeepEqualMemo'\n\nconst stopPropagation = (e: KeyboardEvent): void => {\n e.stopPropagation()\n e.preventDefault()\n e.stopImmediatePropagation()\n}\n\nconst useSafeLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect\n\nconst pressedDownKeys = new Set<string>()\n\nexport default function useHotkeys<T extends HTMLElement>(\n keys: Keys,\n callback: HotkeyCallback,\n options?: OptionsOrDependencyArray,\n dependencies?: OptionsOrDependencyArray,\n) {\n const ref = useRef<RefType<T>>(null)\n\n const _options: Options | undefined = !(options instanceof Array) ? (options as Options) : !(dependencies instanceof Array) ? (dependencies as Options) : undefined\n const _deps: DependencyList = options instanceof Array ? options : dependencies instanceof Array ? dependencies : []\n\n const cb = useCallback(callback, [..._deps])\n const memoisedOptions = useDeepEqualMemo(_options)\n\n const { enabledScopes } = useHotkeysContext()\n const proxy = useBoundHotkeysProxy()\n\n useSafeLayoutEffect(() => {\n if (memoisedOptions?.enabled === false || !isScopeActive(enabledScopes, memoisedOptions?.scopes)) {\n return\n }\n\n const listener = (e: KeyboardEvent) => {\n if (isKeyboardEventTriggeredByInput(e) && !isHotkeyEnabledOnTag(e, memoisedOptions?.enableOnFormTags)) {\n return\n }\n\n // TODO: SINCE THE EVENT IS NOW ATTACHED TO THE REF, THE ACTIVE ELEMENT CAN NEVER BE INSIDE THE REF. THE HOTKEY ONLY TRIGGERS IF THE\n // REF IS THE ACTIVE ELEMENT. THIS IS A PROBLEM SINCE FOCUSED SUB COMPONENTS WON'T TRIGGER THE HOTKEY.\n if (ref.current !== null && document.activeElement !== ref.current && !ref.current.contains(document.activeElement)) {\n stopPropagation(e)\n\n return\n }\n\n if (((e.target as HTMLElement)?.isContentEditable && !memoisedOptions?.enableOnContentEditable)) {\n return\n }\n\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => {\n const hotkey = parseHotkey(key, memoisedOptions?.combinationKey)\n\n if (isHotkeyMatchingKeyboardEvent(e, hotkey, pressedDownKeys) || hotkey.keys?.includes('*')) {\n maybePreventDefault(e, hotkey, memoisedOptions?.preventDefault)\n\n if (!isHotkeyEnabled(e, hotkey, memoisedOptions?.enabled)) {\n stopPropagation(e)\n\n return\n }\n\n cb(e, hotkey)\n }\n })\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n pressedDownKeys.add(event.key.toLowerCase())\n\n if ((memoisedOptions?.keydown === undefined && memoisedOptions?.keyup !== true) || memoisedOptions?.keydown) {\n listener(event)\n }\n }\n\n const handleKeyUp = (event: KeyboardEvent) => {\n if (event.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n if (event.key.toLowerCase() !== 'meta') {\n pressedDownKeys.delete(event.key.toLowerCase())\n } else {\n // On macOS pressing down the meta key prevents triggering the keyup event for any other key https://stackoverflow.com/a/57153300/735226.\n pressedDownKeys.clear()\n }\n\n if (memoisedOptions?.keyup) {\n listener(event)\n }\n }\n\n // @ts-ignore\n (ref.current || document).addEventListener('keyup', handleKeyUp);\n // @ts-ignore\n (ref.current || document).addEventListener('keydown', handleKeyDown)\n\n if (proxy) {\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => proxy.addHotkey(parseHotkey(key, memoisedOptions?.combinationKey)))\n }\n\n return () => {\n // @ts-ignore\n (ref.current || document).removeEventListener('keyup', handleKeyUp);\n // @ts-ignore\n (ref.current || document).removeEventListener('keydown', handleKeyDown)\n\n if (proxy) {\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => proxy.removeHotkey(parseHotkey(key, memoisedOptions?.combinationKey)))\n }\n }\n }, [keys, cb, memoisedOptions, enabledScopes])\n\n return ref\n}\n"],"names":["reservedModifierKeywords","mappedKeys","esc","left","up","right","down","parseKeysHookInput","keys","splitKey","split","parseHotkey","hotkey","combinationKey","toLocaleLowerCase","map","k","trim","modifiers","alt","includes","shift","meta","mod","singleCharKeys","filter","deepEqual","x","y","Object","length","reduce","isEqual","key","currentlyPressedKeys","Set","isHotkeyPressed","hotkeyArray","Array","isArray","every","parsedHotkey","pressedHotkey","pushToCurrentlyPressedKeys","forEach","add","removeFromCurrentlyPressedKeys","window","addEventListener","document","e","undefined","maybePreventDefault","preventDefault","isHotkeyEnabled","enabled","isKeyboardEventTriggeredByInput","ev","isHotkeyEnabledOnTag","enabledOnTags","target","targetTagName","tagName","Boolean","some","tag","toLowerCase","isScopeActive","activeScopes","scopes","console","warn","scope","isHotkeyMatchingKeyboardEvent","pressedDownKeys","pressedKeyUppercase","code","altKey","shiftKey","metaKey","ctrlKey","keyCode","replace","pressedKey","has","BoundHotkeysProxyProvider","createContext","useBoundHotkeysProxy","useContext","BoundHotkeysProxyProviderProvider","addHotkey","removeHotkey","children","_jsx","HotkeysContext","hotkeys","enabledScopes","toggleScope","enableScope","disableScope","useHotkeysContext","HotkeysProvider","initiallyActiveScopes","useState","internalActiveScopes","setInternalActiveScopes","boundHotkeys","setBoundHotkeys","useCallback","prev","from","s","addBoundHotkey","removeBoundHotkey","h","useDeepEqualMemo","value","ref","useRef","current","stopPropagation","stopImmediatePropagation","useSafeLayoutEffect","useLayoutEffect","useEffect","useHotkeys","callback","options","dependencies","_options","_deps","cb","memoisedOptions","proxy","listener","enableOnFormTags","activeElement","contains","isContentEditable","enableOnContentEditable","handleKeyDown","event","keydown","keyup","handleKeyUp","clear","removeEventListener"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var e=require("react"),t=require("react/jsx-runtime");function n(){return(n=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function r(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function o(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(n)return(n=n.call(e)).next.bind(n);if(Array.isArray(e)||(n=function(e,t){if(e){if("string"==typeof e)return r(e,void 0);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?r(e,void 0):void 0}}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var o=0;return function(){return o>=e.length?{done:!0}:{done:!1,value:e[o++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i=["shift","alt","meta","mod"],u={esc:"escape",return:"enter",left:"arrowleft",up:"arrowup",right:"arrowright",down:"arrowdown",1:"digit1",2:"digit2",3:"digit3",4:"digit4",5:"digit5",6:"digit6",7:"digit7",8:"digit8",9:"digit9"};function a(e,t){return void 0===t&&(t=","),"string"==typeof e?e.split(t):e}function c(e,t){void 0===t&&(t="+");var r=e.toLocaleLowerCase().split(t).map((function(e){return e.trim()})).map((function(e){return u[e]||e}));return n({},{alt:r.includes("alt"),shift:r.includes("shift"),meta:r.includes("meta"),mod:r.includes("mod")},{keys:r.filter((function(e){return!i.includes(e)}))})}function l(e,t){
|
|
1
|
+
"use strict";var e=require("react"),t=require("react/jsx-runtime");function n(){return(n=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function r(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function o(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(n)return(n=n.call(e)).next.bind(n);if(Array.isArray(e)||(n=function(e,t){if(e){if("string"==typeof e)return r(e,void 0);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?r(e,void 0):void 0}}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var o=0;return function(){return o>=e.length?{done:!0}:{done:!1,value:e[o++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i=["shift","alt","meta","mod"],u={esc:"escape",return:"enter",left:"arrowleft",up:"arrowup",right:"arrowright",down:"arrowdown",1:"digit1",2:"digit2",3:"digit3",4:"digit4",5:"digit5",6:"digit6",7:"digit7",8:"digit8",9:"digit9"};function a(e,t){return void 0===t&&(t=","),"string"==typeof e?e.split(t):e}function c(e,t){void 0===t&&(t="+");var r=e.toLocaleLowerCase().split(t).map((function(e){return e.trim()})).map((function(e){return u[e]||e}));return n({},{alt:r.includes("alt"),shift:r.includes("shift"),meta:r.includes("meta"),mod:r.includes("mod")},{keys:r.filter((function(e){return!i.includes(e)}))})}function l(e,t){return e&&t&&"object"==typeof e&&"object"==typeof t?Object.keys(e).length===Object.keys(t).length&&Object.keys(e).reduce((function(n,r){return n&&l(e[r],t[r])}),!0):e===t}var d=new Set;function s(e,t){return void 0===t&&(t=","),(Array.isArray(e)?e:e.split(t)).every((function(e){for(var t,n=c(e),r=o(d);!(t=r()).done;)if(l(n,t.value))return!0}))}function f(e,t){var n=e.target;void 0===t&&(t=!1);var r=n&&n.tagName;return t instanceof Array?Boolean(r&&t&&t.some((function(e){return e.toLowerCase()===r.toLowerCase()}))):Boolean(r&&t&&!0===t)}"undefined"!=typeof window&&window.addEventListener("DOMContentLoaded",(function(){document.addEventListener("keydown",(function(e){var t;void 0!==e.key&&(t=e.key,(Array.isArray(t)?t:[t]).forEach((function(e){return d.add(c(e))})))})),document.addEventListener("keyup",(function(e){var t;void 0!==e.key&&(t=e.key,(Array.isArray(t)?t:[t]).forEach((function(e){for(var t,n=c(e),r=o(d);!(t=r()).done;){var i=t.value;l(n,i)&&d.delete(i)}})))}))}));var v=e.createContext(void 0);function y(e){return t.jsx(v.Provider,{value:{addHotkey:e.addHotkey,removeHotkey:e.removeHotkey},children:e.children})}var p=e.createContext({hotkeys:[],enabledScopes:[],toggleScope:function(){},enableScope:function(){},disableScope:function(){}}),m=function(){return e.useContext(p)},k=function(e){e.stopPropagation(),e.preventDefault(),e.stopImmediatePropagation()},b="undefined"!=typeof window?e.useLayoutEffect:e.useEffect,h=new Set;exports.HotkeysProvider=function(n){var r=n.initiallyActiveScopes,o=void 0===r?["*"]:r,i=n.children,u=e.useState((null==o?void 0:o.length)>0?o:["*"]),a=u[0],c=u[1],d=e.useState([]),s=d[0],f=d[1],v=e.useCallback((function(e){c((function(t){return t.includes("*")?[e]:Array.from(new Set([].concat(t,[e])))}))}),[]),m=e.useCallback((function(e){c((function(t){return 0===t.filter((function(t){return t!==e})).length?["*"]:t.filter((function(t){return t!==e}))}))}),[]),k=e.useCallback((function(e){c((function(t){return t.includes(e)?0===t.filter((function(t){return t!==e})).length?["*"]:t.filter((function(t){return t!==e})):t.includes("*")?[e]:Array.from(new Set([].concat(t,[e])))}))}),[]),b=e.useCallback((function(e){f((function(t){return[].concat(t,[e])}))}),[]),h=e.useCallback((function(e){f((function(t){return t.filter((function(t){return!l(t,e)}))}))}),[]);return t.jsx(p.Provider,{value:{enabledScopes:a,hotkeys:s,enableScope:v,disableScope:m,toggleScope:k},children:t.jsx(y,{addHotkey:b,removeHotkey:h,children:i})})},exports.isHotkeyPressed=s,exports.useHotkeys=function(t,n,r,o){var i=e.useRef(null),u=r instanceof Array?o instanceof Array?void 0:o:r,d=e.useCallback(n,[].concat(r instanceof Array?r:o instanceof Array?o:[])),y=function(t){var n=e.useRef(void 0);return l(n.current,t)||(n.current=t),n.current}(u),p=m().enabledScopes,g=e.useContext(v);return b((function(){if(!1!==(null==y?void 0:y.enabled)&&(n=null==y?void 0:y.scopes,0===(e=p).length&&n?(console.warn('A hotkey has the "scopes" option set, however no active scopes were found. If you want to use the global scopes feature, you need to wrap your app in a <HotkeysProvider>'),1):!n||e.some((function(e){return n.includes(e)}))||e.includes("*"))){var e,n,r=function(e){var n;f(e,["input","textarea","select"])&&!f(e,null==y?void 0:y.enableOnFormTags)||(null===i.current||document.activeElement===i.current||i.current.contains(document.activeElement)?(null==(n=e.target)||!n.isContentEditable||null!=y&&y.enableOnContentEditable)&&a(t,null==y?void 0:y.splitKey).forEach((function(t){var n,r=c(t,null==y?void 0:y.combinationKey);if(function(e,t,n){var r=t.alt,o=t.meta,i=t.mod,u=t.shift,a=t.keys,c=e.key,l=e.code,d=s("alt"),f=s("shift"),v=s("meta"),y=s("ctrl"),p=l.toLowerCase().replace("key",""),m=c.toLowerCase();if(d!==r&&"alt"!==m)return!1;if(f!==u&&"shift"!==m)return!1;if(i){if(!v&&!y)return!1}else if(v!==o&&y!==o&&"meta"!==p&&"ctrl"!==p)return!1;return!(!a||1!==a.length||!a.includes(m)&&!a.includes(p))||(a?a.every((function(e){return n.has(e)})):!a)}(e,r,h)||null!=(n=r.keys)&&n.includes("*")){if(function(e,t,n){("function"==typeof n&&n(e,t)||!0===n)&&e.preventDefault()}(e,r,null==y?void 0:y.preventDefault),!function(e,t,n){return"function"==typeof n?n(e,t):!0===n||void 0===n}(e,r,null==y?void 0:y.enabled))return void k(e);d(e,r)}})):k(e))},o=function(e){void 0!==e.key&&(h.add(e.key.toLowerCase()),(void 0===(null==y?void 0:y.keydown)&&!0!==(null==y?void 0:y.keyup)||null!=y&&y.keydown)&&r(e))},u=function(e){void 0!==e.key&&("meta"!==e.key.toLowerCase()?h.delete(e.key.toLowerCase()):h.clear(),null!=y&&y.keyup&&r(e))};return(i.current||document).addEventListener("keyup",u),(i.current||document).addEventListener("keydown",o),g&&a(t,null==y?void 0:y.splitKey).forEach((function(e){return g.addHotkey(c(e,null==y?void 0:y.combinationKey))})),function(){(i.current||document).removeEventListener("keyup",u),(i.current||document).removeEventListener("keydown",o),g&&a(t,null==y?void 0:y.splitKey).forEach((function(e){return g.removeHotkey(c(e,null==y?void 0:y.combinationKey))}))}}}),[t,d,y,p]),i},exports.useHotkeysContext=m;
|
|
2
2
|
//# sourceMappingURL=react-hotkeys-hook.cjs.production.min.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react-hotkeys-hook.cjs.production.min.js","sources":["../src/parseHotkeys.ts","../src/validators.ts","../src/BoundHotkeysProxyProvider.tsx","../src/HotkeysProvider.tsx","../src/deepEqual.ts","../src/useHotkeys.ts","../src/isHotkeyPressed.ts","../src/useDeepEqualMemo.ts"],"sourcesContent":["import { Hotkey, KeyboardModifiers, Keys } from './types'\n\nconst reservedModifierKeywords = ['shift', 'alt', 'meta', 'mod']\n\nconst mappedKeys: Record<string, string> = {\n esc: 'escape',\n return: 'enter',\n left: 'arrowleft',\n up: 'arrowup',\n right: 'arrowright',\n down: 'arrowdown',\n '1': 'digit1',\n '2': 'digit2',\n '3': 'digit3',\n '4': 'digit4',\n '5': 'digit5',\n '6': 'digit6',\n '7': 'digit7',\n '8': 'digit8',\n '9': 'digit9',\n}\n\nexport function parseKeysHookInput(keys: Keys, splitKey: string = ','): string[] {\n if (typeof keys === 'string') {\n return keys.split(splitKey)\n }\n\n return keys\n}\n\nexport function parseHotkey(hotkey: string, combinationKey: string = '+'): Hotkey {\n const keys = hotkey\n .toLocaleLowerCase()\n .split(combinationKey)\n .map(k => k.trim())\n .map(k => mappedKeys[k] || k)\n\n const modifiers: KeyboardModifiers = {\n alt: keys.includes('alt'),\n shift: keys.includes('shift'),\n meta: keys.includes('meta'),\n mod: keys.includes('mod'),\n }\n\n const singleCharKeys = keys.filter((k) => !reservedModifierKeywords.includes(k))\n\n return {\n ...modifiers,\n keys: singleCharKeys,\n }\n}\n","import { FormTags, Hotkey, Scopes, Trigger } from './types'\n\nexport function maybePreventDefault(e: KeyboardEvent, hotkey: Hotkey, preventDefault?: Trigger): void {\n if ((typeof preventDefault === 'function' && preventDefault(e, hotkey)) || preventDefault === true) {\n e.preventDefault()\n }\n}\n\nexport function isHotkeyEnabled(e: KeyboardEvent, hotkey: Hotkey, enabled?: Trigger): boolean {\n if (typeof enabled === 'function') {\n return enabled(e, hotkey)\n }\n\n return enabled === true || enabled === undefined\n}\n\nexport function isKeyboardEventTriggeredByInput(ev: KeyboardEvent): boolean {\n return isHotkeyEnabledOnTag(ev, ['input', 'textarea', 'select'])\n}\n\nexport function isHotkeyEnabledOnTag({ target }: KeyboardEvent, enabledOnTags: FormTags[] | boolean = false): boolean {\n const targetTagName = target && (target as HTMLElement).tagName\n\n if (enabledOnTags instanceof Array) {\n return Boolean(targetTagName && enabledOnTags && enabledOnTags.some(tag => tag.toLowerCase() === targetTagName.toLowerCase()))\n }\n\n return Boolean(targetTagName && enabledOnTags && enabledOnTags === true)\n}\n\nexport function isScopeActive(activeScopes: string[], scopes?: Scopes): boolean {\n if (activeScopes.length === 0 && scopes) {\n console.warn(\n 'A hotkey has the \"scopes\" option set, however no active scopes were found. If you want to use the global scopes feature, you need to wrap your app in a <HotkeysProvider>'\n )\n\n return true\n }\n\n if (!scopes) {\n return true\n }\n\n return activeScopes.some(scope => scopes.includes(scope)) || activeScopes.includes('*')\n}\n\nexport const isHotkeyMatchingKeyboardEvent = (e: KeyboardEvent, hotkey: Hotkey, pressedDownKeys: Set<string>): boolean => {\n const { alt, meta, mod, shift, keys } = hotkey\n const { altKey, ctrlKey, metaKey, shiftKey, key: pressedKeyUppercase, code } = e\n\n const keyCode = code.toLowerCase().replace('key', '')\n const pressedKey = pressedKeyUppercase.toLowerCase()\n\n if (altKey !== alt && pressedKey !== 'alt') {\n return false\n }\n\n if (shiftKey !== shift && pressedKey !== 'shift') {\n return false\n }\n\n // Mod is a special key name that is checking for meta on macOS and ctrl on other platforms\n if (mod) {\n if (!metaKey && !ctrlKey) {\n return false\n }\n } else {\n if (metaKey !== meta && ctrlKey !== meta && keyCode !== 'meta' && keyCode !== 'ctrl') {\n return false\n }\n }\n\n // All modifiers are correct, now check the key\n // If the key is set we check for the key\n if (keys && keys.length === 1 && (keys.includes(pressedKey) || keys.includes(keyCode))) {\n return true\n } else if (keys) {\n // Check if all keys are present in pressedDownKeys set\n return keys.every(key => pressedDownKeys.has(key))\n }\n else if (!keys) {\n // If the key is not set, we only listen for modifiers, that check went alright, so we return true\n return true\n }\n\n // There is nothing that matches.\n return false\n}\n","import { createContext, ReactNode, useContext } from 'react'\nimport { Hotkey } from './types'\n\ntype BoundHotkeysProxyProviderType = {\n addHotkey: (hotkey: Hotkey) => void,\n removeHotkey: (hotkey: Hotkey) => void,\n}\n\nconst BoundHotkeysProxyProvider = createContext<BoundHotkeysProxyProviderType | undefined>(undefined)\n\nexport const useBoundHotkeysProxy = () => {\n return useContext(BoundHotkeysProxyProvider)\n}\n\ninterface Props {\n children: ReactNode\n addHotkey: (hotkey: Hotkey) => void\n removeHotkey: (hotkey: Hotkey) => void\n}\n\nexport default function BoundHotkeysProxyProviderProvider({ addHotkey, removeHotkey, children }: Props) {\n return <BoundHotkeysProxyProvider.Provider value={{addHotkey, removeHotkey}}>{children}</BoundHotkeysProxyProvider.Provider>\n}\n","import { Hotkey } from './types'\nimport { createContext, ReactNode, useMemo, useState, useContext } from 'react'\nimport BoundHotkeysProxyProviderProvider from './BoundHotkeysProxyProvider'\n\nexport type HotkeysContextType = {\n hotkeys: ReadonlyArray<Hotkey>\n enabledScopes: string[]\n toggleScope: (scope: string) => void\n enableScope: (scope: string) => void\n disableScope: (scope: string) => void\n}\n\n// The context is only needed for special features like global scoping, so we use a graceful default fallback\nconst HotkeysContext = createContext<HotkeysContextType>({\n hotkeys: [],\n enabledScopes: [], // This array has to be empty instead of containing '*' as default, to check if the provider is set or not\n toggleScope: () => {},\n enableScope: () => {},\n disableScope: () => {},\n})\n\nexport const useHotkeysContext = () => {\n return useContext(HotkeysContext)\n}\n\ninterface Props {\n initiallyActiveScopes?: string[]\n children: ReactNode\n}\n\nexport const HotkeysProvider = ({initiallyActiveScopes = ['*'], children}: Props) => {\n const [internalActiveScopes, setInternalActiveScopes] = useState(initiallyActiveScopes?.length > 0 ? initiallyActiveScopes : ['*'])\n const [boundHotkeys, setBoundHotkeys] = useState<Hotkey[]>([]);\n\n const isAllActive = useMemo(() => internalActiveScopes.includes('*'), [internalActiveScopes])\n\n const enableScope = (scope: string) => {\n if (isAllActive) {\n setInternalActiveScopes([scope])\n } else {\n setInternalActiveScopes(Array.from(new Set([...internalActiveScopes, scope])))\n }\n }\n\n const disableScope = (scope: string) => {\n const scopes = internalActiveScopes.filter(s => s !== scope)\n\n if (scopes.length === 0) {\n setInternalActiveScopes(['*'])\n } else {\n setInternalActiveScopes(scopes)\n }\n }\n\n const toggleScope = (scope: string) => {\n if (internalActiveScopes.includes(scope)) {\n disableScope(scope)\n } else {\n enableScope(scope)\n }\n }\n\n const addBoundHotkey = (hotkey: Hotkey) => {\n setBoundHotkeys([...boundHotkeys, hotkey])\n }\n\n const removeBoundHotkey = (hotkey: Hotkey) => {\n setBoundHotkeys(boundHotkeys.filter(h => h.keys !== hotkey.keys))\n }\n\n return (\n <HotkeysContext.Provider value={{enabledScopes: internalActiveScopes, hotkeys: boundHotkeys, enableScope, disableScope, toggleScope}}>\n <BoundHotkeysProxyProviderProvider addHotkey={addBoundHotkey} removeHotkey={removeBoundHotkey}>\n {children}\n </BoundHotkeysProxyProviderProvider>\n </HotkeysContext.Provider>\n )\n}\n","export default function deepEqual(x: any, y: any): boolean {\n //@ts-ignore\n return (x && y && typeof x === 'object' && typeof y === 'object')\n //@ts-ignore\n ? (Object.keys(x).length === Object.keys(y).length) && Object.keys(x).reduce(function(isEqual, key) {\n return isEqual && deepEqual(x[key], y[key])\n }, true)\n : (x === y)\n}\n","import { HotkeyCallback, Keys, Options, OptionsOrDependencyArray, RefType } from './types'\nimport { DependencyList, useCallback, useEffect, useLayoutEffect, useRef } from 'react'\nimport { parseHotkey, parseKeysHookInput } from './parseHotkeys'\nimport {\n isHotkeyEnabled,\n isHotkeyEnabledOnTag,\n isHotkeyMatchingKeyboardEvent,\n isKeyboardEventTriggeredByInput,\n isScopeActive,\n maybePreventDefault,\n} from './validators'\nimport { useHotkeysContext } from './HotkeysProvider'\nimport { useBoundHotkeysProxy } from './BoundHotkeysProxyProvider'\nimport useDeepEqualMemo from './useDeepEqualMemo'\n\nconst stopPropagation = (e: KeyboardEvent): void => {\n e.stopPropagation()\n e.preventDefault()\n e.stopImmediatePropagation()\n}\n\nconst useSafeLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect\n\nconst pressedDownKeys = new Set<string>()\n\nexport default function useHotkeys<T extends HTMLElement>(\n keys: Keys,\n callback: HotkeyCallback,\n options?: OptionsOrDependencyArray,\n dependencies?: OptionsOrDependencyArray,\n) {\n const ref = useRef<RefType<T>>(null)\n\n const _options: Options | undefined = !(options instanceof Array) ? (options as Options) : !(dependencies instanceof Array) ? (dependencies as Options) : undefined\n const _deps: DependencyList = options instanceof Array ? options : dependencies instanceof Array ? dependencies : []\n\n const cb = useCallback(callback, [..._deps])\n const memoisedOptions = useDeepEqualMemo(_options)\n\n const { enabledScopes } = useHotkeysContext()\n const proxy = useBoundHotkeysProxy()\n\n useSafeLayoutEffect(() => {\n if (memoisedOptions?.enabled === false || !isScopeActive(enabledScopes, memoisedOptions?.scopes)) {\n return\n }\n\n const listener = (e: KeyboardEvent) => {\n if (isKeyboardEventTriggeredByInput(e) && !isHotkeyEnabledOnTag(e, memoisedOptions?.enableOnFormTags)) {\n return\n }\n\n // TODO: SINCE THE EVENT IS NOW ATTACHED TO THE REF, THE ACTIVE ELEMENT CAN NEVER BE INSIDE THE REF. THE HOTKEY ONLY TRIGGERS IF THE\n // REF IS THE ACTIVE ELEMENT. THIS IS A PROBLEM SINCE FOCUSED SUB COMPONENTS WONT TRIGGER THE HOTKEY.\n if (ref.current !== null && document.activeElement !== ref.current && !ref.current.contains(document.activeElement)) {\n stopPropagation(e)\n\n return\n }\n\n if (((e.target as HTMLElement)?.isContentEditable && !memoisedOptions?.enableOnContentEditable)) {\n return\n }\n\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => {\n const hotkey = parseHotkey(key, memoisedOptions?.combinationKey)\n\n if (isHotkeyMatchingKeyboardEvent(e, hotkey, pressedDownKeys) || hotkey.keys?.includes('*')) {\n maybePreventDefault(e, hotkey, memoisedOptions?.preventDefault)\n\n if (!isHotkeyEnabled(e, hotkey, memoisedOptions?.enabled)) {\n stopPropagation(e)\n\n return\n }\n\n cb(e, hotkey)\n }\n })\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n pressedDownKeys.add(event.key.toLowerCase())\n\n if ((memoisedOptions?.keydown === undefined && memoisedOptions?.keyup !== true) || memoisedOptions?.keydown) {\n listener(event)\n }\n }\n\n const handleKeyUp = (event: KeyboardEvent) => {\n if (event.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n if (event.key.toLowerCase() !== 'meta') {\n pressedDownKeys.delete(event.key.toLowerCase())\n } else {\n // On macOS pressing down the meta key prevents triggering the keyup event for any other key https://stackoverflow.com/a/57153300/735226.\n pressedDownKeys.clear()\n }\n\n if (memoisedOptions?.keyup) {\n listener(event)\n }\n }\n\n // @ts-ignore\n (ref.current || document).addEventListener('keyup', handleKeyUp);\n // @ts-ignore\n (ref.current || document).addEventListener('keydown', handleKeyDown)\n\n if (proxy) {\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => proxy.addHotkey(parseHotkey(key, memoisedOptions?.combinationKey)))\n }\n\n return () => {\n // @ts-ignore\n (ref.current || document).removeEventListener('keyup', handleKeyUp);\n // @ts-ignore\n (ref.current || document).removeEventListener('keydown', handleKeyDown)\n\n if (proxy) {\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => proxy.removeHotkey(parseHotkey(key, memoisedOptions?.combinationKey)))\n }\n }\n }, [keys, cb, memoisedOptions, enabledScopes])\n\n return ref\n}\n","import { Hotkey } from './types'\nimport { parseHotkey } from './parseHotkeys'\nimport deepEqual from './deepEqual'\n\nconst currentlyPressedKeys: Set<Hotkey> = new Set<Hotkey>()\n\nexport function isHotkeyPressed(key: string | string[], splitKey: string = ','): boolean {\n const hotkeyArray = Array.isArray(key) ? key : key.split(splitKey)\n\n return hotkeyArray.every((hotkey) => {\n const parsedHotkey = parseHotkey(hotkey)\n\n for (const pressedHotkey of currentlyPressedKeys) {\n if (deepEqual(parsedHotkey, pressedHotkey)) {\n return true\n }\n }\n })\n}\n\nexport function pushToCurrentlyPressedKeys(key: string | string[]): void {\n const hotkeyArray = Array.isArray(key) ? key : [key]\n\n hotkeyArray.forEach(hotkey => currentlyPressedKeys.add(parseHotkey(hotkey)))\n}\n\nexport function removeFromCurrentlyPressedKeys(key: string | string[]): void {\n const hotkeyArray = Array.isArray(key) ? key : [key]\n\n hotkeyArray.forEach((hotkey) => {\n const parsedHotkey = parseHotkey(hotkey)\n\n for (const pressedHotkey of currentlyPressedKeys) {\n if (pressedHotkey.keys?.every((key) => parsedHotkey.keys?.includes(key))) {\n currentlyPressedKeys.delete(pressedHotkey)\n }\n }\n })\n}\n\n(() => {\n if (typeof window !== 'undefined') {\n window.addEventListener('DOMContentLoaded', () => {\n document.addEventListener('keydown', e => {\n if (e.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n pushToCurrentlyPressedKeys(e.key)\n })\n\n document.addEventListener('keyup', e => {\n if (e.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n removeFromCurrentlyPressedKeys(e.key)\n })\n })\n }\n})()\n","import { useRef } from 'react'\nimport deepEqual from './deepEqual'\n\nexport default function useDeepEqualMemo<T>(value: T) {\n const ref = useRef<T | undefined>(undefined)\n\n if (!deepEqual(ref.current, value)) {\n ref.current = value\n }\n\n return ref.current\n}\n"],"names":["reservedModifierKeywords","mappedKeys","esc","return","left","up","right","down","1","2","3","4","5","6","7","8","9","parseKeysHookInput","keys","splitKey","split","parseHotkey","hotkey","combinationKey","toLocaleLowerCase","map","k","trim","alt","includes","shift","meta","mod","filter","isHotkeyEnabledOnTag","enabledOnTags","target","targetTagName","tagName","Array","Boolean","some","tag","toLowerCase","BoundHotkeysProxyProvider","createContext","undefined","BoundHotkeysProxyProviderProvider","_jsx","Provider","value","addHotkey","removeHotkey","children","HotkeysContext","hotkeys","enabledScopes","toggleScope","enableScope","disableScope","useHotkeysContext","useContext","deepEqual","x","y","Object","length","reduce","isEqual","key","stopPropagation","e","preventDefault","stopImmediatePropagation","useSafeLayoutEffect","window","useLayoutEffect","useEffect","pressedDownKeys","Set","currentlyPressedKeys","addEventListener","document","isArray","forEach","add","parsedHotkey","pressedHotkey","_pressedHotkey$keys","every","_parsedHotkey$keys","initiallyActiveScopes","useState","internalActiveScopes","setInternalActiveScopes","boundHotkeys","setBoundHotkeys","isAllActive","useMemo","scope","from","scopes","s","h","callback","options","dependencies","ref","useRef","_options","cb","useCallback","memoisedOptions","current","useDeepEqualMemo","proxy","enabled","activeScopes","console","warn","listener","enableOnFormTags","activeElement","contains","_e$target","isContentEditable","enableOnContentEditable","altKey","ctrlKey","metaKey","shiftKey","pressedKeyUppercase","keyCode","code","replace","pressedKey","has","isHotkeyMatchingKeyboardEvent","_hotkey$keys","maybePreventDefault","isHotkeyEnabled","handleKeyDown","event","keydown","keyup","handleKeyUp","clear","removeEventListener"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"react-hotkeys-hook.cjs.production.min.js","sources":["../src/parseHotkeys.ts","../src/deepEqual.ts","../src/isHotkeyPressed.ts","../src/validators.ts","../src/BoundHotkeysProxyProvider.tsx","../src/HotkeysProvider.tsx","../src/useHotkeys.ts","../src/useDeepEqualMemo.ts"],"sourcesContent":["import { Hotkey, KeyboardModifiers, Keys } from './types'\n\nconst reservedModifierKeywords = ['shift', 'alt', 'meta', 'mod']\n\nconst mappedKeys: Record<string, string> = {\n esc: 'escape',\n return: 'enter',\n left: 'arrowleft',\n up: 'arrowup',\n right: 'arrowright',\n down: 'arrowdown',\n '1': 'digit1',\n '2': 'digit2',\n '3': 'digit3',\n '4': 'digit4',\n '5': 'digit5',\n '6': 'digit6',\n '7': 'digit7',\n '8': 'digit8',\n '9': 'digit9',\n}\n\nexport function parseKeysHookInput(keys: Keys, splitKey: string = ','): string[] {\n if (typeof keys === 'string') {\n return keys.split(splitKey)\n }\n\n return keys\n}\n\nexport function parseHotkey(hotkey: string, combinationKey: string = '+'): Hotkey {\n const keys = hotkey\n .toLocaleLowerCase()\n .split(combinationKey)\n .map(k => k.trim())\n .map(k => mappedKeys[k] || k)\n\n const modifiers: KeyboardModifiers = {\n alt: keys.includes('alt'),\n shift: keys.includes('shift'),\n meta: keys.includes('meta'),\n mod: keys.includes('mod'),\n }\n\n const singleCharKeys = keys.filter((k) => !reservedModifierKeywords.includes(k))\n\n return {\n ...modifiers,\n keys: singleCharKeys,\n }\n}\n","export default function deepEqual(x: any, y: any): boolean {\n //@ts-ignore\n return (x && y && typeof x === 'object' && typeof y === 'object')\n //@ts-ignore\n ? (Object.keys(x).length === Object.keys(y).length) && Object.keys(x).reduce(function(isEqual, key) {\n return isEqual && deepEqual(x[key], y[key])\n }, true)\n : (x === y)\n}\n","import { Hotkey } from './types'\nimport { parseHotkey } from './parseHotkeys'\nimport deepEqual from './deepEqual'\n\nconst currentlyPressedKeys: Set<Hotkey> = new Set<Hotkey>()\n\nexport function isHotkeyPressed(key: string | string[], splitKey: string = ','): boolean {\n const hotkeyArray = Array.isArray(key) ? key : key.split(splitKey)\n\n return hotkeyArray.every((hotkey) => {\n const parsedHotkey = parseHotkey(hotkey)\n\n for (const pressedHotkey of currentlyPressedKeys) {\n if (deepEqual(parsedHotkey, pressedHotkey)) {\n return true\n }\n }\n })\n}\n\nfunction pushToCurrentlyPressedKeys(key: string | string[]): void {\n const hotkeyArray = Array.isArray(key) ? key : [key]\n\n hotkeyArray.forEach(hotkey => currentlyPressedKeys.add(parseHotkey(hotkey)))\n}\n\nfunction removeFromCurrentlyPressedKeys(key: string | string[]): void {\n const hotkeyArray = Array.isArray(key) ? key : [key]\n\n hotkeyArray.forEach((hotkey) => {\n const parsedHotkey = parseHotkey(hotkey)\n\n for (const pressedHotkey of currentlyPressedKeys) {\n if (deepEqual(parsedHotkey, pressedHotkey)) {\n currentlyPressedKeys.delete(pressedHotkey)\n }\n }\n })\n}\n\n(() => {\n if (typeof window !== 'undefined') {\n window.addEventListener('DOMContentLoaded', () => {\n document.addEventListener('keydown', e => {\n if (e.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n pushToCurrentlyPressedKeys(e.key)\n })\n\n document.addEventListener('keyup', e => {\n if (e.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n removeFromCurrentlyPressedKeys(e.key)\n })\n })\n }\n})()\n","import { FormTags, Hotkey, Scopes, Trigger } from './types'\nimport { isHotkeyPressed } from './isHotkeyPressed'\n\nexport function maybePreventDefault(e: KeyboardEvent, hotkey: Hotkey, preventDefault?: Trigger): void {\n if ((typeof preventDefault === 'function' && preventDefault(e, hotkey)) || preventDefault === true) {\n e.preventDefault()\n }\n}\n\nexport function isHotkeyEnabled(e: KeyboardEvent, hotkey: Hotkey, enabled?: Trigger): boolean {\n if (typeof enabled === 'function') {\n return enabled(e, hotkey)\n }\n\n return enabled === true || enabled === undefined\n}\n\nexport function isKeyboardEventTriggeredByInput(ev: KeyboardEvent): boolean {\n return isHotkeyEnabledOnTag(ev, ['input', 'textarea', 'select'])\n}\n\nexport function isHotkeyEnabledOnTag({ target }: KeyboardEvent, enabledOnTags: FormTags[] | boolean = false): boolean {\n const targetTagName = target && (target as HTMLElement).tagName\n\n if (enabledOnTags instanceof Array) {\n return Boolean(targetTagName && enabledOnTags && enabledOnTags.some(tag => tag.toLowerCase() === targetTagName.toLowerCase()))\n }\n\n return Boolean(targetTagName && enabledOnTags && enabledOnTags === true)\n}\n\nexport function isScopeActive(activeScopes: string[], scopes?: Scopes): boolean {\n if (activeScopes.length === 0 && scopes) {\n console.warn(\n 'A hotkey has the \"scopes\" option set, however no active scopes were found. If you want to use the global scopes feature, you need to wrap your app in a <HotkeysProvider>'\n )\n\n return true\n }\n\n if (!scopes) {\n return true\n }\n\n return activeScopes.some(scope => scopes.includes(scope)) || activeScopes.includes('*')\n}\n\nexport const isHotkeyMatchingKeyboardEvent = (e: KeyboardEvent, hotkey: Hotkey, pressedDownKeys: Set<string>): boolean => {\n const { alt, meta, mod, shift, keys } = hotkey\n const { key: pressedKeyUppercase, code } = e\n\n const altKey = isHotkeyPressed('alt')\n const shiftKey = isHotkeyPressed('shift')\n const metaKey = isHotkeyPressed('meta')\n const ctrlKey = isHotkeyPressed('ctrl')\n\n const keyCode = code.toLowerCase().replace('key', '')\n const pressedKey = pressedKeyUppercase.toLowerCase()\n\n if (altKey !== alt && pressedKey !== 'alt') {\n return false\n }\n\n if (shiftKey !== shift && pressedKey !== 'shift') {\n return false\n }\n\n // Mod is a special key name that is checking for meta on macOS and ctrl on other platforms\n if (mod) {\n if (!metaKey && !ctrlKey) {\n return false\n }\n } else {\n if (metaKey !== meta && ctrlKey !== meta && keyCode !== 'meta' && keyCode !== 'ctrl') {\n return false\n }\n }\n\n // All modifiers are correct, now check the key\n // If the key is set, we check for the key\n if (keys && keys.length === 1 && (keys.includes(pressedKey) || keys.includes(keyCode))) {\n return true\n } else if (keys) {\n // Check if all keys are present in pressedDownKeys set\n return keys.every(key => pressedDownKeys.has(key))\n }\n else if (!keys) {\n // If the key is not set, we only listen for modifiers, that check went alright, so we return true\n return true\n }\n\n // There is nothing that matches.\n return false\n}\n","import { createContext, ReactNode, useContext } from 'react'\nimport { Hotkey } from './types'\n\ntype BoundHotkeysProxyProviderType = {\n addHotkey: (hotkey: Hotkey) => void,\n removeHotkey: (hotkey: Hotkey) => void,\n}\n\nconst BoundHotkeysProxyProvider = createContext<BoundHotkeysProxyProviderType | undefined>(undefined)\n\nexport const useBoundHotkeysProxy = () => {\n return useContext(BoundHotkeysProxyProvider)\n}\n\ninterface Props {\n children: ReactNode\n addHotkey: (hotkey: Hotkey) => void\n removeHotkey: (hotkey: Hotkey) => void\n}\n\nexport default function BoundHotkeysProxyProviderProvider({ addHotkey, removeHotkey, children }: Props) {\n return <BoundHotkeysProxyProvider.Provider value={{addHotkey, removeHotkey}}>{children}</BoundHotkeysProxyProvider.Provider>\n}\n","import { Hotkey } from './types'\nimport { createContext, ReactNode, useState, useContext, useCallback } from 'react'\nimport BoundHotkeysProxyProviderProvider from './BoundHotkeysProxyProvider'\nimport deepEqual from './deepEqual'\n\nexport type HotkeysContextType = {\n hotkeys: ReadonlyArray<Hotkey>\n enabledScopes: string[]\n toggleScope: (scope: string) => void\n enableScope: (scope: string) => void\n disableScope: (scope: string) => void\n}\n\n// The context is only needed for special features like global scoping, so we use a graceful default fallback\nconst HotkeysContext = createContext<HotkeysContextType>({\n hotkeys: [],\n enabledScopes: [], // This array has to be empty instead of containing '*' as default, to check if the provider is set or not\n toggleScope: () => {},\n enableScope: () => {},\n disableScope: () => {},\n})\n\nexport const useHotkeysContext = () => {\n return useContext(HotkeysContext)\n}\n\ninterface Props {\n initiallyActiveScopes?: string[]\n children: ReactNode\n}\n\nexport const HotkeysProvider = ({initiallyActiveScopes = ['*'], children}: Props) => {\n const [internalActiveScopes, setInternalActiveScopes] = useState(initiallyActiveScopes?.length > 0 ? initiallyActiveScopes : ['*'])\n const [boundHotkeys, setBoundHotkeys] = useState<Hotkey[]>([]);\n\n const enableScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.includes('*')) {\n return [scope]\n }\n\n return Array.from(new Set([...prev, scope]))\n })\n }, [])\n\n const disableScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.filter(s => s !== scope).length === 0) {\n return ['*']\n } else {\n return prev.filter(s => s !== scope)\n }\n })\n }, [])\n\n const toggleScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.includes(scope)) {\n if (prev.filter(s => s !== scope).length === 0) {\n return ['*']\n } else {\n return prev.filter(s => s !== scope)\n }\n } else {\n if (prev.includes('*')) {\n return [scope]\n }\n\n return Array.from(new Set([...prev, scope]))\n }\n })\n }, [])\n\n const addBoundHotkey = useCallback((hotkey: Hotkey) => {\n setBoundHotkeys((prev) => [...prev, hotkey])\n }, [])\n\n const removeBoundHotkey = useCallback((hotkey: Hotkey) => {\n setBoundHotkeys((prev) => prev.filter(h => !deepEqual(h, hotkey)))\n }, [])\n\n return (\n <HotkeysContext.Provider value={{enabledScopes: internalActiveScopes, hotkeys: boundHotkeys, enableScope, disableScope, toggleScope}}>\n <BoundHotkeysProxyProviderProvider addHotkey={addBoundHotkey} removeHotkey={removeBoundHotkey}>\n {children}\n </BoundHotkeysProxyProviderProvider>\n </HotkeysContext.Provider>\n )\n}\n","import { HotkeyCallback, Keys, Options, OptionsOrDependencyArray, RefType } from './types'\nimport { DependencyList, useCallback, useEffect, useLayoutEffect, useRef } from 'react'\nimport { parseHotkey, parseKeysHookInput } from './parseHotkeys'\nimport {\n isHotkeyEnabled,\n isHotkeyEnabledOnTag,\n isHotkeyMatchingKeyboardEvent,\n isKeyboardEventTriggeredByInput,\n isScopeActive,\n maybePreventDefault,\n} from './validators'\nimport { useHotkeysContext } from './HotkeysProvider'\nimport { useBoundHotkeysProxy } from './BoundHotkeysProxyProvider'\nimport useDeepEqualMemo from './useDeepEqualMemo'\n\nconst stopPropagation = (e: KeyboardEvent): void => {\n e.stopPropagation()\n e.preventDefault()\n e.stopImmediatePropagation()\n}\n\nconst useSafeLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect\n\nconst pressedDownKeys = new Set<string>()\n\nexport default function useHotkeys<T extends HTMLElement>(\n keys: Keys,\n callback: HotkeyCallback,\n options?: OptionsOrDependencyArray,\n dependencies?: OptionsOrDependencyArray,\n) {\n const ref = useRef<RefType<T>>(null)\n\n const _options: Options | undefined = !(options instanceof Array) ? (options as Options) : !(dependencies instanceof Array) ? (dependencies as Options) : undefined\n const _deps: DependencyList = options instanceof Array ? options : dependencies instanceof Array ? dependencies : []\n\n const cb = useCallback(callback, [..._deps])\n const memoisedOptions = useDeepEqualMemo(_options)\n\n const { enabledScopes } = useHotkeysContext()\n const proxy = useBoundHotkeysProxy()\n\n useSafeLayoutEffect(() => {\n if (memoisedOptions?.enabled === false || !isScopeActive(enabledScopes, memoisedOptions?.scopes)) {\n return\n }\n\n const listener = (e: KeyboardEvent) => {\n if (isKeyboardEventTriggeredByInput(e) && !isHotkeyEnabledOnTag(e, memoisedOptions?.enableOnFormTags)) {\n return\n }\n\n // TODO: SINCE THE EVENT IS NOW ATTACHED TO THE REF, THE ACTIVE ELEMENT CAN NEVER BE INSIDE THE REF. THE HOTKEY ONLY TRIGGERS IF THE\n // REF IS THE ACTIVE ELEMENT. THIS IS A PROBLEM SINCE FOCUSED SUB COMPONENTS WON'T TRIGGER THE HOTKEY.\n if (ref.current !== null && document.activeElement !== ref.current && !ref.current.contains(document.activeElement)) {\n stopPropagation(e)\n\n return\n }\n\n if (((e.target as HTMLElement)?.isContentEditable && !memoisedOptions?.enableOnContentEditable)) {\n return\n }\n\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => {\n const hotkey = parseHotkey(key, memoisedOptions?.combinationKey)\n\n if (isHotkeyMatchingKeyboardEvent(e, hotkey, pressedDownKeys) || hotkey.keys?.includes('*')) {\n maybePreventDefault(e, hotkey, memoisedOptions?.preventDefault)\n\n if (!isHotkeyEnabled(e, hotkey, memoisedOptions?.enabled)) {\n stopPropagation(e)\n\n return\n }\n\n cb(e, hotkey)\n }\n })\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n pressedDownKeys.add(event.key.toLowerCase())\n\n if ((memoisedOptions?.keydown === undefined && memoisedOptions?.keyup !== true) || memoisedOptions?.keydown) {\n listener(event)\n }\n }\n\n const handleKeyUp = (event: KeyboardEvent) => {\n if (event.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n if (event.key.toLowerCase() !== 'meta') {\n pressedDownKeys.delete(event.key.toLowerCase())\n } else {\n // On macOS pressing down the meta key prevents triggering the keyup event for any other key https://stackoverflow.com/a/57153300/735226.\n pressedDownKeys.clear()\n }\n\n if (memoisedOptions?.keyup) {\n listener(event)\n }\n }\n\n // @ts-ignore\n (ref.current || document).addEventListener('keyup', handleKeyUp);\n // @ts-ignore\n (ref.current || document).addEventListener('keydown', handleKeyDown)\n\n if (proxy) {\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => proxy.addHotkey(parseHotkey(key, memoisedOptions?.combinationKey)))\n }\n\n return () => {\n // @ts-ignore\n (ref.current || document).removeEventListener('keyup', handleKeyUp);\n // @ts-ignore\n (ref.current || document).removeEventListener('keydown', handleKeyDown)\n\n if (proxy) {\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => proxy.removeHotkey(parseHotkey(key, memoisedOptions?.combinationKey)))\n }\n }\n }, [keys, cb, memoisedOptions, enabledScopes])\n\n return ref\n}\n","import { useRef } from 'react'\nimport deepEqual from './deepEqual'\n\nexport default function useDeepEqualMemo<T>(value: T) {\n const ref = useRef<T | undefined>(undefined)\n\n if (!deepEqual(ref.current, value)) {\n ref.current = value\n }\n\n return ref.current\n}\n"],"names":["reservedModifierKeywords","mappedKeys","esc","return","left","up","right","down","1","2","3","4","5","6","7","8","9","parseKeysHookInput","keys","splitKey","split","parseHotkey","hotkey","combinationKey","toLocaleLowerCase","map","k","trim","alt","includes","shift","meta","mod","filter","deepEqual","x","y","Object","length","reduce","isEqual","key","currentlyPressedKeys","Set","isHotkeyPressed","Array","isArray","every","parsedHotkey","isHotkeyEnabledOnTag","enabledOnTags","target","targetTagName","tagName","Boolean","some","tag","toLowerCase","window","addEventListener","document","e","undefined","forEach","add","pressedHotkey","BoundHotkeysProxyProvider","createContext","BoundHotkeysProxyProviderProvider","_jsx","Provider","value","addHotkey","removeHotkey","children","HotkeysContext","hotkeys","enabledScopes","toggleScope","enableScope","disableScope","useHotkeysContext","useContext","stopPropagation","preventDefault","stopImmediatePropagation","useSafeLayoutEffect","useLayoutEffect","useEffect","pressedDownKeys","initiallyActiveScopes","useState","internalActiveScopes","setInternalActiveScopes","boundHotkeys","setBoundHotkeys","useCallback","scope","prev","from","s","addBoundHotkey","removeBoundHotkey","h","callback","options","dependencies","ref","useRef","_options","cb","memoisedOptions","current","useDeepEqualMemo","proxy","enabled","scopes","activeScopes","console","warn","listener","enableOnFormTags","activeElement","contains","_e$target","isContentEditable","enableOnContentEditable","pressedKeyUppercase","code","altKey","shiftKey","metaKey","ctrlKey","keyCode","replace","pressedKey","has","isHotkeyMatchingKeyboardEvent","_hotkey$keys","maybePreventDefault","isHotkeyEnabled","handleKeyDown","event","keydown","keyup","handleKeyUp","clear","removeEventListener"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useContext, createContext, useState,
|
|
1
|
+
import { useContext, createContext, useState, useCallback, useRef, useLayoutEffect, useEffect } from 'react';
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
3
|
|
|
4
4
|
function _extends() {
|
|
@@ -97,6 +97,70 @@ function parseHotkey(hotkey, combinationKey) {
|
|
|
97
97
|
});
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
function deepEqual(x, y) {
|
|
101
|
+
//@ts-ignore
|
|
102
|
+
return x && y && typeof x === 'object' && typeof y === 'object'
|
|
103
|
+
//@ts-ignore
|
|
104
|
+
? Object.keys(x).length === Object.keys(y).length && Object.keys(x).reduce(function (isEqual, key) {
|
|
105
|
+
return isEqual && deepEqual(x[key], y[key]);
|
|
106
|
+
}, true) : x === y;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
var currentlyPressedKeys = /*#__PURE__*/new Set();
|
|
110
|
+
function isHotkeyPressed(key, splitKey) {
|
|
111
|
+
if (splitKey === void 0) {
|
|
112
|
+
splitKey = ',';
|
|
113
|
+
}
|
|
114
|
+
var hotkeyArray = Array.isArray(key) ? key : key.split(splitKey);
|
|
115
|
+
return hotkeyArray.every(function (hotkey) {
|
|
116
|
+
var parsedHotkey = parseHotkey(hotkey);
|
|
117
|
+
for (var _iterator = _createForOfIteratorHelperLoose(currentlyPressedKeys), _step; !(_step = _iterator()).done;) {
|
|
118
|
+
var pressedHotkey = _step.value;
|
|
119
|
+
if (deepEqual(parsedHotkey, pressedHotkey)) {
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
function pushToCurrentlyPressedKeys(key) {
|
|
126
|
+
var hotkeyArray = Array.isArray(key) ? key : [key];
|
|
127
|
+
hotkeyArray.forEach(function (hotkey) {
|
|
128
|
+
return currentlyPressedKeys.add(parseHotkey(hotkey));
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
function removeFromCurrentlyPressedKeys(key) {
|
|
132
|
+
var hotkeyArray = Array.isArray(key) ? key : [key];
|
|
133
|
+
hotkeyArray.forEach(function (hotkey) {
|
|
134
|
+
var parsedHotkey = parseHotkey(hotkey);
|
|
135
|
+
for (var _iterator2 = _createForOfIteratorHelperLoose(currentlyPressedKeys), _step2; !(_step2 = _iterator2()).done;) {
|
|
136
|
+
var pressedHotkey = _step2.value;
|
|
137
|
+
if (deepEqual(parsedHotkey, pressedHotkey)) {
|
|
138
|
+
currentlyPressedKeys["delete"](pressedHotkey);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
(function () {
|
|
144
|
+
if (typeof window !== 'undefined') {
|
|
145
|
+
window.addEventListener('DOMContentLoaded', function () {
|
|
146
|
+
document.addEventListener('keydown', function (e) {
|
|
147
|
+
if (e.key === undefined) {
|
|
148
|
+
// Synthetic event (e.g., Chrome autofill). Ignore.
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
pushToCurrentlyPressedKeys(e.key);
|
|
152
|
+
});
|
|
153
|
+
document.addEventListener('keyup', function (e) {
|
|
154
|
+
if (e.key === undefined) {
|
|
155
|
+
// Synthetic event (e.g., Chrome autofill). Ignore.
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
removeFromCurrentlyPressedKeys(e.key);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
})();
|
|
163
|
+
|
|
100
164
|
function maybePreventDefault(e, hotkey, preventDefault) {
|
|
101
165
|
if (typeof preventDefault === 'function' && preventDefault(e, hotkey) || preventDefault === true) {
|
|
102
166
|
e.preventDefault();
|
|
@@ -142,12 +206,12 @@ var isHotkeyMatchingKeyboardEvent = function isHotkeyMatchingKeyboardEvent(e, ho
|
|
|
142
206
|
mod = hotkey.mod,
|
|
143
207
|
shift = hotkey.shift,
|
|
144
208
|
keys = hotkey.keys;
|
|
145
|
-
var
|
|
146
|
-
ctrlKey = e.ctrlKey,
|
|
147
|
-
metaKey = e.metaKey,
|
|
148
|
-
shiftKey = e.shiftKey,
|
|
149
|
-
pressedKeyUppercase = e.key,
|
|
209
|
+
var pressedKeyUppercase = e.key,
|
|
150
210
|
code = e.code;
|
|
211
|
+
var altKey = isHotkeyPressed('alt');
|
|
212
|
+
var shiftKey = isHotkeyPressed('shift');
|
|
213
|
+
var metaKey = isHotkeyPressed('meta');
|
|
214
|
+
var ctrlKey = isHotkeyPressed('ctrl');
|
|
151
215
|
var keyCode = code.toLowerCase().replace('key', '');
|
|
152
216
|
var pressedKey = pressedKeyUppercase.toLowerCase();
|
|
153
217
|
if (altKey !== alt && pressedKey !== 'alt') {
|
|
@@ -167,7 +231,7 @@ var isHotkeyMatchingKeyboardEvent = function isHotkeyMatchingKeyboardEvent(e, ho
|
|
|
167
231
|
}
|
|
168
232
|
}
|
|
169
233
|
// All modifiers are correct, now check the key
|
|
170
|
-
// If the key is set we check for the key
|
|
234
|
+
// If the key is set, we check for the key
|
|
171
235
|
if (keys && keys.length === 1 && (keys.includes(pressedKey) || keys.includes(keyCode))) {
|
|
172
236
|
return true;
|
|
173
237
|
} else if (keys) {
|
|
@@ -220,41 +284,59 @@ var HotkeysProvider = function HotkeysProvider(_ref) {
|
|
|
220
284
|
var _useState2 = useState([]),
|
|
221
285
|
boundHotkeys = _useState2[0],
|
|
222
286
|
setBoundHotkeys = _useState2[1];
|
|
223
|
-
var
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
} else {
|
|
230
|
-
setInternalActiveScopes(Array.from(new Set([].concat(internalActiveScopes, [scope]))));
|
|
231
|
-
}
|
|
232
|
-
};
|
|
233
|
-
var disableScope = function disableScope(scope) {
|
|
234
|
-
var scopes = internalActiveScopes.filter(function (s) {
|
|
235
|
-
return s !== scope;
|
|
287
|
+
var enableScope = useCallback(function (scope) {
|
|
288
|
+
setInternalActiveScopes(function (prev) {
|
|
289
|
+
if (prev.includes('*')) {
|
|
290
|
+
return [scope];
|
|
291
|
+
}
|
|
292
|
+
return Array.from(new Set([].concat(prev, [scope])));
|
|
236
293
|
});
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
294
|
+
}, []);
|
|
295
|
+
var disableScope = useCallback(function (scope) {
|
|
296
|
+
setInternalActiveScopes(function (prev) {
|
|
297
|
+
if (prev.filter(function (s) {
|
|
298
|
+
return s !== scope;
|
|
299
|
+
}).length === 0) {
|
|
300
|
+
return ['*'];
|
|
301
|
+
} else {
|
|
302
|
+
return prev.filter(function (s) {
|
|
303
|
+
return s !== scope;
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
}, []);
|
|
308
|
+
var toggleScope = useCallback(function (scope) {
|
|
309
|
+
setInternalActiveScopes(function (prev) {
|
|
310
|
+
if (prev.includes(scope)) {
|
|
311
|
+
if (prev.filter(function (s) {
|
|
312
|
+
return s !== scope;
|
|
313
|
+
}).length === 0) {
|
|
314
|
+
return ['*'];
|
|
315
|
+
} else {
|
|
316
|
+
return prev.filter(function (s) {
|
|
317
|
+
return s !== scope;
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
} else {
|
|
321
|
+
if (prev.includes('*')) {
|
|
322
|
+
return [scope];
|
|
323
|
+
}
|
|
324
|
+
return Array.from(new Set([].concat(prev, [scope])));
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
}, []);
|
|
328
|
+
var addBoundHotkey = useCallback(function (hotkey) {
|
|
329
|
+
setBoundHotkeys(function (prev) {
|
|
330
|
+
return [].concat(prev, [hotkey]);
|
|
331
|
+
});
|
|
332
|
+
}, []);
|
|
333
|
+
var removeBoundHotkey = useCallback(function (hotkey) {
|
|
334
|
+
setBoundHotkeys(function (prev) {
|
|
335
|
+
return prev.filter(function (h) {
|
|
336
|
+
return !deepEqual(h, hotkey);
|
|
337
|
+
});
|
|
338
|
+
});
|
|
339
|
+
}, []);
|
|
258
340
|
return /*#__PURE__*/jsx(HotkeysContext.Provider, {
|
|
259
341
|
value: {
|
|
260
342
|
enabledScopes: internalActiveScopes,
|
|
@@ -271,15 +353,6 @@ var HotkeysProvider = function HotkeysProvider(_ref) {
|
|
|
271
353
|
});
|
|
272
354
|
};
|
|
273
355
|
|
|
274
|
-
function deepEqual(x, y) {
|
|
275
|
-
//@ts-ignore
|
|
276
|
-
return x && y && typeof x === 'object' && typeof y === 'object'
|
|
277
|
-
//@ts-ignore
|
|
278
|
-
? Object.keys(x).length === Object.keys(y).length && Object.keys(x).reduce(function (isEqual, key) {
|
|
279
|
-
return isEqual && deepEqual(x[key], y[key]);
|
|
280
|
-
}, true) : x === y;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
356
|
function useDeepEqualMemo(value) {
|
|
284
357
|
var ref = useRef(undefined);
|
|
285
358
|
if (!deepEqual(ref.current, value)) {
|
|
@@ -314,7 +387,7 @@ function useHotkeys(keys, callback, options, dependencies) {
|
|
|
314
387
|
return;
|
|
315
388
|
}
|
|
316
389
|
// TODO: SINCE THE EVENT IS NOW ATTACHED TO THE REF, THE ACTIVE ELEMENT CAN NEVER BE INSIDE THE REF. THE HOTKEY ONLY TRIGGERS IF THE
|
|
317
|
-
// REF IS THE ACTIVE ELEMENT. THIS IS A PROBLEM SINCE FOCUSED SUB COMPONENTS
|
|
390
|
+
// REF IS THE ACTIVE ELEMENT. THIS IS A PROBLEM SINCE FOCUSED SUB COMPONENTS WON'T TRIGGER THE HOTKEY.
|
|
318
391
|
if (ref.current !== null && document.activeElement !== ref.current && !ref.current.contains(document.activeElement)) {
|
|
319
392
|
stopPropagation(e);
|
|
320
393
|
return;
|
|
@@ -384,64 +457,5 @@ function useHotkeys(keys, callback, options, dependencies) {
|
|
|
384
457
|
return ref;
|
|
385
458
|
}
|
|
386
459
|
|
|
387
|
-
var currentlyPressedKeys = /*#__PURE__*/new Set();
|
|
388
|
-
function isHotkeyPressed(key, splitKey) {
|
|
389
|
-
if (splitKey === void 0) {
|
|
390
|
-
splitKey = ',';
|
|
391
|
-
}
|
|
392
|
-
var hotkeyArray = Array.isArray(key) ? key : key.split(splitKey);
|
|
393
|
-
return hotkeyArray.every(function (hotkey) {
|
|
394
|
-
var parsedHotkey = parseHotkey(hotkey);
|
|
395
|
-
for (var _iterator = _createForOfIteratorHelperLoose(currentlyPressedKeys), _step; !(_step = _iterator()).done;) {
|
|
396
|
-
var pressedHotkey = _step.value;
|
|
397
|
-
if (deepEqual(parsedHotkey, pressedHotkey)) {
|
|
398
|
-
return true;
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
});
|
|
402
|
-
}
|
|
403
|
-
function pushToCurrentlyPressedKeys(key) {
|
|
404
|
-
var hotkeyArray = Array.isArray(key) ? key : [key];
|
|
405
|
-
hotkeyArray.forEach(function (hotkey) {
|
|
406
|
-
return currentlyPressedKeys.add(parseHotkey(hotkey));
|
|
407
|
-
});
|
|
408
|
-
}
|
|
409
|
-
function removeFromCurrentlyPressedKeys(key) {
|
|
410
|
-
var hotkeyArray = Array.isArray(key) ? key : [key];
|
|
411
|
-
hotkeyArray.forEach(function (hotkey) {
|
|
412
|
-
var parsedHotkey = parseHotkey(hotkey);
|
|
413
|
-
for (var _iterator2 = _createForOfIteratorHelperLoose(currentlyPressedKeys), _step2; !(_step2 = _iterator2()).done;) {
|
|
414
|
-
var _pressedHotkey$keys;
|
|
415
|
-
var pressedHotkey = _step2.value;
|
|
416
|
-
if ((_pressedHotkey$keys = pressedHotkey.keys) != null && _pressedHotkey$keys.every(function (key) {
|
|
417
|
-
var _parsedHotkey$keys;
|
|
418
|
-
return (_parsedHotkey$keys = parsedHotkey.keys) == null ? void 0 : _parsedHotkey$keys.includes(key);
|
|
419
|
-
})) {
|
|
420
|
-
currentlyPressedKeys["delete"](pressedHotkey);
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
});
|
|
424
|
-
}
|
|
425
|
-
(function () {
|
|
426
|
-
if (typeof window !== 'undefined') {
|
|
427
|
-
window.addEventListener('DOMContentLoaded', function () {
|
|
428
|
-
document.addEventListener('keydown', function (e) {
|
|
429
|
-
if (e.key === undefined) {
|
|
430
|
-
// Synthetic event (e.g., Chrome autofill). Ignore.
|
|
431
|
-
return;
|
|
432
|
-
}
|
|
433
|
-
pushToCurrentlyPressedKeys(e.key);
|
|
434
|
-
});
|
|
435
|
-
document.addEventListener('keyup', function (e) {
|
|
436
|
-
if (e.key === undefined) {
|
|
437
|
-
// Synthetic event (e.g., Chrome autofill). Ignore.
|
|
438
|
-
return;
|
|
439
|
-
}
|
|
440
|
-
removeFromCurrentlyPressedKeys(e.key);
|
|
441
|
-
});
|
|
442
|
-
});
|
|
443
|
-
}
|
|
444
|
-
})();
|
|
445
|
-
|
|
446
460
|
export { HotkeysProvider, isHotkeyPressed, useHotkeys, useHotkeysContext };
|
|
447
461
|
//# sourceMappingURL=react-hotkeys-hook.esm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react-hotkeys-hook.esm.js","sources":["../src/parseHotkeys.ts","../src/validators.ts","../src/BoundHotkeysProxyProvider.tsx","../src/HotkeysProvider.tsx","../src/deepEqual.ts","../src/useDeepEqualMemo.ts","../src/useHotkeys.ts","../src/isHotkeyPressed.ts"],"sourcesContent":["import { Hotkey, KeyboardModifiers, Keys } from './types'\n\nconst reservedModifierKeywords = ['shift', 'alt', 'meta', 'mod']\n\nconst mappedKeys: Record<string, string> = {\n esc: 'escape',\n return: 'enter',\n left: 'arrowleft',\n up: 'arrowup',\n right: 'arrowright',\n down: 'arrowdown',\n '1': 'digit1',\n '2': 'digit2',\n '3': 'digit3',\n '4': 'digit4',\n '5': 'digit5',\n '6': 'digit6',\n '7': 'digit7',\n '8': 'digit8',\n '9': 'digit9',\n}\n\nexport function parseKeysHookInput(keys: Keys, splitKey: string = ','): string[] {\n if (typeof keys === 'string') {\n return keys.split(splitKey)\n }\n\n return keys\n}\n\nexport function parseHotkey(hotkey: string, combinationKey: string = '+'): Hotkey {\n const keys = hotkey\n .toLocaleLowerCase()\n .split(combinationKey)\n .map(k => k.trim())\n .map(k => mappedKeys[k] || k)\n\n const modifiers: KeyboardModifiers = {\n alt: keys.includes('alt'),\n shift: keys.includes('shift'),\n meta: keys.includes('meta'),\n mod: keys.includes('mod'),\n }\n\n const singleCharKeys = keys.filter((k) => !reservedModifierKeywords.includes(k))\n\n return {\n ...modifiers,\n keys: singleCharKeys,\n }\n}\n","import { FormTags, Hotkey, Scopes, Trigger } from './types'\n\nexport function maybePreventDefault(e: KeyboardEvent, hotkey: Hotkey, preventDefault?: Trigger): void {\n if ((typeof preventDefault === 'function' && preventDefault(e, hotkey)) || preventDefault === true) {\n e.preventDefault()\n }\n}\n\nexport function isHotkeyEnabled(e: KeyboardEvent, hotkey: Hotkey, enabled?: Trigger): boolean {\n if (typeof enabled === 'function') {\n return enabled(e, hotkey)\n }\n\n return enabled === true || enabled === undefined\n}\n\nexport function isKeyboardEventTriggeredByInput(ev: KeyboardEvent): boolean {\n return isHotkeyEnabledOnTag(ev, ['input', 'textarea', 'select'])\n}\n\nexport function isHotkeyEnabledOnTag({ target }: KeyboardEvent, enabledOnTags: FormTags[] | boolean = false): boolean {\n const targetTagName = target && (target as HTMLElement).tagName\n\n if (enabledOnTags instanceof Array) {\n return Boolean(targetTagName && enabledOnTags && enabledOnTags.some(tag => tag.toLowerCase() === targetTagName.toLowerCase()))\n }\n\n return Boolean(targetTagName && enabledOnTags && enabledOnTags === true)\n}\n\nexport function isScopeActive(activeScopes: string[], scopes?: Scopes): boolean {\n if (activeScopes.length === 0 && scopes) {\n console.warn(\n 'A hotkey has the \"scopes\" option set, however no active scopes were found. If you want to use the global scopes feature, you need to wrap your app in a <HotkeysProvider>'\n )\n\n return true\n }\n\n if (!scopes) {\n return true\n }\n\n return activeScopes.some(scope => scopes.includes(scope)) || activeScopes.includes('*')\n}\n\nexport const isHotkeyMatchingKeyboardEvent = (e: KeyboardEvent, hotkey: Hotkey, pressedDownKeys: Set<string>): boolean => {\n const { alt, meta, mod, shift, keys } = hotkey\n const { altKey, ctrlKey, metaKey, shiftKey, key: pressedKeyUppercase, code } = e\n\n const keyCode = code.toLowerCase().replace('key', '')\n const pressedKey = pressedKeyUppercase.toLowerCase()\n\n if (altKey !== alt && pressedKey !== 'alt') {\n return false\n }\n\n if (shiftKey !== shift && pressedKey !== 'shift') {\n return false\n }\n\n // Mod is a special key name that is checking for meta on macOS and ctrl on other platforms\n if (mod) {\n if (!metaKey && !ctrlKey) {\n return false\n }\n } else {\n if (metaKey !== meta && ctrlKey !== meta && keyCode !== 'meta' && keyCode !== 'ctrl') {\n return false\n }\n }\n\n // All modifiers are correct, now check the key\n // If the key is set we check for the key\n if (keys && keys.length === 1 && (keys.includes(pressedKey) || keys.includes(keyCode))) {\n return true\n } else if (keys) {\n // Check if all keys are present in pressedDownKeys set\n return keys.every(key => pressedDownKeys.has(key))\n }\n else if (!keys) {\n // If the key is not set, we only listen for modifiers, that check went alright, so we return true\n return true\n }\n\n // There is nothing that matches.\n return false\n}\n","import { createContext, ReactNode, useContext } from 'react'\nimport { Hotkey } from './types'\n\ntype BoundHotkeysProxyProviderType = {\n addHotkey: (hotkey: Hotkey) => void,\n removeHotkey: (hotkey: Hotkey) => void,\n}\n\nconst BoundHotkeysProxyProvider = createContext<BoundHotkeysProxyProviderType | undefined>(undefined)\n\nexport const useBoundHotkeysProxy = () => {\n return useContext(BoundHotkeysProxyProvider)\n}\n\ninterface Props {\n children: ReactNode\n addHotkey: (hotkey: Hotkey) => void\n removeHotkey: (hotkey: Hotkey) => void\n}\n\nexport default function BoundHotkeysProxyProviderProvider({ addHotkey, removeHotkey, children }: Props) {\n return <BoundHotkeysProxyProvider.Provider value={{addHotkey, removeHotkey}}>{children}</BoundHotkeysProxyProvider.Provider>\n}\n","import { Hotkey } from './types'\nimport { createContext, ReactNode, useMemo, useState, useContext } from 'react'\nimport BoundHotkeysProxyProviderProvider from './BoundHotkeysProxyProvider'\n\nexport type HotkeysContextType = {\n hotkeys: ReadonlyArray<Hotkey>\n enabledScopes: string[]\n toggleScope: (scope: string) => void\n enableScope: (scope: string) => void\n disableScope: (scope: string) => void\n}\n\n// The context is only needed for special features like global scoping, so we use a graceful default fallback\nconst HotkeysContext = createContext<HotkeysContextType>({\n hotkeys: [],\n enabledScopes: [], // This array has to be empty instead of containing '*' as default, to check if the provider is set or not\n toggleScope: () => {},\n enableScope: () => {},\n disableScope: () => {},\n})\n\nexport const useHotkeysContext = () => {\n return useContext(HotkeysContext)\n}\n\ninterface Props {\n initiallyActiveScopes?: string[]\n children: ReactNode\n}\n\nexport const HotkeysProvider = ({initiallyActiveScopes = ['*'], children}: Props) => {\n const [internalActiveScopes, setInternalActiveScopes] = useState(initiallyActiveScopes?.length > 0 ? initiallyActiveScopes : ['*'])\n const [boundHotkeys, setBoundHotkeys] = useState<Hotkey[]>([]);\n\n const isAllActive = useMemo(() => internalActiveScopes.includes('*'), [internalActiveScopes])\n\n const enableScope = (scope: string) => {\n if (isAllActive) {\n setInternalActiveScopes([scope])\n } else {\n setInternalActiveScopes(Array.from(new Set([...internalActiveScopes, scope])))\n }\n }\n\n const disableScope = (scope: string) => {\n const scopes = internalActiveScopes.filter(s => s !== scope)\n\n if (scopes.length === 0) {\n setInternalActiveScopes(['*'])\n } else {\n setInternalActiveScopes(scopes)\n }\n }\n\n const toggleScope = (scope: string) => {\n if (internalActiveScopes.includes(scope)) {\n disableScope(scope)\n } else {\n enableScope(scope)\n }\n }\n\n const addBoundHotkey = (hotkey: Hotkey) => {\n setBoundHotkeys([...boundHotkeys, hotkey])\n }\n\n const removeBoundHotkey = (hotkey: Hotkey) => {\n setBoundHotkeys(boundHotkeys.filter(h => h.keys !== hotkey.keys))\n }\n\n return (\n <HotkeysContext.Provider value={{enabledScopes: internalActiveScopes, hotkeys: boundHotkeys, enableScope, disableScope, toggleScope}}>\n <BoundHotkeysProxyProviderProvider addHotkey={addBoundHotkey} removeHotkey={removeBoundHotkey}>\n {children}\n </BoundHotkeysProxyProviderProvider>\n </HotkeysContext.Provider>\n )\n}\n","export default function deepEqual(x: any, y: any): boolean {\n //@ts-ignore\n return (x && y && typeof x === 'object' && typeof y === 'object')\n //@ts-ignore\n ? (Object.keys(x).length === Object.keys(y).length) && Object.keys(x).reduce(function(isEqual, key) {\n return isEqual && deepEqual(x[key], y[key])\n }, true)\n : (x === y)\n}\n","import { useRef } from 'react'\nimport deepEqual from './deepEqual'\n\nexport default function useDeepEqualMemo<T>(value: T) {\n const ref = useRef<T | undefined>(undefined)\n\n if (!deepEqual(ref.current, value)) {\n ref.current = value\n }\n\n return ref.current\n}\n","import { HotkeyCallback, Keys, Options, OptionsOrDependencyArray, RefType } from './types'\nimport { DependencyList, useCallback, useEffect, useLayoutEffect, useRef } from 'react'\nimport { parseHotkey, parseKeysHookInput } from './parseHotkeys'\nimport {\n isHotkeyEnabled,\n isHotkeyEnabledOnTag,\n isHotkeyMatchingKeyboardEvent,\n isKeyboardEventTriggeredByInput,\n isScopeActive,\n maybePreventDefault,\n} from './validators'\nimport { useHotkeysContext } from './HotkeysProvider'\nimport { useBoundHotkeysProxy } from './BoundHotkeysProxyProvider'\nimport useDeepEqualMemo from './useDeepEqualMemo'\n\nconst stopPropagation = (e: KeyboardEvent): void => {\n e.stopPropagation()\n e.preventDefault()\n e.stopImmediatePropagation()\n}\n\nconst useSafeLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect\n\nconst pressedDownKeys = new Set<string>()\n\nexport default function useHotkeys<T extends HTMLElement>(\n keys: Keys,\n callback: HotkeyCallback,\n options?: OptionsOrDependencyArray,\n dependencies?: OptionsOrDependencyArray,\n) {\n const ref = useRef<RefType<T>>(null)\n\n const _options: Options | undefined = !(options instanceof Array) ? (options as Options) : !(dependencies instanceof Array) ? (dependencies as Options) : undefined\n const _deps: DependencyList = options instanceof Array ? options : dependencies instanceof Array ? dependencies : []\n\n const cb = useCallback(callback, [..._deps])\n const memoisedOptions = useDeepEqualMemo(_options)\n\n const { enabledScopes } = useHotkeysContext()\n const proxy = useBoundHotkeysProxy()\n\n useSafeLayoutEffect(() => {\n if (memoisedOptions?.enabled === false || !isScopeActive(enabledScopes, memoisedOptions?.scopes)) {\n return\n }\n\n const listener = (e: KeyboardEvent) => {\n if (isKeyboardEventTriggeredByInput(e) && !isHotkeyEnabledOnTag(e, memoisedOptions?.enableOnFormTags)) {\n return\n }\n\n // TODO: SINCE THE EVENT IS NOW ATTACHED TO THE REF, THE ACTIVE ELEMENT CAN NEVER BE INSIDE THE REF. THE HOTKEY ONLY TRIGGERS IF THE\n // REF IS THE ACTIVE ELEMENT. THIS IS A PROBLEM SINCE FOCUSED SUB COMPONENTS WONT TRIGGER THE HOTKEY.\n if (ref.current !== null && document.activeElement !== ref.current && !ref.current.contains(document.activeElement)) {\n stopPropagation(e)\n\n return\n }\n\n if (((e.target as HTMLElement)?.isContentEditable && !memoisedOptions?.enableOnContentEditable)) {\n return\n }\n\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => {\n const hotkey = parseHotkey(key, memoisedOptions?.combinationKey)\n\n if (isHotkeyMatchingKeyboardEvent(e, hotkey, pressedDownKeys) || hotkey.keys?.includes('*')) {\n maybePreventDefault(e, hotkey, memoisedOptions?.preventDefault)\n\n if (!isHotkeyEnabled(e, hotkey, memoisedOptions?.enabled)) {\n stopPropagation(e)\n\n return\n }\n\n cb(e, hotkey)\n }\n })\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n pressedDownKeys.add(event.key.toLowerCase())\n\n if ((memoisedOptions?.keydown === undefined && memoisedOptions?.keyup !== true) || memoisedOptions?.keydown) {\n listener(event)\n }\n }\n\n const handleKeyUp = (event: KeyboardEvent) => {\n if (event.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n if (event.key.toLowerCase() !== 'meta') {\n pressedDownKeys.delete(event.key.toLowerCase())\n } else {\n // On macOS pressing down the meta key prevents triggering the keyup event for any other key https://stackoverflow.com/a/57153300/735226.\n pressedDownKeys.clear()\n }\n\n if (memoisedOptions?.keyup) {\n listener(event)\n }\n }\n\n // @ts-ignore\n (ref.current || document).addEventListener('keyup', handleKeyUp);\n // @ts-ignore\n (ref.current || document).addEventListener('keydown', handleKeyDown)\n\n if (proxy) {\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => proxy.addHotkey(parseHotkey(key, memoisedOptions?.combinationKey)))\n }\n\n return () => {\n // @ts-ignore\n (ref.current || document).removeEventListener('keyup', handleKeyUp);\n // @ts-ignore\n (ref.current || document).removeEventListener('keydown', handleKeyDown)\n\n if (proxy) {\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => proxy.removeHotkey(parseHotkey(key, memoisedOptions?.combinationKey)))\n }\n }\n }, [keys, cb, memoisedOptions, enabledScopes])\n\n return ref\n}\n","import { Hotkey } from './types'\nimport { parseHotkey } from './parseHotkeys'\nimport deepEqual from './deepEqual'\n\nconst currentlyPressedKeys: Set<Hotkey> = new Set<Hotkey>()\n\nexport function isHotkeyPressed(key: string | string[], splitKey: string = ','): boolean {\n const hotkeyArray = Array.isArray(key) ? key : key.split(splitKey)\n\n return hotkeyArray.every((hotkey) => {\n const parsedHotkey = parseHotkey(hotkey)\n\n for (const pressedHotkey of currentlyPressedKeys) {\n if (deepEqual(parsedHotkey, pressedHotkey)) {\n return true\n }\n }\n })\n}\n\nexport function pushToCurrentlyPressedKeys(key: string | string[]): void {\n const hotkeyArray = Array.isArray(key) ? key : [key]\n\n hotkeyArray.forEach(hotkey => currentlyPressedKeys.add(parseHotkey(hotkey)))\n}\n\nexport function removeFromCurrentlyPressedKeys(key: string | string[]): void {\n const hotkeyArray = Array.isArray(key) ? key : [key]\n\n hotkeyArray.forEach((hotkey) => {\n const parsedHotkey = parseHotkey(hotkey)\n\n for (const pressedHotkey of currentlyPressedKeys) {\n if (pressedHotkey.keys?.every((key) => parsedHotkey.keys?.includes(key))) {\n currentlyPressedKeys.delete(pressedHotkey)\n }\n }\n })\n}\n\n(() => {\n if (typeof window !== 'undefined') {\n window.addEventListener('DOMContentLoaded', () => {\n document.addEventListener('keydown', e => {\n if (e.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n pushToCurrentlyPressedKeys(e.key)\n })\n\n document.addEventListener('keyup', e => {\n if (e.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n removeFromCurrentlyPressedKeys(e.key)\n })\n })\n }\n})()\n"],"names":["reservedModifierKeywords","mappedKeys","esc","left","up","right","down","parseKeysHookInput","keys","splitKey","split","parseHotkey","hotkey","combinationKey","toLocaleLowerCase","map","k","trim","modifiers","alt","includes","shift","meta","mod","singleCharKeys","filter","maybePreventDefault","e","preventDefault","isHotkeyEnabled","enabled","undefined","isKeyboardEventTriggeredByInput","ev","isHotkeyEnabledOnTag","enabledOnTags","target","targetTagName","tagName","Array","Boolean","some","tag","toLowerCase","isScopeActive","activeScopes","scopes","length","console","warn","scope","isHotkeyMatchingKeyboardEvent","pressedDownKeys","altKey","ctrlKey","metaKey","shiftKey","pressedKeyUppercase","key","code","keyCode","replace","pressedKey","every","has","BoundHotkeysProxyProvider","createContext","useBoundHotkeysProxy","useContext","BoundHotkeysProxyProviderProvider","addHotkey","removeHotkey","children","_jsx","HotkeysContext","hotkeys","enabledScopes","toggleScope","enableScope","disableScope","useHotkeysContext","HotkeysProvider","initiallyActiveScopes","useState","internalActiveScopes","setInternalActiveScopes","boundHotkeys","setBoundHotkeys","isAllActive","useMemo","from","Set","s","addBoundHotkey","removeBoundHotkey","h","deepEqual","x","y","Object","reduce","isEqual","useDeepEqualMemo","value","ref","useRef","current","stopPropagation","stopImmediatePropagation","useSafeLayoutEffect","window","useLayoutEffect","useEffect","useHotkeys","callback","options","dependencies","_options","_deps","cb","useCallback","memoisedOptions","proxy","listener","enableOnFormTags","document","activeElement","contains","isContentEditable","enableOnContentEditable","forEach","handleKeyDown","event","add","keydown","keyup","handleKeyUp","clear","addEventListener","removeEventListener","currentlyPressedKeys","isHotkeyPressed","hotkeyArray","isArray","parsedHotkey","pressedHotkey","pushToCurrentlyPressedKeys","removeFromCurrentlyPressedKeys"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"react-hotkeys-hook.esm.js","sources":["../src/parseHotkeys.ts","../src/deepEqual.ts","../src/isHotkeyPressed.ts","../src/validators.ts","../src/BoundHotkeysProxyProvider.tsx","../src/HotkeysProvider.tsx","../src/useDeepEqualMemo.ts","../src/useHotkeys.ts"],"sourcesContent":["import { Hotkey, KeyboardModifiers, Keys } from './types'\n\nconst reservedModifierKeywords = ['shift', 'alt', 'meta', 'mod']\n\nconst mappedKeys: Record<string, string> = {\n esc: 'escape',\n return: 'enter',\n left: 'arrowleft',\n up: 'arrowup',\n right: 'arrowright',\n down: 'arrowdown',\n '1': 'digit1',\n '2': 'digit2',\n '3': 'digit3',\n '4': 'digit4',\n '5': 'digit5',\n '6': 'digit6',\n '7': 'digit7',\n '8': 'digit8',\n '9': 'digit9',\n}\n\nexport function parseKeysHookInput(keys: Keys, splitKey: string = ','): string[] {\n if (typeof keys === 'string') {\n return keys.split(splitKey)\n }\n\n return keys\n}\n\nexport function parseHotkey(hotkey: string, combinationKey: string = '+'): Hotkey {\n const keys = hotkey\n .toLocaleLowerCase()\n .split(combinationKey)\n .map(k => k.trim())\n .map(k => mappedKeys[k] || k)\n\n const modifiers: KeyboardModifiers = {\n alt: keys.includes('alt'),\n shift: keys.includes('shift'),\n meta: keys.includes('meta'),\n mod: keys.includes('mod'),\n }\n\n const singleCharKeys = keys.filter((k) => !reservedModifierKeywords.includes(k))\n\n return {\n ...modifiers,\n keys: singleCharKeys,\n }\n}\n","export default function deepEqual(x: any, y: any): boolean {\n //@ts-ignore\n return (x && y && typeof x === 'object' && typeof y === 'object')\n //@ts-ignore\n ? (Object.keys(x).length === Object.keys(y).length) && Object.keys(x).reduce(function(isEqual, key) {\n return isEqual && deepEqual(x[key], y[key])\n }, true)\n : (x === y)\n}\n","import { Hotkey } from './types'\nimport { parseHotkey } from './parseHotkeys'\nimport deepEqual from './deepEqual'\n\nconst currentlyPressedKeys: Set<Hotkey> = new Set<Hotkey>()\n\nexport function isHotkeyPressed(key: string | string[], splitKey: string = ','): boolean {\n const hotkeyArray = Array.isArray(key) ? key : key.split(splitKey)\n\n return hotkeyArray.every((hotkey) => {\n const parsedHotkey = parseHotkey(hotkey)\n\n for (const pressedHotkey of currentlyPressedKeys) {\n if (deepEqual(parsedHotkey, pressedHotkey)) {\n return true\n }\n }\n })\n}\n\nfunction pushToCurrentlyPressedKeys(key: string | string[]): void {\n const hotkeyArray = Array.isArray(key) ? key : [key]\n\n hotkeyArray.forEach(hotkey => currentlyPressedKeys.add(parseHotkey(hotkey)))\n}\n\nfunction removeFromCurrentlyPressedKeys(key: string | string[]): void {\n const hotkeyArray = Array.isArray(key) ? key : [key]\n\n hotkeyArray.forEach((hotkey) => {\n const parsedHotkey = parseHotkey(hotkey)\n\n for (const pressedHotkey of currentlyPressedKeys) {\n if (deepEqual(parsedHotkey, pressedHotkey)) {\n currentlyPressedKeys.delete(pressedHotkey)\n }\n }\n })\n}\n\n(() => {\n if (typeof window !== 'undefined') {\n window.addEventListener('DOMContentLoaded', () => {\n document.addEventListener('keydown', e => {\n if (e.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n pushToCurrentlyPressedKeys(e.key)\n })\n\n document.addEventListener('keyup', e => {\n if (e.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n removeFromCurrentlyPressedKeys(e.key)\n })\n })\n }\n})()\n","import { FormTags, Hotkey, Scopes, Trigger } from './types'\nimport { isHotkeyPressed } from './isHotkeyPressed'\n\nexport function maybePreventDefault(e: KeyboardEvent, hotkey: Hotkey, preventDefault?: Trigger): void {\n if ((typeof preventDefault === 'function' && preventDefault(e, hotkey)) || preventDefault === true) {\n e.preventDefault()\n }\n}\n\nexport function isHotkeyEnabled(e: KeyboardEvent, hotkey: Hotkey, enabled?: Trigger): boolean {\n if (typeof enabled === 'function') {\n return enabled(e, hotkey)\n }\n\n return enabled === true || enabled === undefined\n}\n\nexport function isKeyboardEventTriggeredByInput(ev: KeyboardEvent): boolean {\n return isHotkeyEnabledOnTag(ev, ['input', 'textarea', 'select'])\n}\n\nexport function isHotkeyEnabledOnTag({ target }: KeyboardEvent, enabledOnTags: FormTags[] | boolean = false): boolean {\n const targetTagName = target && (target as HTMLElement).tagName\n\n if (enabledOnTags instanceof Array) {\n return Boolean(targetTagName && enabledOnTags && enabledOnTags.some(tag => tag.toLowerCase() === targetTagName.toLowerCase()))\n }\n\n return Boolean(targetTagName && enabledOnTags && enabledOnTags === true)\n}\n\nexport function isScopeActive(activeScopes: string[], scopes?: Scopes): boolean {\n if (activeScopes.length === 0 && scopes) {\n console.warn(\n 'A hotkey has the \"scopes\" option set, however no active scopes were found. If you want to use the global scopes feature, you need to wrap your app in a <HotkeysProvider>'\n )\n\n return true\n }\n\n if (!scopes) {\n return true\n }\n\n return activeScopes.some(scope => scopes.includes(scope)) || activeScopes.includes('*')\n}\n\nexport const isHotkeyMatchingKeyboardEvent = (e: KeyboardEvent, hotkey: Hotkey, pressedDownKeys: Set<string>): boolean => {\n const { alt, meta, mod, shift, keys } = hotkey\n const { key: pressedKeyUppercase, code } = e\n\n const altKey = isHotkeyPressed('alt')\n const shiftKey = isHotkeyPressed('shift')\n const metaKey = isHotkeyPressed('meta')\n const ctrlKey = isHotkeyPressed('ctrl')\n\n const keyCode = code.toLowerCase().replace('key', '')\n const pressedKey = pressedKeyUppercase.toLowerCase()\n\n if (altKey !== alt && pressedKey !== 'alt') {\n return false\n }\n\n if (shiftKey !== shift && pressedKey !== 'shift') {\n return false\n }\n\n // Mod is a special key name that is checking for meta on macOS and ctrl on other platforms\n if (mod) {\n if (!metaKey && !ctrlKey) {\n return false\n }\n } else {\n if (metaKey !== meta && ctrlKey !== meta && keyCode !== 'meta' && keyCode !== 'ctrl') {\n return false\n }\n }\n\n // All modifiers are correct, now check the key\n // If the key is set, we check for the key\n if (keys && keys.length === 1 && (keys.includes(pressedKey) || keys.includes(keyCode))) {\n return true\n } else if (keys) {\n // Check if all keys are present in pressedDownKeys set\n return keys.every(key => pressedDownKeys.has(key))\n }\n else if (!keys) {\n // If the key is not set, we only listen for modifiers, that check went alright, so we return true\n return true\n }\n\n // There is nothing that matches.\n return false\n}\n","import { createContext, ReactNode, useContext } from 'react'\nimport { Hotkey } from './types'\n\ntype BoundHotkeysProxyProviderType = {\n addHotkey: (hotkey: Hotkey) => void,\n removeHotkey: (hotkey: Hotkey) => void,\n}\n\nconst BoundHotkeysProxyProvider = createContext<BoundHotkeysProxyProviderType | undefined>(undefined)\n\nexport const useBoundHotkeysProxy = () => {\n return useContext(BoundHotkeysProxyProvider)\n}\n\ninterface Props {\n children: ReactNode\n addHotkey: (hotkey: Hotkey) => void\n removeHotkey: (hotkey: Hotkey) => void\n}\n\nexport default function BoundHotkeysProxyProviderProvider({ addHotkey, removeHotkey, children }: Props) {\n return <BoundHotkeysProxyProvider.Provider value={{addHotkey, removeHotkey}}>{children}</BoundHotkeysProxyProvider.Provider>\n}\n","import { Hotkey } from './types'\nimport { createContext, ReactNode, useState, useContext, useCallback } from 'react'\nimport BoundHotkeysProxyProviderProvider from './BoundHotkeysProxyProvider'\nimport deepEqual from './deepEqual'\n\nexport type HotkeysContextType = {\n hotkeys: ReadonlyArray<Hotkey>\n enabledScopes: string[]\n toggleScope: (scope: string) => void\n enableScope: (scope: string) => void\n disableScope: (scope: string) => void\n}\n\n// The context is only needed for special features like global scoping, so we use a graceful default fallback\nconst HotkeysContext = createContext<HotkeysContextType>({\n hotkeys: [],\n enabledScopes: [], // This array has to be empty instead of containing '*' as default, to check if the provider is set or not\n toggleScope: () => {},\n enableScope: () => {},\n disableScope: () => {},\n})\n\nexport const useHotkeysContext = () => {\n return useContext(HotkeysContext)\n}\n\ninterface Props {\n initiallyActiveScopes?: string[]\n children: ReactNode\n}\n\nexport const HotkeysProvider = ({initiallyActiveScopes = ['*'], children}: Props) => {\n const [internalActiveScopes, setInternalActiveScopes] = useState(initiallyActiveScopes?.length > 0 ? initiallyActiveScopes : ['*'])\n const [boundHotkeys, setBoundHotkeys] = useState<Hotkey[]>([]);\n\n const enableScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.includes('*')) {\n return [scope]\n }\n\n return Array.from(new Set([...prev, scope]))\n })\n }, [])\n\n const disableScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.filter(s => s !== scope).length === 0) {\n return ['*']\n } else {\n return prev.filter(s => s !== scope)\n }\n })\n }, [])\n\n const toggleScope = useCallback((scope: string) => {\n setInternalActiveScopes((prev) => {\n if (prev.includes(scope)) {\n if (prev.filter(s => s !== scope).length === 0) {\n return ['*']\n } else {\n return prev.filter(s => s !== scope)\n }\n } else {\n if (prev.includes('*')) {\n return [scope]\n }\n\n return Array.from(new Set([...prev, scope]))\n }\n })\n }, [])\n\n const addBoundHotkey = useCallback((hotkey: Hotkey) => {\n setBoundHotkeys((prev) => [...prev, hotkey])\n }, [])\n\n const removeBoundHotkey = useCallback((hotkey: Hotkey) => {\n setBoundHotkeys((prev) => prev.filter(h => !deepEqual(h, hotkey)))\n }, [])\n\n return (\n <HotkeysContext.Provider value={{enabledScopes: internalActiveScopes, hotkeys: boundHotkeys, enableScope, disableScope, toggleScope}}>\n <BoundHotkeysProxyProviderProvider addHotkey={addBoundHotkey} removeHotkey={removeBoundHotkey}>\n {children}\n </BoundHotkeysProxyProviderProvider>\n </HotkeysContext.Provider>\n )\n}\n","import { useRef } from 'react'\nimport deepEqual from './deepEqual'\n\nexport default function useDeepEqualMemo<T>(value: T) {\n const ref = useRef<T | undefined>(undefined)\n\n if (!deepEqual(ref.current, value)) {\n ref.current = value\n }\n\n return ref.current\n}\n","import { HotkeyCallback, Keys, Options, OptionsOrDependencyArray, RefType } from './types'\nimport { DependencyList, useCallback, useEffect, useLayoutEffect, useRef } from 'react'\nimport { parseHotkey, parseKeysHookInput } from './parseHotkeys'\nimport {\n isHotkeyEnabled,\n isHotkeyEnabledOnTag,\n isHotkeyMatchingKeyboardEvent,\n isKeyboardEventTriggeredByInput,\n isScopeActive,\n maybePreventDefault,\n} from './validators'\nimport { useHotkeysContext } from './HotkeysProvider'\nimport { useBoundHotkeysProxy } from './BoundHotkeysProxyProvider'\nimport useDeepEqualMemo from './useDeepEqualMemo'\n\nconst stopPropagation = (e: KeyboardEvent): void => {\n e.stopPropagation()\n e.preventDefault()\n e.stopImmediatePropagation()\n}\n\nconst useSafeLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect\n\nconst pressedDownKeys = new Set<string>()\n\nexport default function useHotkeys<T extends HTMLElement>(\n keys: Keys,\n callback: HotkeyCallback,\n options?: OptionsOrDependencyArray,\n dependencies?: OptionsOrDependencyArray,\n) {\n const ref = useRef<RefType<T>>(null)\n\n const _options: Options | undefined = !(options instanceof Array) ? (options as Options) : !(dependencies instanceof Array) ? (dependencies as Options) : undefined\n const _deps: DependencyList = options instanceof Array ? options : dependencies instanceof Array ? dependencies : []\n\n const cb = useCallback(callback, [..._deps])\n const memoisedOptions = useDeepEqualMemo(_options)\n\n const { enabledScopes } = useHotkeysContext()\n const proxy = useBoundHotkeysProxy()\n\n useSafeLayoutEffect(() => {\n if (memoisedOptions?.enabled === false || !isScopeActive(enabledScopes, memoisedOptions?.scopes)) {\n return\n }\n\n const listener = (e: KeyboardEvent) => {\n if (isKeyboardEventTriggeredByInput(e) && !isHotkeyEnabledOnTag(e, memoisedOptions?.enableOnFormTags)) {\n return\n }\n\n // TODO: SINCE THE EVENT IS NOW ATTACHED TO THE REF, THE ACTIVE ELEMENT CAN NEVER BE INSIDE THE REF. THE HOTKEY ONLY TRIGGERS IF THE\n // REF IS THE ACTIVE ELEMENT. THIS IS A PROBLEM SINCE FOCUSED SUB COMPONENTS WON'T TRIGGER THE HOTKEY.\n if (ref.current !== null && document.activeElement !== ref.current && !ref.current.contains(document.activeElement)) {\n stopPropagation(e)\n\n return\n }\n\n if (((e.target as HTMLElement)?.isContentEditable && !memoisedOptions?.enableOnContentEditable)) {\n return\n }\n\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => {\n const hotkey = parseHotkey(key, memoisedOptions?.combinationKey)\n\n if (isHotkeyMatchingKeyboardEvent(e, hotkey, pressedDownKeys) || hotkey.keys?.includes('*')) {\n maybePreventDefault(e, hotkey, memoisedOptions?.preventDefault)\n\n if (!isHotkeyEnabled(e, hotkey, memoisedOptions?.enabled)) {\n stopPropagation(e)\n\n return\n }\n\n cb(e, hotkey)\n }\n })\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n pressedDownKeys.add(event.key.toLowerCase())\n\n if ((memoisedOptions?.keydown === undefined && memoisedOptions?.keyup !== true) || memoisedOptions?.keydown) {\n listener(event)\n }\n }\n\n const handleKeyUp = (event: KeyboardEvent) => {\n if (event.key === undefined) {\n // Synthetic event (e.g., Chrome autofill). Ignore.\n return\n }\n\n if (event.key.toLowerCase() !== 'meta') {\n pressedDownKeys.delete(event.key.toLowerCase())\n } else {\n // On macOS pressing down the meta key prevents triggering the keyup event for any other key https://stackoverflow.com/a/57153300/735226.\n pressedDownKeys.clear()\n }\n\n if (memoisedOptions?.keyup) {\n listener(event)\n }\n }\n\n // @ts-ignore\n (ref.current || document).addEventListener('keyup', handleKeyUp);\n // @ts-ignore\n (ref.current || document).addEventListener('keydown', handleKeyDown)\n\n if (proxy) {\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => proxy.addHotkey(parseHotkey(key, memoisedOptions?.combinationKey)))\n }\n\n return () => {\n // @ts-ignore\n (ref.current || document).removeEventListener('keyup', handleKeyUp);\n // @ts-ignore\n (ref.current || document).removeEventListener('keydown', handleKeyDown)\n\n if (proxy) {\n parseKeysHookInput(keys, memoisedOptions?.splitKey).forEach((key) => proxy.removeHotkey(parseHotkey(key, memoisedOptions?.combinationKey)))\n }\n }\n }, [keys, cb, memoisedOptions, enabledScopes])\n\n return ref\n}\n"],"names":["reservedModifierKeywords","mappedKeys","esc","left","up","right","down","parseKeysHookInput","keys","splitKey","split","parseHotkey","hotkey","combinationKey","toLocaleLowerCase","map","k","trim","modifiers","alt","includes","shift","meta","mod","singleCharKeys","filter","deepEqual","x","y","Object","length","reduce","isEqual","key","currentlyPressedKeys","Set","isHotkeyPressed","hotkeyArray","Array","isArray","every","parsedHotkey","pressedHotkey","pushToCurrentlyPressedKeys","forEach","add","removeFromCurrentlyPressedKeys","window","addEventListener","document","e","undefined","maybePreventDefault","preventDefault","isHotkeyEnabled","enabled","isKeyboardEventTriggeredByInput","ev","isHotkeyEnabledOnTag","enabledOnTags","target","targetTagName","tagName","Boolean","some","tag","toLowerCase","isScopeActive","activeScopes","scopes","console","warn","scope","isHotkeyMatchingKeyboardEvent","pressedDownKeys","pressedKeyUppercase","code","altKey","shiftKey","metaKey","ctrlKey","keyCode","replace","pressedKey","has","BoundHotkeysProxyProvider","createContext","useBoundHotkeysProxy","useContext","BoundHotkeysProxyProviderProvider","addHotkey","removeHotkey","children","_jsx","HotkeysContext","hotkeys","enabledScopes","toggleScope","enableScope","disableScope","useHotkeysContext","HotkeysProvider","initiallyActiveScopes","useState","internalActiveScopes","setInternalActiveScopes","boundHotkeys","setBoundHotkeys","useCallback","prev","from","s","addBoundHotkey","removeBoundHotkey","h","useDeepEqualMemo","value","ref","useRef","current","stopPropagation","stopImmediatePropagation","useSafeLayoutEffect","useLayoutEffect","useEffect","useHotkeys","callback","options","dependencies","_options","_deps","cb","memoisedOptions","proxy","listener","enableOnFormTags","activeElement","contains","isContentEditable","enableOnContentEditable","handleKeyDown","event","keydown","keyup","handleKeyUp","clear","removeEventListener"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-hotkeys-hook",
|
|
3
|
-
"version": "4.0
|
|
3
|
+
"version": "4.1.0-0",
|
|
4
4
|
"repository": "https://JohannesKlauss@github.com/JohannesKlauss/react-keymap-hook.git",
|
|
5
5
|
"homepage": "https://johannesklauss.github.io/react-hotkeys-hook/",
|
|
6
6
|
"author": "Johannes Klauss",
|
package/src/HotkeysProvider.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Hotkey } from './types'
|
|
2
|
-
import { createContext, ReactNode,
|
|
2
|
+
import { createContext, ReactNode, useState, useContext, useCallback } from 'react'
|
|
3
3
|
import BoundHotkeysProxyProviderProvider from './BoundHotkeysProxyProvider'
|
|
4
|
+
import deepEqual from './deepEqual'
|
|
4
5
|
|
|
5
6
|
export type HotkeysContextType = {
|
|
6
7
|
hotkeys: ReadonlyArray<Hotkey>
|
|
@@ -32,41 +33,51 @@ export const HotkeysProvider = ({initiallyActiveScopes = ['*'], children}: Props
|
|
|
32
33
|
const [internalActiveScopes, setInternalActiveScopes] = useState(initiallyActiveScopes?.length > 0 ? initiallyActiveScopes : ['*'])
|
|
33
34
|
const [boundHotkeys, setBoundHotkeys] = useState<Hotkey[]>([]);
|
|
34
35
|
|
|
35
|
-
const
|
|
36
|
+
const enableScope = useCallback((scope: string) => {
|
|
37
|
+
setInternalActiveScopes((prev) => {
|
|
38
|
+
if (prev.includes('*')) {
|
|
39
|
+
return [scope]
|
|
40
|
+
}
|
|
36
41
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
} else {
|
|
41
|
-
setInternalActiveScopes(Array.from(new Set([...internalActiveScopes, scope])))
|
|
42
|
-
}
|
|
43
|
-
}
|
|
42
|
+
return Array.from(new Set([...prev, scope]))
|
|
43
|
+
})
|
|
44
|
+
}, [])
|
|
44
45
|
|
|
45
|
-
const disableScope = (scope: string) => {
|
|
46
|
-
|
|
46
|
+
const disableScope = useCallback((scope: string) => {
|
|
47
|
+
setInternalActiveScopes((prev) => {
|
|
48
|
+
if (prev.filter(s => s !== scope).length === 0) {
|
|
49
|
+
return ['*']
|
|
50
|
+
} else {
|
|
51
|
+
return prev.filter(s => s !== scope)
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
}, [])
|
|
47
55
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
56
|
+
const toggleScope = useCallback((scope: string) => {
|
|
57
|
+
setInternalActiveScopes((prev) => {
|
|
58
|
+
if (prev.includes(scope)) {
|
|
59
|
+
if (prev.filter(s => s !== scope).length === 0) {
|
|
60
|
+
return ['*']
|
|
61
|
+
} else {
|
|
62
|
+
return prev.filter(s => s !== scope)
|
|
63
|
+
}
|
|
64
|
+
} else {
|
|
65
|
+
if (prev.includes('*')) {
|
|
66
|
+
return [scope]
|
|
67
|
+
}
|
|
54
68
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
enableScope(scope)
|
|
60
|
-
}
|
|
61
|
-
}
|
|
69
|
+
return Array.from(new Set([...prev, scope]))
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
}, [])
|
|
62
73
|
|
|
63
|
-
const addBoundHotkey = (hotkey: Hotkey) => {
|
|
64
|
-
setBoundHotkeys([...
|
|
65
|
-
}
|
|
74
|
+
const addBoundHotkey = useCallback((hotkey: Hotkey) => {
|
|
75
|
+
setBoundHotkeys((prev) => [...prev, hotkey])
|
|
76
|
+
}, [])
|
|
66
77
|
|
|
67
|
-
const removeBoundHotkey = (hotkey: Hotkey) => {
|
|
68
|
-
setBoundHotkeys(
|
|
69
|
-
}
|
|
78
|
+
const removeBoundHotkey = useCallback((hotkey: Hotkey) => {
|
|
79
|
+
setBoundHotkeys((prev) => prev.filter(h => !deepEqual(h, hotkey)))
|
|
80
|
+
}, [])
|
|
70
81
|
|
|
71
82
|
return (
|
|
72
83
|
<HotkeysContext.Provider value={{enabledScopes: internalActiveScopes, hotkeys: boundHotkeys, enableScope, disableScope, toggleScope}}>
|
package/src/isHotkeyPressed.ts
CHANGED
|
@@ -18,20 +18,20 @@ export function isHotkeyPressed(key: string | string[], splitKey: string = ','):
|
|
|
18
18
|
})
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
function pushToCurrentlyPressedKeys(key: string | string[]): void {
|
|
22
22
|
const hotkeyArray = Array.isArray(key) ? key : [key]
|
|
23
23
|
|
|
24
24
|
hotkeyArray.forEach(hotkey => currentlyPressedKeys.add(parseHotkey(hotkey)))
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
function removeFromCurrentlyPressedKeys(key: string | string[]): void {
|
|
28
28
|
const hotkeyArray = Array.isArray(key) ? key : [key]
|
|
29
29
|
|
|
30
30
|
hotkeyArray.forEach((hotkey) => {
|
|
31
31
|
const parsedHotkey = parseHotkey(hotkey)
|
|
32
32
|
|
|
33
33
|
for (const pressedHotkey of currentlyPressedKeys) {
|
|
34
|
-
if (
|
|
34
|
+
if (deepEqual(parsedHotkey, pressedHotkey)) {
|
|
35
35
|
currentlyPressedKeys.delete(pressedHotkey)
|
|
36
36
|
}
|
|
37
37
|
}
|
package/src/useHotkeys.ts
CHANGED
|
@@ -51,7 +51,7 @@ export default function useHotkeys<T extends HTMLElement>(
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
// TODO: SINCE THE EVENT IS NOW ATTACHED TO THE REF, THE ACTIVE ELEMENT CAN NEVER BE INSIDE THE REF. THE HOTKEY ONLY TRIGGERS IF THE
|
|
54
|
-
// REF IS THE ACTIVE ELEMENT. THIS IS A PROBLEM SINCE FOCUSED SUB COMPONENTS
|
|
54
|
+
// REF IS THE ACTIVE ELEMENT. THIS IS A PROBLEM SINCE FOCUSED SUB COMPONENTS WON'T TRIGGER THE HOTKEY.
|
|
55
55
|
if (ref.current !== null && document.activeElement !== ref.current && !ref.current.contains(document.activeElement)) {
|
|
56
56
|
stopPropagation(e)
|
|
57
57
|
|
package/src/validators.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { FormTags, Hotkey, Scopes, Trigger } from './types'
|
|
2
|
+
import { isHotkeyPressed } from './isHotkeyPressed'
|
|
2
3
|
|
|
3
4
|
export function maybePreventDefault(e: KeyboardEvent, hotkey: Hotkey, preventDefault?: Trigger): void {
|
|
4
5
|
if ((typeof preventDefault === 'function' && preventDefault(e, hotkey)) || preventDefault === true) {
|
|
@@ -46,7 +47,12 @@ export function isScopeActive(activeScopes: string[], scopes?: Scopes): boolean
|
|
|
46
47
|
|
|
47
48
|
export const isHotkeyMatchingKeyboardEvent = (e: KeyboardEvent, hotkey: Hotkey, pressedDownKeys: Set<string>): boolean => {
|
|
48
49
|
const { alt, meta, mod, shift, keys } = hotkey
|
|
49
|
-
const {
|
|
50
|
+
const { key: pressedKeyUppercase, code } = e
|
|
51
|
+
|
|
52
|
+
const altKey = isHotkeyPressed('alt')
|
|
53
|
+
const shiftKey = isHotkeyPressed('shift')
|
|
54
|
+
const metaKey = isHotkeyPressed('meta')
|
|
55
|
+
const ctrlKey = isHotkeyPressed('ctrl')
|
|
50
56
|
|
|
51
57
|
const keyCode = code.toLowerCase().replace('key', '')
|
|
52
58
|
const pressedKey = pressedKeyUppercase.toLowerCase()
|
|
@@ -71,7 +77,7 @@ export const isHotkeyMatchingKeyboardEvent = (e: KeyboardEvent, hotkey: Hotkey,
|
|
|
71
77
|
}
|
|
72
78
|
|
|
73
79
|
// All modifiers are correct, now check the key
|
|
74
|
-
// If the key is set we check for the key
|
|
80
|
+
// If the key is set, we check for the key
|
|
75
81
|
if (keys && keys.length === 1 && (keys.includes(pressedKey) || keys.includes(keyCode))) {
|
|
76
82
|
return true
|
|
77
83
|
} else if (keys) {
|