Small keyboard shortcut management for DOM-based applications.
npm install keyboard-manager --save
Keyboard Manager uses a simple queue, processed from newest to oldest, of listener functions to execute keyboard shortcuts. Keyboard event propagation stops when handled, but returning true
from the listener will continue propagation to older listeners.
import { Keyboard, stringifyKey, createShortcuts } from "keyboard-manager";
const keyboard = new Keyboard();
const shortcut1 = stringifyKey("cmd", "a"); //=> "65 91"
const shortcut2 = stringifyKey("cmd", "up"); //=> "38 91"
// Bind event listeners to all combos or specific keys using `createShortcuts`.
keyboard.addListener(
createShortcuts({
[shortcut1]: (e) => e.preventDefault(),
[shortcut2]: (e) => e.preventDefault(),
})
);
// Attach event listener to document.
window.addEventListener("keydown", keyboard.getHandler(), false);
// Mount a keyboard inside another listener.
new Keyboard().addListener(keyboard.getListener());
The stringifyKey(...keys)
function returns a consistent identity string for the keyboard shortcut. Internally, keyboardEventCombo(e)
will map keyboard events to the matching string.
The createShortcuts(map [, returnValue])
function accepts a map of keyboard shortcut functions and returns a single listener function for mounting with keyboard.addListener(callback)
.
Tip: returnValue
defaults to true
for propagation. Setting to false
will stop propagation, effectively creating a new shortcut "scope". This is useful for features, such as full-screen modals or recording keyboard shortcuts, where key presses should not interact with the rest of the document.
Wrap any listener in filterInputEvent(callback)
to automatically ignore and propagate events originating from an input-like element (<input />
, <select />
, <textarea />
or content-editable elements).
import {
stringifyKey,
createShortcuts,
filterInputEvent,
} from "keyboard-manager";
const listener = createShortcuts({
[stringifyKey("a")]: filterInputEvent((e) => e.preventDefault()),
});
const dispatcher = new Keyboard()
// Create two `Keyboard` instances, allowing globally unhandled shortcuts
// to propagate into application shortcuts (i.e. OS-like functionality).
const appKeyboard = new Keyboard()
const globalKeyboard = new Keyboard()
// Dispatch order is determined by listeners, recent listeners execute first.
dispatcher.addListener(appKeyboard.getListener())
dispatcher.addListener(globalKeyboard.getListener()))
Keyboard Manager serializes each keydown
event to the character (e.key
) and modifiers (e.shiftKey
, e.ctrlKey
, e.altKey
, e.metaKey
). For example, cmd + a
maps to meta a
.
- Mac OS doesn't emit
keyup
events whilecmd
is pressed. - The DOM won't receive a
keyup
event when you lose focus on the window. - Keyboard shortcuts don't need to combine non-modifier characters.
This project is written using TypeScript and publishes the definitions directly to NPM.
Apache 2.0