[Touch] Suite of touchable events on TouchableHighlight/Opacity
Summary: The following props are now supported on TouchableHighlight/Opacity components: - onPress (was there before) - onPressIn - onPressOut - onLongPress There is a `TouchableFeedbackPropType` that is shared amongst the Touchable family for consistency. Added UIExplorer example to demonstrate and test. Fixes #101. Closes https://github.com/facebook/react-native/pull/102 Github Author: James Ide <ide@jameside.com> Test Plan: Imported from GitHub, without a `Test Plan:` line.
This commit is contained in:
Родитель
d0d774d403
Коммит
337329451d
|
@ -12,6 +12,7 @@ var {
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
Text,
|
Text,
|
||||||
TouchableHighlight,
|
TouchableHighlight,
|
||||||
|
TouchableOpacity,
|
||||||
View,
|
View,
|
||||||
} = React;
|
} = React;
|
||||||
|
|
||||||
|
@ -57,6 +58,13 @@ exports.examples = [
|
||||||
render: function() {
|
render: function() {
|
||||||
return <TextOnPressBox />;
|
return <TextOnPressBox />;
|
||||||
},
|
},
|
||||||
|
}, {
|
||||||
|
title: 'Touchable feedback events',
|
||||||
|
description: '<Touchable*> components accept onPress, onPressIn, ' +
|
||||||
|
'onPressOut, and onLongPress as props.',
|
||||||
|
render: function() {
|
||||||
|
return <TouchableFeedbackEvents />;
|
||||||
|
},
|
||||||
}];
|
}];
|
||||||
|
|
||||||
var TextOnPressBox = React.createClass({
|
var TextOnPressBox = React.createClass({
|
||||||
|
@ -95,11 +103,46 @@ var TextOnPressBox = React.createClass({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var TouchableFeedbackEvents = React.createClass({
|
||||||
|
getInitialState: function() {
|
||||||
|
return {
|
||||||
|
eventLog: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<View style={[styles.row, {justifyContent: 'center'}]}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.wrapper}
|
||||||
|
onPress={() => this._appendEvent('press')}
|
||||||
|
onPressIn={() => this._appendEvent('pressIn')}
|
||||||
|
onPressOut={() => this._appendEvent('pressOut')}
|
||||||
|
onLongPress={() => this._appendEvent('longPress')}>
|
||||||
|
<Text style={styles.button}>
|
||||||
|
Press Me
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
<View style={styles.eventLogBox}>
|
||||||
|
{this.state.eventLog.map((e, ii) => <Text key={ii}>{e}</Text>)}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
_appendEvent: function(eventName) {
|
||||||
|
var limit = 6;
|
||||||
|
var eventLog = this.state.eventLog.slice(0, limit - 1);
|
||||||
|
eventLog.unshift(eventName);
|
||||||
|
this.setState({eventLog});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
var heartImage = {uri: 'https://pbs.twimg.com/media/BlXBfT3CQAA6cVZ.png:small'};
|
var heartImage = {uri: 'https://pbs.twimg.com/media/BlXBfT3CQAA6cVZ.png:small'};
|
||||||
|
|
||||||
var styles = StyleSheet.create({
|
var styles = StyleSheet.create({
|
||||||
row: {
|
row: {
|
||||||
alignItems: 'center',
|
justifyContent: 'center',
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
},
|
},
|
||||||
icon: {
|
icon: {
|
||||||
|
@ -113,6 +156,9 @@ var styles = StyleSheet.create({
|
||||||
text: {
|
text: {
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
},
|
},
|
||||||
|
button: {
|
||||||
|
color: '#007AFF',
|
||||||
|
},
|
||||||
wrapper: {
|
wrapper: {
|
||||||
borderRadius: 8,
|
borderRadius: 8,
|
||||||
},
|
},
|
||||||
|
@ -127,6 +173,14 @@ var styles = StyleSheet.create({
|
||||||
borderColor: '#f0f0f0',
|
borderColor: '#f0f0f0',
|
||||||
backgroundColor: '#f9f9f9',
|
backgroundColor: '#f9f9f9',
|
||||||
},
|
},
|
||||||
|
eventLogBox: {
|
||||||
|
padding: 10,
|
||||||
|
margin: 10,
|
||||||
|
height: 120,
|
||||||
|
borderWidth: 1 / PixelRatio.get(),
|
||||||
|
borderColor: '#f0f0f0',
|
||||||
|
backgroundColor: '#f9f9f9',
|
||||||
|
},
|
||||||
textBlock: {
|
textBlock: {
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
color: 'blue',
|
color: 'blue',
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* @providesModule TouchableFeedbackPropType
|
||||||
|
* @flow
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var { PropTypes } = require('React');
|
||||||
|
|
||||||
|
var TouchableFeedbackPropType = {
|
||||||
|
/**
|
||||||
|
* Called when the touch is released, but not if cancelled (e.g. by a scroll
|
||||||
|
* that steals the responder lock).
|
||||||
|
*/
|
||||||
|
onPress: PropTypes.func,
|
||||||
|
onPressIn: PropTypes.func,
|
||||||
|
onPressOut: PropTypes.func,
|
||||||
|
onLongPress: PropTypes.func,
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = TouchableFeedbackPropType;
|
|
@ -11,6 +11,7 @@ var ReactIOSViewAttributes = require('ReactIOSViewAttributes');
|
||||||
var StyleSheet = require('StyleSheet');
|
var StyleSheet = require('StyleSheet');
|
||||||
var TimerMixin = require('TimerMixin');
|
var TimerMixin = require('TimerMixin');
|
||||||
var Touchable = require('Touchable');
|
var Touchable = require('Touchable');
|
||||||
|
var TouchableFeedbackPropType = require('TouchableFeedbackPropType');
|
||||||
var View = require('View');
|
var View = require('View');
|
||||||
|
|
||||||
var cloneWithProps = require('cloneWithProps');
|
var cloneWithProps = require('cloneWithProps');
|
||||||
|
@ -50,6 +51,7 @@ var DEFAULT_PROPS = {
|
||||||
|
|
||||||
var TouchableHighlight = React.createClass({
|
var TouchableHighlight = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
|
...TouchableFeedbackPropType,
|
||||||
/**
|
/**
|
||||||
* Called when the touch is released, but not if cancelled (e.g. by
|
* Called when the touch is released, but not if cancelled (e.g. by
|
||||||
* a scroll that steals the responder lock).
|
* a scroll that steals the responder lock).
|
||||||
|
@ -127,12 +129,14 @@ var TouchableHighlight = React.createClass({
|
||||||
this.clearTimeout(this._hideTimeout);
|
this.clearTimeout(this._hideTimeout);
|
||||||
this._hideTimeout = null;
|
this._hideTimeout = null;
|
||||||
this._showUnderlay();
|
this._showUnderlay();
|
||||||
|
this.props.onPressIn && this.props.onPressIn();
|
||||||
},
|
},
|
||||||
|
|
||||||
touchableHandleActivePressOut: function() {
|
touchableHandleActivePressOut: function() {
|
||||||
if (!this._hideTimeout) {
|
if (!this._hideTimeout) {
|
||||||
this._hideUnderlay();
|
this._hideUnderlay();
|
||||||
}
|
}
|
||||||
|
this.props.onPressOut && this.props.onPressOut();
|
||||||
},
|
},
|
||||||
|
|
||||||
touchableHandlePress: function() {
|
touchableHandlePress: function() {
|
||||||
|
@ -142,6 +146,10 @@ var TouchableHighlight = React.createClass({
|
||||||
this.props.onPress && this.props.onPress();
|
this.props.onPress && this.props.onPress();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
touchableHandleLongPress: function() {
|
||||||
|
this.props.onLongPress && this.props.onLongPress();
|
||||||
|
},
|
||||||
|
|
||||||
touchableGetPressRectOffset: function() {
|
touchableGetPressRectOffset: function() {
|
||||||
return PRESS_RECT_OFFSET; // Always make sure to predeclare a constant!
|
return PRESS_RECT_OFFSET; // Always make sure to predeclare a constant!
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,6 +9,7 @@ var NativeMethodsMixin = require('NativeMethodsMixin');
|
||||||
var POPAnimationMixin = require('POPAnimationMixin');
|
var POPAnimationMixin = require('POPAnimationMixin');
|
||||||
var React = require('React');
|
var React = require('React');
|
||||||
var Touchable = require('Touchable');
|
var Touchable = require('Touchable');
|
||||||
|
var TouchableFeedbackPropType = require('TouchableFeedbackPropType');
|
||||||
|
|
||||||
var cloneWithProps = require('cloneWithProps');
|
var cloneWithProps = require('cloneWithProps');
|
||||||
var ensureComponentIsNative = require('ensureComponentIsNative');
|
var ensureComponentIsNative = require('ensureComponentIsNative');
|
||||||
|
@ -41,11 +42,7 @@ var TouchableOpacity = React.createClass({
|
||||||
mixins: [Touchable.Mixin, NativeMethodsMixin, POPAnimationMixin],
|
mixins: [Touchable.Mixin, NativeMethodsMixin, POPAnimationMixin],
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
/**
|
...TouchableFeedbackPropType,
|
||||||
* Called when the touch is released, but not if cancelled (e.g. by
|
|
||||||
* a scroll that steals the responder lock).
|
|
||||||
*/
|
|
||||||
onPress: React.PropTypes.func,
|
|
||||||
/**
|
/**
|
||||||
* Determines what the opacity of the wrapped view should be when touch is
|
* Determines what the opacity of the wrapped view should be when touch is
|
||||||
* active.
|
* active.
|
||||||
|
@ -97,10 +94,12 @@ var TouchableOpacity = React.createClass({
|
||||||
this.refs[CHILD_REF].setNativeProps({
|
this.refs[CHILD_REF].setNativeProps({
|
||||||
opacity: this.props.activeOpacity
|
opacity: this.props.activeOpacity
|
||||||
});
|
});
|
||||||
|
this.props.onPressIn && this.props.onPressIn();
|
||||||
},
|
},
|
||||||
|
|
||||||
touchableHandleActivePressOut: function() {
|
touchableHandleActivePressOut: function() {
|
||||||
this.setOpacityTo(1.0);
|
this.setOpacityTo(1.0);
|
||||||
|
this.props.onPressOut && this.props.onPressOut();
|
||||||
},
|
},
|
||||||
|
|
||||||
touchableHandlePress: function() {
|
touchableHandlePress: function() {
|
||||||
|
@ -108,6 +107,10 @@ var TouchableOpacity = React.createClass({
|
||||||
this.props.onPress && this.props.onPress();
|
this.props.onPress && this.props.onPress();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
touchableHandleLongPress: function() {
|
||||||
|
this.props.onLongPress && this.props.onLongPress();
|
||||||
|
},
|
||||||
|
|
||||||
touchableGetPressRectOffset: function() {
|
touchableGetPressRectOffset: function() {
|
||||||
return PRESS_RECT_OFFSET; // Always make sure to predeclare a constant!
|
return PRESS_RECT_OFFSET; // Always make sure to predeclare a constant!
|
||||||
},
|
},
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
var React = require('React');
|
var React = require('React');
|
||||||
var Touchable = require('Touchable');
|
var Touchable = require('Touchable');
|
||||||
var View = require('View');
|
var TouchableFeedbackPropType = require('TouchableFeedbackPropType');
|
||||||
|
|
||||||
var copyProperties = require('copyProperties');
|
var copyProperties = require('copyProperties');
|
||||||
var onlyChild = require('onlyChild');
|
var onlyChild = require('onlyChild');
|
||||||
|
@ -29,12 +29,7 @@ var PRESS_RECT_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
|
||||||
var TouchableWithoutFeedback = React.createClass({
|
var TouchableWithoutFeedback = React.createClass({
|
||||||
mixins: [Touchable.Mixin],
|
mixins: [Touchable.Mixin],
|
||||||
|
|
||||||
propTypes: {
|
propTypes: TouchableFeedbackPropType,
|
||||||
onPress: React.PropTypes.func,
|
|
||||||
onPressIn: React.PropTypes.func,
|
|
||||||
onPressOut: React.PropTypes.func,
|
|
||||||
onLongPress: React.PropTypes.func,
|
|
||||||
},
|
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return this.touchableGetInitialState();
|
return this.touchableGetInitialState();
|
||||||
|
|
Загрузка…
Ссылка в новой задаче