Security News
New Python Packaging Proposal Aims to Solve Phantom Dependency Problem with SBOMs
PEP 770 proposes adding SBOM support to Python packages to improve transparency and catch hidden non-Python dependencies that security tools often miss.
@noriginmedia/react-spatial-navigation
Advanced tools
HOC-based Spatial Navigation (key navigaition) solution for React
The main motivation to create this package was to bring the best Developer Experience and Performance when working with Key Navigation and React. Ideally you wouldn't want to have any logic to define the navigation in your app. It should be as easy as just to tell which components should be navigable. With this package all you have to do is to initialize it, wrap your components with the HOC and set initial focus. The spatial navigation system will automatically figure out which components to focus next when you navigate with the directional keys.
Will be published soon.
Will be published soon ¯\_(ツ)_/¯
...
"react-spatial-navigation": "git+https://github.com/NoriginMedia/react-spatial-navigation.git#master"
...
// Somewhere at the root of the app
import {initNavigation, setKeyMap} from 'react-spatial-navigation';
initNavigation();
// Optional
setKeyMap({
'left': 9001,
'up': 9002,
'right': 9003,
'down': 9004,
'enter': 9005
});
import {withFocusable} from 'react-spatial-navigation';
...
const FocusableComponent = withFocusable()(Component);
import {withFocusable} from 'react-spatial-navigation';
...
const FocusableComponent = withFocusable({
propagateFocus: true,
trackChildren: true,
forgetLastFocusedChild: true
})(Component);
import {withFocusable} from 'react-spatial-navigation';
...
const FocusableComponent = withFocusable()(Component);
const ParentComponent = (props) => (<View>
...
<FocusableComponent
propagateFocus
trackChildren
forgetLastFocusedChild
focusKey={'FOCUSABLE_COMPONENT'}
onEnterPress={props.onItemPress}
onBecameFocused={props.onItemFocused}
/>
...
</View>);
import {withFocusable} from 'react-spatial-navigation';
const Component = ({focused, setFocus}) => (<View>
<View style={focused ? styles.focusedStyle : styles.defaultStyle} />
<TouchableOpacity
onPress={() => {
setFocus('SOME_ANOTHER_COMPONENT');
}}
/>
</View>);
const FocusableComponent = withFocusable()(Component);
import React, {PureComponent} from 'react';
import {withFocusable} from 'react-spatial-navigation';
...
class Menu extends PureComponent {
componentDidMount() {
// this.props.setFocus(); // If you need to focus first child automatically
this.props.setFocus('MENU-6'); // If you need to focus specific item that you know focus key of
}
render() {
return (<View style={hasFocusedChild ? styles.menuExpanded : styles.defaultStyle}>
<MenuItemFocusable />
<MenuItemFocusable />
<MenuItemFocusable />
<MenuItemFocusable />
<MenuItemFocusable />
<MenuItemFocusable focusKey={'MENU-6'} />
</View>);
}
}
const MenuFocusable = withFocusable({
trackChildren: true,
propagateFocus: true
})(Menu);
initNavigation
: functionFunction that needs to be called to enable Spatial Navigation system and bind key event listeners. Accepts initConfig as a param.
initNavigation({
debug: true,
visualDebug: true
})
debug
: booleanEnable console debugging
visualDebug
: booleanEnable visual debugging (all layouts, reference points and siblings refernce points are printed on canvases)
setKeyMap
: functionFunction to set custom key codes.
setKeyMap({
'left': 9001,
'up': 9002,
'right': 9003,
'down': 9004,
'enter': 9005
});
withFocusable
: functionMain HOC wrapper function. Accepts config as a param.
const FocusableComponent = withFocusable({...})(Component);
propagateFocus
: booleanDetermine whether to automatically propagate focus to child focusable component when this component gets focused.
trackChildren
: booleanDetermine whether to track when any child component is focused. Wrapped component can rely on hasFocusedChild
prop when this mode is enabled. Otherwise hasFocusedChild
will be always false
.
hasFocusedChild
changesforgetLastFocusedChild
: booleanDetermine whether this component should not remember the last focused child components. By default when focus goes away from the component and then it gets focused again, it will focus the last focused child. This functionality is enabled by default.
All these props are optional.
propagateFocus
: booleanSame as in config.
trackChildren
: booleanSame as in config.
forgetLastFocusedChild
: booleanSame as in config.
focusKey
: stringString that is used as a component focus key. Should be unique, otherwise it will override previously stored component with the same focus key in the Spatial Navigation service storage of focusable components. If this is not specified, the focus key will be generated automatically.
onEnterPress
: functionCallback function that is called when the item is currently focused and Enter (OK) key is pressed.
Payload: All the props passed to HOC is passed back to this callback. Useful to avoid creating callback functions during render.
const onPress = ({prop1, prop2}) => {...};
...
<FocusableItem
prop1={111}
prop2={222}
onPress={onPress}
/>
...
onBecameFocused
: functionCallback function that is called when the item becomes focused directly or during propagation of the focus to the children components. For example when you have nested tree of 5 focusable components, each of which has propagateFocus
, this callback will be called on every level of propagation.
Payload:
Component layout object is passed as a first param. All the component props passed back to this callback. Useful to avoid creating callback functions during render. x
and y
are relative coordinates to parent DOM (not the Focusable parent) element. left
and top
are absolute coordinates on the screen.
const onFocused = ({width, height, x, y, top, left}, {prop1, prop2}) => {...};
...
<FocusableItem
prop1={111}
prop2={222}
onBecameFocused={onFocused}
/>
...
focusKey
: stringFocus key that represents the focus key that was applied to HOC component. Might be null
when not set. It is recommended to not rely on this prop ¯\_(ツ)_/¯
realFocusKey
: stringFocus key that is either the focusKey
prop of the HOC, or automatically generated focus key like sn:focusable-item-23
.
parentFocusKey
: stringFocus key of the parent component. If it is a top level focusable component, this prop will be SN:ROOT
focused
: booleanWhether component is currently focused. It is only true
if this exact component is focused, e.g. when this component propagates focus to child component, this value will be false
.
hasFocusedChild
: booleanThis prop indicates that the component currently has some focused child on any depth of the focusable tree.
setFocus
: functionThis method sets the focus to another component (when focus key is passed as param) or steals the focus to itself (when used w/o params).
setFocus(); // set focus to self
setFocus('SOME_COMPONENT'); // set focus to another component if you know its focus key
pauseSpatialNavigation
: functionThis function pauses key listeners. Useful when you need to temporary disable navigation. (e.g. when player controls are hidden during video playback and you want to bind the keys to show controls again).
resumeSpatialNavigation
: functionThis function resumes key listeners if it was paused with pauseSpatialNavigation
This library is using Parcel to serve the web build.
To run the testbed app locally:
npm start
This will start local server on localhost:1234
Source code is in src/App.js
parentFocusKey
.withFocusable
HOCrealFocusKey
is created once at component mount in withStateHandlers
. It either takes the focusKey
prop value or is automatically generated.setFocus
method is bound with the current component realFocusKey
so you can call it w/o params to focus component itself.parentFocusKey
is propagated to children components through context. This is done because the focusable components tree is not necessary the same as the DOM tree.spatialNavigation
service storage of all focusable components.spatialNavigation
ServiceaddFocusable
and removed in removeFocusable
setFocus
. First it decides next focus key (getNextFocusKey
), then set focus to the new component (setCurrentFocusedKey
), then the service updates all components that has focused child and finally updates layout (coordinates and dimensions) for all focusable component.getNextFocusKey
is used to determine the good candidate to focus when you call setFocus
. This method will either return the target focus key for the component you are trying to focus, or go down by the focusable tree and select the best child component to focus. This function is recoursive and going down by the focusable tree.smartNavigate
is similar to the previous one, but is called in response to a key press event. It tries to focus the best sibling candidate in the direction of key press, or delegates this task to a focusable parent, that will do the same attempt for its sibling and so on.Please follow the Contribution Guide
MIT Licensed
FAQs
HOC-based Spatial Navigation (key navigation) solution for React
The npm package @noriginmedia/react-spatial-navigation receives a total of 4,183 weekly downloads. As such, @noriginmedia/react-spatial-navigation popularity was classified as popular.
We found that @noriginmedia/react-spatial-navigation demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 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.
Security News
PEP 770 proposes adding SBOM support to Python packages to improve transparency and catch hidden non-Python dependencies that security tools often miss.
Security News
Socket CEO Feross Aboukhadijeh discusses open source security challenges, including zero-day attacks and supply chain risks, on the Cyber Security Council podcast.
Security News
Research
Socket researchers uncover how threat actors weaponize Out-of-Band Application Security Testing (OAST) techniques across the npm, PyPI, and RubyGems ecosystems to exfiltrate sensitive data.