greena13 / react-hotkeys Goto Github PK
View Code? Open in Web Editor NEWDeclarative hotkey and focus area management for React
Home Page: https://github.com/greena13/react-hotkeys
License: ISC License
Declarative hotkey and focus area management for React
Home Page: https://github.com/greena13/react-hotkeys
License: ISC License
I'd like to be able to have HotKeys autofocus, so I can easily set up global hotkeys.
Proposal: when given an autoFocus
prop, HotKeys would render FocusTrap with ref={n => n && setTimeout(() => n.focus())}
.
Using version 0.8.0, everything works great. When I upgrade to 0.9.0, I can't get any of my handlers to fire. Any idea why that might be?
Roughly my components look like this:
const keyMap = {
onEnter: 'return'
};
const handlers = {
onEnter: this.doStuff
};
<HotKeys keyMap={keyMap} handlers={handlers}>
...
</HotKeys>
I tried attached focused
and attached={window}
because I thought maybe they weren't in focus, but that didn't work, either.
Hi.
I need to use hotkeys inside a modal overlay.
After the overlay is rendered, currently, the user must click into the container element once to give it focus, after that the hotkeys work as expected.
However, what I need is to have the hotkeys ready right away after the modal has opened up, without further mouse interaction.
This is kinda what I have, and I also tried manually focussing an element inside HotKeys, but it doesn't work. How can this be achieved?
componentDidMount() {
setTimeout(() => {
this.refs.video.focus();
//this.refs.dummyInput.focus();
//neither way, works, timeout doesn't make a difference either
}, 500);
}
render() {
return (
<div className='MediaPlayer'>
<HotKeys keyMap={this.hotKeys} handlers={this}>
<video ref='video' src={this.props.videoSrc}/>
{/*<input type='hidden' ref='dummyInput' />*/}
</HotKeys>
</div>
);
}
I guess i could make it work by using HotKeys further up the component tree, but I guess I would have to define some part of the logic outside of the target component as well? (keyMap, handlers), should be encapsulated inside the 'app' running inside the modal overlay, shouldn't be known outside of it.
I tried the focused
prop too, but it didn't help.
Unless one exists, have not seen. Would like to add to react.rocks -- thanks
Hey there!
I simply no longer have (read: never really have gad) the time or incentive to maintain and take forward this project.
I'm happy to hand over the reigns to anyone who will be able to modernise the project and help respond to the small amount of requests that come in.
If you're interested please comment below! And sorry to everyone relying on this project who has not been able to update to the latest React.
Chris
Not sure if this is better put in mousetrap
or react-hotkeys
, but I have the following use case.
I have an input field that I want particular hotkeys to work on, so I have
<HotKeys ...>
<input type='text' />
</Hotkeys>
However, because I have hotkeys further up the stack that would conflict with entering text in the input, I want to use only hotkeys in the immediately surrounding context, and not forward events up.
Is this possible?
const keyMap = {
'zoomIn': 'ctrl+plus',
'zoomOut': 'ctrl+-',
};
I tried ctrl++ also, though I was pretty sure that was wrong. Both have no effect. Any advice?
<HotKeys/> wraps its children into a <div tabIndex="-1"/>. When the user clicks the form outside of any control, the whole form gets a weird focused border created by the browser (Chrome has a particularly visible one).
Is there a way to prevent this?
Some probably stupid ideas:
Hi,
I'm not sure if that just stupid me, or it indeed doesn't work as expected.
I have the following structure:
Main
`-- Panel
|-- List
`-- Input
Main component is wrapped with HotKeys and the mixin applied. Currently I'm playing with one key - f
.
Main
has only keyMap
defined, but the handler for f
is defined in Input
component. The handler gets called only if I place focus on Input
.
The idea is to be able to call handler of the hotkey on Input
, if the focus is placed on its parent, in this case the parent is Main
.
The idea is to be able to place focus on the input from any place of the app.
Is this possible, did I miss something, or I should pick another way?
HotKeys
currently creates a Mousetrap instance for each component mounted. This could be optimized for the cases where you had many hotkey targets (imagine hundreds of node's you had a 'delete' hotkey for) by having a single instance where handlers were bound to.
Just trying to repeat your quick example.
Got this:
Warning: owner-based and parent-based contexts differ
(values: `undefined` vs `[object Object]`) for key (hotKeyMap)
while mounting Node
(see: http://fb.me/react-context-by-parent)
I've simplified it to just two directly nested , and same happens.
const bar = () => console.log('this works');
const foo = () => console.log('this does not work');
<HotKeys keyMap={{foo: "q", bar: "w"}} handlers={{bar: bar }}>
<HotKeys handlers={{foo: foo }}>
some plain text
</HotKeys>
</HotKeys>
Gist by link from warning does not give for me any answers why exactly this happens and how to fix it, so I report this issue.
Using React 0.13.3
Hi there,
Thank you for great contributions. I've been waiting for this!
It works mostly fine but I was wondering whether you have plans to add support for hold or keyup handler.
The use case for this is that you might want to trigger hotkey handler if a key is pressed in a certain period of time. For example, if you hold command key on Mailbox for Mac, the icons are replaced with shortcut key icons which are useful.
This library has been tremendously helpful in implementing key-related events. And a HotKeys HOC would make the application of the functionalities more standardized and decoupled as opposed to manually wrapped each component (that needs keyboard actions) with the HotKeys tag in the component file.
I'd like to propose the following API:
const withKeyboardNavigation = (Component, keyMap) => (
class WithKeyboardNavigationWrapper extends PureComponent {
...
_getBoundHandlers() {
// returns bounded handlers
}
...
render () {
// returns HOC-wrapped Component with keyMap & handlers props on the <HotKeys> tag, and a11y props on the <wrappedComponent> tag.
The keyboard action and the keyboard event are states on the HOC, and are passed in as props to the wrappedComponent. The component can then implement the appropriate methods according to the given props.
Thoughts?
React issues a warning saying "Unknown props keyMap
, handlers
, component
on
Seems like we should exclude or explicitly distinguish properties in 'this.props' when passing/getting it into/from other components.
I am using the following keyMap:
const keyMap = {
'last': 'end'
};
However when I press "end", it will trigger the handler as expected, but also scroll down the page (as if there was no hotkey). How can I make sure the hotkey supersedes the default key behavior?
The webpack excludes doesn't list react-dom and therefore the outputted JS includes all of it. This results in a minified JS size of ~150kB. Simply adding react-dom to excludes reduces the output size to 18kB.
Would it be reasonable to make the assumption that react-dom is already available rather than including it here as well?
And have FocusTrapHOC
provides a non-intrusive API for those who want it?
Want to use it, but there's no bower support.
Issue to track/discuss upcoming features/changes.
Mousetrap
reference (ie. import {Mousetrap} from 'react-hotkeys';
)Add *.js.flow Flow type definitions to document the module and its exports.
This will need to be done as a index.js.flow
file that is included in all relevant release bundles.
Your link to the reactiflux Slack group on the Readme seems to be broken! :(
Warning: owner-based and parent-based contexts differ (values: `undefined` vs
`[object Object]`) for key (hotKeyMap) while mounting HotKeys
(see: http://fb.me/react-context-by-parent)
I'm using ES6 classes with my react components. I get the warning above as soon as I have a component within another component. I've tried giving them both their own keyMap prop, but nothing seems to get rid of that warning.
Any clues?
Its seems that there is little response to any support issues raised on this project.
Is there any intent to keep this project going?
Do you need help with supporting this?
My company needs to supports keyboard navigation and high levels of accessibility so we see the value in a framework helping to manage that aspect. We are currently evaluating whether to continue to use this component, but if we cant get P.Rs accepted to fix bugs, its makes us unlikely to want to continue using it.
Would appreciate some information on where this repo is heading. If the burden of supporting this is to much we may fork this and enhance it internally. Thanks.
As well as using the HotKeys
component there could possibly be a Higher Order Component provided.
Need to think how this would look/work though.
In a *.tsx file, I get a TypeScript error trying to set the className
prop on a HotKeys
component.
Code
<HotKeys className='foo' handlers={this.hotKeyHandlers}>
...
</HotKeys>
Error
Error:(71, 20) TS2322:Type '{ className: "foo"; handlers: { saveDocument: () => void; }; children: Element[]; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<HotKeys> & Readonly<{ children?: ReactNode; }> & R...'.
Property 'className' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<HotKeys> & Readonly<{ children?: ReactNode; }> & R...'.
Even with the correct key name like 'ArrowUp'. other keys (e.g. 'r') work.
I'm using this library on a smart TV platform and some of the keycodes don't seem to exist in Mousetrap. Mousetrap has support for this but it's not exposed to react-hotkeys
What I tried to do:
Add a customKeyCodes prop
propTypes: {
children: React.PropTypes.node,
onFocus: React.PropTypes.func,
onBlur: React.PropTypes.func,
keyMap: React.PropTypes.object,
handlers: React.PropTypes.object,
focused: React.PropTypes.bool, // externally controlled focus
attach: React.PropTypes.any, // dom element to listen for key events,
customKeyCodes: React.ProptTypes.array // custom keycodes in the format {123, 'banana', 456, foobar}
},
and this inside componentDidMount():
// add custom keycodes to Mousetrap
if (this.props.customKeyCodes) {
this.__mousetrap__.addKeycodes(this.props.customKeyCodes);
}
HOWEVER it seems you're doing some clever abstractions. If you're available to point me in the right direction, I'd like to make this work!
Need to generate docs for public React components/api's.
Could use https://github.com/reactjs/react-docgen?
There are currently no tests that cover the documented behaviour "Hard Sequence Handlers".
One or more tests are needed to verify that this functionality is currently as stated in the documentation, and will not quietly break in the future.
<HotKeys keyMap={KeyMap.globalSectionRadioGroup}
handlers={keyEventHandler}
attach={window}
component="li"
ref={(li) => {this.focsuedSection = li;}}
onClick={this.onSectionClick.bind(this, section.props, idx)}
styleName={section.props.selected ? sectionRadioSelectedCls: sectionRadioCls}
key={section.props.id || section.props.text}>
<div styleName="section-label">{section.props.text}</div>
{type === "primary" && <div styleName={section.props.selected ? "section-marker-selected" : "section-marker"} />}
</HotKeys>;
It will only trigger when i am focused on element. but not directly capturing event on window.
Just upgraded and spent some time walking through and trying to find where this is breaking. To be honest I'm not totally sure.
It does seem to be calling updateHotKeys a ton. Not sure why but it looks like it runs it as it's pushing each shortcut into an array, or something along these lines. Very strange but if I put a debugger here it actually gets called once for every shortcut I define, as though it's building an array of them one by one and then calling this function each time.
Not sure if that's it. I tested manually by creating my own little mousetrap thing and it works fine, so it's not mousetrap. I don't see anything else obvious that would cause this break though.
Peer dependency fails
Sometimes when switching between mounting/unmounting components I get the following error. Has anyone seen this before? I'm using react-hotkeys 0.5.0 and react 0.13.3 w/ react-router 0.13.3
Uncaught TypeError: Cannot read property 'reset' of undefineds.default.createClass.componentWillUnmount @ HotKeys.js:107x.unmountComponent @ ReactCompositeComponent.js:273o.unmountComponent @ ReactReconciler.js:56x.unmountComponent @ ReactCompositeComponent.js:279o.unmountComponent @ ReactReconciler.js:56s.unmountChildren @ ReactChildReconciler.js:119b.Mixin.unmountChildren @ ReactMultiChild.js:329a.Mixin.unmountComponent @ ReactDOMComponent.js:481o.unmountComponent @ ReactReconciler.js:56x.unmountComponent @ ReactCompositeComponent.js:279o.unmountComponent @ ReactReconciler.js:56s.unmountChildren @ ReactChildReconciler.js:119b.Mixin.unmountChildren @ ReactMultiChild.js:329a.Mixin.unmountComponent @ ReactDOMComponent.js:481o.unmountComponent @ ReactReconciler.js:56x.unmountComponent @ ReactCompositeComponent.js:279o.unmountComponent @ ReactReconciler.js:56s.unmountChildren @ ReactChildReconciler.js:119b.Mixin.unmountChildren @ ReactMultiChild.js:329a.Mixin.unmountComponent @ ReactDOMComponent.js:481o.unmountComponent @ ReactReconciler.js:56x.unmountComponent @ ReactCompositeComponent.js:279o.unmountComponent @ ReactReconciler.js:56s.unmountChildren @ ReactChildReconciler.js:119b.Mixin.unmountChildren @ ReactMultiChild.js:329a.Mixin.unmountComponent @ ReactDOMComponent.js:481o.unmountComponent @ ReactReconciler.js:56x.unmountComponent @ ReactCompositeComponent.js:279o.unmountComponent @ ReactReconciler.js:56x.unmountComponent @ ReactCompositeComponent.js:279o.unmountComponent @ ReactReconciler.js:56x.unmountComponent @ ReactCompositeComponent.js:279o.unmountComponent @ ReactReconciler.js:56x.unmountComponent @ ReactCompositeComponent.js:279o.unmountComponent @ ReactReconciler.js:56x.unmountComponent @ ReactCompositeComponent.js:279o.unmountComponent @ ReactReconciler.js:56x._updateRenderedComponent @ ReactCompositeComponent.js:758x._performComponentUpdate @ ReactCompositeComponent.js:726x.updateComponent @ ReactCompositeComponent.js:642x.receiveComponent @ ReactCompositeComponent.js:506o.receiveComponent @ ReactReconciler.js:97x._updateRenderedComponent @ ReactCompositeComponent.js:748x._performComponentUpdate @ ReactCompositeComponent.js:726x.updateComponent @ ReactCompositeComponent.js:642x.receiveComponent @ ReactCompositeComponent.js:506o.receiveComponent @ ReactReconciler.js:97s.updateChildren @ ReactChildReconciler.js:83b.Mixin._updateChildren @ ReactMultiChild.js:277b.Mixin.updateChildren @ ReactMultiChild.js:251a.Mixin._updateDOMChildren @ ReactDOMComponent.js:470a.Mixin.updateComponent @ ReactDOMComponent.js:319a.Mixin.receiveComponent @ ReactDOMComponent.js:303o.receiveComponent @ ReactReconciler.js:97x._updateRenderedComponent @ ReactCompositeComponent.js:748x._performComponentUpdate @ ReactCompositeComponent.js:726x.updateComponent @ ReactCompositeComponent.js:642x.receiveComponent @ ReactCompositeComponent.js:506o.receiveComponent @ ReactReconciler.js:97x._updateRenderedComponent @ ReactCompositeComponent.js:748x._performComponentUpdate @ ReactCompositeComponent.js:726x.updateComponent @ ReactCompositeComponent.js:642x.receiveComponent @ ReactCompositeComponent.js:506o.receiveComponent @ ReactReconciler.js:97x._updateRenderedComponent @ ReactCompositeComponent.js:748x._performComponentUpdate @ ReactCompositeComponent.js:726x.updateComponent @ ReactCompositeComponent.js:642x.receiveComponent @ ReactCompositeComponent.js:506o.receiveComponent @ ReactReconciler.js:97x._updateRenderedComponent @ ReactCompositeComponent.js:748x._performComponentUpdate @ ReactCompositeComponent.js:726x.updateComponent @ ReactCompositeComponent.js:642x.receiveComponent @ ReactCompositeComponent.js:506o.receiveComponent @ ReactReconciler.js:97x._updateRenderedComponent @ ReactCompositeComponent.js:748x._performComponentUpdate @ ReactCompositeComponent.js:726x.updateComponent @ ReactCompositeComponent.js:642x.receiveComponent @ ReactCompositeComponent.js:506o.receiveComponent @ ReactReconciler.js:97x._updateRenderedComponent @ ReactCompositeComponent.js:748x._performComponentUpdate @ ReactCompositeComponent.js:726x.updateComponent @ ReactCompositeComponent.js:642x.receiveComponent @ ReactCompositeComponent.js:506o.receiveComponent @ ReactReconciler.js:97x._updateRenderedComponent @ ReactCompositeComponent.js:748x._performComponentUpdate @ ReactCompositeComponent.js:726x.updateComponent @ ReactCompositeComponent.js:642x.receiveComponent @ ReactCompositeComponent.js:506o.receiveComponent @ ReactReconciler.js:97x._updateRenderedComponent @ ReactCompositeComponent.js:748x._performComponentUpdate @ ReactCompositeComponent.js:726x.updateComponent @ ReactCompositeComponent.js:642x.receiveComponent @ ReactCompositeComponent.js:506o.receiveComponent @ ReactReconciler.js:97x._updateRenderedComponent @ ReactCompositeComponent.js:748x._performComponentUpdate @ ReactCompositeComponent.js:726x.updateComponent @ ReactCompositeComponent.js:642x.receiveComponent @ ReactCompositeComponent.js:506o.receiveComponent @ ReactReconciler.js:97x._updateRenderedComponent @ ReactCompositeComponent.js:748x._performComponentUpdate @ ReactCompositeComponent.js:726x.updateComponent @ ReactCompositeComponent.js:642x.receiveComponent @ ReactCompositeComponent.js:506o.receiveComponent @ ReactReconciler.js:97x._updateRenderedComponent @ ReactCompositeComponent.js:748x._performComponentUpdate @ ReactCompositeComponent.js:726x.updateComponent @ ReactCompositeComponent.js:642x.receiveComponent @ ReactCompositeComponent.js:506o.receiveComponent @ ReactReconciler.js:97x._updateRenderedComponent @ ReactCompositeComponent.js:748x._performComponentUpdate @ ReactCompositeComponent.js:726x.updateComponent @ ReactCompositeComponent.js:642x.receiveComponent @ ReactCompositeComponent.js:506o.receiveComponent @ ReactReconciler.js:97x._updateRenderedComponent @ ReactCompositeComponent.js:748x._performComponentUpdate @ ReactCompositeComponent.js:726x.updateComponent @ ReactCompositeComponent.js:642x.receiveComponent @ ReactCompositeComponent.js:506o.receiveComponent @ ReactReconciler.js:97x.performUpdateIfNecessary @ ReactCompositeComponent.js:524o.performUpdateIfNecessary @ ReactReconciler.js:115s @ ReactUpdates.js:151i.perform @ Transaction.js:134i.perform @ Transaction.js:134m.perform @ ReactUpdates.js:95k @ ReactUpdates.js:175M.close @ ReactUpdates.js:51i.closeAll @ Transaction.js:207i.perform @ Transaction.js:148m.perform @ ReactUpdates.js:95k @ ReactUpdates.js:175i.closeAll @ Transaction.js:207i.perform @ Transaction.js:148d.batchedUpdates @ ReactDefaultBatchingStrategy.js:66o @ ReactUpdates.js:110b.dispatchEvent @ ReactEventListener.js:174
Is this currently possible? F5 doesn't seem to work if I pass that in as the key string.
I've set up hotkeys in a top level component. Within that are elements. If I enter hotkeys in those elements they trigger. Is there a way to prevent that?
Please add change log file or release note for every release version. It provides new features were added and breaking changes were produced in a release version and help developers update to newer versions smoothly
I'm trying to set up hotkeys that just 'always work' regardless of what is in focus. Right now, I'm binding the hotkeys to the outer-layer of my app, but that still doesn't work unless the user clicks somewhere in the 'stage' to get focus (and the focus can be lost in weird ways too). Any good workarounds?
FWIW the code in question is here: https://github.com/cpsubrian/react-zelda/blob/master/src/components/handlers/AppHandler.js
I want use it with keycode 10009 (Tizen RETURN)?
A single key sequence could be handled by "in focus" multiple components however in most use cases it does not make much sense for a parent to handle the same hotkey if a child has already dealt with it. For this reason hotkey events will not propagate beyond the component which handles them by default.
So how can we override this default?
React v15.5 has depreciated React.createClass. This line raises a warning while using react-hotkeys: " Warning: FocusTrap: React.createClass is deprecated and will be removed in version 16"
Hi!
I have nested a hotkey element and an input element within another hotkey element:
import React from 'react';
import {HotKeys} from 'react-hotkeys';
const Neat = React.createClass({
onKeyDown (event) {
},
render () {
var handlers = {
'up': function(event) {
console.log('up');
},
'down': function(event) {
console.log('down');
}
};
var inputHandlers = {
'up': function(event) {
console.log('inputHandler up');
},
'down': function(event) {
console.log('inputHandler down');
}
};
return (<div>
<HotKeys handlers={inputHandlers}>
<HotKeys handlers={handlers}>
<div> hello </div>
</HotKeys>
<input ref='input' onKeyDown={this.onKeyDown}>
</input>
</HotKeys>
</div>);
}
});
module.exports = Neat;
Here's how I reproduced the issue:
This is the minimal example to reproduce the problem I had.
The behavior depends on the order of keys pressed and whether you focus on a certain element. (stateful!) I wonder if it's something with mousetrap or the way we use it..
It has been previously suggested that this package should drop support for Bower.
Now the React Team has decided to drop Bower support as of React 16.1.0.
This issue is to capture any discussion around dropping Bower support.
I'm not sure if you've encountered this โ but I can't seem to have react-hotkeys
catch simulated events on react components, like with enzyme's simulate
method.
Hi,
Was wondering if you would be interested in accepting a P.R which a minimal react-hotkeys dist without any third party dependencies included, e.g. no lodash. This is helpful if Lodash is already loaded from elsewhere.
I'm having some trouble preventing the actions from happening in input fields. According to mousetraps' website, there is a default function in mousetrap that will ignore commands if it's coming from an input field.
However, with React-Hotkeys, not only are the events bubbling out of the input fields, I can't seem to find a way to control which keys I want to escape.
Has anyone else had issues like this. I'm using the latest version of react-hotkeys. Maybe someone knows atleast which event I can listen for on the input field to stop propagation.
Right now, they hotkey events at the top container seem to handling the events first.
I'm guessing I'll have to use something like this: https://github.com/erikras/react-native-listener....
Hey
i'm using the NPM package React-Iframe
And i cant get the hotkeys to work on the iframe
any ideas?
DOM (and React) events bubble up the DOM unless a handler in the chain calls e.stopPropagation(). This behavior gives developers control over how events are handled.
HotKeys used to have this behavior but it changed some time since 0.5.0. Now, if there is a child handler the keyboard event stops processing regardless of whether the child handler handled the event or not. It is no longer possible to write code like this:
...
handleUpKey: (event) => {
if (this.x) {
event.stopPropagation();
this.doX();
} else {
// let event bubble and be handled by parent
}
},
render: () => {
return <HotKeys handlers={{'up': this.handleUpKey}}>...</HotKeys>;
}
It would be great to have the DOM like behavior back.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.