What is React keyboard event handler?
It is a react component that helps us in handling keyboard events like keyup, keydown, keypress etc.
Main Features of React Keyboard Event Handler
1) It supports combined keys (for example CTRL+S and even CTRL+ SHIFT+s)
2) It also supports handling modifier key alone (for example, handle pressing ctrl key)
3) Almost all keys including function keys like F1, F2 etc. are supported.
4) It provides us with easy to use and consistent key names to help free us from dealing with numeric key codes and /or browser compatibility.
5) It also supports key aliases such as ‘alphanumeric’ and all shortcuts for handling a wide range of keys.
6) Lastly, it also supports multiple handler instances and provides an easy way to control, enable/ disable status for each handler by the use of Props.
Usage of React Keyboard Event Handler:
By default, KeyboardEventhandler only handles global key events sources from document.body. These are events fired without any focused element (event.target). It will not handle key events that are sourced from form controls (e.g. input), links, or any tab-enabled (focusable) elements (e.g. elements with tabIndex attribute).
Web browsers generally come with default keyboard behaviors for tab-enabled elements. It may be more appropriate to let them. Browser do its job in most cases.
Enter the default react starter code given below.
import KeyboardEventHandler from ‘react-keyboard-event-handler’;
const ComponentA = (props) => (<div>
<div>key detected: {props.eventKey}</div>
<KeyboardEventHandler
handleKeys={[‘a’, ‘b’, ‘c’]}
onKeyEvent={(key, e) => console.log(`do something upon keydown event of ${key}`)} />
</div>);
This default setting however can be changed by setting handleFocusableElements prop to true.
Handling Key Events sourced from children elements:
If KeyboardEventHandler is wrapped around any of the children elements, it will handle and ONLY hsndle key events sourced from its descendant elements. This includes any form of controls, links or tab-enabled elements.
import KeyboardEventHandler from ‘react-keyboard-event-handler’;
const ComponentA = (props) => (<div>
<div>key detected: {props.eventKey}</div>
<KeyboardEventHandler
handleKeys={[‘a’, ‘b’, ‘c’]}
onKeyEvent={(key, e) => console.log(`do something upon keydown event of ${key}`)} >
<input type=”text” placeholder=”Key events will be handled”/>
<a href=”#” >Key events from focusable element will be handled</a>
</KeyboardEventHandler>
</div>);
For form control elements, React provides with onKeyDown, onKeyPress and onKeyUp synthetic events. However, you may find it easier to work with the key names/alias provided by KeyboardEventHandler.
API Summary-
Property | Type | Default | Description |
handleKeys | Array | [] | An array of keys this handler should handle. There are also some handy alias for keys, see bellow for details. e.g. [‘a’, ‘b’, ‘numeric’] |
handleEventType | String | keydown | Keyboard event type. This can be ‘keyup’, ‘keydown’ or ‘keypress’. *Note: ‘keypress’ event only support printable keys. i.e. no support for modifier keys or ‘tab’, ‘enter’ etc. |
handleFocusableElements | Bool | false | By default, handler only handles key events sourced from doucment.body. When this props is set to true, it will also handle key events from all focusable elements. This props only apply when there are no children. |
isDisabled | Boolean | false | Enable/Disable handling keyboard events |
isExclusive | Boolean | false | When set to true, all other handler instances are suspended. This is useful for temporary disabling all other keyboard event handlers. For example, for suppressing any other handlers on a page when a modal opens with its keyboard event handling. |
onKeyEvent | function | () => null | A callback function to call when the handler detects a matched key event. The signature of the callback function is: function(key, event) { … } key The key name matches the current keyboard event. event The native keyboard event. e.g. you can use event.keyCode to get the numeric key code. This is useful for handling keys that are not supported (i.e. does not have a key name defined for the keys). |
children | Any | null | If KeyboardEventHandlerwraps around any children elements, it will handle and ONLY handle key events sourced from its descendant elements, including any form controls, links or tab-enabled elements. handleFocusableElementshas no effect when childrenexists. |
Key Names and Key Alias-
The handle keys prop accepts an array of key names. Key names and key alias-free developers from dealing with numeric codes or key codes and browser compatibility issues. All this is done using the KeyboardEvent.code and KeyboardEvent.key.
– All the key names are in lower case for consistency
– In order to handle combined keys like shift and a, use key names in the format of shift+a
– You can also use key name aliases like ‘numbers’ or ‘alphanumeric’.
Common Keys
One or more common keys can be handled by you by using an array of their names.
<KeyboardEventHandler
handleKeys={[‘a’]}
onKeyEvent={(key, e) => console.log(‘only handle “a” key’)} />
Key name | Description / key code |
a, b, … z | letter keys, 65 ~ 90 and 97 ~ 112 |
0, 1, … 9 | number keys 48 ~ 57 and 41 , 96 ~ 105 |
f1, f2, … f19 | function keys 112 ~ 130 |
backspace | 8 |
del/delete | 46 |
ins/insert | 45 |
tab | 9 |
enter/return | 13 |
esc | 27 |
space | 32 |
pageup | 33 |
pagedown | 34 |
end | 35 |
home | 36 |
left | 37 |
up | 38 |
right | 39 |
down | 40 |
shift | 16 |
ctrl | 17 |
alt | 18 |
cap | 20 |
num | Num Lock, 144 |
clear | 12 |
meta | Meta, Win, Window, Cmd, Command, 91 |
; | 186, 59 |
= | 187, 61 |
, | 188, 44 |
-/minus | 189, 45, 173, 109 |
. | 190, 110 |
/ | 191, 111 |
` | 192 |
[ | 219 |
\ | 220 |
] | 221 |
* | 106 |
+/plus | 107 |
+/plus | 107 |
‘/quote | 222 |
It is important to note that Native Keyboard events with modifier keys will not match common keys in handlekeys. For example, handleKeys={‘a’] will not handler events with combined keys. ‘Ctrl’ and ‘a’.
Modifier Keys-
These keys can be handled by combining them with a common key by using key name in the format of ctrl+a or ctrl+shift+a. To use the + common key with modifier keys, use the alias key ‘plus’.
<KeyboardEventHandler
handleKeys={[‘ctrl+a’]}
onKeyEvent={(key, e) => console.log(‘only handle “a” key with control key pressed’)} />
Key name | Description |
ctrl | control, ctrl key |
shift | shift key |
meta | meta, cmd, Window, command key |
alt | option, alt key |
Key Set Alias:
This function provides an easy way to specify common key sets. It is useful when you want to handle multiple keys and put all the handling and logic for each key inside the handler callback function.
<KeyboardEventHandler
handleKeys={[‘numeric’]}
onKeyEvent={(key, e) => console.log(‘only handle number key events’)} />
Alias | Keys | Description |
‘alphabetic’ | ‘a’, ‘b’, …’z’ | 26 letter keys |
‘numeric’ | ‘0’, ‘1’, ….’9 | 10 number keys |
‘alphanumeric’ | ‘a’…’z’, ‘0’…’9′ | 36 alphanumeric keys |
‘function’ | ‘f1’…’f19’ | 19 Fn keys |
‘all’ | n/a | All keyboard events. If a key event does not match any common keys defined above, the key parameter to the callback function will have the value of ‘other’. You can use the second parameter (the raw key event object) to implement your own key handling logic. |
Higher Order Components-
This is not a place where HoC can be put to good use.
Testing-
There is no good way for testing keyboard events especially while using enzyme as it has two main limitations-
1) Event simulation is limited for shallow rendering
2) Event propagation is not supported.