react-hotkeys-hook
Advanced tools
Comparing version 5.0.0-0 to 5.0.0-1
export declare function isReadonlyArray(value: unknown): value is readonly unknown[]; | ||
export declare function isHotkeyPressed(key: string | readonly string[], splitKey?: string): boolean; | ||
export declare function isHotkeyPressed(key: string | readonly string[], delimiter?: string): boolean; | ||
export declare function pushToCurrentlyPressedKeys(key: string | string[]): void; | ||
export declare function removeFromCurrentlyPressedKeys(key: string | string[]): void; |
import { Hotkey } from './types'; | ||
export declare function mapKey(key: string): string; | ||
export declare function isHotkeyModifier(key: string): boolean; | ||
export declare function parseKeysHookInput(keys: string, splitKey?: string): string[]; | ||
export declare function parseHotkey(hotkey: string, combinationKey?: string, description?: string): Hotkey; | ||
export declare function parseKeysHookInput(keys: string, delimiter?: string): string[]; | ||
export declare function parseHotkey(hotkey: string, splitKey?: string, useKey?: boolean, description?: string): Hotkey; |
@@ -21,3 +21,3 @@ 'use strict'; | ||
var reservedModifierKeywords = ['shift', 'alt', 'meta', 'mod', 'ctrl']; | ||
var reservedModifierKeywords = ['shift', 'alt', 'meta', 'mod', 'ctrl', 'control']; | ||
var mappedKeys = { | ||
@@ -30,3 +30,2 @@ esc: 'escape', | ||
down: 'arrowdown', | ||
space: ' ', | ||
ShiftLeft: 'shift', | ||
@@ -49,13 +48,16 @@ ShiftRight: 'shift', | ||
} | ||
function parseKeysHookInput(keys, splitKey) { | ||
if (splitKey === void 0) { | ||
splitKey = ','; | ||
function parseKeysHookInput(keys, delimiter) { | ||
if (delimiter === void 0) { | ||
delimiter = ','; | ||
} | ||
return keys.split(splitKey); | ||
return keys.toLowerCase().split(delimiter); | ||
} | ||
function parseHotkey(hotkey, combinationKey, description) { | ||
if (combinationKey === void 0) { | ||
combinationKey = '+'; | ||
function parseHotkey(hotkey, splitKey, useKey, description) { | ||
if (splitKey === void 0) { | ||
splitKey = '+'; | ||
} | ||
var keys = hotkey.toLocaleLowerCase().split(combinationKey).map(function (k) { | ||
if (useKey === void 0) { | ||
useKey = false; | ||
} | ||
var keys = hotkey.toLocaleLowerCase().split(splitKey).map(function (k) { | ||
return mapKey(k); | ||
@@ -68,3 +70,4 @@ }); | ||
meta: keys.includes('meta'), | ||
mod: keys.includes('mod') | ||
mod: keys.includes('mod'), | ||
useKey: useKey | ||
}; | ||
@@ -83,15 +86,14 @@ var singleCharKeys = keys.filter(function (k) { | ||
document.addEventListener('keydown', function (e) { | ||
if (e.key === undefined) { | ||
if (e.code === undefined) { | ||
// Synthetic event (e.g., Chrome autofill). Ignore. | ||
return; | ||
} | ||
console.log('keydown', e.key, mapKey(e.key), e.key.length); | ||
pushToCurrentlyPressedKeys([mapKey(e.key)]); | ||
pushToCurrentlyPressedKeys([mapKey(e.code)]); | ||
}); | ||
document.addEventListener('keyup', function (e) { | ||
if (e.key === undefined) { | ||
if (e.code === undefined) { | ||
// Synthetic event (e.g., Chrome autofill). Ignore. | ||
return; | ||
} | ||
removeFromCurrentlyPressedKeys([mapKey(e.key)]); | ||
removeFromCurrentlyPressedKeys([mapKey(e.code)]); | ||
}); | ||
@@ -110,7 +112,7 @@ } | ||
} | ||
function isHotkeyPressed(key, splitKey) { | ||
if (splitKey === void 0) { | ||
splitKey = ','; | ||
function isHotkeyPressed(key, delimiter) { | ||
if (delimiter === void 0) { | ||
delimiter = ','; | ||
} | ||
var hotkeyArray = isReadonlyArray(key) ? key : key.split(splitKey); | ||
var hotkeyArray = isReadonlyArray(key) ? key : key.split(delimiter); | ||
return hotkeyArray.every(function (hotkey) { | ||
@@ -177,3 +179,3 @@ return currentlyPressedKeys.has(hotkey.trim().toLowerCase()); | ||
} | ||
return Boolean(targetTagName && enabledOnTags && enabledOnTags === true); | ||
return Boolean(targetTagName && enabledOnTags && enabledOnTags); | ||
} | ||
@@ -201,4 +203,6 @@ function isScopeActive(activeScopes, scopes) { | ||
ctrl = hotkey.ctrl, | ||
keys = hotkey.keys; | ||
var pressedKeyUppercase = e.key, | ||
keys = hotkey.keys, | ||
useKey = hotkey.useKey; | ||
var code = e.code, | ||
producedKey = e.key, | ||
ctrlKey = e.ctrlKey, | ||
@@ -208,4 +212,7 @@ metaKey = e.metaKey, | ||
altKey = e.altKey; | ||
var pressedKey = pressedKeyUppercase.toLowerCase(); | ||
if (!(keys != null && keys.includes(pressedKey)) && !['ctrl', 'control', 'unknown', 'meta', 'alt', 'shift', 'os'].includes(pressedKey)) { | ||
var mappedCode = mapKey(code); | ||
if (useKey && (keys == null ? void 0 : keys.length) === 1 && keys.includes(producedKey)) { | ||
return true; | ||
} | ||
if (!(keys != null && keys.includes(mappedCode)) && !['ctrl', 'control', 'unknown', 'meta', 'alt', 'shift', 'os'].includes(mappedCode)) { | ||
return false; | ||
@@ -215,6 +222,6 @@ } | ||
// We check the pressed keys for compatibility with the keyup event. In keyup events the modifier flags are not set. | ||
if (alt === !altKey && pressedKey !== 'alt') { | ||
if (alt !== altKey && mappedCode !== 'alt') { | ||
return false; | ||
} | ||
if (shift === !shiftKey && pressedKey !== 'shift') { | ||
if (shift !== shiftKey && mappedCode !== 'shift') { | ||
return false; | ||
@@ -228,6 +235,6 @@ } | ||
} else { | ||
if (meta === !metaKey && pressedKey !== 'meta' && pressedKey !== 'os') { | ||
if (meta !== metaKey && mappedCode !== 'meta' && mappedCode !== 'os') { | ||
return false; | ||
} | ||
if (ctrl === !ctrlKey && pressedKey !== 'ctrl' && pressedKey !== 'control') { | ||
if (ctrl !== ctrlKey && mappedCode !== 'ctrl' && mappedCode !== 'control') { | ||
return false; | ||
@@ -239,3 +246,3 @@ } | ||
// If the key is set, we check for the key | ||
if (keys && keys.length === 1 && keys.includes(pressedKey)) { | ||
if (keys && keys.length === 1 && keys.includes(mappedCode)) { | ||
return true; | ||
@@ -374,3 +381,3 @@ } else if (keys) { | ||
var _options = !(options instanceof Array) ? options : !(dependencies instanceof Array) ? dependencies : undefined; | ||
var _keys = isReadonlyArray(keys) ? keys.join(_options == null ? void 0 : _options.splitKey) : keys; | ||
var _keys = isReadonlyArray(keys) ? keys.join(_options == null ? void 0 : _options.delimiter) : keys; | ||
var _deps = options instanceof Array ? options : dependencies instanceof Array ? dependencies : undefined; | ||
@@ -412,5 +419,5 @@ var memoisedCB = react.useCallback(callback, _deps != null ? _deps : []); | ||
} | ||
parseKeysHookInput(_keys, memoisedOptions == null ? void 0 : memoisedOptions.splitKey).forEach(function (key) { | ||
parseKeysHookInput(_keys, memoisedOptions == null ? void 0 : memoisedOptions.delimiter).forEach(function (key) { | ||
var _hotkey$keys; | ||
var hotkey = parseHotkey(key, memoisedOptions == null ? void 0 : memoisedOptions.combinationKey); | ||
var hotkey = parseHotkey(key, memoisedOptions == null ? void 0 : memoisedOptions.splitKey, memoisedOptions == null ? void 0 : memoisedOptions.useKey); | ||
if (isHotkeyMatchingKeyboardEvent(e, hotkey, memoisedOptions == null ? void 0 : memoisedOptions.ignoreModifiers) || (_hotkey$keys = hotkey.keys) != null && _hotkey$keys.includes('*')) { | ||
@@ -437,7 +444,7 @@ if (memoisedOptions != null && memoisedOptions.ignoreEventWhen != null && memoisedOptions.ignoreEventWhen(e)) { | ||
var handleKeyDown = function handleKeyDown(event) { | ||
if (event.key === undefined) { | ||
if (event.code === undefined) { | ||
// Synthetic event (e.g., Chrome autofill). Ignore. | ||
return; | ||
} | ||
pushToCurrentlyPressedKeys(mapKey(event.key)); | ||
pushToCurrentlyPressedKeys(mapKey(event.code)); | ||
if ((memoisedOptions == null ? void 0 : memoisedOptions.keydown) === undefined && (memoisedOptions == null ? void 0 : memoisedOptions.keyup) !== true || memoisedOptions != null && memoisedOptions.keydown) { | ||
@@ -448,7 +455,7 @@ listener(event); | ||
var handleKeyUp = function handleKeyUp(event) { | ||
if (event.key === undefined) { | ||
if (event.code === undefined) { | ||
// Synthetic event (e.g., Chrome autofill). Ignore. | ||
return; | ||
} | ||
removeFromCurrentlyPressedKeys(mapKey(event.key)); | ||
removeFromCurrentlyPressedKeys(mapKey(event.code)); | ||
hasTriggeredRef.current = false; | ||
@@ -465,4 +472,4 @@ if (memoisedOptions != null && memoisedOptions.keyup) { | ||
if (proxy) { | ||
parseKeysHookInput(_keys, memoisedOptions == null ? void 0 : memoisedOptions.splitKey).forEach(function (key) { | ||
return proxy.addHotkey(parseHotkey(key, memoisedOptions == null ? void 0 : memoisedOptions.combinationKey, memoisedOptions == null ? void 0 : memoisedOptions.description)); | ||
parseKeysHookInput(_keys, memoisedOptions == null ? void 0 : memoisedOptions.delimiter).forEach(function (key) { | ||
return proxy.addHotkey(parseHotkey(key, memoisedOptions == null ? void 0 : memoisedOptions.splitKey, memoisedOptions == null ? void 0 : memoisedOptions.useKey, memoisedOptions == null ? void 0 : memoisedOptions.description)); | ||
}); | ||
@@ -476,4 +483,4 @@ } | ||
if (proxy) { | ||
parseKeysHookInput(_keys, memoisedOptions == null ? void 0 : memoisedOptions.splitKey).forEach(function (key) { | ||
return proxy.removeHotkey(parseHotkey(key, memoisedOptions == null ? void 0 : memoisedOptions.combinationKey, memoisedOptions == null ? void 0 : memoisedOptions.description)); | ||
parseKeysHookInput(_keys, memoisedOptions == null ? void 0 : memoisedOptions.delimiter).forEach(function (key) { | ||
return proxy.removeHotkey(parseHotkey(key, memoisedOptions == null ? void 0 : memoisedOptions.splitKey, memoisedOptions == null ? void 0 : memoisedOptions.useKey, memoisedOptions == null ? void 0 : memoisedOptions.description)); | ||
}); | ||
@@ -494,3 +501,3 @@ } | ||
var handler = react.useCallback(function (event) { | ||
if (event.key === undefined) { | ||
if (event.code === undefined) { | ||
// Synthetic event (e.g., Chrome autofill). Ignore. | ||
@@ -503,3 +510,3 @@ return; | ||
var newKeys = new Set(prev); | ||
newKeys.add(mapKey(event.key)); | ||
newKeys.add(mapKey(event.code)); | ||
return newKeys; | ||
@@ -522,5 +529,9 @@ }); | ||
}, [handler, stop]); | ||
var resetKeys = react.useCallback(function () { | ||
setKeys(new Set()); | ||
}, []); | ||
return [keys, { | ||
start: start, | ||
stop: stop, | ||
resetKeys: resetKeys, | ||
isRecording: isRecording | ||
@@ -527,0 +538,0 @@ }]; |
@@ -1,2 +0,2 @@ | ||
"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 o in n)Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o])}return e}).apply(this,arguments)}var o=["shift","alt","meta","mod","ctrl"],r={esc:"escape",return:"enter",left:"arrowleft",right:"arrowright",up:"arrowup",down:"arrowdown",space:" ",ShiftLeft:"shift",ShiftRight:"shift",AltLeft:"alt",AltRight:"alt",MetaLeft:"meta",MetaRight:"meta",OSLeft:"meta",OSRight:"meta",ControlLeft:"ctrl",ControlRight:"ctrl"};function i(e){return(r[e.trim()]||e.trim()).toLowerCase().replace(/key|digit|numpad/,"")}function u(e,t){return void 0===t&&(t=","),e.split(t)}function c(e,t,r){void 0===t&&(t="+");var u=e.toLocaleLowerCase().split(t).map((function(e){return i(e)}));return n({},{alt:u.includes("alt"),ctrl:u.includes("ctrl")||u.includes("control"),shift:u.includes("shift"),meta:u.includes("meta"),mod:u.includes("mod")},{keys:u.filter((function(e){return!o.includes(e)})),description:r})}"undefined"!=typeof document&&(document.addEventListener("keydown",(function(e){void 0!==e.key&&(console.log("keydown",e.key,i(e.key),e.key.length),f([i(e.key)]))})),document.addEventListener("keyup",(function(e){void 0!==e.key&&d([i(e.key)])}))),"undefined"!=typeof window&&window.addEventListener("blur",(function(){a.clear()}));var a=new Set;function l(e){return Array.isArray(e)}function s(e,t){return void 0===t&&(t=","),(l(e)?e:e.split(t)).every((function(e){return a.has(e.trim().toLowerCase())}))}function f(e){var t=Array.isArray(e)?e:[e];a.has("meta")&&a.forEach((function(e){return!function(e){return o.includes(e)}(e)&&a.delete(e.toLowerCase())})),t.forEach((function(e){return a.add(e.toLowerCase())}))}function d(e){var t=Array.isArray(e)?e:[e];"meta"===e?a.clear():t.forEach((function(e){return a.delete(e.toLowerCase())}))}function v(e,t){var n=e.target;void 0===t&&(t=!1);var o=n&&n.tagName;return l(t)?Boolean(o&&t&&t.some((function(e){return e.toLowerCase()===o.toLowerCase()}))):Boolean(o&&t&&!0===t)}var y=e.createContext(void 0);function p(e){return t.jsx(y.Provider,{value:{addHotkey:e.addHotkey,removeHotkey:e.removeHotkey},children:e.children})}function k(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,o){return n&&k(e[o],t[o])}),!0):e===t}var m=e.createContext({hotkeys:[],activeScopes:[],toggleScope:function(){},enableScope:function(){},disableScope:function(){}}),h=function(){return e.useContext(m)},w=function(e){e.stopPropagation(),e.preventDefault(),e.stopImmediatePropagation()},g="undefined"!=typeof window?e.useLayoutEffect:e.useEffect;exports.HotkeysProvider=function(n){var o=n.initiallyActiveScopes,r=n.children,i=e.useState(void 0===o?["*"]:o),u=i[0],c=i[1],a=e.useState([]),l=a[0],s=a[1],f=e.useCallback((function(e){c((function(t){return t.includes("*")?[e]:Array.from(new Set([].concat(t,[e])))}))}),[]),d=e.useCallback((function(e){c((function(t){return t.filter((function(t){return t!==e}))}))}),[]),v=e.useCallback((function(e){c((function(t){return t.includes(e)?t.filter((function(t){return t!==e})):t.includes("*")?[e]:Array.from(new Set([].concat(t,[e])))}))}),[]),y=e.useCallback((function(e){s((function(t){return[].concat(t,[e])}))}),[]),h=e.useCallback((function(e){s((function(t){return t.filter((function(t){return!k(t,e)}))}))}),[]);return t.jsx(m.Provider,{value:{activeScopes:u,hotkeys:l,enableScope:f,disableScope:d,toggleScope:v},children:t.jsx(p,{addHotkey:y,removeHotkey:h,children:r})})},exports.isHotkeyPressed=s,exports.useHotkeys=function(t,n,o,r){var a=e.useRef(null),p=e.useRef(!1),m=o instanceof Array?r instanceof Array?void 0:r:o,b=l(t)?t.join(null==m?void 0:m.splitKey):t,C=o instanceof Array?o:r instanceof Array?r:void 0,L=e.useCallback(n,null!=C?C:[]),S=e.useRef(L);S.current=C?L:n;var E=function(t){var n=e.useRef(void 0);return k(n.current,t)||(n.current=t),n.current}(m),A=h().activeScopes,x=e.useContext(y);return g((function(){if(!1!==(null==E?void 0:E.enabled)&&function(e,t){return 0===e.length&&t?(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>'),!0):!t||e.some((function(e){return t.includes(e)}))||e.includes("*")}(A,null==E?void 0:E.scopes)){var e=function(e,t){var n;if(void 0===t&&(t=!1),!v(e,["input","textarea","select"])||v(e,null==E?void 0:E.enableOnFormTags)){if(null!==a.current){var o=a.current.getRootNode();if((o instanceof Document||o instanceof ShadowRoot)&&o.activeElement!==a.current&&!a.current.contains(o.activeElement))return void w(e)}(null==(n=e.target)||!n.isContentEditable||null!=E&&E.enableOnContentEditable)&&u(b,null==E?void 0:E.splitKey).forEach((function(n){var o,r=c(n,null==E?void 0:E.combinationKey);if(function(e,t,n){void 0===n&&(n=!1);var o=t.alt,r=t.meta,i=t.mod,u=t.shift,c=t.ctrl,a=t.keys,l=e.ctrlKey,f=e.metaKey,d=e.shiftKey,v=e.altKey,y=e.key.toLowerCase();if(!(null!=a&&a.includes(y)||["ctrl","control","unknown","meta","alt","shift","os"].includes(y)))return!1;if(!n){if(o===!v&&"alt"!==y)return!1;if(u===!d&&"shift"!==y)return!1;if(i){if(!f&&!l)return!1}else{if(r===!f&&"meta"!==y&&"os"!==y)return!1;if(c===!l&&"ctrl"!==y&&"control"!==y)return!1}}return!(!a||1!==a.length||!a.includes(y))||(a?s(a):!a)}(e,r,null==E?void 0:E.ignoreModifiers)||null!=(o=r.keys)&&o.includes("*")){if(null!=E&&null!=E.ignoreEventWhen&&E.ignoreEventWhen(e))return;if(t&&p.current)return;if(function(e,t,n){("function"==typeof n&&n(e,t)||!0===n)&&e.preventDefault()}(e,r,null==E?void 0:E.preventDefault),!function(e,t,n){return"function"==typeof n?n(e,t):!0===n||void 0===n}(e,r,null==E?void 0:E.enabled))return void w(e);S.current(e,r),t||(p.current=!0)}}))}},t=function(t){void 0!==t.key&&(f(i(t.key)),(void 0===(null==E?void 0:E.keydown)&&!0!==(null==E?void 0:E.keyup)||null!=E&&E.keydown)&&e(t))},n=function(t){void 0!==t.key&&(d(i(t.key)),p.current=!1,null!=E&&E.keyup&&e(t,!0))},o=a.current||(null==m?void 0:m.document)||document;return o.addEventListener("keyup",n),o.addEventListener("keydown",t),x&&u(b,null==E?void 0:E.splitKey).forEach((function(e){return x.addHotkey(c(e,null==E?void 0:E.combinationKey,null==E?void 0:E.description))})),function(){o.removeEventListener("keyup",n),o.removeEventListener("keydown",t),x&&u(b,null==E?void 0:E.splitKey).forEach((function(e){return x.removeHotkey(c(e,null==E?void 0:E.combinationKey,null==E?void 0:E.description))}))}}}),[b,E,A]),a},exports.useHotkeysContext=h,exports.useRecordHotkeys=function(){var t=e.useState(new Set),n=t[0],o=t[1],r=e.useState(!1),u=r[0],c=r[1],a=e.useCallback((function(e){void 0!==e.key&&(e.preventDefault(),e.stopPropagation(),o((function(t){var n=new Set(t);return n.add(i(e.key)),n})))}),[]),l=e.useCallback((function(){"undefined"!=typeof document&&(document.removeEventListener("keydown",a),c(!1))}),[a]);return[n,{start:e.useCallback((function(){o(new Set),"undefined"!=typeof document&&(l(),document.addEventListener("keydown",a),c(!0))}),[a,l]),stop:l,isRecording:u}]}; | ||
"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 o in n)Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o])}return e}).apply(this,arguments)}var o=["shift","alt","meta","mod","ctrl","control"],r={esc:"escape",return:"enter",left:"arrowleft",right:"arrowright",up:"arrowup",down:"arrowdown",ShiftLeft:"shift",ShiftRight:"shift",AltLeft:"alt",AltRight:"alt",MetaLeft:"meta",MetaRight:"meta",OSLeft:"meta",OSRight:"meta",ControlLeft:"ctrl",ControlRight:"ctrl"};function i(e){return(r[e.trim()]||e.trim()).toLowerCase().replace(/key|digit|numpad/,"")}function u(e,t){return void 0===t&&(t=","),e.toLowerCase().split(t)}function c(e,t,r,u){void 0===t&&(t="+"),void 0===r&&(r=!1);var c=e.toLocaleLowerCase().split(t).map((function(e){return i(e)}));return n({},{alt:c.includes("alt"),ctrl:c.includes("ctrl")||c.includes("control"),shift:c.includes("shift"),meta:c.includes("meta"),mod:c.includes("mod"),useKey:r},{keys:c.filter((function(e){return!o.includes(e)})),description:u})}"undefined"!=typeof document&&(document.addEventListener("keydown",(function(e){void 0!==e.code&&s([i(e.code)])})),document.addEventListener("keyup",(function(e){void 0!==e.code&&f([i(e.code)])}))),"undefined"!=typeof window&&window.addEventListener("blur",(function(){l.clear()}));var l=new Set;function a(e){return Array.isArray(e)}function d(e,t){return void 0===t&&(t=","),(a(e)?e:e.split(t)).every((function(e){return l.has(e.trim().toLowerCase())}))}function s(e){var t=Array.isArray(e)?e:[e];l.has("meta")&&l.forEach((function(e){return!function(e){return o.includes(e)}(e)&&l.delete(e.toLowerCase())})),t.forEach((function(e){return l.add(e.toLowerCase())}))}function f(e){var t=Array.isArray(e)?e:[e];"meta"===e?l.clear():t.forEach((function(e){return l.delete(e.toLowerCase())}))}function v(e,t){var n=e.target;void 0===t&&(t=!1);var o=n&&n.tagName;return a(t)?Boolean(o&&t&&t.some((function(e){return e.toLowerCase()===o.toLowerCase()}))):Boolean(o&&t&&t)}var y=e.createContext(void 0);function p(e){return t.jsx(y.Provider,{value:{addHotkey:e.addHotkey,removeHotkey:e.removeHotkey},children:e.children})}function m(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,o){return n&&m(e[o],t[o])}),!0):e===t}var h=e.createContext({hotkeys:[],activeScopes:[],toggleScope:function(){},enableScope:function(){},disableScope:function(){}}),k=function(){return e.useContext(h)},w=function(e){e.stopPropagation(),e.preventDefault(),e.stopImmediatePropagation()},g="undefined"!=typeof window?e.useLayoutEffect:e.useEffect;exports.HotkeysProvider=function(n){var o=n.initiallyActiveScopes,r=n.children,i=e.useState(void 0===o?["*"]:o),u=i[0],c=i[1],l=e.useState([]),a=l[0],d=l[1],s=e.useCallback((function(e){c((function(t){return t.includes("*")?[e]:Array.from(new Set([].concat(t,[e])))}))}),[]),f=e.useCallback((function(e){c((function(t){return t.filter((function(t){return t!==e}))}))}),[]),v=e.useCallback((function(e){c((function(t){return t.includes(e)?t.filter((function(t){return t!==e})):t.includes("*")?[e]:Array.from(new Set([].concat(t,[e])))}))}),[]),y=e.useCallback((function(e){d((function(t){return[].concat(t,[e])}))}),[]),k=e.useCallback((function(e){d((function(t){return t.filter((function(t){return!m(t,e)}))}))}),[]);return t.jsx(h.Provider,{value:{activeScopes:u,hotkeys:a,enableScope:s,disableScope:f,toggleScope:v},children:t.jsx(p,{addHotkey:y,removeHotkey:k,children:r})})},exports.isHotkeyPressed=d,exports.useHotkeys=function(t,n,o,r){var l=e.useRef(null),p=e.useRef(!1),h=o instanceof Array?r instanceof Array?void 0:r:o,b=a(t)?t.join(null==h?void 0:h.delimiter):t,C=o instanceof Array?o:r instanceof Array?r:void 0,S=e.useCallback(n,null!=C?C:[]),L=e.useRef(S);L.current=C?S:n;var E=function(t){var n=e.useRef(void 0);return m(n.current,t)||(n.current=t),n.current}(h),A=k().activeScopes,x=e.useContext(y);return g((function(){if(!1!==(null==E?void 0:E.enabled)&&function(e,t){return 0===e.length&&t?(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>'),!0):!t||e.some((function(e){return t.includes(e)}))||e.includes("*")}(A,null==E?void 0:E.scopes)){var e=function(e,t){var n;if(void 0===t&&(t=!1),!v(e,["input","textarea","select"])||v(e,null==E?void 0:E.enableOnFormTags)){if(null!==l.current){var o=l.current.getRootNode();if((o instanceof Document||o instanceof ShadowRoot)&&o.activeElement!==l.current&&!l.current.contains(o.activeElement))return void w(e)}(null==(n=e.target)||!n.isContentEditable||null!=E&&E.enableOnContentEditable)&&u(b,null==E?void 0:E.delimiter).forEach((function(n){var o,r=c(n,null==E?void 0:E.splitKey,null==E?void 0:E.useKey);if(function(e,t,n){void 0===n&&(n=!1);var o=t.alt,r=t.meta,u=t.mod,c=t.shift,l=t.ctrl,a=t.keys,s=t.useKey,f=e.key,v=e.ctrlKey,y=e.metaKey,p=e.shiftKey,m=e.altKey,h=i(e.code);if(s&&1===(null==a?void 0:a.length)&&a.includes(f))return!0;if(!(null!=a&&a.includes(h)||["ctrl","control","unknown","meta","alt","shift","os"].includes(h)))return!1;if(!n){if(o!==m&&"alt"!==h)return!1;if(c!==p&&"shift"!==h)return!1;if(u){if(!y&&!v)return!1}else{if(r!==y&&"meta"!==h&&"os"!==h)return!1;if(l!==v&&"ctrl"!==h&&"control"!==h)return!1}}return!(!a||1!==a.length||!a.includes(h))||(a?d(a):!a)}(e,r,null==E?void 0:E.ignoreModifiers)||null!=(o=r.keys)&&o.includes("*")){if(null!=E&&null!=E.ignoreEventWhen&&E.ignoreEventWhen(e))return;if(t&&p.current)return;if(function(e,t,n){("function"==typeof n&&n(e,t)||!0===n)&&e.preventDefault()}(e,r,null==E?void 0:E.preventDefault),!function(e,t,n){return"function"==typeof n?n(e,t):!0===n||void 0===n}(e,r,null==E?void 0:E.enabled))return void w(e);L.current(e,r),t||(p.current=!0)}}))}},t=function(t){void 0!==t.code&&(s(i(t.code)),(void 0===(null==E?void 0:E.keydown)&&!0!==(null==E?void 0:E.keyup)||null!=E&&E.keydown)&&e(t))},n=function(t){void 0!==t.code&&(f(i(t.code)),p.current=!1,null!=E&&E.keyup&&e(t,!0))},o=l.current||(null==h?void 0:h.document)||document;return o.addEventListener("keyup",n),o.addEventListener("keydown",t),x&&u(b,null==E?void 0:E.delimiter).forEach((function(e){return x.addHotkey(c(e,null==E?void 0:E.splitKey,null==E?void 0:E.useKey,null==E?void 0:E.description))})),function(){o.removeEventListener("keyup",n),o.removeEventListener("keydown",t),x&&u(b,null==E?void 0:E.delimiter).forEach((function(e){return x.removeHotkey(c(e,null==E?void 0:E.splitKey,null==E?void 0:E.useKey,null==E?void 0:E.description))}))}}}),[b,E,A]),l},exports.useHotkeysContext=k,exports.useRecordHotkeys=function(){var t=e.useState(new Set),n=t[0],o=t[1],r=e.useState(!1),u=r[0],c=r[1],l=e.useCallback((function(e){void 0!==e.code&&(e.preventDefault(),e.stopPropagation(),o((function(t){var n=new Set(t);return n.add(i(e.code)),n})))}),[]),a=e.useCallback((function(){"undefined"!=typeof document&&(document.removeEventListener("keydown",l),c(!1))}),[l]),d=e.useCallback((function(){o(new Set),"undefined"!=typeof document&&(a(),document.addEventListener("keydown",l),c(!0))}),[l,a]),s=e.useCallback((function(){o(new Set)}),[]);return[n,{start:d,stop:a,resetKeys:s,isRecording:u}]}; | ||
//# sourceMappingURL=react-hotkeys-hook.cjs.production.min.js.map |
@@ -19,3 +19,3 @@ import { useContext, createContext, useState, useCallback, useRef, useLayoutEffect, useEffect } from 'react'; | ||
var reservedModifierKeywords = ['shift', 'alt', 'meta', 'mod', 'ctrl']; | ||
var reservedModifierKeywords = ['shift', 'alt', 'meta', 'mod', 'ctrl', 'control']; | ||
var mappedKeys = { | ||
@@ -28,3 +28,2 @@ esc: 'escape', | ||
down: 'arrowdown', | ||
space: ' ', | ||
ShiftLeft: 'shift', | ||
@@ -47,13 +46,16 @@ ShiftRight: 'shift', | ||
} | ||
function parseKeysHookInput(keys, splitKey) { | ||
if (splitKey === void 0) { | ||
splitKey = ','; | ||
function parseKeysHookInput(keys, delimiter) { | ||
if (delimiter === void 0) { | ||
delimiter = ','; | ||
} | ||
return keys.split(splitKey); | ||
return keys.toLowerCase().split(delimiter); | ||
} | ||
function parseHotkey(hotkey, combinationKey, description) { | ||
if (combinationKey === void 0) { | ||
combinationKey = '+'; | ||
function parseHotkey(hotkey, splitKey, useKey, description) { | ||
if (splitKey === void 0) { | ||
splitKey = '+'; | ||
} | ||
var keys = hotkey.toLocaleLowerCase().split(combinationKey).map(function (k) { | ||
if (useKey === void 0) { | ||
useKey = false; | ||
} | ||
var keys = hotkey.toLocaleLowerCase().split(splitKey).map(function (k) { | ||
return mapKey(k); | ||
@@ -66,3 +68,4 @@ }); | ||
meta: keys.includes('meta'), | ||
mod: keys.includes('mod') | ||
mod: keys.includes('mod'), | ||
useKey: useKey | ||
}; | ||
@@ -81,15 +84,14 @@ var singleCharKeys = keys.filter(function (k) { | ||
document.addEventListener('keydown', function (e) { | ||
if (e.key === undefined) { | ||
if (e.code === undefined) { | ||
// Synthetic event (e.g., Chrome autofill). Ignore. | ||
return; | ||
} | ||
console.log('keydown', e.key, mapKey(e.key), e.key.length); | ||
pushToCurrentlyPressedKeys([mapKey(e.key)]); | ||
pushToCurrentlyPressedKeys([mapKey(e.code)]); | ||
}); | ||
document.addEventListener('keyup', function (e) { | ||
if (e.key === undefined) { | ||
if (e.code === undefined) { | ||
// Synthetic event (e.g., Chrome autofill). Ignore. | ||
return; | ||
} | ||
removeFromCurrentlyPressedKeys([mapKey(e.key)]); | ||
removeFromCurrentlyPressedKeys([mapKey(e.code)]); | ||
}); | ||
@@ -108,7 +110,7 @@ } | ||
} | ||
function isHotkeyPressed(key, splitKey) { | ||
if (splitKey === void 0) { | ||
splitKey = ','; | ||
function isHotkeyPressed(key, delimiter) { | ||
if (delimiter === void 0) { | ||
delimiter = ','; | ||
} | ||
var hotkeyArray = isReadonlyArray(key) ? key : key.split(splitKey); | ||
var hotkeyArray = isReadonlyArray(key) ? key : key.split(delimiter); | ||
return hotkeyArray.every(function (hotkey) { | ||
@@ -175,3 +177,3 @@ return currentlyPressedKeys.has(hotkey.trim().toLowerCase()); | ||
} | ||
return Boolean(targetTagName && enabledOnTags && enabledOnTags === true); | ||
return Boolean(targetTagName && enabledOnTags && enabledOnTags); | ||
} | ||
@@ -199,4 +201,6 @@ function isScopeActive(activeScopes, scopes) { | ||
ctrl = hotkey.ctrl, | ||
keys = hotkey.keys; | ||
var pressedKeyUppercase = e.key, | ||
keys = hotkey.keys, | ||
useKey = hotkey.useKey; | ||
var code = e.code, | ||
producedKey = e.key, | ||
ctrlKey = e.ctrlKey, | ||
@@ -206,4 +210,7 @@ metaKey = e.metaKey, | ||
altKey = e.altKey; | ||
var pressedKey = pressedKeyUppercase.toLowerCase(); | ||
if (!(keys != null && keys.includes(pressedKey)) && !['ctrl', 'control', 'unknown', 'meta', 'alt', 'shift', 'os'].includes(pressedKey)) { | ||
var mappedCode = mapKey(code); | ||
if (useKey && (keys == null ? void 0 : keys.length) === 1 && keys.includes(producedKey)) { | ||
return true; | ||
} | ||
if (!(keys != null && keys.includes(mappedCode)) && !['ctrl', 'control', 'unknown', 'meta', 'alt', 'shift', 'os'].includes(mappedCode)) { | ||
return false; | ||
@@ -213,6 +220,6 @@ } | ||
// We check the pressed keys for compatibility with the keyup event. In keyup events the modifier flags are not set. | ||
if (alt === !altKey && pressedKey !== 'alt') { | ||
if (alt !== altKey && mappedCode !== 'alt') { | ||
return false; | ||
} | ||
if (shift === !shiftKey && pressedKey !== 'shift') { | ||
if (shift !== shiftKey && mappedCode !== 'shift') { | ||
return false; | ||
@@ -226,6 +233,6 @@ } | ||
} else { | ||
if (meta === !metaKey && pressedKey !== 'meta' && pressedKey !== 'os') { | ||
if (meta !== metaKey && mappedCode !== 'meta' && mappedCode !== 'os') { | ||
return false; | ||
} | ||
if (ctrl === !ctrlKey && pressedKey !== 'ctrl' && pressedKey !== 'control') { | ||
if (ctrl !== ctrlKey && mappedCode !== 'ctrl' && mappedCode !== 'control') { | ||
return false; | ||
@@ -237,3 +244,3 @@ } | ||
// If the key is set, we check for the key | ||
if (keys && keys.length === 1 && keys.includes(pressedKey)) { | ||
if (keys && keys.length === 1 && keys.includes(mappedCode)) { | ||
return true; | ||
@@ -372,3 +379,3 @@ } else if (keys) { | ||
var _options = !(options instanceof Array) ? options : !(dependencies instanceof Array) ? dependencies : undefined; | ||
var _keys = isReadonlyArray(keys) ? keys.join(_options == null ? void 0 : _options.splitKey) : keys; | ||
var _keys = isReadonlyArray(keys) ? keys.join(_options == null ? void 0 : _options.delimiter) : keys; | ||
var _deps = options instanceof Array ? options : dependencies instanceof Array ? dependencies : undefined; | ||
@@ -410,5 +417,5 @@ var memoisedCB = useCallback(callback, _deps != null ? _deps : []); | ||
} | ||
parseKeysHookInput(_keys, memoisedOptions == null ? void 0 : memoisedOptions.splitKey).forEach(function (key) { | ||
parseKeysHookInput(_keys, memoisedOptions == null ? void 0 : memoisedOptions.delimiter).forEach(function (key) { | ||
var _hotkey$keys; | ||
var hotkey = parseHotkey(key, memoisedOptions == null ? void 0 : memoisedOptions.combinationKey); | ||
var hotkey = parseHotkey(key, memoisedOptions == null ? void 0 : memoisedOptions.splitKey, memoisedOptions == null ? void 0 : memoisedOptions.useKey); | ||
if (isHotkeyMatchingKeyboardEvent(e, hotkey, memoisedOptions == null ? void 0 : memoisedOptions.ignoreModifiers) || (_hotkey$keys = hotkey.keys) != null && _hotkey$keys.includes('*')) { | ||
@@ -435,7 +442,7 @@ if (memoisedOptions != null && memoisedOptions.ignoreEventWhen != null && memoisedOptions.ignoreEventWhen(e)) { | ||
var handleKeyDown = function handleKeyDown(event) { | ||
if (event.key === undefined) { | ||
if (event.code === undefined) { | ||
// Synthetic event (e.g., Chrome autofill). Ignore. | ||
return; | ||
} | ||
pushToCurrentlyPressedKeys(mapKey(event.key)); | ||
pushToCurrentlyPressedKeys(mapKey(event.code)); | ||
if ((memoisedOptions == null ? void 0 : memoisedOptions.keydown) === undefined && (memoisedOptions == null ? void 0 : memoisedOptions.keyup) !== true || memoisedOptions != null && memoisedOptions.keydown) { | ||
@@ -446,7 +453,7 @@ listener(event); | ||
var handleKeyUp = function handleKeyUp(event) { | ||
if (event.key === undefined) { | ||
if (event.code === undefined) { | ||
// Synthetic event (e.g., Chrome autofill). Ignore. | ||
return; | ||
} | ||
removeFromCurrentlyPressedKeys(mapKey(event.key)); | ||
removeFromCurrentlyPressedKeys(mapKey(event.code)); | ||
hasTriggeredRef.current = false; | ||
@@ -463,4 +470,4 @@ if (memoisedOptions != null && memoisedOptions.keyup) { | ||
if (proxy) { | ||
parseKeysHookInput(_keys, memoisedOptions == null ? void 0 : memoisedOptions.splitKey).forEach(function (key) { | ||
return proxy.addHotkey(parseHotkey(key, memoisedOptions == null ? void 0 : memoisedOptions.combinationKey, memoisedOptions == null ? void 0 : memoisedOptions.description)); | ||
parseKeysHookInput(_keys, memoisedOptions == null ? void 0 : memoisedOptions.delimiter).forEach(function (key) { | ||
return proxy.addHotkey(parseHotkey(key, memoisedOptions == null ? void 0 : memoisedOptions.splitKey, memoisedOptions == null ? void 0 : memoisedOptions.useKey, memoisedOptions == null ? void 0 : memoisedOptions.description)); | ||
}); | ||
@@ -474,4 +481,4 @@ } | ||
if (proxy) { | ||
parseKeysHookInput(_keys, memoisedOptions == null ? void 0 : memoisedOptions.splitKey).forEach(function (key) { | ||
return proxy.removeHotkey(parseHotkey(key, memoisedOptions == null ? void 0 : memoisedOptions.combinationKey, memoisedOptions == null ? void 0 : memoisedOptions.description)); | ||
parseKeysHookInput(_keys, memoisedOptions == null ? void 0 : memoisedOptions.delimiter).forEach(function (key) { | ||
return proxy.removeHotkey(parseHotkey(key, memoisedOptions == null ? void 0 : memoisedOptions.splitKey, memoisedOptions == null ? void 0 : memoisedOptions.useKey, memoisedOptions == null ? void 0 : memoisedOptions.description)); | ||
}); | ||
@@ -492,3 +499,3 @@ } | ||
var handler = useCallback(function (event) { | ||
if (event.key === undefined) { | ||
if (event.code === undefined) { | ||
// Synthetic event (e.g., Chrome autofill). Ignore. | ||
@@ -501,3 +508,3 @@ return; | ||
var newKeys = new Set(prev); | ||
newKeys.add(mapKey(event.key)); | ||
newKeys.add(mapKey(event.code)); | ||
return newKeys; | ||
@@ -520,5 +527,9 @@ }); | ||
}, [handler, stop]); | ||
var resetKeys = useCallback(function () { | ||
setKeys(new Set()); | ||
}, []); | ||
return [keys, { | ||
start: start, | ||
stop: stop, | ||
resetKeys: resetKeys, | ||
isRecording: isRecording | ||
@@ -525,0 +536,0 @@ }]; |
@@ -12,2 +12,3 @@ import type { DependencyList } from 'react'; | ||
mod?: boolean; | ||
useKey?: boolean; | ||
}; | ||
@@ -27,4 +28,4 @@ export declare type Hotkey = KeyboardModifiers & { | ||
ignoreEventWhen?: (e: KeyboardEvent) => boolean; | ||
combinationKey?: string; | ||
splitKey?: string; | ||
delimiter?: string; | ||
scopes?: Scopes; | ||
@@ -37,3 +38,4 @@ keyup?: boolean; | ||
ignoreModifiers?: boolean; | ||
useKey?: boolean; | ||
}; | ||
export declare type OptionsOrDependencyArray = Options | DependencyList; |
export default function useRecordHotkeys(): readonly [Set<string>, { | ||
readonly start: () => void; | ||
readonly stop: () => void; | ||
readonly resetKeys: () => void; | ||
readonly isRecording: boolean; | ||
}]; |
{ | ||
"name": "react-hotkeys-hook", | ||
"description": "React hook for handling keyboard shortcuts", | ||
"version": "5.0.0-0", | ||
"version": "5.0.0-1", | ||
"repository": { | ||
@@ -91,3 +91,3 @@ "type": "git", | ||
"@types/jest": "29.5.11", | ||
"@types/react": "18.2.46", | ||
"@types/react": "18.2.47", | ||
"@types/react-dom": "18.2.18", | ||
@@ -94,0 +94,0 @@ "@typescript-eslint/eslint-plugin": "5.60.0", |
@@ -5,3 +5,3 @@ import { isHotkeyModifier, mapKey } from './parseHotkeys' | ||
document.addEventListener('keydown', (e) => { | ||
if (e.key === undefined) { | ||
if (e.code === undefined) { | ||
// Synthetic event (e.g., Chrome autofill). Ignore. | ||
@@ -11,9 +11,7 @@ return | ||
console.log('keydown', e.key, mapKey(e.key), e.key.length) | ||
pushToCurrentlyPressedKeys([mapKey(e.key)]) | ||
pushToCurrentlyPressedKeys([mapKey(e.code)]) | ||
}) | ||
document.addEventListener('keyup', (e) => { | ||
if (e.key === undefined) { | ||
if (e.code === undefined) { | ||
// Synthetic event (e.g., Chrome autofill). Ignore. | ||
@@ -23,3 +21,3 @@ return | ||
removeFromCurrentlyPressedKeys([mapKey(e.key)]) | ||
removeFromCurrentlyPressedKeys([mapKey(e.code)]) | ||
}) | ||
@@ -42,4 +40,4 @@ } | ||
export function isHotkeyPressed(key: string | readonly string[], splitKey = ','): boolean { | ||
const hotkeyArray = isReadonlyArray(key) ? key : key.split(splitKey) | ||
export function isHotkeyPressed(key: string | readonly string[], delimiter = ','): boolean { | ||
const hotkeyArray = isReadonlyArray(key) ? key : key.split(delimiter) | ||
@@ -46,0 +44,0 @@ return hotkeyArray.every((hotkey) => currentlyPressedKeys.has(hotkey.trim().toLowerCase())) |
import { Hotkey, KeyboardModifiers } from './types' | ||
const reservedModifierKeywords = ['shift', 'alt', 'meta', 'mod', 'ctrl'] | ||
const reservedModifierKeywords = ['shift', 'alt', 'meta', 'mod', 'ctrl', 'control'] | ||
@@ -12,3 +12,2 @@ const mappedKeys: Record<string, string> = { | ||
down: 'arrowdown', | ||
space: ' ', | ||
ShiftLeft: 'shift', | ||
@@ -34,10 +33,10 @@ ShiftRight: 'shift', | ||
export function parseKeysHookInput(keys: string, splitKey = ','): string[] { | ||
return keys.split(splitKey) | ||
export function parseKeysHookInput(keys: string, delimiter = ','): string[] { | ||
return keys.toLowerCase().split(delimiter) | ||
} | ||
export function parseHotkey(hotkey: string, combinationKey = '+', description?: string): Hotkey { | ||
export function parseHotkey(hotkey: string, splitKey = '+', useKey = false, description?: string): Hotkey { | ||
const keys = hotkey | ||
.toLocaleLowerCase() | ||
.split(combinationKey) | ||
.split(splitKey) | ||
.map((k) => mapKey(k)) | ||
@@ -51,2 +50,3 @@ | ||
mod: keys.includes('mod'), | ||
useKey, | ||
} | ||
@@ -53,0 +53,0 @@ |
@@ -15,2 +15,3 @@ import type { DependencyList } from 'react' | ||
mod?: boolean | ||
useKey?: boolean // Custom modifier to listen to the produced key instead of the code | ||
} | ||
@@ -31,17 +32,32 @@ | ||
export type Options = { | ||
enabled?: Trigger // Main setting that determines if the hotkey is enabled or not. (Default: true) | ||
enableOnFormTags?: readonly FormTags[] | boolean // Enable hotkeys on a list of tags. (Default: false) | ||
enableOnContentEditable?: boolean // Enable hotkeys on tags with contentEditable props. (Default: false) | ||
ignoreEventWhen?: (e: KeyboardEvent) => boolean // Ignore evenets based on a condition (Default: undefined) | ||
combinationKey?: string // Character to split keys in hotkeys combinations. (Default: +) | ||
splitKey?: string // Character to separate different hotkeys. (Default: ,) | ||
scopes?: Scopes // Scope | ||
keyup?: boolean // Trigger on keyup event? (Default: undefined) | ||
keydown?: boolean // Trigger on keydown event? (Default: true) | ||
preventDefault?: Trigger // Prevent default browser behavior? (Default: false) | ||
description?: string // Use this option to describe what the hotkey does. (Default: undefined) | ||
document?: Document // Listen to events on the document instead of the window. (Default: false) | ||
ignoreModifiers?: boolean // Ignore modifiers when matching hotkeys. (Default: false) | ||
// Main setting that determines if the hotkey is enabled or not. (Default: true) | ||
enabled?: Trigger | ||
// Enable hotkeys on a list of tags. (Default: false) | ||
enableOnFormTags?: readonly FormTags[] | boolean | ||
// Enable hotkeys on tags with contentEditable props. (Default: false) | ||
enableOnContentEditable?: boolean | ||
// Ignore evenets based on a condition (Default: undefined) | ||
ignoreEventWhen?: (e: KeyboardEvent) => boolean | ||
// Character to split keys in hotkeys combinations. (Default: +) | ||
splitKey?: string | ||
// Character to separate different hotkeys. (Default: ,) | ||
delimiter?: string | ||
// Scope of the hotkey. (Default: undefined) | ||
scopes?: Scopes | ||
// Trigger on keyup event? (Default: undefined) | ||
keyup?: boolean | ||
// Trigger on keydown event? (Default: true) | ||
keydown?: boolean | ||
// Prevent default browser behavior? (Default: false) | ||
preventDefault?: Trigger | ||
// Use this option to describe what the hotkey does. (Default: undefined) | ||
description?: string | ||
// Listen to events on the document instead of the window. (Default: false) | ||
document?: Document | ||
// Ignore modifiers when matching hotkeys. (Default: false) | ||
ignoreModifiers?: boolean | ||
// Listen to the produced key instead of the code. (Default: false) | ||
useKey?: boolean | ||
} | ||
export type OptionsOrDependencyArray = Options | DependencyList |
@@ -39,3 +39,3 @@ import { HotkeyCallback, Keys, Options, OptionsOrDependencyArray, RefType } from './types' | ||
: undefined | ||
const _keys: string = isReadonlyArray(keys) ? keys.join(_options?.splitKey) : keys | ||
const _keys: string = isReadonlyArray(keys) ? keys.join(_options?.delimiter) : keys | ||
const _deps: DependencyList | undefined = | ||
@@ -87,4 +87,4 @@ options instanceof Array ? options : dependencies instanceof Array ? dependencies : undefined | ||
parseKeysHookInput(_keys, memoisedOptions?.splitKey).forEach((key) => { | ||
const hotkey = parseHotkey(key, memoisedOptions?.combinationKey) | ||
parseKeysHookInput(_keys, memoisedOptions?.delimiter).forEach((key) => { | ||
const hotkey = parseHotkey(key, memoisedOptions?.splitKey, memoisedOptions?.useKey) | ||
@@ -119,3 +119,3 @@ if (isHotkeyMatchingKeyboardEvent(e, hotkey, memoisedOptions?.ignoreModifiers) || hotkey.keys?.includes('*')) { | ||
const handleKeyDown = (event: KeyboardEvent) => { | ||
if (event.key === undefined) { | ||
if (event.code === undefined) { | ||
// Synthetic event (e.g., Chrome autofill). Ignore. | ||
@@ -125,3 +125,3 @@ return | ||
pushToCurrentlyPressedKeys(mapKey(event.key)) | ||
pushToCurrentlyPressedKeys(mapKey(event.code)) | ||
@@ -134,3 +134,3 @@ if ((memoisedOptions?.keydown === undefined && memoisedOptions?.keyup !== true) || memoisedOptions?.keydown) { | ||
const handleKeyUp = (event: KeyboardEvent) => { | ||
if (event.key === undefined) { | ||
if (event.code === undefined) { | ||
// Synthetic event (e.g., Chrome autofill). Ignore. | ||
@@ -140,3 +140,3 @@ return | ||
removeFromCurrentlyPressedKeys(mapKey(event.key)) | ||
removeFromCurrentlyPressedKeys(mapKey(event.code)) | ||
@@ -158,4 +158,6 @@ hasTriggeredRef.current = false | ||
if (proxy) { | ||
parseKeysHookInput(_keys, memoisedOptions?.splitKey).forEach((key) => | ||
proxy.addHotkey(parseHotkey(key, memoisedOptions?.combinationKey, memoisedOptions?.description)) | ||
parseKeysHookInput(_keys, memoisedOptions?.delimiter).forEach((key) => | ||
proxy.addHotkey( | ||
parseHotkey(key, memoisedOptions?.splitKey, memoisedOptions?.useKey, memoisedOptions?.description) | ||
) | ||
) | ||
@@ -171,4 +173,6 @@ } | ||
if (proxy) { | ||
parseKeysHookInput(_keys, memoisedOptions?.splitKey).forEach((key) => | ||
proxy.removeHotkey(parseHotkey(key, memoisedOptions?.combinationKey, memoisedOptions?.description)) | ||
parseKeysHookInput(_keys, memoisedOptions?.delimiter).forEach((key) => | ||
proxy.removeHotkey( | ||
parseHotkey(key, memoisedOptions?.splitKey, memoisedOptions?.useKey, memoisedOptions?.description) | ||
) | ||
) | ||
@@ -175,0 +179,0 @@ } |
@@ -9,3 +9,3 @@ import { useCallback, useState } from 'react' | ||
const handler = useCallback((event: KeyboardEvent) => { | ||
if (event.key === undefined) { | ||
if (event.code === undefined) { | ||
// Synthetic event (e.g., Chrome autofill). Ignore. | ||
@@ -21,3 +21,3 @@ return | ||
newKeys.add(mapKey(event.key)) | ||
newKeys.add(mapKey(event.code)) | ||
@@ -48,3 +48,7 @@ return newKeys | ||
return [keys, { start, stop, isRecording }] as const | ||
const resetKeys = useCallback(() => { | ||
setKeys(new Set<string>()) | ||
}, []) | ||
return [keys, { start, stop, resetKeys, isRecording }] as const | ||
} |
import { FormTags, Hotkey, Scopes, Trigger } from './types' | ||
import { isHotkeyPressed, isReadonlyArray } from './isHotkeyPressed' | ||
import { mapKey } from './parseHotkeys' | ||
@@ -34,3 +35,3 @@ export function maybePreventDefault(e: KeyboardEvent, hotkey: Hotkey, preventDefault?: Trigger): void { | ||
return Boolean(targetTagName && enabledOnTags && enabledOnTags === true) | ||
return Boolean(targetTagName && enabledOnTags && enabledOnTags) | ||
} | ||
@@ -55,10 +56,14 @@ | ||
export const isHotkeyMatchingKeyboardEvent = (e: KeyboardEvent, hotkey: Hotkey, ignoreModifiers = false): boolean => { | ||
const { alt, meta, mod, shift, ctrl, keys } = hotkey | ||
const { key: pressedKeyUppercase, ctrlKey, metaKey, shiftKey, altKey } = e | ||
const { alt, meta, mod, shift, ctrl, keys, useKey } = hotkey | ||
const { code, key: producedKey, ctrlKey, metaKey, shiftKey, altKey } = e | ||
const pressedKey = pressedKeyUppercase.toLowerCase() | ||
const mappedCode = mapKey(code) | ||
if (useKey && keys?.length === 1 && keys.includes(producedKey)) { | ||
return true | ||
} | ||
if ( | ||
!keys?.includes(pressedKey) && | ||
!['ctrl', 'control', 'unknown', 'meta', 'alt', 'shift', 'os'].includes(pressedKey) | ||
!keys?.includes(mappedCode) && | ||
!['ctrl', 'control', 'unknown', 'meta', 'alt', 'shift', 'os'].includes(mappedCode) | ||
) { | ||
@@ -70,7 +75,7 @@ return false | ||
// We check the pressed keys for compatibility with the keyup event. In keyup events the modifier flags are not set. | ||
if (alt === !altKey && pressedKey !== 'alt') { | ||
if (alt !== altKey && mappedCode !== 'alt') { | ||
return false | ||
} | ||
if (shift === !shiftKey && pressedKey !== 'shift') { | ||
if (shift !== shiftKey && mappedCode !== 'shift') { | ||
return false | ||
@@ -85,7 +90,7 @@ } | ||
} else { | ||
if (meta === !metaKey && pressedKey !== 'meta' && pressedKey !== 'os') { | ||
if (meta !== metaKey && mappedCode !== 'meta' && mappedCode !== 'os') { | ||
return false | ||
} | ||
if (ctrl === !ctrlKey && pressedKey !== 'ctrl' && pressedKey !== 'control') { | ||
if (ctrl !== ctrlKey && mappedCode !== 'ctrl' && mappedCode !== 'control') { | ||
return false | ||
@@ -98,3 +103,3 @@ } | ||
// If the key is set, we check for the key | ||
if (keys && keys.length === 1 && keys.includes(pressedKey)) { | ||
if (keys && keys.length === 1 && keys.includes(mappedCode)) { | ||
return true | ||
@@ -101,0 +106,0 @@ } else if (keys) { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
194611
1711