src/tools/hotkeys.js
import React from 'react';
import { setDisplayName, wrapDisplayName } from 'recompose';
import * as Key from './keycodes';
/**
* Список KeyCode в формате `KEY_BACKSPACE = 8`
* @example
* import { KEY_UP_ARROW, KEY_DOWN_ARROW } from 'tools/keycodes';
* hotkeys(TablePanel, {
* [KEY_UP_ARROW]: 'onPressArrowUp',
* [KEY_DOWN_ARROW]: 'onPressArrowDown'
* })
*/
export { Key };
/**
* HOC компонент для настройки работы с клавиатурой.
* Важно! Component не должен быть в другой оберетке, требуется компонент в котором буду методы из config
* @param BaseComponent - компонент который надо обернуть и в котором находятся методы
* @param {object} config - мапа вида {KEY_CODE: METHOD_NAME}
* @example hotkeys(Component, confg)
*/
export function hotkeys(BaseComponent, config) {
class HOC extends React.Component {
constructor(props) {
super(props);
this.onKeyDown = this.onKeyDown.bind(this);
}
onKeyDown(e) {
let callback = config[e.keyCode];
this.checkAndCall(callback, e);
}
checkAndCall(methodName, args) {
let cmp = this.baseComponent;
if (cmp && typeof cmp[methodName] === 'function') {
cmp[methodName](args);
}
}
render() {
return (
<div tabIndex="-1" onKeyDown={this.onKeyDown}>
<BaseComponent
ref={cmp => {
this.baseComponent = cmp;
}}
{...this.props}
/>
</div>
);
}
}
if (process.env.NODE_ENV !== 'production') {
return setDisplayName(wrapDisplayName(BaseComponent, 'hotkeys'))(HOC);
}
return HOC;
}