
Research
Malicious npm Packages Impersonate Flashbots SDKs, Targeting Ethereum Wallet Credentials
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
react-keys
Advanced tools
Simple way to bind keyboard to react with redux.
The need a fast way to bind keys to a react-powered UI with awesome redux for state management.
react-keys
requires React 15 or later
npm install react-keys
or yarn add react-keys
While not having direct dependencies, react-keys have to be used with react
, react-dom
and redux
:
yarn add react
yarn add react-dom
yarn add redux
import { keysInit, keyReducer, getCurrentBinderId } from 'react-keys';
import { createStore, combineReducers } from 'redux';
import { connect } from 'react-redux';
import PureMosaic from '../PureMosaic'; // Pure React Component
//ONE
const store = createStore(
combineReducers({
'@@keys': keysReducer, // you need to link the react-keys reducer with the @@keys id
})
);
//TWO
keysInit({ store: store }); // add the store there
//THREE
const Mosaic = connect(() => getCurrentBinderId()())(PureMosaic); // listen every changes of your mosaic like that
This is the entry point you need to define your redux store here. You can also define global behaviors
store
(redux store / mandatory) Link the redux store to react-keys
eventCb
(function / optional) Define a callback triggered when short/long press are donedebounce
(number / optional) define a global debounce in ms, it can be overrided by components (default : 10
)config
(object / optional) define keys to work with, this is the core concept for Keys components and it works as belowlongPressTouch
(array / optional) define list of keycode active for long press handling ( default : [37, 38, 39, 40]
)The default config of react-keys
is
{
left: 37,
up: 38,
right: 39,
down: 40,
enter: 13,
}
You can get your computed config by calling like that
import { config } from 'react-keys';
const getConfig = () => config();
You can use them by adding a prop to Keys
component with the keyword on
before the key with CamelCase (onBack
, onUp
, onEnter
...)
You can extend this config by adding your own object config that will extend the default config.
react-keys
has two main Component
to deal with keyboard : Keys
and Binder
. Keys
is basically an handler for keydown
that execute a callback from a specific key
. Binder
helps you to navigate throw lists with spacial context.
You can mount has much as Keys
or Binder
you want at same time but there is just one handler triggered by key action.
By default the priority is given to the lastest Component
mounted. You can configure that by setting a priority
property on Keys
and Binder
.
That means a Binder
with priority 1
mounted before a Keys
with priority 0
(default) will still trigger the action.
When a Keys
or Binder
is unmonted
, react-keys
will figure out which Component
will take the lead.
Very basic way to handle keyboard events. Yet is pretty powerfull :-)
import { Keys } from 'react-keys';
function onBack() {
alert('alert bro');
}
const Component = ({ isActive }) => {
return (
<>
<Keys
id="rk-basic"
onBack={() => console.log('Did I just push A ?')}
active={isActive}
/>
<h1>Check that out !</h1>
</>
);
};
id
(string / mandatory) component idon${keyCode}
(function / optional) keyCode callbackactive
(boolean / optional) determine is Keys
component is active (default true
)debounce
(number / optional) define a debounce for keys press in ms (default global debounce)priority
(number / optional) define the priority from others (default 0
)A basic component that can execute a callback when observing a sequence. This component has two props:
sequence
(string / mandatory) the sequence to observe.cb
(function / mandatory) the callback to execute.import { Catcher } from 'react-keys';
const ComponentWithCatcher = () => {
return (
<div>
<Catcher
sequence="424242"
cb={() => console.log('Yeah ! Cheat code activated')}
/>
</div>
);
};
// When 42 is enter 3 times
// It will print on console 'Yeah ! Cheat code activated'
Fancy React component to deal with space navigation. It handles communication with multiple Binder
compoments to create something great !
import { Binder, keysInit } from 'react-keys';
keysInit(); // must call it once at the app starting to enable the triggering
function renderWithId(id) {
ReactDOM.render(
<Mosaic binderId="mosaic-1" selectedId={id} />,
document.getElementById('body')
);
}
function onKey(element) {
renderWithId(element.id);
}
const Card = ({ id, active }) => {
const style = active ? 'selected' : '';
return (
<li id={id} className={style}>
#{id}
</li>
);
};
const Mosaic = ({ binderId, selectedId }) => {
return (
<Binder
id={binderId}
active={true}
onLeft={onKey}
onUp={onKey}
onDown={onKey}
onRight={onKey}
>
<ul>
<Card id={binderId + '-1'} active={selectedId === binderId + '-1'} /> //
element need a unique id
<Card id={binderId + '-2'} active={selectedId === binderId + '-2'} />
<Card id={binderId + '-3'} active={selectedId === binderId + '-3'} />
</ul>
</Binder>
);
};
renderWithId('mosaic-1-1');
<Binder ...options />
id
(string / mandatory) Define the binder idactive
(boolean / optional) determine if binder is active (default false
)selector
(string / optional) DOM selector which define each element (default li
)priority
(number / optional) define priority among others binders when mouting (default 0
)wrapper
(string / optional) DOM selector which define parent element (default document
)filter
(string / optional) class name which exclude elementdebounce
(number / optional) define a debounce for keys press in ms (default global debounce)memory
(boolean / optional) define if binder state has to be saved on unmounting (default false
)strategy
(string / optional) define strape strategy on enter: start
/ mirror
/ none
(default none
)refreshStrategy
(string / optional) define how the focus behave on binder elements update (which element will be focused): first
/ previous
(default first
)position
(string / optional) to better handle for enterStrategy (vertial/horizontal) (default horizontal
)visibilityOffset
(number / optional) set an offset un pixel to determine if an element is visible or hidden (default 0
)direction
(string / optional) give a hint to react-keys
to know if the direction is mainly horizontal
or vertical
(default none
)gap
(number / optional) reduce or increase elements margin (default 0
)`boundedGap
(number / optional) reduce or increase bounded margin (default 0
)triggerClick
(boolean / optional) elements will trigger a click event on enter event (default true
)`topGap
(number / optional) reduce or increase last top margin (default 0
)longPress
(boolean / optional) active long press handler (default true
)rightGap
(number / optional) reduce or increase last right margin (default 0
)leftGap
(number / optional) reduce or increase last left margin (default 0
)downGap
(number / optional) reduce or increase last down margin (default 0
)onRight
(function / optional) callback for right events function(nextElement)
onLeft
(function / optional) callback for left events function(nextElement)
onUp
(function / optional) callback for up events function(nextElement)
onDown
(function / optional) callback for down events function(nextElement)
onEnter
(function / optional) callback for enter events function(nextElement)
onRightExit
(function/string / optional) triggered when right event would go outside the elements block, it can be a function or the binder id we want to reachonLeftExit
(function/string / optional) triggered when left event would go outside the elements block, it can be a function or the binder id we want to reachonUpExit
(function/string / optional) triggered when up event would go outside the elements block, it can be a function or the binder id we want to reachonDownExit
(function/string / optional) triggered when down event would go outside the elements block, it can be a function or the binder id we want to reachimport { Binder, keysSelector } from 'react-keys';
const PureMosaic = ({ selectedId, marginTop, marginLeft }) => {
return (
<Binder
id="rk-binder"
wrapper="#myWrapper"
gap={20}
onEnter={element => console.log(`ENTER with ${element.id}`)}
>
<div id="myWrapper">
<ul style={{ marginTop: marginTop, marginLeft: marginLeft }}>
<li id="1" className={selectedId === '1' ? 'selected' : ''}>
#1
</li>
<li id="2" className={selectedId === '2' ? 'selected' : ''}>
#2
</li>
<li id="3" className={selectedId === '3' ? 'selected' : ''}>
#3
</li>
<li id="4" className={selectedId === '4' ? 'selected' : ''}>
#4
</li>
<li id="5" className={selectedId === '5' ? 'selected' : ''}>
#5
</li>
<li id="6" className={selectedId === '6' ? 'selected' : ''}>
#6
</li>
</ul>
</div>
</Binder>
);
};
const Mosaic = connect(() => ({
selectedId: getCurrentSelectedId()(),
marginTop: getBinderMarginTop('rk-binder')(),
marginLeft: getBinderMarginLeft('rk-binder')(),
}))(PureMosaic); // listen every changes of your mosaic like that
the keys store will manage the state of each binders (no matter how many they are).
Selectors give you easy control on your data binder, here few selectors for common use. they return a function
isCurrentBinder(binderId)
determine if your binder is the current binderisBinderActive(binderId)
determine if your binder is activegetBinderMarginLeft(binderId)
determine marginLeft of a bindergetBinderMarginTop(binderId)
determine marginTop of a bindergetBinderSelectedId(binderId)
determine selectedId of a bindergetCurrentSelectedId()
get selected id of current active bindergetCurrentBinder()
get state of current active bindergetCurrentBinderId()
get id of current active bindergetBinders()
get an array of all bindersgetKeyCode()
get key code currently pressedisLongPress()
determine if it is a long pressisVisibleInBinder(binderId, elementId)
determine if an element is visible inside its binderactiveBinder(binderId, selectedId(optional))
activate a new binder by giving its id (first id by default)resetBinder(binderId, selectedId(optional))
reset binder by giving its id (first id by default)updateBinder(binderState)
when you want to update the state manually (you must know what you do !)removeBinder(binderId)
remove a binder from the app state, useful when you want re-init the binderFor some reason you want sometime block a specific binder or a specific key, you can perform that with these functions. Don't forget to unblock when you block :-)
bock(values or array of values(optional))
it can be keyCode or binderId. when no argument are passed, it blocks everything.unblock(values or array of values(optional))
it can be keyCode or binderId. when no argument are passed, it unblocks everything.blockExcept(values or array of values)
it can be keyCode or binderId. Note when you want toi except a binder, you have to refers its keyCode associatedblockExcept('binderId', [
config().down,
config().up,
config().left,
config().right,
config().enter,
]);
unblockExcept(values or array of values)
it can be keyCode or binderId.catcher(sequence, callback)
it trigger the callback when a string
sequence is catchednpm run test
FAQs
Simple way to bind keyboard to react thinking with flux
The npm package react-keys receives a total of 140 weekly downloads. As such, react-keys popularity was classified as not popular.
We found that react-keys demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
Security News
Ruby maintainers from Bundler and rbenv teams are building rv to bring Python uv's speed and unified tooling approach to Ruby development.
Security News
Following last week’s supply chain attack, Nx published findings on the GitHub Actions exploit and moved npm publishing to Trusted Publishers.