Skip to content

Option ignoreInputs does not work for React Aria Collections #83

@junlarsen

Description

@junlarsen

TanStack Hotkeys version

v0.5.0

Framework/Library version

React 19.2.4 with TanStack Hotkeys 0.7.0

Describe the bug and the steps to reproduce it

As a preface, thanks for building this library, it's very nice!

I'm honestly not quite sure if this really is a TanStack Hotkeys bug, but likely more a niche that React Aria does with its collections API. In any case I would at least like to report the behavior I have come across.

React Aria has this concept called Collection APIs which they use to render lists/trees/grids. A lot of their components use this collection API. In this case I had troubles with their https://react-aria.adobe.com/Autocomplete component that provides a search field to filter a list.

For the Autocomplete component, they intercept the keydown event when the user types into the <input /> field, and instead dispatches it down to the collection (https://github.com/adobe/react-spectrum/blob/%40react-aria/autocomplete%403.0.0-rc.6/packages/%40react-aria/autocomplete/src/useAutocomplete.ts#L281-L303)

This results in the event target that TanStack Hotkeys picks up to be the collection, and not the input element, thus isInputElement (https://github.com/TanStack/hotkeys/blob/%40tanstack/react-hotkeys%400.7.0/packages/hotkeys/src/manager.utils.ts#L48) returns false for the event. This means that other shortcuts will still trigger when the user types into a React Aria Autocomplete field.

Once again unsure if this qualifies as a bug for TanStack Hotkeys. In any case I have this patch locally that also checks document.activeElement that appears to work.

diff --git a/dist/hotkey-manager.js b/dist/hotkey-manager.js
index f0208b5b63d4a397395ea0e26e7bc2a7c8b91993..c3c778700030d3caa2feaf34a33aa2f4ed467a8e 100644
--- a/dist/hotkey-manager.js
+++ b/dist/hotkey-manager.js
@@ -223,7 +223,11 @@ var HotkeyManager = class HotkeyManager {
 			if (!isEventForTarget(event, target)) continue;
 			if (!registration.options.enabled) continue;
 			if (registration.options.ignoreInputs !== false) {
-				if (isInputElement(event.target)) {
+				// Also check document.activeElement: some libraries (e.g. react-aria Autocomplete)
+				// stop propagation on the input's keydown and re-dispatch a new KeyboardEvent on a
+				// list item, so event.target is the list element rather than the focused input.
+				const focusedElement = typeof document !== "undefined" ? document.activeElement : null;
+				if (isInputElement(event.target) || isInputElement(focusedElement)) {
 					if (event.target !== registration.target) continue;
 				}
 			}

Your Minimal, Reproducible Example - (Sandbox Highly Recommended)

https://stackblitz.com/edit/tanstack-hotkeys-tq75phfp?file=src%2Findex.tsx

Screenshots or Videos (Optional)

Sorry I wasn't able to get my screen recorder working, but if you open the StackBlitz:

  1. Try pressing q without having the input selected, and you will see an alert. This works as it should.
  2. Click on the input element, and start typing q, and you will see the alert, despite us being inside an input element. Again because Aria cancels and sends the event to the collection

Do you intend to try to help solve this bug with your own PR?

Yes, I think I know how to fix it and will discuss it in the comments of this issue

Terms & Code of Conduct

  • I agree to follow this project's Code of Conduct
  • I understand that if my bug cannot be reliable reproduced in a debuggable environment, it will probably not be fixed and this issue may even be closed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions