greena13 / react-hotkeys

Declarative hotkey and focus area management for React
https://github.com/greena13/react-hotkeys
ISC License
2.15k stars 161 forks source link

[BUG] Shift+Space combination doesn't work and breaks other bindings #300

Open andrew-sv opened 3 years ago

andrew-sv commented 3 years ago

Describe the bug Here is the link to sandbox where this bug can be reproduced: [https://codesandbox.io/s/happy-johnson-su7vz] Steps to reproduce: 1) Focus button and press Shift+Space 2) It writes message to console "(Shift+Space) pressed" 3) Press Shift+Space one more time. It doesn't output anything to console. 4) Refocus element and try to press Shift without space. You can see "(Shift+Space) pressed" in console. 5) Try to press another combination: Shift+R. It doesn't work. 6) If you reload the page and try similar steps with Shift+R combination, everything will work fine.

How are you using react hotkeys components? (HotKeys, GlobalHotKeys, IgnoreKeys etc)

**Expected behavior** Shift+Space combination should work properly. **Platform (please complete the following information):** - react-hotkeys v2.0.0 - Browser: chrome - OS: Windows **Are you willing and able to create a PR request to fix this issue?** Yes. **Include the smallest log that includes your issue:** ``` HotKeys (C0🔺): Registered component in application key map: { "childIds": [], "parentId": null, "keyMap": { "ACTION1": "shift+space", "ACTION2": "shift+r" } } HotKeys (Fundefinedundefined-C0🔺): Registered component mount: { "childIds": [], "parentId": null, "keyMap": { "ACTION1": "shift+space", "ACTION2": "shift+r" } } HotKeys (Fundefinedundefined-C0🔺-P0🔺): Focused HotKeys (Fundefinedundefined-C0🔺-P0🔺): New component options: { "actions": { "ACTION1": [ { "prefix": "", "actionName": "ACTION1", "sequenceLength": 1, "id": "Shift+ ", "keyDictionary": { "Shift": true, " ": true }, "keyEventType": 0, "size": 2 } ], "ACTION2": [ { "prefix": "", "actionName": "ACTION2", "sequenceLength": 1, "id": "Shift+r", "keyDictionary": { "Shift": true, "r": true }, "keyEventType": 0, "size": 2 } ] }, "handlers": { "ACTION1": "spy", "ACTION2": "spy" }, "componentId": 0, "options": { "defaultKeyEvent": "keydown" } } HotKeys (Fundefinedundefined-C0🔺-P0🔺-E1💚): New 'Shift' keydown event. HotKeys (Fundefinedundefined-C0🔺-P0🔺-E1💚): Added 'Shift' to current combination: 'Shift'. HotKeys (Fundefinedundefined-C0🔺-P0🔺-E1💚): Key history: [ { "keys": { "Shift": [ [ 0, 0, 0 ], [ 1, 0, 0 ] ] }, "ids": [ "Shift" ], "keyAliases": {} } ]. HotKeys (F0📕-C0🔺-P0🔺-E1💚): Attempting to find action matching 'Shift' keydown . . . HotKeys (Fundefinedundefined-C0🔺-P0🔺-E1💚): Internal key mapping: { "": { "actionConfigs": { "Shift+ ": { "prefix": "", "sequenceLength": 1, "id": "Shift+ ", "keyDictionary": { "Shift": true, " ": true }, "size": 2, "events": { "0": { "actionName": "ACTION1", "handler": "spy" } } }, "Shift+r": { "prefix": "", "sequenceLength": 1, "id": "Shift+r", "keyDictionary": { "Shift": true, "r": true }, "size": 2, "events": { "0": { "actionName": "ACTION2", "handler": "spy" } } } }, "order": null } } HotKeys (Fundefinedundefined-C0🔺-P0🔺-E1💚): No matching actions found for 'Shift' keydown. HotKeys (Fundefinedundefined-C0🔺-P0🔺-E3💛): New (simulated) 'Shift' keypress event. HotKeys (Fundefinedundefined-C0🔺-P0🔺-E3💛): Key history: [ { "keys": { "Shift": [ [ 1, 0, 0 ], [ 1, 2, 0 ] ] }, "ids": [ "Shift" ], "keyAliases": {} } ]. HotKeys (Fundefinedundefined-C0🔺-P0🔺-E3💛): Ignored 'Shift' keypress because it doesn't have any keypress handlers. HotKeys (Fundefinedundefined-C0🔺-P0🔺-E4💜): New ' ' keydown event. HotKeys (Fundefinedundefined-C0🔺-P0🔺-E4💜): Added ' ' to current combination: 'Shift+ '. HotKeys (Fundefinedundefined-C0🔺-P0🔺-E4💜): Key history: [ { "keys": { "Shift": [ [ 1, 0, 0 ], [ 1, 2, 0 ] ], " ": [ [ 0, 0, 0 ], [ 1, 0, 0 ] ] }, "ids": [ "Shift+ " ], "keyAliases": {} } ]. HotKeys (F0📕-C0🔺-P0🔺-E4💜): Attempting to find action matching 'Shift+ ' keydown . . . HotKeys (Fundefinedundefined-C0🔺-P0🔺-E4💜): Internal key mapping: { "": { "actionConfigs": { "Shift+ ": { "prefix": "", "sequenceLength": 1, "id": "Shift+ ", "keyDictionary": { "Shift": true, " ": true }, "size": 2, "events": { "0": { "actionName": "ACTION1", "handler": "spy" } } }, "Shift+r": { "prefix": "", "sequenceLength": 1, "id": "Shift+r", "keyDictionary": { "Shift": true, "r": true }, "size": 2, "events": { "0": { "actionName": "ACTION2", "handler": "spy" } } } }, "order": [ "Shift+ ", "Shift+r" ] } } HotKeys (Fundefinedundefined-C0🔺-P0🔺-E4💜): Found action that matches 'Shift+ ': ACTION1. Calling handler . . . HotKeys (Fundefinedundefined-C0🔺-P0🔺-E4💜): Stopping further event propagation. HotKeys (Fundefinedundefined-C0🔺-P0🔺-E6❤️): New (simulated) ' ' keypress event. HotKeys (Fundefinedundefined-C0🔺-P0🔺-E6❤️): Key history: [ { "keys": { "Shift": [ [ 1, 0, 0 ], [ 1, 2, 0 ] ], " ": [ [ 1, 0, 0 ], [ 1, 2, 0 ] ] }, "ids": [ "Shift+ " ], "keyAliases": {} } ]. HotKeys (Fundefinedundefined-C0🔺-P0🔺-E6❤️): Ignored 'Shift+ ' keypress because it doesn't have any keypress handlers. HotKeys (F0📕-C0🔺-P0🔺-E6❤️): Lost focus. HotKeys (Fundefinedundefined-C0🔺-P0🔺): Focused HotKeys (Fundefinedundefined-C0🔺-P0🔺): New component options: { "actions": { "ACTION1": [ { "prefix": "", "actionName": "ACTION1", "sequenceLength": 1, "id": "Shift+ ", "keyDictionary": { "Shift": true, " ": true }, "keyEventType": 0, "size": 2 } ], "ACTION2": [ { "prefix": "", "actionName": "ACTION2", "sequenceLength": 1, "id": "Shift+r", "keyDictionary": { "Shift": true, "r": true }, "keyEventType": 0, "size": 2 } ] }, "handlers": { "ACTION1": "handler", "ACTION2": "spy" }, "componentId": 0, "options": { "defaultKeyEvent": "keydown" } } HotKeys (Fundefinedundefined-C0🔺-P0🔺-E7💚): New 'Shift' keydown event. HotKeys (Fundefinedundefined-C0🔺-P0🔺-E7💚): Started a new combination with 'Shift'. HotKeys (Fundefinedundefined-C0🔺-P0🔺-E7💚): Key history: [ { "keys": { "Shift": [ [ 1, 0, 0 ], [ 1, 2, 0 ] ], " ": [ [ 1, 0, 0 ], [ 1, 2, 0 ] ] }, "ids": [ "Shift+ " ], "keyAliases": {} }, { "keys": { "Shift": [ [ 0, 0, 0 ], [ 1, 0, 0 ] ], " ": [ [ 1, 0, 0 ], [ 1, 2, 0 ] ] }, "ids": [ "Shift+ " ], "keyAliases": {} } ]. HotKeys (F1📗-C0🔺-P0🔺-E7💚): Attempting to find action matching 'Shift+ ' keydown . . . HotKeys (Fundefinedundefined-C0🔺-P0🔺-E7💚): Internal key mapping: { "": { "actionConfigs": { "Shift+ ": { "prefix": "", "sequenceLength": 1, "id": "Shift+ ", "keyDictionary": { "Shift": true, " ": true }, "size": 2, "events": { "0": { "actionName": "ACTION1", "handler": "handler" } } }, "Shift+r": { "prefix": "", "sequenceLength": 1, "id": "Shift+r", "keyDictionary": { "Shift": true, "r": true }, "size": 2, "events": { "0": { "actionName": "ACTION2", "handler": "spy" } } } }, "order": null } } HotKeys (Fundefinedundefined-C0🔺-P0🔺-E7💚): Found action that matches 'Shift+ ': ACTION1. Calling handler . . . HotKeys (Fundefinedundefined-C0🔺-P0🔺-E7💚): Stopping further event propagation. HotKeys (Fundefinedundefined-C0🔺-P0🔺-E9💛): New (simulated) 'Shift' keypress event. HotKeys (Fundefinedundefined-C0🔺-P0🔺-E9💛): Key history: [ { "keys": { "Shift": [ [ 1, 0, 0 ], [ 1, 2, 0 ] ], " ": [ [ 1, 0, 0 ], [ 1, 2, 0 ] ] }, "ids": [ "Shift+ " ], "keyAliases": {} }, { "keys": { "Shift": [ [ 1, 0, 0 ], [ 1, 2, 0 ] ], " ": [ [ 1, 0, 0 ], [ 1, 2, 0 ] ] }, "ids": [ "Shift+ " ], "keyAliases": {} } ]. HotKeys (Fundefinedundefined-C0🔺-P0🔺-E9💛): Ignored 'Shift+ ' keypress because it doesn't have any keypress handlers. HotKeys (Fundefinedundefined-C0🔺-P0🔺-E10💜): New 'Shift' keyup event. HotKeys (Fundefinedundefined-C0🔺-P0🔺-E10💜): Key history: [ { "keys": { "Shift": [ [ 1, 0, 0 ], [ 1, 2, 0 ] ], " ": [ [ 1, 0, 0 ], [ 1, 2, 0 ] ] }, "ids": [ "Shift+ " ], "keyAliases": {} }, { "keys": { "Shift": [ [ 1, 2, 0 ], [ 1, 2, 1 ] ], " ": [ [ 1, 0, 0 ], [ 1, 2, 0 ] ] }, "ids": [ "Shift+ " ], "keyAliases": {} } ]. HotKeys (Fundefinedundefined-C0🔺-P0🔺-E10💜): Ignored 'Shift+ ' keyup because it doesn't have any keyup handlers. expected handler to have been called exactly once, but it was called twice handler([SyntheticEvent] { _dispatchInstances: null, _dispatchListeners: null, _targetInst: [FiberNode] { _debugHookTypes: null, _debugID: 138, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: null, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: null, child: null, childExpirationTime: 0, dependencies: null, effectTag: 0, elementType: "div", expirationTime: 0, firstEffect: null, index: 0, key: null, lastEffect: null, memoizedProps: { className: "childElement" }, memoizedState: null, mode: 0, nextEffect: null, pendingProps: [Circular], ref: null, return: [FiberNode] { _debugHookTypes: null, _debugID: 136, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: [FiberNode] { _debugHookTypes: null, _debugID: 134, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: [FiberNode] { _debugHookTypes: null, _debugID: 130, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: [FiberNode] { _debugHookTypes: null, _debugID: 128, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: null, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: null, child: [Circular], childExpirationTime: 0, dependencies: null, effectTag: 1, elementType: function WrapperComponent() {}, expirationTime: 0, firstEffect: [Circular], index: 0, key: null, lastEffect: [Circular], memoizedProps: { Component: function HotKeysEnabled() {}, context: null, props: { children: { $$typeof: Symbol(react.element), _owner: null, _store: { }, key: null, props: [Circular], ref: null, type: "div" }, handlers: { ACTION1: function spy() {}, ACTION2: function spy() {} }, keyMap: { ACTION1: "shift+space", ACTION2: "shift+r" } }, refProp: null, wrappingComponentProps: null }, memoizedState: { context: null, mount: true, props: [Circular], wrappingComponentProps: null }, mode: 0, nextEffect: null, pendingProps: [Circular], ref: null, return: [FiberNode] { _debugHookTypes: null, _debugID: 125, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: null, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: [FiberNode] { _debugHookTypes: null, _debugID: 125, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: null, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: [Circular], child: null, childExpirationTime: 0, dependencies: null, effectTag: 0, elementType: null, expirationTime: 1073741823, firstEffect: null, index: 0, key: null, lastEffect: null, memoizedProps: null, memoizedState: null, mode: 0, nextEffect: null, pendingProps: null, ref: null, return: null, selfBaseDuration: 0, sibling: null, stateNode: [FiberRootNode] { callbackExpirationTime: 0, callbackNode: null, callbackPriority: 90, containerInfo:
<[...]
, context: { }, current: [Circular], finishedExpirationTime: 0, finishedWork: null, firstPendingTime: 0, firstSuspendedTime: 0, hydrate: false, interactionThreadID: 17, lastExpiredTime: 0, lastPingedTime: 0, lastSuspendedTime: 0, memoizedInteractions: Set {}, nextKnownPendingLevel: 0, pendingChildren: null, pendingContext: null, pendingInteractionMap: [Map] { }, pingCache: null, tag: 0, timeoutHandle: -1 }, tag: 3, treeBaseDuration: 0, type: null, updateQueue: { baseQueue: { callback: null, expirationTime: 1073741823, next: [Circular], payload: { element: { $$typeof: Symbol(react.element), _owner: null, _store: { }, key: null, props: [Circular], ref: null, type: function WrapperComponent() {} } }, priority: 97, suspenseConfig: null, tag: 0 }, baseState: null, effects: null, shared: { pending: null } } }, child: [Circular], childExpirationTime: 0, dependencies: null, effectTag: 0, elementType: null, expirationTime: 0, firstEffect: [Circular], index: 0, key: null, lastEffect: [Circular], memoizedProps: null, memoizedState: { element: [Circular] }, mode: 0, nextEffect: null, pendingProps: null, ref: null, return: null, selfBaseDuration: 0, sibling: null, stateNode: [Circular], tag: 3, treeBaseDuration: 0, type: null, updateQueue: { baseQueue: null, baseState: [Circular], effects: null, shared: [Circular] } }, selfBaseDuration: 0, sibling: null, stateNode: [WrapperComponent] { _reactInternalFiber: [Circular], _reactInternalInstance: { }, context: [Circular], props: [Circular], refs: { }, state: [Circular], updater: { enqueueForceUpdate: function enqueueForceUpdate() {}, enqueueReplaceState: function enqueueReplaceState() {}, enqueueSetState: function enqueueSetState() {}, isMounted: function isMounted() {} } }, tag: 1, treeBaseDuration: 0, type: function WrapperComponent() {}, updateQueue: { baseQueue: null, baseState: [Circular], effects: null, shared: { pending: null } } }, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: null, child: [FiberNode] { _debugHookTypes: null, _debugID: 132, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: [Circular], _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: null, child: [Circular], childExpirationTime: 0, dependencies: null, effectTag: 0, elementType: { $$typeof: Symbol(react.provider), _context: { $$typeof: Symbol(react.context), Consumer: { $$typeof: Symbol(react.context), _calculateChangedBits: null, _context: [Circular] }, Provider: [Circular], _calculateChangedBits: null, _currentRenderer: { }, _currentRenderer2: null, _currentValue: { hotKeysParentId: undefined }, _currentValue2: [Circular], _threadCount: 0 } }, expirationTime: 0, firstEffect: null, index: 0, key: null, lastEffect: null, memoizedProps: { children: { $$typeof: Symbol(react.element), _owner: [Circular], _store: { }, key: null, props: { children: [Circular], hotKeys: { onBlur: function () {}, onFocus: function () {}, onKeyDown: function () {}, onKeyPress: function () {}, onKeyUp: function () {}, tabIndex: "-1" } }, ref: null, type: function HotKeysWrapper() {} }, value: { hotKeysParentId: 0 } }, memoizedState: null, mode: 0, nextEffect: null, pendingProps: [Circular], ref: null, return: [Circular], selfBaseDuration: 0, sibling: null, stateNode: null, tag: 10, treeBaseDuration: 0, type: [Circular], updateQueue: null }, childExpirationTime: 0, dependencies: { expirationTime: 0, firstContext: { context: [Circular], next: null, observedBits: 1073741823 }, responders: null }, effectTag: 5, elementType: function HotKeysEnabled() {}, expirationTime: 0, firstEffect: null, index: 0, key: null, lastEffect: null, memoizedProps: { children: [Circular], handlers: [Circular], keyMap: [Circular] }, memoizedState: null, mode: 0, nextEffect: null, pendingProps: [Circular], ref: null, return: [Circular], selfBaseDuration: 0, sibling: null, stateNode: [HotKeysEnabled] { _manager: [FocusOnlyComponentManager] { _focusTreeIds: [1], _focused: true, _hotKeysOptions: { }, childContext: [Circular], id: 0 }, _reactInternalFiber: [Circular], _reactInternalInstance: [Circular], context: [Circular], props: [Circular], refs: [Circular], state: null, updater: [Circular] }, tag: 1, treeBaseDuration: 0, type: function HotKeysEnabled() {}, updateQueue: { baseQueue: null, baseState: null, effects: null, shared: { pending: null } } }, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: null, child: [Circular], childExpirationTime: 0, dependencies: null, effectTag: 1, elementType: function HotKeysWrapper() {}, expirationTime: 0, firstEffect: null, index: 0, key: null, lastEffect: null, memoizedProps: [Circular], memoizedState: null, mode: 0, nextEffect: null, pendingProps: [Circular], ref: null, return: [Circular], selfBaseDuration: 0, sibling: null, stateNode: [HotKeysWrapper] { _reactInternalFiber: [Circular], _reactInternalInstance: [Circular], context: [Circular], props: [Circular], refs: [Circular], state: null, updater: [Circular] }, tag: 1, treeBaseDuration: 0, type: function HotKeysWrapper() {}, updateQueue: { baseQueue: null, baseState: null, effects: null, shared: { pending: null } } }, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: null, child: [Circular], childExpirationTime: 0, dependencies: null, effectTag: 0, elementType: "div", expirationTime: 0, firstEffect: null, index: 0, key: null, lastEffect: null, memoizedProps: { children: [Circular], onBlur: function () {}, onFocus: function () {}, onKeyDown: function () {}, onKeyPress: function () {}, onKeyUp: function () {}, tabIndex: "-1" }, memoizedState: null, mode: 0, nextEffect: null, pendingProps: [Circular], ref: null, return: [Circular], selfBaseDuration: 0, sibling: null, stateNode:
, tag: 5, treeBaseDuration: 0, type: "div", updateQueue: null }, bubbles: undefined, cancelable: undefined, currentTarget: null, defaultPrevented: undefined, dispatchConfig: { dependencies: ["keydown"], eventPriority: 0, phasedRegistrationNames: { bubbled: "onKeyDown", captured: "onKeyDownCapture" } }, eventPhase: undefined, isDefaultPrevented: function functionThatReturnsFalse() {}, isPersistent: function functionThatReturnsTrue() {}, isPropagationStopped: function functionThatReturnsTrue() {}, isTrusted: undefined, key: " ", nativeEvent: [Event] { cancelBubble: true, target:
, type: "keydown" }, target:
, timeStamp: 1612787515578, type: "keydown" }) at ActionResolver._handleMatchFound (D:\GitHub\react-hotkeys\src\lib\matching\/ActionResolver.js:194:17) handler([SyntheticEvent] { _dispatchInstances: null, _dispatchListeners: null, _targetInst: [FiberNode] { _debugHookTypes: null, _debugID: 138, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: null, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: null, child: null, childExpirationTime: 0, dependencies: null, effectTag: 0, elementType: "div", expirationTime: 0, firstEffect: null, index: 0, key: null, lastEffect: null, memoizedProps: { className: "childElement" }, memoizedState: null, mode: 0, nextEffect: null, pendingProps: [Circular], ref: null, return: [FiberNode] { _debugHookTypes: null, _debugID: 136, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: [FiberNode] { _debugHookTypes: null, _debugID: 134, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: [FiberNode] { _debugHookTypes: null, _debugID: 130, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: [FiberNode] { _debugHookTypes: null, _debugID: 128, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: null, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: null, child: [Circular], childExpirationTime: 0, dependencies: null, effectTag: 1, elementType: function WrapperComponent() {}, expirationTime: 0, firstEffect: [Circular], index: 0, key: null, lastEffect: [Circular], memoizedProps: { Component: function HotKeysEnabled() {}, context: null, props: { children: { $$typeof: Symbol(react.element), _owner: null, _store: { }, key: null, props: [Circular], ref: null, type: "div" }, handlers: { ACTION1: function spy() {}, ACTION2: function spy() {} }, keyMap: { ACTION1: "shift+space", ACTION2: "shift+r" } }, refProp: null, wrappingComponentProps: null }, memoizedState: { context: null, mount: true, props: [Circular], wrappingComponentProps: null }, mode: 0, nextEffect: null, pendingProps: [Circular], ref: null, return: [FiberNode] { _debugHookTypes: null, _debugID: 125, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: null, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: [FiberNode] { _debugHookTypes: null, _debugID: 125, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: null, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: [Circular], child: null, childExpirationTime: 0, dependencies: null, effectTag: 0, elementType: null, expirationTime: 1073741823, firstEffect: null, index: 0, key: null, lastEffect: null, memoizedProps: null, memoizedState: null, mode: 0, nextEffect: null, pendingProps: null, ref: null, return: null, selfBaseDuration: 0, sibling: null, stateNode: [FiberRootNode] { callbackExpirationTime: 0, callbackNode: null, callbackPriority: 90, containerInfo:
<[...]
, context: { }, current: [Circular], finishedExpirationTime: 0, finishedWork: null, firstPendingTime: 0, firstSuspendedTime: 0, hydrate: false, interactionThreadID: 17, lastExpiredTime: 0, lastPingedTime: 0, lastSuspendedTime: 0, memoizedInteractions: Set {}, nextKnownPendingLevel: 0, pendingChildren: null, pendingContext: null, pendingInteractionMap: [Map] { }, pingCache: null, tag: 0, timeoutHandle: -1 }, tag: 3, treeBaseDuration: 0, type: null, updateQueue: { baseQueue: { callback: null, expirationTime: 1073741823, next: [Circular], payload: { element: { $$typeof: Symbol(react.element), _owner: null, _store: { }, key: null, props: [Circular], ref: null, type: function WrapperComponent() {} } }, priority: 97, suspenseConfig: null, tag: 0 }, baseState: null, effects: null, shared: { pending: null } } }, child: [Circular], childExpirationTime: 0, dependencies: null, effectTag: 0, elementType: null, expirationTime: 0, firstEffect: [Circular], index: 0, key: null, lastEffect: [Circular], memoizedProps: null, memoizedState: { element: [Circular] }, mode: 0, nextEffect: null, pendingProps: null, ref: null, return: null, selfBaseDuration: 0, sibling: null, stateNode: [Circular], tag: 3, treeBaseDuration: 0, type: null, updateQueue: { baseQueue: null, baseState: [Circular], effects: null, shared: [Circular] } }, selfBaseDuration: 0, sibling: null, stateNode: [WrapperComponent] { _reactInternalFiber: [Circular], _reactInternalInstance: { }, context: [Circular], props: [Circular], refs: { }, state: [Circular], updater: { enqueueForceUpdate: function enqueueForceUpdate() {}, enqueueReplaceState: function enqueueReplaceState() {}, enqueueSetState: function enqueueSetState() {}, isMounted: function isMounted() {} } }, tag: 1, treeBaseDuration: 0, type: function WrapperComponent() {}, updateQueue: { baseQueue: null, baseState: [Circular], effects: null, shared: { pending: null } } }, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: null, child: [FiberNode] { _debugHookTypes: null, _debugID: 132, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: [Circular], _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: null, child: [Circular], childExpirationTime: 0, dependencies: null, effectTag: 0, elementType: { $$typeof: Symbol(react.provider), _context: { $$typeof: Symbol(react.context), Consumer: { $$typeof: Symbol(react.context), _calculateChangedBits: null, _context: [Circular] }, Provider: [Circular], _calculateChangedBits: null, _currentRenderer: { }, _currentRenderer2: null, _currentValue: { hotKeysParentId: undefined }, _currentValue2: [Circular], _threadCount: 0 } }, expirationTime: 0, firstEffect: null, index: 0, key: null, lastEffect: null, memoizedProps: { children: { $$typeof: Symbol(react.element), _owner: [Circular], _store: { }, key: null, props: { children: [Circular], hotKeys: { onBlur: function () {}, onFocus: function () {}, onKeyDown: function () {}, onKeyPress: function () {}, onKeyUp: function () {}, tabIndex: "-1" } }, ref: null, type: function HotKeysWrapper() {} }, value: { hotKeysParentId: 0 } }, memoizedState: null, mode: 0, nextEffect: null, pendingProps: [Circular], ref: null, return: [Circular], selfBaseDuration: 0, sibling: null, stateNode: null, tag: 10, treeBaseDuration: 0, type: [Circular], updateQueue: null }, childExpirationTime: 0, dependencies: { expirationTime: 0, firstContext: { context: [Circular], next: null, observedBits: 1073741823 }, responders: null }, effectTag: 5, elementType: function HotKeysEnabled() {}, expirationTime: 0, firstEffect: null, index: 0, key: null, lastEffect: null, memoizedProps: { children: [Circular], handlers: [Circular], keyMap: [Circular] }, memoizedState: null, mode: 0, nextEffect: null, pendingProps: [Circular], ref: null, return: [Circular], selfBaseDuration: 0, sibling: null, stateNode: [HotKeysEnabled] { _manager: [FocusOnlyComponentManager] { _focusTreeIds: [1], _focused: true, _hotKeysOptions: { }, childContext: [Circular], id: 0 }, _reactInternalFiber: [Circular], _reactInternalInstance: [Circular], context: [Circular], props: [Circular], refs: [Circular], state: null, updater: [Circular] }, tag: 1, treeBaseDuration: 0, type: function HotKeysEnabled() {}, updateQueue: { baseQueue: null, baseState: null, effects: null, shared: { pending: null } } }, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: null, child: [Circular], childExpirationTime: 0, dependencies: null, effectTag: 1, elementType: function HotKeysWrapper() {}, expirationTime: 0, firstEffect: null, index: 0, key: null, lastEffect: null, memoizedProps: [Circular], memoizedState: null, mode: 0, nextEffect: null, pendingProps: [Circular], ref: null, return: [Circular], selfBaseDuration: 0, sibling: null, stateNode: [HotKeysWrapper] { _reactInternalFiber: [Circular], _reactInternalInstance: [Circular], context: [Circular], props: [Circular], refs: [Circular], state: null, updater: [Circular] }, tag: 1, treeBaseDuration: 0, type: function HotKeysWrapper() {}, updateQueue: { baseQueue: null, baseState: null, effects: null, shared: { pending: null } } }, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: null, child: [Circular], childExpirationTime: 0, dependencies: null, effectTag: 0, elementType: "div", expirationTime: 0, firstEffect: null, index: 0, key: null, lastEffect: null, memoizedProps: { children: [Circular], onBlur: function () {}, onFocus: function () {}, onKeyDown: function () {}, onKeyPress: function () {}, onKeyUp: function () {}, tabIndex: "-1" }, memoizedState: null, mode: 0, nextEffect: null, pendingProps: [Circular], ref: null, return: [Circular], selfBaseDuration: 0, sibling: null, stateNode:
, tag: 5, treeBaseDuration: 0, type: "div", updateQueue: null }, bubbles: undefined, cancelable: undefined, currentTarget: null, defaultPrevented: undefined, dispatchConfig: { dependencies: ["keydown"], eventPriority: 0, phasedRegistrationNames: { bubbled: "onKeyDown", captured: "onKeyDownCapture" } }, eventPhase: undefined, isDefaultPrevented: function functionThatReturnsFalse() {}, isPersistent: function functionThatReturnsTrue() {}, isPropagationStopped: function functionThatReturnsTrue() {}, isTrusted: undefined, key: "Shift", nativeEvent: [Event] { cancelBubble: true, target:
, type: "keydown" }, target:
, timeStamp: 1612787515581, type: "keydown" }) at ActionResolver._handleMatchFound (D:\GitHub\react-hotkeys\src\lib\matching\/ActionResolver.js:194:17) AssertionError: expected handler to have been called exactly once, but it was called twice handler([SyntheticEvent] { _dispatchInstances: null, _dispatchListeners: null, _targetInst: [FiberNode] { _debugHookTypes: null, _debugID: 138, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: null, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: null, child: null, childExpirationTime: 0, dependencies: null, effectTag: 0, elementType: "div", expirationTime: 0, firstEffect: null, index: 0, key: null, lastEffect: null, memoizedProps: { className: "childElement" }, memoizedState: null, mode: 0, nextEffect: null, pendingProps: [Circular], ref: null, return: [FiberNode] { _debugHookTypes: null, _debugID: 136, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: [FiberNode] { _debugHookTypes: null, _debugID: 134, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: [FiberNode] { _debugHookTypes: null, _debugID: 130, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: [FiberNode] { _debugHookTypes: null, _debugID: 128, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: null, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: null, child: [Circular], childExpirationTime: 0, dependencies: null, effectTag: 1, elementType: function WrapperComponent() {}, expirationTime: 0, firstEffect: [Circular], index: 0, key: null, lastEffect: [Circular], memoizedProps: { Component: function HotKeysEnabled() {}, context: null, props: { children: { $$typeof: Symbol(react.element), _owner: null, _store: { }, key: null, props: [Circular], ref: null, type: "div" }, handlers: { ACTION1: function spy() {}, ACTION2: function spy() {} }, keyMap: { ACTION1: "shift+space", ACTION2: "shift+r" } }, refProp: null, wrappingComponentProps: null }, memoizedState: { context: null, mount: true, props: [Circular], wrappingComponentProps: null }, mode: 0, nextEffect: null, pendingProps: [Circular], ref: null, return: [FiberNode] { _debugHookTypes: null, _debugID: 125, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: null, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: [FiberNode] { _debugHookTypes: null, _debugID: 125, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: null, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: [Circular], child: null, childExpirationTime: 0, dependencies: null, effectTag: 0, elementType: null, expirationTime: 1073741823, firstEffect: null, index: 0, key: null, lastEffect: null, memoizedProps: null, memoizedState: null, mode: 0, nextEffect: null, pendingProps: null, ref: null, return: null, selfBaseDuration: 0, sibling: null, stateNode: [FiberRootNode] { callbackExpirationTime: 0, callbackNode: null, callbackPriority: 90, containerInfo:
<[...]
, context: { }, current: [Circular], finishedExpirationTime: 0, finishedWork: null, firstPendingTime: 0, firstSuspendedTime: 0, hydrate: false, interactionThreadID: 17, lastExpiredTime: 0, lastPingedTime: 0, lastSuspendedTime: 0, memoizedInteractions: Set {}, nextKnownPendingLevel: 0, pendingChildren: null, pendingContext: null, pendingInteractionMap: [Map] { }, pingCache: null, tag: 0, timeoutHandle: -1 }, tag: 3, treeBaseDuration: 0, type: null, updateQueue: { baseQueue: { callback: null, expirationTime: 1073741823, next: [Circular], payload: { element: { $$typeof: Symbol(react.element), _owner: null, _store: { }, key: null, props: [Circular], ref: null, type: function WrapperComponent() {} } }, priority: 97, suspenseConfig: null, tag: 0 }, baseState: null, effects: null, shared: { pending: null } } }, child: [Circular], childExpirationTime: 0, dependencies: null, effectTag: 0, elementType: null, expirationTime: 0, firstEffect: [Circular], index: 0, key: null, lastEffect: [Circular], memoizedProps: null, memoizedState: { element: [Circular] }, mode: 0, nextEffect: null, pendingProps: null, ref: null, return: null, selfBaseDuration: 0, sibling: null, stateNode: [Circular], tag: 3, treeBaseDuration: 0, type: null, updateQueue: { baseQueue: null, baseState: [Circular], effects: null, shared: [Circular] } }, selfBaseDuration: 0, sibling: null, stateNode: [WrapperComponent] { _reactInternalFiber: [Circular], _reactInternalInstance: { }, context: [Circular], props: [Circular], refs: { }, state: [Circular], updater: { enqueueForceUpdate: function enqueueForceUpdate() {}, enqueueReplaceState: function enqueueReplaceState() {}, enqueueSetState: function enqueueSetState() {}, isMounted: function isMounted() {} } }, tag: 1, treeBaseDuration: 0, type: function WrapperComponent() {}, updateQueue: { baseQueue: null, baseState: [Circular], effects: null, shared: { pending: null } } }, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: null, child: [FiberNode] { _debugHookTypes: null, _debugID: 132, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: [Circular], _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: null, child: [Circular], childExpirationTime: 0, dependencies: null, effectTag: 0, elementType: { $$typeof: Symbol(react.provider), _context: { $$typeof: Symbol(react.context), Consumer: { $$typeof: Symbol(react.context), _calculateChangedBits: null, _context: [Circular] }, Provider: [Circular], _calculateChangedBits: null, _currentRenderer: { }, _currentRenderer2: null, _currentValue: { hotKeysParentId: undefined }, _currentValue2: [Circular], _threadCount: 0 } }, expirationTime: 0, firstEffect: null, index: 0, key: null, lastEffect: null, memoizedProps: { children: { $$typeof: Symbol(react.element), _owner: [Circular], _store: { }, key: null, props: { children: [Circular], hotKeys: { onBlur: function () {}, onFocus: function () {}, onKeyDown: function () {}, onKeyPress: function () {}, onKeyUp: function () {}, tabIndex: "-1" } }, ref: null, type: function HotKeysWrapper() {} }, value: { hotKeysParentId: 0 } }, memoizedState: null, mode: 0, nextEffect: null, pendingProps: [Circular], ref: null, return: [Circular], selfBaseDuration: 0, sibling: null, stateNode: null, tag: 10, treeBaseDuration: 0, type: [Circular], updateQueue: null }, childExpirationTime: 0, dependencies: { expirationTime: 0, firstContext: { context: [Circular], next: null, observedBits: 1073741823 }, responders: null }, effectTag: 5, elementType: function HotKeysEnabled() {}, expirationTime: 0, firstEffect: null, index: 0, key: null, lastEffect: null, memoizedProps: { children: [Circular], handlers: [Circular], keyMap: [Circular] }, memoizedState: null, mode: 0, nextEffect: null, pendingProps: [Circular], ref: null, return: [Circular], selfBaseDuration: 0, sibling: null, stateNode: [HotKeysEnabled] { _manager: [FocusOnlyComponentManager] { _focusTreeIds: [1], _focused: true, _hotKeysOptions: { }, childContext: [Circular], id: 0 }, _reactInternalFiber: [Circular], _reactInternalInstance: [Circular], context: [Circular], props: [Circular], refs: [Circular], state: null, updater: [Circular] }, tag: 1, treeBaseDuration: 0, type: function HotKeysEnabled() {}, updateQueue: { baseQueue: null, baseState: null, effects: null, shared: { pending: null } } }, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: null, child: [Circular], childExpirationTime: 0, dependencies: null, effectTag: 1, elementType: function HotKeysWrapper() {}, expirationTime: 0, firstEffect: null, index: 0, key: null, lastEffect: null, memoizedProps: [Circular], memoizedState: null, mode: 0, nextEffect: null, pendingProps: [Circular], ref: null, return: [Circular], selfBaseDuration: 0, sibling: null, stateNode: [HotKeysWrapper] { _reactInternalFiber: [Circular], _reactInternalInstance: [Circular], context: [Circular], props: [Circular], refs: [Circular], state: null, updater: [Circular] }, tag: 1, treeBaseDuration: 0, type: function HotKeysWrapper() {}, updateQueue: { baseQueue: null, baseState: null, effects: null, shared: { pending: null } } }, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: null, child: [Circular], childExpirationTime: 0, dependencies: null, effectTag: 0, elementType: "div", expirationTime: 0, firstEffect: null, index: 0, key: null, lastEffect: null, memoizedProps: { children: [Circular], onBlur: function () {}, onFocus: function () {}, onKeyDown: function () {}, onKeyPress: function () {}, onKeyUp: function () {}, tabIndex: "-1" }, memoizedState: null, mode: 0, nextEffect: null, pendingProps: [Circular], ref: null, return: [Circular], selfBaseDuration: 0, sibling: null, stateNode:
, tag: 5, treeBaseDuration: 0, type: "div", updateQueue: null }, bubbles: undefined, cancelable: undefined, currentTarget: null, defaultPrevented: undefined, dispatchConfig: { dependencies: ["keydown"], eventPriority: 0, phasedRegistrationNames: { bubbled: "onKeyDown", captured: "onKeyDownCapture" } }, eventPhase: undefined, isDefaultPrevented: function functionThatReturnsFalse() {}, isPersistent: function functionThatReturnsTrue() {}, isPropagationStopped: function functionThatReturnsTrue() {}, isTrusted: undefined, key: " ", nativeEvent: [Event] { cancelBubble: true, target:
, type: "keydown" }, target:
, timeStamp: 1612787515578, type: "keydown" }) at ActionResolver._handleMatchFound (src\lib\matching\/ActionResolver.js:194:17) handler([SyntheticEvent] { _dispatchInstances: null, _dispatchListeners: null, _targetInst: [FiberNode] { _debugHookTypes: null, _debugID: 138, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: null, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: null, child: null, childExpirationTime: 0, dependencies: null, effectTag: 0, elementType: "div", expirationTime: 0, firstEffect: null, index: 0, key: null, lastEffect: null, memoizedProps: { className: "childElement" }, memoizedState: null, mode: 0, nextEffect: null, pendingProps: [Circular], ref: null, return: [FiberNode] { _debugHookTypes: null, _debugID: 136, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: [FiberNode] { _debugHookTypes: null, _debugID: 134, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: [FiberNode] { _debugHookTypes: null, _debugID: 130, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: [FiberNode] { _debugHookTypes: null, _debugID: 128, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: null, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: null, child: [Circular], childExpirationTime: 0, dependencies: null, effectTag: 1, elementType: function WrapperComponent() {}, expirationTime: 0, firstEffect: [Circular], index: 0, key: null, lastEffect: [Circular], memoizedProps: { Component: function HotKeysEnabled() {}, context: null, props: { children: { $$typeof: Symbol(react.element), _owner: null, _store: { }, key: null, props: [Circular], ref: null, type: "div" }, handlers: { ACTION1: function spy() {}, ACTION2: function spy() {} }, keyMap: { ACTION1: "shift+space", ACTION2: "shift+r" } }, refProp: null, wrappingComponentProps: null }, memoizedState: { context: null, mount: true, props: [Circular], wrappingComponentProps: null }, mode: 0, nextEffect: null, pendingProps: [Circular], ref: null, return: [FiberNode] { _debugHookTypes: null, _debugID: 125, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: null, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: [FiberNode] { _debugHookTypes: null, _debugID: 125, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: null, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: [Circular], child: null, childExpirationTime: 0, dependencies: null, effectTag: 0, elementType: null, expirationTime: 1073741823, firstEffect: null, index: 0, key: null, lastEffect: null, memoizedProps: null, memoizedState: null, mode: 0, nextEffect: null, pendingProps: null, ref: null, return: null, selfBaseDuration: 0, sibling: null, stateNode: [FiberRootNode] { callbackExpirationTime: 0, callbackNode: null, callbackPriority: 90, containerInfo:
<[...]
, context: { }, current: [Circular], finishedExpirationTime: 0, finishedWork: null, firstPendingTime: 0, firstSuspendedTime: 0, hydrate: false, interactionThreadID: 17, lastExpiredTime: 0, lastPingedTime: 0, lastSuspendedTime: 0, memoizedInteractions: Set {}, nextKnownPendingLevel: 0, pendingChildren: null, pendingContext: null, pendingInteractionMap: [Map] { }, pingCache: null, tag: 0, timeoutHandle: -1 }, tag: 3, treeBaseDuration: 0, type: null, updateQueue: { baseQueue: { callback: null, expirationTime: 1073741823, next: [Circular], payload: { element: { $$typeof: Symbol(react.element), _owner: null, _store: { }, key: null, props: [Circular], ref: null, type: function WrapperComponent() {} } }, priority: 97, suspenseConfig: null, tag: 0 }, baseState: null, effects: null, shared: { pending: null } } }, child: [Circular], childExpirationTime: 0, dependencies: null, effectTag: 0, elementType: null, expirationTime: 0, firstEffect: [Circular], index: 0, key: null, lastEffect: [Circular], memoizedProps: null, memoizedState: { element: [Circular] }, mode: 0, nextEffect: null, pendingProps: null, ref: null, return: null, selfBaseDuration: 0, sibling: null, stateNode: [Circular], tag: 3, treeBaseDuration: 0, type: null, updateQueue: { baseQueue: null, baseState: [Circular], effects: null, shared: [Circular] } }, selfBaseDuration: 0, sibling: null, stateNode: [WrapperComponent] { _reactInternalFiber: [Circular], _reactInternalInstance: { }, context: [Circular], props: [Circular], refs: { }, state: [Circular], updater: { enqueueForceUpdate: function enqueueForceUpdate() {}, enqueueReplaceState: function enqueueReplaceState() {}, enqueueSetState: function enqueueSetState() {}, isMounted: function isMounted() {} } }, tag: 1, treeBaseDuration: 0, type: function WrapperComponent() {}, updateQueue: { baseQueue: null, baseState: [Circular], effects: null, shared: { pending: null } } }, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: null, child: [FiberNode] { _debugHookTypes: null, _debugID: 132, _debugIsCurrentlyTiming: false, _debugNeedsRemount: false, _debugOwner: [Circular], _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: null, child: [Circular], childExpirationTime: 0, dependencies: null, effectTag: 0, elementType: { $$typeof: Symbol(react.provider), _context: { $$typeof: Symbol(react.context), Consumer: { $$typeof: Symbol(react.context), _calculateChangedBits: null, _context: [Circular] }, Provider: [Circular], _calculateChangedBits: null, _currentRenderer: { }, _currentRenderer2: null, _currentValue: { hotKeysParentId: undefined }, _currentValue2: [Circular], _threadCount: 0 } }, expirationTime: 0, firstEffect: null, index: 0, key: null, lastEffect: null, memoizedProps: { children: { $$typeof: Symbol(react.element), _owner: [Circular], _store: { }, key: null, props: { children: [Circular], hotKeys: { onBlur: function () {}, onFocus: function () {}, onKeyDown: function () {}, onKeyPress: function () {}, onKeyUp: function () {}, tabIndex: "-1" } }, ref: null, type: function HotKeysWrapper() {} }, value: { hotKeysParentId: 0 } }, memoizedState: null, mode: 0, nextEffect: null, pendingProps: [Circular], ref: null, return: [Circular], selfBaseDuration: 0, sibling: null, stateNode: null, tag: 10, treeBaseDuration: 0, type: [Circular], updateQueue: null }, childExpirationTime: 0, dependencies: { expirationTime: 0, firstContext: { context: [Circular], next: null, observedBits: 1073741823 }, responders: null }, effectTag: 5, elementType: function HotKeysEnabled() {}, expirationTime: 0, firstEffect: null, index: 0, key: null, lastEffect: null, memoizedProps: { children: [Circular], handlers: [Circular], keyMap: [Circular] }, memoizedState: null, mode: 0, nextEffect: null, pendingProps: [Circular], ref: null, return: [Circular], selfBaseDuration: 0, sibling: null, stateNode: [HotKeysEnabled] { _manager: [FocusOnlyComponentManager] { _focusTreeIds: [1], _focused: true, _hotKeysOptions: { }, childContext: [Circular], id: 0 }, _reactInternalFiber: [Circular], _reactInternalInstance: [Circular], context: [Circular], props: [Circular], refs: [Circular], state: null, updater: [Circular] }, tag: 1, treeBaseDuration: 0, type: function HotKeysEnabled() {}, updateQueue: { baseQueue: null, baseState: null, effects: null, shared: { pending: null } } }, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: null, child: [Circular], childExpirationTime: 0, dependencies: null, effectTag: 1, elementType: function HotKeysWrapper() {}, expirationTime: 0, firstEffect: null, index: 0, key: null, lastEffect: null, memoizedProps: [Circular], memoizedState: null, mode: 0, nextEffect: null, pendingProps: [Circular], ref: null, return: [Circular], selfBaseDuration: 0, sibling: null, stateNode: [HotKeysWrapper] { _reactInternalFiber: [Circular], _reactInternalInstance: [Circular], context: [Circular], props: [Circular], refs: [Circular], state: null, updater: [Circular] }, tag: 1, treeBaseDuration: 0, type: function HotKeysWrapper() {}, updateQueue: { baseQueue: null, baseState: null, effects: null, shared: { pending: null } } }, _debugSource: null, actualDuration: 0, actualStartTime: -1, alternate: null, child: [Circular], childExpirationTime: 0, dependencies: null, effectTag: 0, elementType: "div", expirationTime: 0, firstEffect: null, index: 0, key: null, lastEffect: null, memoizedProps: { children: [Circular], onBlur: function () {}, onFocus: function () {}, onKeyDown: function () {}, onKeyPress: function () {}, onKeyUp: function () {}, tabIndex: "-1" }, memoizedState: null, mode: 0, nextEffect: null, pendingProps: [Circular], ref: null, return: [Circular], selfBaseDuration: 0, sibling: null, stateNode:
, tag: 5, treeBaseDuration: 0, type: "div", updateQueue: null }, bubbles: undefined, cancelable: undefined, currentTarget: null, defaultPrevented: undefined, dispatchConfig: { dependencies: ["keydown"], eventPriority: 0, phasedRegistrationNames: { bubbled: "onKeyDown", captured: "onKeyDownCapture" } }, eventPhase: undefined, isDefaultPrevented: function functionThatReturnsFalse() {}, isPersistent: function functionThatReturnsTrue() {}, isPropagationStopped: function functionThatReturnsTrue() {}, isTrusted: undefined, key: "Shift", nativeEvent: [Event] { cancelBubble: true, target:
, type: "keydown" }, target:
, timeStamp: 1612787515581, type: "keydown" }) at ActionResolver._handleMatchFound (src\lib\matching\/ActionResolver.js:194:17) at Context. (test\HotKeys\/CombinationsInvolvingShiftKey.spec.js:92:7) ``` **What Configuration options are you using?** ``` configure({ logLevel: "verbose" }) ``` Here is a small unit test demonstrating the issue (CombinationsInvolvingShiftKey.spec.js): ``` describe('and there are handlers defined for "shift+space" and "shift+r"', () => { beforeEach(function () { this.keyMap = { 'ACTION1': 'shift+space', 'ACTION2': 'shift+r' }; this.handler1 = sinon.spy(); this.handler2 = sinon.spy(); const handlers = { 'ACTION1': this.handler1, 'ACTION2': this.handler2 }; this.wrapper = mount(
); this.targetElement = new FocusableElement(this.wrapper, '.childElement'); this.targetElement.focus(); }); it(`then calls the handler for "Shift+space" and press "Shift"`, function() { this.targetElement.keyDown('Shift'); this.targetElement.keyDown(' '); this.targetElement.focus(); this.targetElement.keyDown('Shift'); this.targetElement.keyUp('Shift'); expect(this.handler1).to.have.been.calledOnce; }); it(`then calls the handler for "Shift+space" and "Shift+r"`, function() { this.targetElement.keyDown('Shift'); this.targetElement.keyDown(' '); this.targetElement.focus(); this.targetElement.keyDown('Shift'); this.targetElement.keyDown('r'); this.targetElement.keyUp('r'); this.targetElement.keyUp('Shift'); expect(this.handler2).to.have.been.called; }); }); ```
andrew-sv commented 3 years ago

I found out what is causing the issue. It seems Space and Enter key handlers simulate keyPress event even if these two keys can trigger native events. Here is the small program demonstrating which key triggers keyPress event in React. Sandbox Space and Enter keys produce KeyPress event. My suggestion is to fix it either in hasKeyPressEvent function (hasKeyPressEvent.js) or remove Space and Enter keys from translateToKey map (translateToKey.js). I prefer the second case.