@vgerbot/shortcuts
🔌 Install
Using npm/yarn
$ npm i @vgerbot/shortcuts
$ # or
$ yarn add @vgerbot/shortcuts
Then import/require the module:
const { } = require('@vgerbot/shortcuts');
// or
import { } from '@vgerbot/shortcuts';
Using CDN
-
jsDelivr:
<script src="//cdn.jsdelivr.net/npm/@vgerbot/shortcuts/lib/index.min.js"></script>
-
unpkg
<script src="//unpkg.com/@vgerbot/shortcuts/lib/index.min.js"></script>
Then:
<script>
const {} = Shortcuts;
</script>
📚 Usage
Pattern matching
import { match } from '@vgerbot/shortcuts';
const matcher = match
.case('Ctrl+A', (shortcutEvent) => console.log(`Pressed '${shortcutEvent.shortcut}`)) // output when matching: Pressed 'Ctrl+A'
.case('Mod+Z', (shortcutEvent) => console.log(`Pressed '${shortcutEvent.shortcut}'`)) // output when matching: Mac: `Pressed 'Meta+A'`, Win,Linux:`Pressed 'Ctrl+A'`
.case('Ctrl+P|Shift+Ctrl+P', (shortcutEvent) => console.log(`Pressed '${shortcutEvent.shortcut}`)) // output when matching: `Pressed 'Ctrl+P'` or `Pressed 'Shift+Ctrl+P'`
;
document.body.addEventListener('keydown', e => {
matcher(e);
})
You may omit .case
.
import { match } from '@vgerbot/shortcuts';
const matcher = match('Ctrl+A', (shortcutEvent) => console.log(`Pressed '${shortcutEvent.shortcut}`)) // output when matching: Pressed 'Ctrl+A'
('Mod+Z', (shortcutEvent) => console.log(`Pressed '${shortcutEvent.shortcut}'`)) // output when matching: Mac: `Pressed 'Meta+A'`, Win,Linux:`Pressed 'Ctrl+A'`
('Ctrl+P|Shift+Ctrl+P', (shortcutEvent) => console.log(`Pressed '${shortcutEvent.shortcut}`)) // output when matching: `Pressed 'Ctrl+P'` or `Pressed 'Shift+Ctrl+P'`
;
document.body.addEventListener('keydown', e => {
matcher(e);
})
The result of the callback will be returned from matcher.
import { match } from '@vgerbot/shortcuts';
const matcher =
match('Ctrl+A', () => 'A')
('Ctrl+B', () => 'B')
document.body.addEventListener('keydown', e => {
const result = matcher(e);
console.log(result); // If there is no match, `undefined` will be returned.
})
If you provide a value instead of a function, that value will be returnd
import { match } from '@vgerbot/shortcuts';
const matcher =
match('Ctrl+A', 'A')
('Ctrl+B', 'B')
document.body.addEventListener('keydown', e => {
const result = matcher(e);
console.log(result); // If there is no match, `undefined` will be returned.
})
You may use the .else
to define a callback if no shortcut pattern matches.
import { match } from '@vgerbot/shortcuts';
const matcher =
match('Ctrl+A', 'A')
('Ctrl+B', 'B')
.else(() => console.log('no shortcut pattern matches'));
document.body.addEventListener('keydown', e => {
matcher(e);
})
Keymap configuration
import { Keyboard } from '@vgerbot/shortcuts';
const keyboard = new Keyboard();
keyboard.keymap({
commands: {
copy: {
shortcut: 'Ctrl+C',
preventDefault: true
},
paste: {
shortcut: 'Ctrl+V',
preventDefault: true
},
print: 'Ctrl+P',
find: 'Ctrl+F',
replace: 'Ctrl+H',
devtool: 'F12',
close: 'Ctrl+W',
confirm: {
shortcut: 'Enter',
interceptors: [
(event, next) => {
if(event.target.nodeName === 'INPUT') {
return;
}
next(event);
}
]
}
},
contexts: {
default: {
commands: ['devtool', 'print']
},
closable: {
abstract: true,
commands: ['close']
},
searchable: {
abstract: true,
commands: ['find', 'replace']
},
editor: {
commands: ['copy', 'paste'],
fallbacks: ['closable', 'searchable']
},
previewer: {
commands: ['print'],
fallbacks: ['searchable']
},
dialog: {
commands: ['confirm'],
fallbacks: ['closable']
}
}
})
With the keymap
method, we can easily override existing shortcut commands:
keyboard.keymap({
commands: {
copy: {
shortcut: 'Ctrl+Alt+C'
}
}
})
This feature is useful for applications that require custom shortcut keys.
Shortcut context
Now that we have everything configured, next we listen for keyboard events with the command name as the event name as shown below:
keyboard.on('close', () => {
console.log('close');
})
However, it does not work now because there is no 'close'
command for the current context. The event can only be responded to if the currently activated context keymap configuration contains the 'close'
command.
keyboard.switchContext('editor');
When the user presses Ctrl+W
, the close event will be executed.
When the context is switched to previewer
, since previewer
does not have a close
command, the user presses Ctrl+W
and the event is no longer triggered.
Fallback context
If a shortcut command is not found in current activated context, by default, the shortcuts
will look for same command in default
context, but if some context has been specified a fallback context, the shortcuts
will look for that fallback context first.
Shortcut macros
import { Keyboard, macros } from '@vgerbot/shortcuts';
const keyboard = new Keyboard();
// These following defines the macros globally.
macros('Mod', isMac ? 'Meta' : 'Ctrl');
macros('Cs', e => {
return e.crlKey && e.shifKey;
});
// or defines the macros for keyboard instance.
keyboard.macros('Mod', isMac ? 'Meta' : 'Ctrl');
keyboard.macros('Cs', e => {
return e.crlKey && e.shifKey;
});
// After that, you can use macros like this:
keyboard.keymap({
commands: {
copy: 'Mod+C', // On Mac OS, it is equivalent to Meta+C, and other systems are equivalent to Ctrl+C
capture: 'Cs+A' // Equivalent to Ctrl+Shift+A
}
})