Manage keyboard shortcuts from one place
Manage keyboard shortcuts from one place.
Managing keyboard shortcuts can sometimes get messy. Or always, if not implemented the right way.
Real problems:
addEventListeners
, removeEventListeners
, …)With react-shortcuts
you can declaratively manage shortcuts for each one of your React components.
Important parts of React Shortcuts:
keymap
definitionShortcutManager
which handles keymap
<Shortcut>
component for handling shortcutsnpm install react-shortcuts
Create a new JS, Coffee, JSON or CSON file wherever you want (which probably is your project root). And define the shortcuts for your React component.
Keymap definition
{
"Namespace": {
"Action": "Shortcut",
"Action_2": ["Shortcut", "Shortcut"],
"Action_3": {
"osx": "Shortcut",
"windows": ["Shortcut", "Shortcut"],
"linux": "Shortcut",
"other": "Shortcut"
}
}
}
Namespace
should ideally be the component’s displayName
.Action
describes what will be happening. For example MODAL_CLOSE
.Keyboard shortcut
can be a string, array of strings or an object whicha
, 6
,…), combinationscommand+shift+k
) or sequences (up up down down left right left right B A
).Combokeys is used under the
hood for handling the shortcuts. Read more about how you can
specify keys.
keymap
definition:
export default {
TODO_ITEM: {
MOVE_LEFT: 'left',
MOVE_RIGHT: 'right',
MOVE_UP: ['up', 'w'],
DELETE: {
osx: ['command+backspace', 'k'],
windows: 'delete',
linux: 'delete',
},
},
}
Save this file as keymap.[js|coffee|json|cson]
and require it into your main
file.
import keymap from './keymap'
Define your keymap in whichever supported format but in the end it must be an
object. ShortcutsManager
can’t parse JSON and will certainly not be happy
about the situation.
import keymap from './keymap'
import { ShortcutManager } from 'react-shortcuts'
const shortcutManager = new ShortcutManager(keymap)
// Or like this
const shortcutManager = new ShortcutManager()
shortcutManager.setKeymap(keymap)
shortcutManager
into getChildContext of some parent component. So that <shortcuts>
can receive it.
class App extends React.Component {
getChildContext() {
return { shortcuts: shortcutManager }
}
}
App.childContextTypes = {
shortcuts: PropTypes.object.isRequired
}
You need to require the component in the file you want to use shortcuts in.
For example <TodoItem>
.
import { Shortcuts } from `react-shortcuts`
class TodoItem extends React.Component {
_handleShortcuts = (action, event) => {
switch (action) {
case 'MOVE_LEFT':
console.log('moving left')
break
case 'MOVE_RIGHT':
console.log('moving right')
break
case 'MOVE_UP':
console.log('moving up')
break
case 'COPY':
console.log('copying stuff')
break
}
}
render() {
return (
<Shortcuts
name='TODO_ITEM'
handler={this._handleShortcuts}
>
<div>Make something amazing today</div>
</Shortcuts>
)
}
}
The
<Shortcuts>
component creates a<shortcuts>
element in HTML, binds
listeners and adds tabIndex to the element so that it’s focusable.
_handleShortcuts
is invoked when some of the defined shortcuts fire.
<Shortcuts>
componenthandler
: funcname
: stringtabIndex
: number-1
className
: stringeventType
: stringstopPropagation
: boolpreventDefault
: booltargetNodeSelector
: DOM Node Selector like body
or .my-class
global
: boolCMD+Q
.isolate
: boolalwaysFireHandler
: boolThis library is inspired by Atom Keymap.