mirror of
https://github.com/status-im/react-native.git
synced 2025-01-10 09:35:48 +00:00
f7f347329e
Summary: <!-- Thank you for sending the PR! We appreciate you spending the time to work on these changes. Help us understand your motivation by explaining why you decided to make this change. You can learn more about contributing to React Native here: http://facebook.github.io/react-native/docs/contributing.html Happy contributing! --> Adding example on components section with [react-native-web-player](https://github.com/dabbott/react-native-web-player) - ActivityIndicator - TouchableOpacity - TouchableHighlight Screenshot on http://localhost:8079/react-native/docs/activityindicator.html ![react-native-activityindicator](https://user-images.githubusercontent.com/13135332/30432801-adca0982-9988-11e7-8e70-94ad9e42ea43.png) Screenshot on http://localhost:8079/react-native/docs/touchableopacity.html ![react-native-touchableopacity](https://user-images.githubusercontent.com/13135332/30432718-80570554-9988-11e7-9c81-15ab98327fed.png) Screenshot on http://localhost:8079/react-native/docs/touchablehighlight.html ![react-native-touchablehighlight](https://user-images.githubusercontent.com/13135332/30432733-8290fbb8-9988-11e7-94a1-86c3166e544d.png) Closes https://github.com/facebook/react-native/pull/15950 Differential Revision: D5881366 Pulled By: hramos fbshipit-source-id: 2926071723defedf9ed5cb1b1128204256c71dd9
265 lines
7.0 KiB
JavaScript
265 lines
7.0 KiB
JavaScript
/**
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule TouchableOpacity
|
|
* @noflow
|
|
*/
|
|
'use strict';
|
|
|
|
// Note (avik): add @flow when Flow supports spread properties in propTypes
|
|
|
|
var Animated = require('Animated');
|
|
var Easing = require('Easing');
|
|
var NativeMethodsMixin = require('NativeMethodsMixin');
|
|
var React = require('React');
|
|
var PropTypes = require('prop-types');
|
|
var TimerMixin = require('react-timer-mixin');
|
|
var Touchable = require('Touchable');
|
|
var TouchableWithoutFeedback = require('TouchableWithoutFeedback');
|
|
|
|
var createReactClass = require('create-react-class');
|
|
var ensurePositiveDelayProps = require('ensurePositiveDelayProps');
|
|
var flattenStyle = require('flattenStyle');
|
|
|
|
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.
|
|
*
|
|
* Opacity is controlled by wrapping the children in an Animated.View, which is
|
|
* added to the view hiearchy. Be aware that this can affect layout.
|
|
*
|
|
* Example:
|
|
*
|
|
* ```
|
|
* renderButton: function() {
|
|
* return (
|
|
* <TouchableOpacity onPress={this._onPressButton}>
|
|
* <Image
|
|
* style={styles.button}
|
|
* source={require('./myButton.png')}
|
|
* />
|
|
* </TouchableOpacity>
|
|
* );
|
|
* },
|
|
* ```
|
|
* ### Example
|
|
*
|
|
* ```ReactNativeWebPlayer
|
|
* import React, { Component } from 'react'
|
|
* import {
|
|
* AppRegistry,
|
|
* StyleSheet,
|
|
* TouchableOpacity,
|
|
* Text,
|
|
* View,
|
|
* } from 'react-native'
|
|
*
|
|
* class App extends Component {
|
|
* constructor(props) {
|
|
* super(props)
|
|
* this.state = { count: 0 }
|
|
* }
|
|
*
|
|
* onPress = () => {
|
|
* this.setState({
|
|
* count: this.state.count+1
|
|
* })
|
|
* }
|
|
*
|
|
* render() {
|
|
* return (
|
|
* <View style={styles.container}>
|
|
* <TouchableOpacity
|
|
* style={styles.button}
|
|
* onPress={this.onPress}
|
|
* >
|
|
* <Text> Touch Here </Text>
|
|
* </TouchableOpacity>
|
|
* <View style={[styles.countContainer]}>
|
|
* <Text style={[styles.countText]}>
|
|
* { this.state.count !== 0 ? this.state.count: null}
|
|
* </Text>
|
|
* </View>
|
|
* </View>
|
|
* )
|
|
* }
|
|
* }
|
|
*
|
|
* const styles = StyleSheet.create({
|
|
* container: {
|
|
* flex: 1,
|
|
* justifyContent: 'center',
|
|
* paddingHorizontal: 10
|
|
* },
|
|
* button: {
|
|
* alignItems: 'center',
|
|
* backgroundColor: '#DDDDDD',
|
|
* padding: 10
|
|
* },
|
|
* countContainer: {
|
|
* alignItems: 'center',
|
|
* padding: 10
|
|
* },
|
|
* countText: {
|
|
* color: '#FF00FF'
|
|
* }
|
|
* })
|
|
*
|
|
* AppRegistry.registerComponent('App', () => App)
|
|
* ```
|
|
*
|
|
*/
|
|
var TouchableOpacity = createReactClass({
|
|
displayName: 'TouchableOpacity',
|
|
mixins: [TimerMixin, Touchable.Mixin, NativeMethodsMixin],
|
|
|
|
propTypes: {
|
|
...TouchableWithoutFeedback.propTypes,
|
|
/**
|
|
* Determines what the opacity of the wrapped view should be when touch is
|
|
* active. Defaults to 0.2.
|
|
*/
|
|
activeOpacity: PropTypes.number,
|
|
/**
|
|
* Apple TV parallax effects
|
|
*/
|
|
tvParallaxProperties: PropTypes.object,
|
|
},
|
|
|
|
getDefaultProps: function() {
|
|
return {
|
|
activeOpacity: 0.2,
|
|
};
|
|
},
|
|
|
|
getInitialState: function() {
|
|
return {
|
|
...this.touchableGetInitialState(),
|
|
anim: new Animated.Value(this._getChildStyleOpacityWithDefault()),
|
|
};
|
|
},
|
|
|
|
componentDidMount: function() {
|
|
ensurePositiveDelayProps(this.props);
|
|
},
|
|
|
|
componentWillReceiveProps: function(nextProps) {
|
|
ensurePositiveDelayProps(nextProps);
|
|
},
|
|
|
|
/**
|
|
* Animate the touchable to a new opacity.
|
|
*/
|
|
setOpacityTo: function(value: number, duration: number) {
|
|
Animated.timing(
|
|
this.state.anim,
|
|
{
|
|
toValue: value,
|
|
duration: duration,
|
|
easing: Easing.inOut(Easing.quad),
|
|
useNativeDriver: true,
|
|
}
|
|
).start();
|
|
},
|
|
|
|
/**
|
|
* `Touchable.Mixin` self callbacks. The mixin will invoke these if they are
|
|
* defined on your component.
|
|
*/
|
|
touchableHandleActivePressIn: function(e: Event) {
|
|
if (e.dispatchConfig.registrationName === 'onResponderGrant') {
|
|
this._opacityActive(0);
|
|
} else {
|
|
this._opacityActive(150);
|
|
}
|
|
this.props.onPressIn && this.props.onPressIn(e);
|
|
},
|
|
|
|
touchableHandleActivePressOut: function(e: Event) {
|
|
this._opacityInactive(250);
|
|
this.props.onPressOut && this.props.onPressOut(e);
|
|
},
|
|
|
|
touchableHandlePress: function(e: Event) {
|
|
this.props.onPress && this.props.onPress(e);
|
|
},
|
|
|
|
touchableHandleLongPress: function(e: Event) {
|
|
this.props.onLongPress && this.props.onLongPress(e);
|
|
},
|
|
|
|
touchableGetPressRectOffset: function() {
|
|
return this.props.pressRetentionOffset || PRESS_RETENTION_OFFSET;
|
|
},
|
|
|
|
touchableGetHitSlop: function() {
|
|
return this.props.hitSlop;
|
|
},
|
|
|
|
touchableGetHighlightDelayMS: function() {
|
|
return this.props.delayPressIn || 0;
|
|
},
|
|
|
|
touchableGetLongPressDelayMS: function() {
|
|
return this.props.delayLongPress === 0 ? 0 :
|
|
this.props.delayLongPress || 500;
|
|
},
|
|
|
|
touchableGetPressOutDelayMS: function() {
|
|
return this.props.delayPressOut;
|
|
},
|
|
|
|
_opacityActive: function(duration: number) {
|
|
this.setOpacityTo(this.props.activeOpacity, duration);
|
|
},
|
|
|
|
_opacityInactive: function(duration: number) {
|
|
this.setOpacityTo(
|
|
this._getChildStyleOpacityWithDefault(),
|
|
duration
|
|
);
|
|
},
|
|
|
|
_getChildStyleOpacityWithDefault: function() {
|
|
var childStyle = flattenStyle(this.props.style) || {};
|
|
return childStyle.opacity == undefined ? 1 : childStyle.opacity;
|
|
},
|
|
|
|
render: function() {
|
|
return (
|
|
<Animated.View
|
|
accessible={this.props.accessible !== false}
|
|
accessibilityLabel={this.props.accessibilityLabel}
|
|
accessibilityComponentType={this.props.accessibilityComponentType}
|
|
accessibilityTraits={this.props.accessibilityTraits}
|
|
style={[this.props.style, {opacity: this.state.anim}]}
|
|
nativeID={this.props.nativeID}
|
|
testID={this.props.testID}
|
|
onLayout={this.props.onLayout}
|
|
isTVSelectable={true}
|
|
tvParallaxProperties={this.props.tvParallaxProperties}
|
|
hitSlop={this.props.hitSlop}
|
|
onStartShouldSetResponder={this.touchableHandleStartShouldSetResponder}
|
|
onResponderTerminationRequest={this.touchableHandleResponderTerminationRequest}
|
|
onResponderGrant={this.touchableHandleResponderGrant}
|
|
onResponderMove={this.touchableHandleResponderMove}
|
|
onResponderRelease={this.touchableHandleResponderRelease}
|
|
onResponderTerminate={this.touchableHandleResponderTerminate}>
|
|
{this.props.children}
|
|
{Touchable.renderDebugView({color: 'cyan', hitSlop: this.props.hitSlop})}
|
|
</Animated.View>
|
|
);
|
|
},
|
|
});
|
|
|
|
module.exports = TouchableOpacity;
|