Skip to content

Commit

Permalink
[Touchable] Expose the touch-retention offset as a prop
Browse files Browse the repository at this point in the history
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 facebook#198
  • Loading branch information
ide committed May 1, 2015
1 parent b99744a commit d5d18eb
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 30 deletions.
32 changes: 23 additions & 9 deletions Libraries/Components/Touchable/TouchableBounce.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
*/
'use strict';

var EdgeInsetsPropType = require('EdgeInsetsPropType');
var NativeMethodsMixin = require('NativeMethodsMixin');
var React = require('React');
var POPAnimation = require('POPAnimation');
Expand All @@ -21,17 +22,16 @@ var merge = require('merge');
var copyProperties = require('copyProperties');
var onlyChild = require('onlyChild');

var TOUCH_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};

type DefaultProps = {
touchRetentionOffset: typeof TOUCH_RETENTION_OFFSET;
};

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};
/**
* Example of using the `TouchableMixin` to play well with other responder
* locking views including `ScrollView`. `TouchableMixin` provides touchable
Expand All @@ -50,6 +50,20 @@ 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.
*/
touchRetentionOffset: EdgeInsetsPropType,
},

getDefaultProps: function(): DefaultProps {
return {
touchRetentionOffset: TOUCH_RETENTION_OFFSET,
};
},

getInitialState: function(): State {
Expand Down Expand Up @@ -114,8 +128,8 @@ var TouchableBounce = React.createClass({
this.props.onPress && this.props.onPress();
},

touchableGetPressRectOffset: function(): typeof PRESS_RECT_OFFSET {
return PRESS_RECT_OFFSET; // Always make sure to predeclare a constant!
touchableGetPressRectOffset: function(): typeof TOUCH_RETENTION_OFFSET {
return this.props.touchRetentionOffset;
},

touchableGetHighlightDelayMS: function(): number {
Expand Down
13 changes: 11 additions & 2 deletions Libraries/Components/Touchable/TouchableHighlight.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

// Note (avik): add @flow when Flow supports spread properties in propTypes

var EdgeInsetsPropType = require('EdgeInsetsPropType');
var NativeMethodsMixin = require('NativeMethodsMixin');
var React = require('React');
var ReactIOSViewAttributes = require('ReactIOSViewAttributes');
Expand All @@ -30,6 +31,7 @@ var onlyChild = require('onlyChild');
var DEFAULT_PROPS = {
activeOpacity: 0.8,
underlayColor: 'black',
touchRetentionOffset: {top: 20, left: 20, right: 20, bottom: 30},
};

/**
Expand Down Expand Up @@ -69,6 +71,14 @@ var TouchableHighlight = React.createClass({
* active.
*/
underlayColor: React.PropTypes.string,
/**
* 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.
*/
touchRetentionOffset: EdgeInsetsPropType,
style: View.propTypes.style,
},

Expand Down Expand Up @@ -153,7 +163,7 @@ var TouchableHighlight = React.createClass({
},

touchableGetPressRectOffset: function() {
return PRESS_RECT_OFFSET; // Always make sure to predeclare a constant!
return this.props.touchRetentionOffset;
},

_showUnderlay: function() {
Expand Down Expand Up @@ -197,7 +207,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 = {
Expand Down
23 changes: 13 additions & 10 deletions Libraries/Components/Touchable/TouchableOpacity.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

// Note (avik): add @flow when Flow supports spread properties in propTypes

var EdgeInsetsPropType = require('EdgeInsetsPropType');
var NativeMethodsMixin = require('NativeMethodsMixin');
var POPAnimationMixin = require('POPAnimationMixin');
var React = require('React');
Expand All @@ -23,6 +24,8 @@ var ensureComponentIsNative = require('ensureComponentIsNative');
var keyOf = require('keyOf');
var onlyChild = require('onlyChild');

var TOUCH_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.
Expand All @@ -44,7 +47,6 @@ var onlyChild = require('onlyChild');
* },
* ```
*/

var TouchableOpacity = React.createClass({
mixins: [Touchable.Mixin, NativeMethodsMixin, POPAnimationMixin],

Expand All @@ -55,11 +57,20 @@ var TouchableOpacity = React.createClass({
* active.
*/
activeOpacity: 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.
*/
touchRetentionOffset: EdgeInsetsPropType,
},

getDefaultProps: function() {
return {
activeOpacity: 0.2,
touchRetentionOffset: TOUCH_RETENTION_OFFSET,
};
},

Expand Down Expand Up @@ -119,7 +130,7 @@ var TouchableOpacity = React.createClass({
},

touchableGetPressRectOffset: function() {
return PRESS_RECT_OFFSET; // Always make sure to predeclare a constant!
return this.props.touchRetentionOffset;
},

touchableGetHighlightDelayMS: function() {
Expand All @@ -141,14 +152,6 @@ 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};

var CHILD_REF = keyOf({childRef: null});

module.exports = TouchableOpacity;
31 changes: 22 additions & 9 deletions Libraries/Components/Touchable/TouchableWithoutFeedback.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,19 @@
*/
'use strict';

var EdgeInsetsPropType = require('EdgeInsetsPropType');
var React = require('React');
var Touchable = require('Touchable');
var onlyChild = require('onlyChild');

/**
* 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 TOUCH_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};

type Event = Object;

type DefaultProps = {
touchRetentionOffset: typeof TOUCH_RETENTION_OFFSET;
};

/**
* Do not use unless you have a very good reason. All the elements that
* respond to press should have a visual feedback when touched. This is
Expand All @@ -42,6 +41,20 @@ var TouchableWithoutFeedback = React.createClass({
onPressIn: React.PropTypes.func,
onPressOut: React.PropTypes.func,
onLongPress: 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.
*/
touchRetentionOffset: EdgeInsetsPropType,
},

getDefaultProps: function(): DefaultProps {
return {
touchRetentionOffset: TOUCH_RETENTION_OFFSET,
}
},

getInitialState: function() {
Expand All @@ -68,8 +81,8 @@ var TouchableWithoutFeedback = React.createClass({
this.props.onLongPress && this.props.onLongPress();
},

touchableGetPressRectOffset: function(): typeof PRESS_RECT_OFFSET {
return PRESS_RECT_OFFSET; // Always make sure to predeclare a constant!
touchableGetPressRectOffset: function(): typeof TOUCH_RETENTION_OFFSET {
return this.props.touchRetentionOffset;
},

touchableGetHighlightDelayMS: function(): number {
Expand Down

0 comments on commit d5d18eb

Please sign in to comment.