Trigger onFocus/onBlur instead of onPressIn/onPressOut (eventually, but for now just deprecate) (#18470)

Summary:
Currently on iOS and Android focus/blur events trigger onPressIn/onPressOut. Based on discussions with people are several companies who use react-native we're proposing instead triggering new events onFocus/onBlur. Initial discussion on Slack with some from the core team on Slack seemed positive.

Couple reasons:

* The current API behavior overloads onPressIn/onPressOut. That means on platforms like react-native-web, if focus/blur support was added (as we're hoping for), even though onPressIn/onPressOut would be useful as the name describes, you wouldn't be able to distinguish between it and browser element focus/blur events.
* The names aren't as self-documenting/intuitive as onFocus/onBlur, especially for react-dom users.

There aren't any current tests around this, but I intend to add them if we solidify the API.

There's also an option question on the transition--do we deprecate the existing API with a warning? This PR just deprecates them, though it will on any TV platform when something becomes focused regardless of whether they use the API or not. This isn't ideal. It's not clear if there are alternatives or if just right away breaking the API for TV users is the correct solution, if we can get consensus between the few parties who are using it.

***

I'm interested to hear counter points or prior discussions.

Cc/ matthargett dlowder-salesforce rozele
Closes https://github.com/facebook/react-native/pull/18470

Differential Revision: D8368109

Pulled By: hramos

fbshipit-source-id: 22587b82e091645e748b6c2d721fdff06d54837f
This commit is contained in:
Jay Phelps 2018-06-11 15:11:01 -07:00 committed by Facebook Github Bot
parent c3c5c3cbce
commit baa61ddc9c
3 changed files with 41 additions and 3 deletions

View File

@ -325,11 +325,17 @@ const TouchableMixin = {
evt.dispatchConfig = {};
if (myTag === evt.tag) {
if (evt.eventType === 'focus') {
cmp.touchableHandleActivePressIn &&
if (cmp.touchableHandleActivePressIn) {
console.warn('Using `touchableHandleActivePressIn` or `onPressIn` to listen for focus events is deprecated. Use `touchableHandleFocus` or `onFocus` instead.');
cmp.touchableHandleActivePressIn(evt);
}
cmp.touchableHandleFocus(evt);
} else if (evt.eventType === 'blur') {
cmp.touchableHandleActivePressOut &&
if (cmp.touchableHandleActivePressOut) {
console.warn('Using `touchableHandleActivePressOut` or `onPressOut` to listen for blur events is deprecated. Use `touchableHandleBlur` or `onBlur` instead.');
cmp.touchableHandleActivePressOut(evt);
}
cmp.touchableHandleBlur(evt);
} else if (evt.eventType === 'select') {
cmp.touchableHandlePress &&
!cmp.props.disabled &&
@ -528,6 +534,27 @@ const TouchableMixin = {
}
},
/**
* Invoked when the item receives focus. Mixers might override this to
* visually distinguish the `VisualRect` so that the user knows that it
* currently has the focus. Most platforms only support a single element being
* focused at a time, in which case there may have been a previously focused
* element that was blurred just prior to this.
*/
touchableHandleFocus: function (e: Event) {
this.props.onFocus && this.props.onFocus(e);
},
/**
* Invoked when the item loses focus. Mixers might override this to
* visually distinguish the `VisualRect` so that the user knows that it
* no longer has focus. Most platforms only support a single element being
* focused at a time, in which case the focus may have moved to another.
*/
touchableHandleBlur: function (e: Event) {
this.props.onBlur && this.props.onBlur(e);
},
// ==== Abstract Application Callbacks ====
/**

View File

@ -56,7 +56,6 @@ const TouchableBounce = ((createReactClass({
propTypes: {
...TouchableWithoutFeedback.propTypes,
// The function passed takes a callback to start the animation which should
// be run after this onPress handler is done. You can use this (for example)
// to update UI before starting the animation.

View File

@ -80,6 +80,18 @@ const TouchableWithoutFeedback = ((createReactClass({
PropTypes.oneOf(AccessibilityTraits),
PropTypes.arrayOf(PropTypes.oneOf(AccessibilityTraits)),
]),
/**
* When `accessible` is true (which is the default) this may be called when
* the OS-specific concept of "focus" occurs. Some platforms may not have
* the concept of focus.
*/
onFocus: PropTypes.func,
/**
* When `accessible` is true (which is the default) this may be called when
* the OS-specific concept of "blur" occurs, meaning the element lost focus.
* Some platforms may not have the concept of blur.
*/
onBlur: PropTypes.func,
/**
* If true, disable all interactions for this component.
*/