Skip to content

Commit

Permalink
Add setNextFocus support (#22082)
Browse files Browse the repository at this point in the history
Summary:
Add properties to be able to set the nextFocus. It can be very useful with Android TV.

New android View properties :

* nextFocusDown binded to [setNextFocusDownId](https://developer.android.com/reference/android/view/View.html#setNextFocusDownId(int))
* nextFocusForward binded to [setNextFocusForwardId](https://developer.android.com/reference/android/view/View.html#setNextFocusForwardId(int))
* nextFocusLeft binded to [setNextFocusLeftId](https://developer.android.com/reference/android/view/View.html#setNextFocusLeftId(int))
* nextFocusRight binded to [setNextFocusRightId](https://developer.android.com/reference/android/view/View.html#setNextFocusRightId(int))
* nextFocusUp binded to [setNextFocusUpId](https://developer.android.com/reference/android/view/View.html#setNextFocusUpId(int))

Can be used to fix :

* Fixes #20593
* Fixes #20100

Same PR as #22080 but accorded to changes on master
Pull Request resolved: #22082

Differential Revision: D14162740

Pulled By: cpojer

fbshipit-source-id: 9a13a185d4e8307ce67014fb076c62d135c487c3
  • Loading branch information
gritwyplay authored and facebook-github-bot committed Feb 21, 2019
1 parent f8a4d28 commit c416b40
Show file tree
Hide file tree
Showing 6 changed files with 231 additions and 1 deletion.
45 changes: 45 additions & 0 deletions Libraries/Components/Button.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,41 @@ type ButtonProps = $ReadOnly<{|
*/
hasTVPreferredFocus?: ?boolean,

/**
* TV next focus down (see documentation for the View component).
*
* @platform android
*/
nextFocusDown?: ?number,

/**
* TV next focus forward (see documentation for the View component).
*
* @platform android
*/
nextFocusForward?: ?number,

/**
* TV next focus left (see documentation for the View component).
*
* @platform android
*/
nextFocusLeft?: ?number,

/**
* TV next focus right (see documentation for the View component).
*
* @platform android
*/
nextFocusRight?: ?number,

/**
* TV next focus up (see documentation for the View component).
*
* @platform android
*/
nextFocusUp?: ?number,

/**
* Text to display for blindness accessibility features
*/
Expand Down Expand Up @@ -95,6 +130,11 @@ class Button extends React.Component<ButtonProps> {
onPress,
title,
hasTVPreferredFocus,
nextFocusDown,
nextFocusForward,
nextFocusLeft,
nextFocusRight,
nextFocusUp,
disabled,
testID,
} = this.props;
Expand Down Expand Up @@ -127,6 +167,11 @@ class Button extends React.Component<ButtonProps> {
accessibilityRole="button"
accessibilityStates={accessibilityStates}
hasTVPreferredFocus={hasTVPreferredFocus}
nextFocusDown={nextFocusDown}
nextFocusForward={nextFocusForward}
nextFocusLeft={nextFocusLeft}
nextFocusRight={nextFocusRight}
nextFocusUp={nextFocusUp}
testID={testID}
disabled={disabled}
onPress={onPress}>
Expand Down
57 changes: 56 additions & 1 deletion Libraries/Components/Touchable/TouchableHighlight.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,18 @@ type IOSProps = $ReadOnly<{|
tvParallaxProperties?: ?TVParallaxPropertiesType,
|}>;

type AndroidProps = $ReadOnly<{|
nextFocusDown?: ?number,
nextFocusForward?: ?number,
nextFocusLeft?: ?number,
nextFocusRight?: ?number,
nextFocusUp?: ?number,
|}>;

type Props = $ReadOnly<{|
...TouchableWithoutFeedbackProps,
...IOSProps,
...AndroidProps,

activeOpacity?: ?number,
underlayColor?: ?ColorValue,
Expand Down Expand Up @@ -189,7 +198,48 @@ const TouchableHighlight = ((createReactClass({
*/
hasTVPreferredFocus: PropTypes.bool,
/**
* Apple TV parallax effects
* TV next focus down (see documentation for the View component).
*
* @platform android
*/
nextFocusDown: PropTypes.number,
/**
* TV next focus forward (see documentation for the View component).
*
* @platform android
*/
nextFocusForward: PropTypes.number,
/**
* TV next focus left (see documentation for the View component).
*
* @platform android
*/
nextFocusLeft: PropTypes.number,
/**
* TV next focus right (see documentation for the View component).
*
* @platform android
*/
nextFocusRight: PropTypes.number,
/**
* TV next focus up (see documentation for the View component).
*
* @platform android
*/
nextFocusUp: PropTypes.number,
/**
* *(Apple TV only)* Object with properties to control Apple TV parallax effects.
*
* enabled: If true, parallax effects are enabled. Defaults to true.
* shiftDistanceX: Defaults to 2.0.
* shiftDistanceY: Defaults to 2.0.
* tiltAngle: Defaults to 0.05.
* magnification: Defaults to 1.0.
* pressMagnification: Defaults to 1.0.
* pressDuration: Defaults to 0.3.
* pressDelay: Defaults to 0.0.
*
* @platform ios
*/
tvParallaxProperties: PropTypes.object,
/**
Expand Down Expand Up @@ -367,6 +417,11 @@ const TouchableHighlight = ((createReactClass({
isTVSelectable={true}
tvParallaxProperties={this.props.tvParallaxProperties}
hasTVPreferredFocus={this.props.hasTVPreferredFocus}
nextFocusDown={this.props.nextFocusDown}
nextFocusForward={this.props.nextFocusForward}
nextFocusLeft={this.props.nextFocusLeft}
nextFocusRight={this.props.nextFocusRight}
nextFocusUp={this.props.nextFocusUp}
onStartShouldSetResponder={this.touchableHandleStartShouldSetResponder}
onResponderTerminationRequest={
this.touchableHandleResponderTerminationRequest
Expand Down
30 changes: 30 additions & 0 deletions Libraries/Components/Touchable/TouchableNativeFeedback.android.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,31 @@ const TouchableNativeFeedback = createReactClass({
*/
hasTVPreferredFocus: PropTypes.bool,

/**
* TV next focus down (see documentation for the View component).
*/
nextFocusDown: PropTypes.number,

/**
* TV next focus forward (see documentation for the View component).
*/
nextFocusForward: PropTypes.number,

/**
* TV next focus left (see documentation for the View component).
*/
nextFocusLeft: PropTypes.number,

/**
* TV next focus right (see documentation for the View component).
*/
nextFocusRight: PropTypes.number,

/**
* TV next focus up (see documentation for the View component).
*/
nextFocusUp: PropTypes.number,

/**
* Set to true to add the ripple effect to the foreground of the view, instead of the
* background. This is useful if one of your child views has a background of its own, or you're
Expand Down Expand Up @@ -303,6 +328,11 @@ const TouchableNativeFeedback = createReactClass({
onLayout: this.props.onLayout,
hitSlop: this.props.hitSlop,
isTVSelectable: true,
nextFocusDown: this.props.nextFocusDown,
nextFocusForward: this.props.nextFocusForward,
nextFocusLeft: this.props.nextFocusLeft,
nextFocusRight: this.props.nextFocusRight,
nextFocusUp: this.props.nextFocusUp,
hasTVPreferredFocus: this.props.hasTVPreferredFocus,
onStartShouldSetResponder: this.touchableHandleStartShouldSetResponder,
onResponderTerminationRequest: this
Expand Down
40 changes: 40 additions & 0 deletions Libraries/Components/Touchable/TouchableOpacity.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ const PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};

type TVProps = $ReadOnly<{|
hasTVPreferredFocus?: ?boolean,
nextFocusDown?: ?number,
nextFocusForward?: ?number,
nextFocusLeft?: ?number,
nextFocusRight?: ?number,
nextFocusUp?: ?number,
tvParallaxProperties?: ?TVParallaxPropertiesType,
|}>;

Expand Down Expand Up @@ -148,6 +153,36 @@ const TouchableOpacity = ((createReactClass({
* TV preferred focus (see documentation for the View component).
*/
hasTVPreferredFocus: PropTypes.bool,
/**
* TV next focus down (see documentation for the View component).
*
* @platform android
*/
nextFocusDown: PropTypes.number,
/**
* TV next focus forward (see documentation for the View component).
*
* @platform android
*/
nextFocusForward: PropTypes.number,
/**
* TV next focus left (see documentation for the View component).
*
* @platform android
*/
nextFocusLeft: PropTypes.number,
/**
* TV next focus right (see documentation for the View component).
*
* @platform android
*/
nextFocusRight: PropTypes.number,
/**
* TV next focus up (see documentation for the View component).
*
* @platform android
*/
nextFocusUp: PropTypes.number,
/**
* Apple TV parallax effects
*/
Expand Down Expand Up @@ -281,6 +316,11 @@ const TouchableOpacity = ((createReactClass({
testID={this.props.testID}
onLayout={this.props.onLayout}
isTVSelectable={true}
nextFocusDown={this.props.nextFocusDown}
nextFocusForward={this.props.nextFocusForward}
nextFocusLeft={this.props.nextFocusLeft}
nextFocusRight={this.props.nextFocusRight}
nextFocusUp={this.props.nextFocusUp}
hasTVPreferredFocus={this.props.hasTVPreferredFocus}
tvParallaxProperties={this.props.tvParallaxProperties}
hitSlop={this.props.hitSlop}
Expand Down
35 changes: 35 additions & 0 deletions Libraries/Components/View/ViewPropTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,41 @@ type AndroidViewProps = $ReadOnly<{|
* See http://facebook.github.io/react-native/docs/view.html#importantforaccessibility
*/
importantForAccessibility?: ?('auto' | 'yes' | 'no' | 'no-hide-descendants'),

/**
* TV next focus down (see documentation for the View component).
*
* @platform android
*/
nextFocusDown?: ?number,

/**
* TV next focus forward (see documentation for the View component).
*
* @platform android
*/
nextFocusForward?: ?number,

/**
* TV next focus left (see documentation for the View component).
*
* @platform android
*/
nextFocusLeft?: ?number,

/**
* TV next focus right (see documentation for the View component).
*
* @platform android
*/
nextFocusRight?: ?number,

/**
* TV next focus up (see documentation for the View component).
*
* @platform android
*/
nextFocusUp?: ?number,
|}>;

type IOSViewProps = $ReadOnly<{|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,31 @@ public void setTVPreferredFocus(ReactViewGroup view, boolean hasTVPreferredFocus
}
}

@ReactProp(name = "nextFocusDown", defaultInt = View.NO_ID)
public void nextFocusDown(ReactViewGroup view, int viewId) {
view.setNextFocusDownId(viewId);
}

@ReactProp(name = "nextFocusForward", defaultInt = View.NO_ID)
public void nextFocusForward(ReactViewGroup view, int viewId) {
view.setNextFocusForwardId(viewId);
}

@ReactProp(name = "nextFocusLeft", defaultInt = View.NO_ID)
public void nextFocusLeft(ReactViewGroup view, int viewId) {
view.setNextFocusLeftId(viewId);
}

@ReactProp(name = "nextFocusRight", defaultInt = View.NO_ID)
public void nextFocusRight(ReactViewGroup view, int viewId) {
view.setNextFocusRightId(viewId);
}

@ReactProp(name = "nextFocusUp", defaultInt = View.NO_ID)
public void nextFocusUp(ReactViewGroup view, int viewId) {
view.setNextFocusUpId(viewId);
}

@ReactPropGroup(names = {
ViewProps.BORDER_RADIUS,
ViewProps.BORDER_TOP_LEFT_RADIUS,
Expand Down

0 comments on commit c416b40

Please sign in to comment.