Define and dispatch keyboard shortcuts with keybuddy.
keybuddy provides a simple and consistent toolset for defining and dispatching keyboard shortcuts in a browser environment.
pnpm add keybuddyimport { bindKey } from 'keybuddy';
bindKey('a', handleKeyPress);
bindKey('shift+r', handleKeyPress);
bindKey('command+shift+r', handleKeyPress);
// sequences
bindKey('cmd+e k', handleKeyPress);
bindKey('g i', handleKeyPress);Initially based on keymaster
Differences:
- Written modern JS using TypeScript
- Custom scope not conflicting with default one
- Unbind requires an action (unsafeUnbindKey for backward compatibility)
- Creator instance to replace document with any other DOM element
- More explicit API
- Provides new fixes and maintaining
- Added sequence support
- Removed support for multiple shortcuts in a single string
Key differences:
- Unbinding requires the handler function:
unbindKey('ctrl+s', handler)instead ofkey.unbind('ctrl+s') - Use
unsafeUnbindKey('ctrl+s')if you need the old behavior (removes all handlers) - Import what you need:
import { bindKey, setScope } from 'keybuddy' - Modern browsers only (no IE11)
- Split multiple key bindings into separate calls
'cmd+r, ctrl+r'intocmd+r,ctrl+r
Keybuddy understands the following modifiers:
shift, alt, option, ctrl, control, command, cmd
Symbol variants: β§, β₯, β, β
The following special keys can be used for shortcuts:
backspace, tab, clear, enter, return, esc, escape, space, left, up, right, down, del, delete, home, end, pageup, pagedown, comma, ., /, `, -, =, ;, ', [, ], \
Keybuddy supports sequence shortcuts - multiple key combinations pressed in order:
// Press 'g', release, then press 'i'
bindKey('g i', () => goToInbox());
// Press Cmd+K, release, then press Cmd+C
bindKey('cmd+k cmd+c', () => copyCode());
// Press Cmd+Z, release, then press 'y'
bindKey('cmd+z y', () => confirmUndo());Syntax:
'cmd+z+y'= chord (all keys held simultaneously)'cmd+z y'= sequence (press Cmd+Z, release, then press Y)
Sequences timeout after 1 second.
Bind a keyboard shortcut to a handler.
import { bindKey, DEFAULT_SCOPE } from 'keybuddy';
bindKey('option+e', action);
bindKey('option+e', 'myScope', action);
bindKey('option+e', DEFAULT_SCOPE, action, { skipOther: true });Options:
skipOther: boolean- If true, this handler takes priority and other handlers for the same shortcut won't fire
Unbind a keyboard shortcut. Action is required.
import { unbindKey } from 'keybuddy';
unbindKey('option+e', action);
unbindKey('option+e', 'myScope', action);Remove all handlers for a key (use with caution).
import { unsafeUnbindKey } from 'keybuddy';
unsafeUnbindKey('option+e');
unsafeUnbindKey('option+e', 'myScope');Check if a shortcut is bound.
import { bindKey, isBound } from 'keybuddy';
bindKey('ctrl+s', saveHandler);
isBound('ctrl+s'); // true
isBound('ctrl+s', { scope: 'editor' }); // falseGet all bound shortcuts in current or specified scope.
import { bindKey, getBoundKeys } from 'keybuddy';
bindKey('ctrl+s', saveHandler);
bindKey('ctrl+z', undoHandler);
getBoundKeys(); // ['ctrl+s', 'ctrl+z']
getBoundKeys({ scope: 'editor' }); // []Get all handlers for a specific shortcut.
import { bindKey, getHandlers } from 'keybuddy';
const save = () => console.log('save');
bindKey('ctrl+s', save);
getHandlers('ctrl+s'); // [save]Returns current scope.
Change the active scope.
Remove all actions in a scope.
Remove all actions.
Remove all actions and event listeners.
Use createKeybuddy to bind shortcuts to a different document or element.
import { createKeybuddy } from 'keybuddy';
const iframe = document.getElementById('iframe').contentWindow;
const myKeybuddy = createKeybuddy(iframe.document);
myKeybuddy.bind('alt+b', action);The default filter skips editable areas (contenteditable, input, select, textarea). You can provide a custom filter:
const myKeybuddy = createKeybuddy(document, (e) => {
return true; // Handle all events
});For iframe usage examples, see cypress/component/iframe-bindings.spec.ts.