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

Commit ee7c8bb

Browse files
Changed onBecameFocused and added onBecameBlurred (#59)
* Changed onBecameFocused and added onBecameBlurred * typos
1 parent b79e1ff commit ee7c8bb

5 files changed

Lines changed: 54 additions & 6 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [2.10.0]
8+
### Changed
9+
- Changed behaviour of `onBecameFocused`, now it's invoked also in case of stealFocus
10+
### Added
11+
- Added `onBecameBlurred` with the same behaviour of `onBecameFocused` but invoked on component losing focus
12+
713
## [2.9.3]
814
### Added
915
- Added `KeyDetails` param on callback functions `onEnterPress` and `onArrowPress`

README.md

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ const ParentComponent = (props) => (<View>
8686
onEnterPress={props.onItemPress}
8787
onArrowPress={props.onArrowPress}
8888
onBecameFocused={props.onItemFocused}
89+
onBecameBlurred={props.onItemBlurred}
8990
/>
9091
...
9192
</View>);
@@ -187,7 +188,7 @@ Enable visual debugging (all layouts, reference points and siblings refernce poi
187188
Enable Native mode. It will block certain web-only functionality such as:
188189
- adding window key listeners
189190
- measuring DOM layout
190-
- `onBecameFocused` callback doesn't return coordinates, but still has node ref to lazy measure layout
191+
- `onBecameFocused` and `onBecameBlurred` callbacks doesn't return coordinates, but still has node ref to lazy measure layout
191192
- coordinates calculations when navigating
192193
- down-tree propagation
193194
- last focused child
@@ -302,7 +303,7 @@ const onPress = (direction, {prop1, prop2}) => {
302303
```
303304

304305
### `onBecameFocused`: function
305-
Callback 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, this callback will be called on every level of down-tree focus propagation.
306+
Callback function that is called when the item becomes focused directly or when any of the children components become focused. For example when you have nested tree of 5 focusable components, this callback will be called on every level of down-tree focus change.
306307

307308
Payload:
308309
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.
@@ -319,6 +320,24 @@ const onFocused = ({width, height, x, y, top, left, node}, {prop1, prop2}) => {.
319320
...
320321
```
321322

323+
### `onBecameBlurred`: function
324+
Callback function that is called when the item loses focus or when all the children components lose focus. For example when you have nested tree of 5 focusable components, this callback will be called on every level of down-tree focus change.
325+
326+
Payload:
327+
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.
328+
329+
```jsx
330+
const onBlur = ({width, height, x, y, top, left, node}, {prop1, prop2}) => {...};
331+
332+
...
333+
<FocusableItem
334+
prop1={111}
335+
prop2={222}
336+
onBecameBlurred={onBlur}
337+
/>
338+
...
339+
```
340+
322341
## Props passed to Wrapped Component
323342
### `focusKey`: string
324343
Focus 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 ¯\\\_(ツ)_

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@noriginmedia/react-spatial-navigation",
3-
"version": "2.9.3",
3+
"version": "2.10.0",
44
"description": "HOC-based Spatial Navigation (key navigation) solution for React",
55
"main": "dist/index.js",
66
"files": [

src/spatialNavigation.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -659,8 +659,6 @@ class SpatialNavigation {
659659
);
660660

661661
if (children.length > 0) {
662-
this.onIntermediateNodeBecameFocused(targetFocusKey);
663-
664662
const {lastFocusedChildKey, preferredChildFocusKey} = targetComponent;
665663

666664
this.log('getNextFocusKey', 'lastFocusedChildKey is', lastFocusedChildKey);
@@ -712,6 +710,7 @@ class SpatialNavigation {
712710
onEnterPressHandler,
713711
onArrowPressHandler,
714712
onBecameFocusedHandler,
713+
onBecameBlurredHandler,
715714
forgetLastFocusedChild,
716715
trackChildren,
717716
onUpdateFocus,
@@ -726,6 +725,7 @@ class SpatialNavigation {
726725
onEnterPressHandler,
727726
onArrowPressHandler,
728727
onBecameFocusedHandler,
728+
onBecameBlurredHandler,
729729
onUpdateFocus,
730730
onUpdateHasFocusedChild,
731731
forgetLastFocusedChild,
@@ -849,12 +849,14 @@ class SpatialNavigation {
849849
const parentComponent = this.focusableComponents[parentFocusKey];
850850

851851
parentComponent && parentComponent.trackChildren && parentComponent.onUpdateHasFocusedChild(false);
852+
this.onIntermediateNodeBecameBlurred(parentFocusKey);
852853
});
853854

854855
forEach(parentsToAddFlag, (parentFocusKey) => {
855856
const parentComponent = this.focusableComponents[parentFocusKey];
856857

857858
parentComponent && parentComponent.trackChildren && parentComponent.onUpdateHasFocusedChild(true);
859+
this.onIntermediateNodeBecameFocused(parentFocusKey);
858860
});
859861

860862
this.parentsHavingFocusedChild = parents;
@@ -907,6 +909,11 @@ class SpatialNavigation {
907909
this.focusableComponents[focusKey].onBecameFocusedHandler(this.getNodeLayoutByFocusKey(focusKey));
908910
}
909911

912+
onIntermediateNodeBecameBlurred(focusKey) {
913+
this.isParticipatingFocusableComponent(focusKey) &&
914+
this.focusableComponents[focusKey].onBecameBlurredHandler(this.getNodeLayoutByFocusKey(focusKey));
915+
}
916+
910917
pause() {
911918
this.paused = true;
912919
}

src/withFocusable.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ const withFocusable = ({
8585
}) => (layout) => {
8686
onBecameFocused(layout, rest);
8787
},
88+
onBecameBlurredHandler: ({
89+
onBecameBlurred = noop,
90+
...rest
91+
}) => (layout) => {
92+
onBecameBlurred(layout, rest);
93+
},
8894
pauseSpatialNavigation: () => SpatialNavigation.pause,
8995
resumeSpatialNavigation: () => SpatialNavigation.resume
9096
}),
@@ -99,6 +105,7 @@ const withFocusable = ({
99105
onEnterPressHandler,
100106
onArrowPressHandler,
101107
onBecameFocusedHandler,
108+
onBecameBlurredHandler,
102109
onUpdateFocus,
103110
onUpdateHasFocusedChild,
104111
trackChildren,
@@ -115,6 +122,7 @@ const withFocusable = ({
115122
onEnterPressHandler,
116123
onArrowPressHandler,
117124
onBecameFocusedHandler,
125+
onBecameBlurredHandler,
118126
onUpdateFocus,
119127
onUpdateHasFocusedChild,
120128
forgetLastFocusedChild: (configForgetLastFocusedChild || forgetLastFocusedChild),
@@ -124,7 +132,12 @@ const withFocusable = ({
124132
},
125133
componentDidUpdate(prevProps) {
126134
const {
127-
focused, realFocusKey: focusKey, onBecameFocusedHandler, preferredChildFocusKey, focusable = true
135+
focused,
136+
realFocusKey: focusKey,
137+
onBecameFocusedHandler,
138+
onBecameBlurredHandler,
139+
preferredChildFocusKey,
140+
focusable = true
128141
} = this.props;
129142

130143
const node = SpatialNavigation.isNativeMode() ? this : findDOMNode(this);
@@ -137,6 +150,8 @@ const withFocusable = ({
137150

138151
if (!prevProps.focused && focused) {
139152
onBecameFocusedHandler(SpatialNavigation.getNodeLayoutByFocusKey(focusKey));
153+
} else if (prevProps.focused && !focused) {
154+
onBecameBlurredHandler(SpatialNavigation.getNodeLayoutByFocusKey(focusKey));
140155
}
141156
},
142157
componentWillUnmount() {
@@ -152,6 +167,7 @@ const withFocusable = ({
152167

153168
omitProps([
154169
'onBecameFocusedHandler',
170+
'onBecameBlurredHandler',
155171
'onEnterPressHandler',
156172
'onArrowPressHandler',
157173
'onUpdateFocus',

0 commit comments

Comments
 (0)