Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Hotkey handlers ignored when not present on initial load #259

Open
tjcarroll11 opened this issue Nov 30, 2019 · 2 comments
Open

[BUG] Hotkey handlers ignored when not present on initial load #259

tjcarroll11 opened this issue Nov 30, 2019 · 2 comments

Comments

@tjcarroll11
Copy link

tjcarroll11 commented Nov 30, 2019

Describe the bug
When my <HotKeys></HotKeys> tag is dynamically added to the UI, its handlers are getting ignored.

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

Here is a trimmed down version of what I'm doing

render() {
  if (this.props.isOpen) {
    return <HotKeys keyMap={keyMap()} handlers={handlers()}>...</HotKeys>
  }
  return <div/>
}

Expected behavior
Hotkey handlers for component in focus are triggered

Platform (please complete the following information):

  • 2.0.0
  • Chrome
  • iOS

Are you willing and able to create a PR request to fix this issue?
Yes, if given a little guidance

Include the smallest log that includes your issue:

HotKeys (F5📗-C1⭐️-P0🔺:) Focused. 

FocusOnlyKeyEventStrategy.js:156 HotKeys (F5📗-C1⭐️-P0🔺:) Component options:
 {
    "actions": {
        "OPEN_FUZZY_SEARCH_FILE": [
            {
                "prefix": "",
                "actionName": "OPEN_FUZZY_SEARCH_FILE",
                "sequenceLength": 1,
                "id": "Enter",
                "keyDictionary": {
                    "Enter": true
                },
                "keyEventType": 0,
                "size": 1
            }
        ],
        "UP_FUZZY_SEARCH_FILE_LIST": [
            {
                "prefix": "",
                "actionName": "UP_FUZZY_SEARCH_FILE_LIST",
                "sequenceLength": 1,
                "id": "ArrowUp",
                "keyDictionary": {
                    "ArrowUp": true
                },
                "keyEventType": 0,
                "size": 1
            }
        ],
        "DOWN_FUZZY_SEARCH_FILE_LIST": [
            {
                "prefix": "",
                "actionName": "DOWN_FUZZY_SEARCH_FILE_LIST",
                "sequenceLength": 1,
                "id": "ArrowDown",
                "keyDictionary": {
                    "ArrowDown": true
                },
                "keyEventType": 0,
                "size": 1
            }
        ]
    },
    "handlers": {
        "OPEN_FUZZY_SEARCH_FILE": "function () { [native code] }",
        "UP_FUZZY_SEARCH_FILE_LIST": "function () { [native code] }",
        "DOWN_FUZZY_SEARCH_FILE_LIST": "function () { [native code] }"
    },
    "componentId": 1,
    "options": {
        "defaultKeyEvent": "keydown"
    }
}
VM1150:1 Bad: [object Object]
GlobalKeyEventStrategy.js:310 HotKeys (GLOBAL-E38💙): New 'c' keydown event (that has NOT passed through React app).
GlobalKeyEventStrategy.js:503 HotKeys (GLOBAL-E38💙): Added 'c' to current combination: 'c'.
GlobalKeyEventStrategy.js:506 HotKeys (GLOBAL-E38💙): Key history: [
    {
        "keys": {
            "c": [
                [
                    0,
                    0,
                    0
                ],
                [
                    1,
                    0,
                    0
                ]
            ]
        },
        "ids": [
            "c"
        ],
        "keyAliases": {}
    }
].
GlobalKeyEventStrategy.js:557 HotKeys (GLOBAL-E38💙): Attempting to find action matching 'c' keydown . . .
AbstractKeyEventStrategy.js:405 HotKeys (GLOBAL-E38💙-C0🔺): Internal key mapping:
 {
    "": {
        "actionConfigs": {
            "Control+p": {
                "prefix": "",
                "sequenceLength": 1,
                "id": "Control+p",
                "keyDictionary": {
                    "Control": true,
                    "p": true
                },
                "size": 2,
                "events": {
                    "0": {
                        "actionName": "OPEN_FUZZY_SEARCH_DIALOG",
                        "handler": "function () { [native code] }"
                    }
                }
            }
        },
        "order": [
            "Control+p"
        ]
    }
}
AbstractKeyEventStrategy.js:429 HotKeys (GLOBAL-E38💙-C0🔺): No matching actions found for 'c' keydown.
FocusOnlyKeyEventStrategy.js:298 HotKeys (F5📗-E39💛-C1⭐️-P0🔺:) New 'c' keydown event.
FocusOnlyKeyEventStrategy.js:533 HotKeys (F5📗-E39💛-C1⭐️-P0🔺:) Added 'c' to current combination: 'c'.
FocusOnlyKeyEventStrategy.js:538 HotKeys (F5📗-E39💛-C1⭐️-P0🔺:) Key history: [
    {
        "keys": {
            "c": [
                [
                    0,
                    0,
                    0
                ],
                [
                    1,
                    0,
                    0
                ]
            ]
        },
        "ids": [
            "c"
        ],
        "keyAliases": {}
    }
].
FocusOnlyKeyEventStrategy.js:648 HotKeys (F5📗-E39💛-C1⭐️-P0🔺:) Attempting to find action matching 'c' keydown . . .
AbstractKeyEventStrategy.js:405 HotKeys (F5📗-E39💛-C0🔺) Internal key mapping:
 {
    "": {
        "actionConfigs": {
            "Enter": {
                "prefix": "",
                "sequenceLength": 1,
                "id": "Enter",
                "keyDictionary": {
                    "Enter": true
                },
                "size": 1,
                "events": {
                    "0": {
                        "actionName": "OPEN_FUZZY_SEARCH_FILE",
                        "handler": "function () { [native code] }"
                    }
                }
            },
            "ArrowUp": {
                "prefix": "",
                "sequenceLength": 1,
                "id": "ArrowUp",
                "keyDictionary": {
                    "ArrowUp": true
                },
                "size": 1,
                "events": {
                    "0": {
                        "actionName": "UP_FUZZY_SEARCH_FILE_LIST",
                        "handler": "function () { [native code] }"
                    }
                }
            },
            "ArrowDown": {
                "prefix": "",
                "sequenceLength": 1,
                "id": "ArrowDown",
                "keyDictionary": {
                    "ArrowDown": true
                },
                "size": 1,
                "events": {
                    "0": {
                        "actionName": "DOWN_FUZZY_SEARCH_FILE_LIST",
                        "handler": "function () { [native code] }"
                    }
                }
            }
        },
        "order": null
    }
}
AbstractKeyEventStrategy.js:429 HotKeys (F5📗-E39💛-C0🔺) No matching actions found for 'c' keydown.
GlobalKeyEventStrategy.js:310 HotKeys (GLOBAL-E40💜): New 'c' keypress event (that has NOT passed through React app).
GlobalKeyEventStrategy.js:506 HotKeys (GLOBAL-E40💜): Key history: [
    {
        "keys": {
            "c": [
                [
                    1,
                    0,
                    0
                ],
                [
                    1,
                    1,
                    0
                ]
            ]
        },
        "ids": [
            "c"
        ],
        "keyAliases": {}
    }
].
GlobalKeyEventStrategy.js:547 HotKeys (GLOBAL-E40💜): Ignored 'c' keypress because it doesn't have any keypress handlers.
FocusOnlyKeyEventStrategy.js:339 HotKeys (F5📗-E40💜-C1⭐️-P0🔺:) Ignored 'c' keypress as it was not expected, and has already been simulated.
EventPropagator.js:252 HotKeys (F5📗-E40💜-Cnull🔺) Stopping further event propagation.
GlobalKeyEventStrategy.js:161 HotKeys (GLOBAL-C0🔺): Global component 0 updated.
GlobalKeyEventStrategy.js:164 HotKeys (GLOBAL-C0🔺): Component options: 
 {
    "actions": {
        "OPEN_FUZZY_SEARCH_DIALOG": [
            {
                "prefix": "",
                "actionName": "OPEN_FUZZY_SEARCH_DIALOG",
                "sequenceLength": 1,
                "id": "Control+p",
                "keyDictionary": {
                    "Control": true,
                    "p": true
                },
                "keyEventType": 0,
                "size": 2
            }
        ]
    },
    "handlers": {
        "OPEN_FUZZY_SEARCH_DIALOG": "function () { [native code] }"
    },
    "componentId": 0,
    "options": {
        "defaultKeyEvent": "keydown"
    }
}
GlobalKeyEventStrategy.js:161 HotKeys (GLOBAL-C0🔺): Global component 0 updated.
GlobalKeyEventStrategy.js:164 HotKeys (GLOBAL-C0🔺): Component options: 
 {
    "actions": {
        "OPEN_FUZZY_SEARCH_DIALOG": [
            {
                "prefix": "",
                "actionName": "OPEN_FUZZY_SEARCH_DIALOG",
                "sequenceLength": 1,
                "id": "Control+p",
                "keyDictionary": {
                    "Control": true,
                    "p": true
                },
                "keyEventType": 0,
                "size": 2
            }
        ]
    },
    "handlers": {
        "OPEN_FUZZY_SEARCH_DIALOG": "function () { [native code] }"
    },
    "componentId": 0,
    "options": {
        "defaultKeyEvent": "keydown"
    }
}
GlobalKeyEventStrategy.js:310 HotKeys (GLOBAL-E41🧡): New 'c' keyup event (that has NOT passed through React app).
GlobalKeyEventStrategy.js:506 HotKeys (GLOBAL-E41🧡): Key history: [
    {
        "keys": {
            "c": [
                [
                    1,
                    1,
                    0
                ],
                [
                    1,
                    1,
                    1
                ]
            ]
        },
        "ids": [
            "c"
        ],
        "keyAliases": {}
    }
].
GlobalKeyEventStrategy.js:547 HotKeys (GLOBAL-E41🧡): Ignored 'c' keyup because it doesn't have any keyup handlers.
GlobalKeyEventStrategy.js:310 HotKeys (GLOBAL-E42❤️): New 'ArrowDown' keydown event (that has NOT passed through React app).
GlobalKeyEventStrategy.js:494 HotKeys (GLOBAL-E42❤️): Started a new combination with 'ArrowDown'.
GlobalKeyEventStrategy.js:495 HotKeys (GLOBAL-E42❤️): Key history: [
    {
        "keys": {
            "c": [
                [
                    1,
                    1,
                    0
                ],
                [
                    1,
                    1,
                    1
                ]
            ]
        },
        "ids": [
            "c"
        ],
        "keyAliases": {}
    },
    {
        "keys": {
            "ArrowDown": [
                [
                    0,
                    0,
                    0
                ],
                [
                    1,
                    0,
                    0
                ]
            ]
        },
        "ids": [
            "ArrowDown"
        ],
        "keyAliases": {}
    }
].
GlobalKeyEventStrategy.js:557 HotKeys (GLOBAL-E42❤️): Attempting to find action matching 'ArrowDown' keydown . . .
AbstractKeyEventStrategy.js:405 HotKeys (GLOBAL-E42❤️-C0🔺): Internal key mapping:
 {
    "": {
        "actionConfigs": {
            "Control+p": {
                "prefix": "",
                "sequenceLength": 1,
                "id": "Control+p",
                "keyDictionary": {
                    "Control": true,
                    "p": true
                },
                "size": 2,
                "events": {
                    "0": {
                        "actionName": "OPEN_FUZZY_SEARCH_DIALOG",
                        "handler": "function () { [native code] }"
                    }
                }
            }
        },
        "order": null
    }
}
AbstractKeyEventStrategy.js:429 HotKeys (GLOBAL-E42❤️-C0🔺): No matching actions found for 'ArrowDown' keydown.
GlobalKeyEventStrategy.js:310 HotKeys (GLOBAL-E43💚): New 'ArrowDown' keyup event (that has NOT passed through React app).
GlobalKeyEventStrategy.js:506 HotKeys (GLOBAL-E43💚): Key history: [
    {
        "keys": {
            "c": [
                [
                    1,
                    1,
                    0
                ],
                [
                    1,
                    1,
                    1
                ]
            ]
        },
        "ids": [
            "c"
        ],
        "keyAliases": {}
    },
    {
        "keys": {
            "ArrowDown": [
                [
                    1,
                    0,
                    0
                ],
                [
                    1,
                    0,
                    1
                ]
            ]
        },
        "ids": [
            "ArrowDown"
        ],
        "keyAliases": {}
    }
].
GlobalKeyEventStrategy.js:547 HotKeys (GLOBAL-E43💚): Ignored 'ArrowDown' keyup because it doesn't have any keyup handlers.

I've found that in another place, when I see "Ignored as it was not expected, and has already been simulated.", my hotkeys all start failing. If I unfocus and refocus, it will fix it. In this case, it only fixes it for literally 1 keypress.

What Configuration options are you using?

configure({
        /**
        * The level of logging of its own behaviour React HotKeys should perform.
        */
       logLevel: 'verbose',

       /**
        * Default key event key maps are bound to (keydown|keypress|keyup)
        */
       defaultKeyEvent: 'keydown',

       /**
        * The default component type to wrap HotKey components' children in, to provide
        * the required focus and keyboard event listening for HotKeys to function
        */
       defaultComponent: 'div',

       /**
        * The default tabIndex value passed to the wrapping component used to contain
        * HotKey components' children. -1 skips focusing the element when tabbing through
        * the DOM, but allows focusing programmatically.
        */
       defaultTabIndex: '-1',

       /**
        * The HTML tags that React HotKeys should ignore key events from. This only works
        * if you are using the default ignoreEventsCondition function.
        * @type {String[]}
        */
       ignoreTags: [],

       /**
        * The function used to determine whether a key event should be ignored by React
        * Hotkeys. By default, keyboard events originating elements with a tag name in
        * ignoreTags, or a isContentEditable property of true, are ignored.
        *
        * @type {Function<KeyboardEvent>}
        */
       ignoreEventsCondition: (e) => {
           return false;
       },

       /**
        * Whether to ignore changes to keyMap and handlers props by default
        * (this reduces a significant amount of unnecessarily resetting
        * internal state)
        * @type {boolean}
        */
       ignoreKeymapAndHandlerChangesByDefault: false,

       /**
        * Whether to ignore repeated keyboard events when a key is being held down
        * @type {boolean}
        */
       ignoreRepeatedEventsWhenKeyHeldDown: true,
       
       /**
        * Whether React HotKeys should simulate keypress events for the keys that do not
        * natively emit them.
        * @type {boolean}
        */
       simulateMissingKeyPressEvents: false,

       /**
        * Whether to call stopPropagation() on events after they are
        * handled (preventing the event from bubbling up any further, both within
        * React Hotkeys and any other event listeners bound in React).
        *
        * This does not affect the behaviour of React Hotkeys, but rather what
        * happens to the event once React Hotkeys is done with it (whether it's
        * allowed to propagate any further through the Render tree).
        */
       stopEventPropagationAfterHandling: true,

       /**
        * Whether to call stopPropagation() on events after they are
        * ignored (preventing the event from bubbling up any further, both within
        * React Hotkeys and any other event listeners bound in React).
        *
        * This does not affect the behaviour of React Hotkeys, but rather what
        * happens to the event once React Hotkeys is done with it (whether it's
        * allowed to propagate any further through the Render tree).
        */
       stopEventPropagationAfterIgnoring: true,
       
       /**
        * Whether to allow combination submatches - e.g. if there is an action 
        * bound to cmd, pressing shift+cmd will *not* trigger that action when
        * allowCombinationSubmatches is false.
        */
       allowCombinationSubmatches: false,
       
       /**
        * A mapping of custom key codes to key names that you can then use in your
        * key sequences
        */
       customKeyCodes: {}
    })
@hellupline
Copy link

I had the same issue, I solved it using innerRef and useLayoutEffect

I hope this helps you:

import React, { useRef, useLayoutEffect } from 'react';
import { HotKeys } from 'react-hotkeys';


const FocusHotKeys: React.FC<Props> = ({ children, handlers, keyMap }) => {
    const ref = useRef<HTMLDivElement>(null);
    useLayoutEffect((): void => {
        if (ref.current) {
            ref.current.focus();
        }
    }, [ref]);
    return (
        <HotKeys innerRef={ref} handlers={handlers} keyMap={keyMap}>
            {children}
        </HotKeys>
    );
};


export default FocusHotKeys;


type Props = {
    handlers: Readonly<{ [key: string]: (keyEvent?: KeyboardEvent) => void }>;
    keyMap: Readonly<{ [key: string]: string }>;
};

@greena13
Copy link
Owner

greena13 commented Jan 1, 2020

Thanks for posting your issue.

Unfortunately I do not have the time to actively work on this package, but I am seeking other active maintainers. If you are willing to create a pull request or help out, that would be an excellent way of moving this forward.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants