@jzarif/kee
v0.1.0
Published
Key combination matching on the modern web
Readme
kee
A stateless keyboard event matcher for the browser. Checks if a KeyboardEvent matches a combo string like Control+a, CmdOrCtrl+Shift+s, or ?Shift+Alt+ArrowUp.
kee abstracts away a lot of the platform specific quirks of keyboard event reporting and attempts to provide reasonable "expected" behavior while making sane compromises.
Install
npm install @jzarif/keeUsage
import { match, matchCode } from '@jzarif/kee';
document.addEventListener('keydown', (event) => {
if (match(event, 'CmdOrCtrl+s')) {
event.preventDefault();
save();
}
if (match(event, 'Control+Shift+z')) {
redo();
}
// matchCode matches on physical key position instead of character
if (matchCode(event, 'Control+KeyA')) {
selectAll();
}
});API
match(event, combo, options?)
Matches a keyboard event against a combo string, using the character the key produces on the user's keyboard layout. Handles edge cases like shifted keys producing different characters, MacOS Alt generating special characters, and international layouts. This is the right choice for most applications (with some important caveats).
matchCode(event, combo, options?)
Matches against event.code (the physical key position). Use this when you care about where a key is on the keyboard rather than what character it produces (e.g., WASD movement in a game). See https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code.
Options
interface MatchOptions {
strictModifiers?: boolean;
}strictModifiersBy default, extra modifiers are ignored:
Control+amatches even if Shift is also held. SetstrictModifiers: trueto reject events with modifiers not listed in the combo.
Combo string format
A combo is one or more modifiers joined by +, followed by a key:
[?]Modifier+[?]Modifier+KeyModifiers
| Modifier | Description |
| ----------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| Control | Control key |
| Shift | Shift key |
| Alt | Alt / Option key |
| Meta | Cmd on MacOS, Win key on Windows |
| CmdOrCtrl | Cmd on MacOS/iOS/iPadOS, Control elsewhere |
| Command | Cmd on MacOS only, never matches on other platforms. Useful in cases where MacOS has special platform shortcuts like Cmd+Backspace |
Optional modifiers
Prefix a modifier with ? to make it optional. This is useful with strictModifiers:
// Matches Control+A with or without Shift, but rejects if Alt or Meta is held
match(event, '?Shift+Control+a', { strictModifiers: true });Without strictModifiers, all unmentioned modifiers are already optional, so ? has no effect.
Keys
Always use the unshifted (bottom character on a keyboard key) character for keys with shifted variants:
Shift+2 (not Shift+@)
Shift+` (not Shift+~)
Shift+; (not Shift+:)
Control+a (not Control+A)For non-character keys, use the standard KeyboardEvent.key name:
Enter, Escape, ArrowUp, ArrowDown, Backspace, Tab, Delete, Home, End, etc.There are two additional key values supported: Space, and Plus. Note that on US layout keyboards, the + key is usually the shifted equivalent of the = key and so the combo should use = instead in that case.
Caveats when using match()
MacOS Alt combos with
match()are problematic.On MacOS, Alt (Option) modifies
event.keyto produce special characters (e.g., Alt+A produceså). kee resolves these back to the base key, but the character map is based on the US layout. On non-US Mac layouts, Alt+letter combos may not resolve correctly.Additionally Alt+`, Alt+e, Alt+i, Alt+n, and Alt+u on MacOS produce "dead" keys. These can be identified on browsers with the Keyboard API is available; on other browsers they cannot be matched with
match().Shifted digit/punctuation matching across keyboard layouts.
When Shift transforms a non-alpha key (e.g
Shift+2 -> @,Shift+; -> :), kee tries to determine the correct base key. On browsers without the Keyboard API kee relies onevent.codefor digit (0-9) keys (since they're almost always in the same physical location on most keyboards) and an internal mapping for symbol keys (like[,=, etc.). That mapping is US layout specific and may not work on keyboards with other localized layouts.
License
MIT
