From 03f4cb27fb65a3d8fa587353573577ecc55bb238 Mon Sep 17 00:00:00 2001 From: James Ide Date: Mon, 16 Nov 2015 13:51:13 -0800 Subject: [PATCH] Expose the touch-retention offset as a prop Summary: The touch-retention offset defines a rect around a touchable component in which the touch is retained. Easiest way to see this is to touch a button in a real navigation bar and slide your finger out of the range and back in. This diff exposes the offset as a prop (I thought touchRetentionOffset was a more informative name than pressRectOffset) Fixes #198 Closes https://github.com/facebook/react-native/pull/713 Reviewed By: svcscm Differential Revision: D2115370 Pulled By: shayne fb-gh-sync-id: c3f57940dfa3806f9c88df03a01d4d65bb58cf32 --- .../Components/Touchable/TouchableBounce.js | 25 +++++++++++-------- .../Touchable/TouchableHighlight.js | 5 ++-- .../TouchableNativeFeedback.android.js | 5 ++-- .../Components/Touchable/TouchableOpacity.js | 15 +++-------- .../Touchable/TouchableWithoutFeedback.js | 23 ++++++++++------- 5 files changed, 37 insertions(+), 36 deletions(-) diff --git a/Libraries/Components/Touchable/TouchableBounce.js b/Libraries/Components/Touchable/TouchableBounce.js index 487836a29550dc..0b7d91152c764a 100644 --- a/Libraries/Components/Touchable/TouchableBounce.js +++ b/Libraries/Components/Touchable/TouchableBounce.js @@ -12,24 +12,19 @@ 'use strict'; var Animated = require('Animated'); +var EdgeInsetsPropType = require('EdgeInsetsPropType'); var NativeMethodsMixin = require('NativeMethodsMixin'); var React = require('React'); var Touchable = require('Touchable'); -var merge = require('merge'); - type Event = Object; + type State = { animationID: ?number; }; -/** - * When the scroll view is disabled, this defines how far your touch may move - * off of the button, before deactivating the button. Once deactivated, try - * moving it back and you'll see that the button is once again reactivated! - * Move it back and forth several times while the scroll view is disabled. - */ -var PRESS_RECT_OFFSET = {top: 20, left: 20, right: 20, bottom: 30}; +var PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30}; + /** * Example of using the `TouchableMixin` to play well with other responder * locking views including `ScrollView`. `TouchableMixin` provides touchable @@ -50,6 +45,14 @@ var TouchableBounce = React.createClass({ onPressWithCompletion: React.PropTypes.func, // the function passed is called after the animation is complete onPressAnimationComplete: React.PropTypes.func, + /** + * When the scroll view is disabled, this defines how far your touch may + * move off of the button, before deactivating the button. Once deactivated, + * try moving it back and you'll see that the button is once again + * reactivated! Move it back and forth several times while the scroll view + * is disabled. Ensure you pass in a constant to reduce memory allocations. + */ + pressRetentionOffset: EdgeInsetsPropType, }, getInitialState: function(): State { @@ -100,8 +103,8 @@ var TouchableBounce = React.createClass({ this.props.onPress && this.props.onPress(e); }, - touchableGetPressRectOffset: function(): typeof PRESS_RECT_OFFSET { - return PRESS_RECT_OFFSET; // Always make sure to predeclare a constant! + touchableGetPressRectOffset: function(): typeof PRESS_RETENTION_OFFSET { + return this.props.pressRetentionOffset || PRESS_RETENTION_OFFSET; }, touchableGetHighlightDelayMS: function(): number { diff --git a/Libraries/Components/Touchable/TouchableHighlight.js b/Libraries/Components/Touchable/TouchableHighlight.js index 16e3bd289d37d1..b7dc706eb6a071 100644 --- a/Libraries/Components/Touchable/TouchableHighlight.js +++ b/Libraries/Components/Touchable/TouchableHighlight.js @@ -34,6 +34,8 @@ var DEFAULT_PROPS = { underlayColor: 'black', }; +var PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30}; + /** * A wrapper for making views respond properly to touches. * On press down, the opacity of the wrapped view is decreased, which allows @@ -169,7 +171,7 @@ var TouchableHighlight = React.createClass({ }, touchableGetPressRectOffset: function() { - return PRESS_RECT_OFFSET; // Always make sure to predeclare a constant! + return this.props.pressRetentionOffset || PRESS_RETENTION_OFFSET; }, touchableGetHighlightDelayMS: function() { @@ -234,7 +236,6 @@ var TouchableHighlight = React.createClass({ } }); -var PRESS_RECT_OFFSET = {top: 20, left: 20, right: 20, bottom: 30}; var CHILD_REF = keyOf({childRef: null}); var UNDERLAY_REF = keyOf({underlayRef: null}); var INACTIVE_CHILD_PROPS = { diff --git a/Libraries/Components/Touchable/TouchableNativeFeedback.android.js b/Libraries/Components/Touchable/TouchableNativeFeedback.android.js index 4d5bad1df6fff4..a508188c932484 100644 --- a/Libraries/Components/Touchable/TouchableNativeFeedback.android.js +++ b/Libraries/Components/Touchable/TouchableNativeFeedback.android.js @@ -47,7 +47,7 @@ var TouchableView = createReactNativeComponentClass({ uiViewClassName: 'RCTView', }); -var PRESS_RECT_OFFSET = {top: 20, left: 20, right: 20, bottom: 30}; +var PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30}; /** * A wrapper for making views respond properly to touches (Android only). @@ -161,7 +161,8 @@ var TouchableNativeFeedback = React.createClass({ }, touchableGetPressRectOffset: function() { - return PRESS_RECT_OFFSET; // Always make sure to predeclare a constant! + // Always make sure to predeclare a constant! + return this.props.pressRetentionOffset || PRESS_RETENTION_OFFSET; }, touchableGetHighlightDelayMS: function() { diff --git a/Libraries/Components/Touchable/TouchableOpacity.js b/Libraries/Components/Touchable/TouchableOpacity.js index eddf2ff83b9e15..5d7d8f3fbb2802 100644 --- a/Libraries/Components/Touchable/TouchableOpacity.js +++ b/Libraries/Components/Touchable/TouchableOpacity.js @@ -21,10 +21,11 @@ var TouchableWithoutFeedback = require('TouchableWithoutFeedback'); var ensurePositiveDelayProps = require('ensurePositiveDelayProps'); var flattenStyle = require('flattenStyle'); -var keyOf = require('keyOf'); type Event = Object; +var PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30}; + /** * A wrapper for making views respond properly to touches. * On press down, the opacity of the wrapped view is decreased, dimming it. @@ -46,7 +47,6 @@ type Event = Object; * }, * ``` */ - var TouchableOpacity = React.createClass({ mixins: [TimerMixin, Touchable.Mixin, NativeMethodsMixin], @@ -120,7 +120,7 @@ var TouchableOpacity = React.createClass({ }, touchableGetPressRectOffset: function() { - return PRESS_RECT_OFFSET; // Always make sure to predeclare a constant! + return this.props.pressRetentionOffset || PRESS_RETENTION_OFFSET; }, touchableGetHighlightDelayMS: function() { @@ -170,13 +170,4 @@ var TouchableOpacity = React.createClass({ }, }); -/** - * When the scroll view is disabled, this defines how far your touch may move - * off of the button, before deactivating the button. Once deactivated, try - * moving it back and you'll see that the button is once again reactivated! - * Move it back and forth several times while the scroll view is disabled. - */ -var PRESS_RECT_OFFSET = {top: 20, left: 20, right: 20, bottom: 30}; - - module.exports = TouchableOpacity; diff --git a/Libraries/Components/Touchable/TouchableWithoutFeedback.js b/Libraries/Components/Touchable/TouchableWithoutFeedback.js index adfe1fbba8b7c0..8c04c945709ccf 100755 --- a/Libraries/Components/Touchable/TouchableWithoutFeedback.js +++ b/Libraries/Components/Touchable/TouchableWithoutFeedback.js @@ -1,3 +1,4 @@ + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -11,22 +12,18 @@ */ 'use strict'; +var EdgeInsetsPropType = require('EdgeInsetsPropType'); var React = require('React'); var TimerMixin = require('react-timer-mixin'); var Touchable = require('Touchable'); var View = require('View'); var ensurePositiveDelayProps = require('ensurePositiveDelayProps'); +var invariant = require('invariant'); var onlyChild = require('onlyChild'); type Event = Object; -/** - * When the scroll view is disabled, this defines how far your touch may move - * off of the button, before deactivating the button. Once deactivated, try - * moving it back and you'll see that the button is once again reactivated! - * Move it back and forth several times while the scroll view is disabled. - */ -var PRESS_RECT_OFFSET = {top: 20, left: 20, right: 20, bottom: 30}; +var PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30}; /** * Do not use unless you have a very good reason. All the elements that @@ -71,6 +68,14 @@ var TouchableWithoutFeedback = React.createClass({ * Delay in ms, from onPressIn, before onLongPress is called. */ delayLongPress: React.PropTypes.number, + /** + * When the scroll view is disabled, this defines how far your touch may + * move off of the button, before deactivating the button. Once deactivated, + * try moving it back and you'll see that the button is once again + * reactivated! Move it back and forth several times while the scroll view + * is disabled. Ensure you pass in a constant to reduce memory allocations. + */ + pressRetentionOffset: EdgeInsetsPropType, }, getInitialState: function() { @@ -105,8 +110,8 @@ var TouchableWithoutFeedback = React.createClass({ this.props.onLongPress && this.props.onLongPress(e); }, - touchableGetPressRectOffset: function(): typeof PRESS_RECT_OFFSET { - return PRESS_RECT_OFFSET; // Always make sure to predeclare a constant! + touchableGetPressRectOffset: function(): typeof PRESS_RETENTION_OFFSET { + return this.props.pressRetentionOffset || PRESS_RETENTION_OFFSET; }, touchableGetHighlightDelayMS: function(): number {