Skip to content
This repository has been archived by the owner on May 5, 2023. It is now read-only.

Commit

Permalink
Allowing to focus component with "setFocus" even if it has "focusable…
Browse files Browse the repository at this point in the history
…=false"
  • Loading branch information
asgvard committed Jul 31, 2019
1 parent 6d9e4ae commit 348dbb3
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 55 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.7.0]
## [2.7.2]
### Changed
- Allowed components to be focused with `setFocus` even if they have `focusable={false}`

## [2.7.1]
### Added
- `focusable` prop that enables component as a focusable target. Default is true. Usable when you need to temporarily disable focusable behaviour on the component. E.g. disabled button state.
### Changed
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,8 @@ Same as in [config](#config).
### `focusable`: boolean
Determine whether this component should be focusable (in other words, whether it's *currently* participating in the spatial navigation tree). This allows a focusable component to be ignored as a navigation target despite being mounted (e.g. due to being off-screen, hidden, or temporarily disabled).

Note that behaviour is undefined for trees of components in which an `focusable={false}` component has any `focusable={true}` components as descendants; it is recommended to ensure that all components in a given branch of the spatial navigation tree have a common `focusable` state.
Note that behaviour is undefined for trees of components in which an `focusable={false}` component has any `focusable={true}` components as descendants; it is recommended to ensure that all components in a given branch of the spatial navigation tree have a common `focusable` state.
Also `focusable={false}` does not prevent component from being directly focused with `setFocus`. It only blocks "automatic" focus logic such as directional navigation, or focusing component as lastFocusedChild or preferredFocusChild.

* **false**
* **true (default)**
Expand Down
56 changes: 26 additions & 30 deletions dist/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,7 @@ var Menu = function (_React$PureComponent2) {
_createClass(Menu, [{
key: 'componentDidMount',
value: function componentDidMount() {
var _this3 = this;

setTimeout(function () {
_this3.props.setFocus();
}, 0);
this.props.setFocus();

window.addEventListener('keydown', this.onPressKey);
}
Expand Down Expand Up @@ -254,14 +250,14 @@ var Content = function (_React$PureComponent3) {
function Content(props) {
_classCallCheck(this, Content);

var _this4 = _possibleConstructorReturn(this, (Content.__proto__ || Object.getPrototypeOf(Content)).call(this, props));
var _this3 = _possibleConstructorReturn(this, (Content.__proto__ || Object.getPrototypeOf(Content)).call(this, props));

_this4.state = {
_this3.state = {
currentProgram: null
};

_this4.onProgramPress = _this4.onProgramPress.bind(_this4);
return _this4;
_this3.onProgramPress = _this3.onProgramPress.bind(_this3);
return _this3;
}

_createClass(Content, [{
Expand Down Expand Up @@ -403,13 +399,13 @@ var Category = function (_React$PureComponent6) {
function Category(props) {
_classCallCheck(this, Category);

var _this7 = _possibleConstructorReturn(this, (Category.__proto__ || Object.getPrototypeOf(Category)).call(this, props));
var _this6 = _possibleConstructorReturn(this, (Category.__proto__ || Object.getPrototypeOf(Category)).call(this, props));

_this7.scrollRef = null;
_this6.scrollRef = null;

_this7.onProgramFocused = _this7.onProgramFocused.bind(_this7);
_this7.onProgramArrowPress = _this7.onProgramArrowPress.bind(_this7);
return _this7;
_this6.onProgramFocused = _this6.onProgramFocused.bind(_this6);
_this6.onProgramArrowPress = _this6.onProgramArrowPress.bind(_this6);
return _this6;
}

_createClass(Category, [{
Expand Down Expand Up @@ -438,7 +434,7 @@ var Category = function (_React$PureComponent6) {
}, {
key: 'render',
value: function render() {
var _this8 = this;
var _this7 = this;

// console.log('Category rendered: ', this.props.realFocusKey);

Expand All @@ -456,20 +452,20 @@ var Category = function (_React$PureComponent6) {
horizontal: true,
ref: function ref(reference) {
if (reference) {
_this8.scrollRef = reference;
_this7.scrollRef = reference;
}
}
},
programs.map(function (program, index) {
return _react2.default.createElement(ProgramFocusable, _extends({}, program, {
focusKey: 'PROGRAM-' + _this8.props.realFocusKey + '-' + index,
onPress: _this8.props.onProgramPress,
onEnterPress: _this8.props.onProgramPress,
focusKey: 'PROGRAM-' + _this7.props.realFocusKey + '-' + index,
onPress: _this7.props.onProgramPress,
onEnterPress: _this7.props.onProgramPress,
key: program.title,
onBecameFocused: _this8.onProgramFocused,
onArrowPress: _this8.onProgramArrowPress,
onBecameFocused: _this7.onProgramFocused,
onArrowPress: _this7.onProgramArrowPress,
programIndex: index,
categoryIndex: _this8.props.categoryIndex
categoryIndex: _this7.props.categoryIndex
}));
})
)
Expand All @@ -496,12 +492,12 @@ var Categories = function (_React$PureComponent7) {
function Categories(props) {
_classCallCheck(this, Categories);

var _this9 = _possibleConstructorReturn(this, (Categories.__proto__ || Object.getPrototypeOf(Categories)).call(this, props));
var _this8 = _possibleConstructorReturn(this, (Categories.__proto__ || Object.getPrototypeOf(Categories)).call(this, props));

_this9.scrollRef = null;
_this8.scrollRef = null;

_this9.onCategoryFocused = _this9.onCategoryFocused.bind(_this9);
return _this9;
_this8.onCategoryFocused = _this8.onCategoryFocused.bind(_this8);
return _this8;
}

_createClass(Categories, [{
Expand All @@ -516,7 +512,7 @@ var Categories = function (_React$PureComponent7) {
}, {
key: 'render',
value: function render() {
var _this10 = this;
var _this9 = this;

// console.log('Categories rendered: ', this.props.realFocusKey);

Expand All @@ -525,7 +521,7 @@ var Categories = function (_React$PureComponent7) {
{
ref: function ref(reference) {
if (reference) {
_this10.scrollRef = reference;
_this9.scrollRef = reference;
}
},
style: styles.categoriesWrapper
Expand All @@ -534,9 +530,9 @@ var Categories = function (_React$PureComponent7) {
return _react2.default.createElement(CategoryFocusable, _extends({
focusKey: 'CATEGORY-' + index
}, category, {
onProgramPress: _this10.props.onProgramPress,
onProgramPress: _this9.props.onProgramPress,
key: category.title,
onBecameFocused: _this10.onCategoryFocused,
onBecameFocused: _this9.onCategoryFocused,
categoryIndex: index

// preferredChildFocusKey={`PROGRAM-CATEGORY-${index}-${programs.length - 1}`}
Expand Down
10 changes: 1 addition & 9 deletions dist/spatialNavigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,6 @@ var SpatialNavigation = function () {

this.log('smartNavigate', 'currentComponent', currentComponent ? currentComponent.focusKey : undefined, currentComponent ? currentComponent.node : undefined);

/* We will not check whether currentComponent is focusable; it's fine to navigate AWAY from a disabled component. */
if (currentComponent) {
var parentFocusKey = currentComponent.parentFocusKey,
focusKey = currentComponent.focusKey,
Expand Down Expand Up @@ -608,7 +607,6 @@ var SpatialNavigation = function () {
}, {
key: 'saveLastFocusedChildKey',
value: function saveLastFocusedChildKey(component, focusKey) {
/* We won't check whether component is focusable; it's fine to save a disabled component as the lastFocusedChild. */
if (component) {
this.log('saveLastFocusedChildKey', component.focusKey + ' lastFocusedChildKey set', focusKey);
component.lastFocusedChildKey = focusKey;
Expand Down Expand Up @@ -803,7 +801,7 @@ var SpatialNavigation = function () {
}, {
key: 'setCurrentFocusedKey',
value: function setCurrentFocusedKey(focusKey) {
if (this.isParticipatingFocusableComponent(this.focusKey) && focusKey !== this.focusKey) {
if (this.isFocusableComponent(this.focusKey) && focusKey !== this.focusKey) {
var oldComponent = this.focusableComponents[this.focusKey];
var parentComponent = this.focusableComponents[oldComponent.parentFocusKey];

Expand Down Expand Up @@ -941,12 +939,6 @@ var SpatialNavigation = function () {
var lastFocusedKey = this.focusKey;
var newFocusKey = this.getNextFocusKey(targetFocusKey);

if (!this.isParticipatingFocusableComponent(newFocusKey)) {
this.log('setFocus', 'noParticipatingFocusTargets', newFocusKey);

return;
}

this.log('setFocus', 'newFocusKey', newFocusKey);

this.setCurrentFocusedKey(newFocusKey);
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@noriginmedia/react-spatial-navigation",
"version": "2.7.1",
"version": "2.7.2",
"description": "HOC-based Spatial Navigation (key navigation) solution for React",
"main": "dist/index.js",
"scripts": {
Expand Down
4 changes: 1 addition & 3 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,7 @@ class Menu extends React.PureComponent {
}

componentDidMount() {
setTimeout(() => {
this.props.setFocus();
}, 0);
this.props.setFocus();

window.addEventListener('keydown', this.onPressKey);
}
Expand Down
10 changes: 1 addition & 9 deletions src/spatialNavigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,6 @@ class SpatialNavigation {
currentComponent ? currentComponent.node : undefined
);

/* We will not check whether currentComponent is focusable; it's fine to navigate AWAY from a disabled component. */
if (currentComponent) {
const {parentFocusKey, focusKey, layout} = currentComponent;

Expand Down Expand Up @@ -551,7 +550,6 @@ class SpatialNavigation {
}

saveLastFocusedChildKey(component, focusKey) {
/* We won't check whether component is focusable; it's fine to save a disabled component as the lastFocusedChild. */
if (component) {
this.log('saveLastFocusedChildKey', `${component.focusKey} lastFocusedChildKey set`, focusKey);
component.lastFocusedChildKey = focusKey;
Expand Down Expand Up @@ -731,7 +729,7 @@ class SpatialNavigation {
}

setCurrentFocusedKey(focusKey) {
if (this.isParticipatingFocusableComponent(this.focusKey) && focusKey !== this.focusKey) {
if (this.isFocusableComponent(this.focusKey) && focusKey !== this.focusKey) {
const oldComponent = this.focusableComponents[this.focusKey];
const parentComponent = this.focusableComponents[oldComponent.parentFocusKey];

Expand Down Expand Up @@ -854,12 +852,6 @@ class SpatialNavigation {
const lastFocusedKey = this.focusKey;
const newFocusKey = this.getNextFocusKey(targetFocusKey);

if (!this.isParticipatingFocusableComponent(newFocusKey)) {
this.log('setFocus', 'noParticipatingFocusTargets', newFocusKey);

return;
}

this.log('setFocus', 'newFocusKey', newFocusKey);

this.setCurrentFocusedKey(newFocusKey);
Expand Down

0 comments on commit 348dbb3

Please sign in to comment.