-
Notifications
You must be signed in to change notification settings - Fork 81
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
Option to disallow keyboard shortcut within <input> #17
Comments
Could you just |
I ended up wrapping my handlers in an extra function like:
|
That's actually not a good way to wrap it, you should be testing the element type directly. Otherwise you'll break other keyboard navigation for accessibility |
@jamiebuilds love the package - do you have an example of what your recommending above? (or somewhere in the docs)? |
@Harrisonl something like this is what I believe @jamiebuilds means: FWIW adding
|
That code is right except I don't know if the check on |
@jamiebuilds Having this feature out of the box or adding a recommended documentation/example to handle this scenario would be great. For applications having a lot of forms, adding If you are building it within the library, here is something for inspiration.
|
We wrapped tinykeys in a hook anyways, so it is easy to wrap all key-bindings in there: import { useEffect } from 'react';
import tinykeys, { KeyBindingMap } from 'tinykeys';
function isEventTargetInputOrTextArea(eventTarget: EventTarget | null) {
if (eventTarget === null) return false;
const eventTargetTagName = (eventTarget as HTMLElement).tagName.toLowerCase();
return ['input', 'textarea'].includes(eventTargetTagName);
}
export default function useTinyKeys(
target: Document | Window | HTMLElement,
bindings: KeyBindingMap,
deps: unknown[],
disableOnInputs: boolean,
) {
useEffect(() => {
const wrappedBindings = disableOnInputs
? Object.fromEntries(
Object.entries(bindings).map(([key, handler]) => [
key,
(event: KeyboardEvent) => {
if (!isEventTargetInputOrTextArea(event.target)) {
handler(event);
}
},
]),
)
: bindings;
const unsubscribe = tinykeys(target as HTMLElement, wrappedBindings);
return () => {
unsubscribe();
};
}, deps);
} Then you can use it like this: useTinyKeys(
window,
{
ArrowLeft: (e) => previous(),
ArrowRight: (e) => next(),
},
[previous, next],
true, // <-- blockOnInputs
); This could be extended to allow custom filters as well, but we only needed to disable key-bindings in text-inputs so far. |
I also made a js version of this @mattiloh react code, for anyone interested. This one disables all keybindings on inputs by default. Codeimport tinykeys from 'tinykeys';
function isEventTargetInputOrTextArea(target) {
if (target === null) return false;
const targetElementName = target.tagName.toLowerCase();
return ['input', 'textarea'].includes(targetElementName);
}
export default function hotkeys(target, bindings, disableOnInputs = true) {
const wrappedBindings = disableOnInputs
? Object.fromEntries(
Object.entries(bindings).map(([key, handler]) => [
key,
event => {
if (!isEventTargetInputOrTextArea(event.target)) {
handler(event);
}
},
])
)
: bindings;
tinykeys(target, wrappedBindings);
} Usagehotkeys(window, {
'g t p': () => {
document.getElementById('nav-projects').click();
},
});
},
false, //disable blockOnInputs
); |
Right now tinykeys runs while I have focus in inputs, and I think that should be able to be disabled.
The text was updated successfully, but these errors were encountered: