UNPKG

5.03 kBMarkdownView Raw
1React Shortcuts
2=========
3
4**Manage keyboard shortcuts from one place.**
5
6[![Build Status](https://travis-ci.org/avocode/react-shortcuts.svg)][travis]
7
8
9Intro
10------
11
12
13Managing keyboard shortcuts can sometimes get messy. Or always, if not implemented the right way.
14
15Real problems:
16
17- You can't easily tell which shortcut is bound to which component
18- You have to write a lot of boilerplate code (`addEventListeners`, `removeEventListeners`, ...)
19- Memory leaks are a real problem if components don’t remove their listeners properly
20- Platform specific shortcuts is another headache
21- It's more difficult to implement feature like user-defined shortcuts
22- You can't easily get allthe application shortcuts and display it (e.g. in settings)
23
24
25**React shortcuts to the rescue!**
26-----------
27
28With `react-shortcuts` you can declaratively manage shortcuts for each one of your React components.
29
30**Important parts of React Shortcuts:**
31
32- Your `keymap` definition
33- `ShortcutManager` which handles `keymap`
34- `<Shortcut>` component for handling shortcuts
35
36**DEMO:** http://avocode.github.io/react-shortcuts/
37
38Quick tour
39----------
40
41
42#### 1. `npm install react-shortcuts`
43
44
45#### 2. **Define application shortcuts**
46
47Create 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.
48
49**Keymap definition**
50
51```
52{
53 "Namespace": {
54 "Action": "Shortcut",
55 "Action_2": ["Shortcut", "Shortcut"],
56 "Action_3": {
57 "osx": "Shortcut",
58 "windows": ["Shortcut", "Shortcut"],
59 "linux": "Shortcut"
60 }
61 }
62}
63```
64
65- `Namespace` should ideally be the component’s `displayName`.
66- `Action` describes what will be happening. For example `MODAL_CLOSE`.
67- `Keyboard shortcut` can be a string, array of strings or an object which
68 specifies platform differences (Windows, OSX, Linux). The
69 shortcut may be composed of single keys (`a`, `6`,…), combinations
70 (`command+shift+k`) or sequences (`up up down down left right left right B A`).
71
72> **Mousetrap** is used under the
73 hood for handling the shortcuts. [Read more][mousetrap] about how you can
74 specify keys.
75
76
77##### Example `keymap` definition (in CoffeeScript):
78
79
80```
81module.exports =
82 TodoItem:
83 MOVE_LEFT: 'left'
84 MOVE_RIGHT: 'right'
85 MOVE_UP: ['up', 'w']
86 COPY:
87 osx: 'command+c'
88 windows: 'ctrl+c'
89 linux: 'ctrl+c'
90```
91
92Save this file as `keymap.[js|coffee|json|cson]` and require it into your main
93file.
94
95```
96keymap = require './keymap'
97```
98
99#### 3. Rise of the ShortcutsManager
100
101Define your keymap in whichever supported format but in the end it must be an
102object. `ShortcutsManager` can’t parse JSON and will certainly not be happy
103about the situation.
104
105```
106keymap = require './keymap'
107ShortcutsManager = require 'react-shortcuts'
108
109shortcutManager = new ShortcutsManager(keymap)
110
111# Or like this
112
113shortcutManager = new ShortcutsManager()
114shortcutManager.setKeymap(keymap)
115
116```
117
118#### 4. Include `shortcutManager` into getChildContext of some parent component. So that `<shortcuts>` can receive it.
119
120```
121App = React.createClass
122 displayName: 'App'
123
124 childContextTypes:
125 shortcuts: React.PropTypes.object.isRequired
126
127 getChildContext: ->
128 shortcuts: shortcutManager
129
130```
131
132#### 5. Require the <shortcuts> component
133
134You need to require the component in the file you want to use shortcuts in.
135For example `<TodoItem>`.
136
137```
138Shortcuts = require `react-shortcuts/component`
139
140TodoItem = React.createClass
141 displayName: 'TodoItem'
142
143 _handleShortcuts: (action) ->
144 switch action
145 when 'MOVE_LEFT' then console.log('moving left')
146 when 'MOVE_RIGHT' then console.log('moving right')
147 when 'MOVE_UP' then console.log('moving up')
148 when 'COPY' then console.log('copying stuff')
149
150 render: ->
151
152 div className: 'todo-item',
153
154 Shortcuts
155 name: @constructor.displayName
156 handler: @_handleShortcuts,
157
158 div null,
159 'Buy some milk'
160
161```
162
163> The `<Shortcuts>` component creates a `<shortcuts>` element in HTML, binds
164 listeners and adds tabIndex to the element so that it’s focusable.
165 `_handleShortcuts` is invoked when some of the defined shortcuts fire.
166
167## Custom props for `<Shortcuts>` component
168
169- `handler`: func.isRequired
170- `name`: string.isRequired
171- `element`: func (React.DOM)
172 - You can render a custom element instead of the default `shortcuts` one
173- `tabIndex`: number
174 - Default is `-1`
175- `className`: string
176- `eventType`: string
177 - Just for gourmets
178- `stopPropagation`: bool
179- `targetNode`: DOM Node
180 - Use this one with caution. It binds listeners to the provided string instead
181 of the component.
182
183
184To not trigger the handler callback set `native-key-bindings` className to whichever element you need.
185
186
187## Thanks, Atom
188
189
190This library is inspired by [Atom Keymap].
191
192
193[Atom Keymap]: https://github.com/atom/atom-keymap/
194[travis]: https://travis-ci.org/avocode/react-shortcuts
195[mousetrap]: https://craig.is/killing/mice
196[keymaps]: https://github.com/atom/atom-keymap/