Closed guillaumepotier closed 6 years ago
@guillaumepotier Yes, this was my expectation also. Seems to be not the case
Inedeed, FYI I went on that handmade solution:
import React, { Component } from 'react'
import keyboardJS from 'keyboardjs'
import moment from 'moment'
export function withKeyboard (WrappedComponent) {
return class Keyboard extends Component {
static displayName = `WithKeyboard(${WrappedComponent.displayName || WrappedComponent.name || 'Component'})`
static getClass = () => (WrappedComponent.getClass ? WrappedComponent.getClass() : WrappedComponent)
constructor (props) {
super(props)
this.isPressed = this.isPressed.bind(this)
this.handleKeypress = this.handleKeypress.bind(this)
this.state = {
pressedKeys: [],
isTrusted: false,
isPressed: this.isPressed,
at: null
}
}
componentDidMount () {
keyboardJS.bind('', this.handleKeypress)
}
handleKeypress ({ isTrusted, pressedKeys }) {
// at precision is 0,1 sec
this.setState({ isTrusted, pressedKeys, at: Math.floor(moment().valueOf() / 100) })
}
// string could be 'a', 'b', 'b + c', 'command+shift+a', etc..
isPressed (string) {
const keys = string
.replace(/\s/g, '') // remove all spaces
.split('+') // split by `+` char
for (let i = 0; i < keys.length; i++) {
if (this.state.pressedKeys.indexOf(keys[i]) === -1) {
return false
}
}
return true
}
componentWillUnmount () {
keyboardJS.unbind('', this.handleKeypress)
}
render () {
return <WrappedComponent {...this.props} keyboard={this.state} />
}
}
}
That way in my components I use that like this:
componentWillUpdate ({ messages, keyboard }) {
if (keyboard.at !== this.props.keyboard.at && keyboard.isPressed('ctrl + m')) {
this.setState({ hiddenMenuPanel: !this.state.hiddenMenuPanel })
}
}
Did not find something better than keyboard.at
with a 100ms
tresshold to avoid inifinite loops.. Kinda ugly, but for now on, its does the job
@guillaumepotier Thanks for sharing!
Sorry for the harsh/clumsy title, but why this API?
I mean, If I understand correctly, in the API, here
It seems that the component explicitly waits for a specific
KEYPRESS
to bes
in order for the component to havethis.props.keyEventName
andthis.props.keyValue
not null (but 115 and s).Why that choice?
I was more expecting a HOC/decorator that would give me in props any keyboard events with their value, my component having to deal with that specifically in
componentWillReceiveProps()
orcomponentWillUpdate()
, but this current API seems very limiting.Unless I'm missing the big picture here :)
Thanks for your lights