UNPKG

citong-react-web

Version:

A framework for building web apps with React

195 lines (166 loc) 5.87 kB
/** * Copyright (c) 2015-present, Alibaba Group Holding Limited. * All rights reserved. * * Copyright (c) 2015, Facebook, Inc. All rights reserved. * * @providesModule ReactTouchableOpacity */ 'use strict'; import Animated from 'ReactAnimated'; import React from 'react'; import TimerMixin from 'react-timer-mixin'; import { Mixin as TouchableMixin } from 'ReactTouchable'; import TouchableWithoutFeedback from 'ReactTouchableWithoutFeedback'; import { Mixin as NativeMethodsMixin } from 'NativeMethodsMixin'; import mixin from 'react-mixin'; import autobind from 'autobind-decorator'; import StyleSheet from 'ReactStyleSheet'; // var ensurePositiveDelayProps = require('ensurePositiveDelayProps'); var flattenStyle = require('ReactFlattenStyle'); type Event = Object; /** * A wrapper for making views respond properly to touches. * On press down, the opacity of the wrapped view is decreased, dimming it. * This is done without actually changing the view hierarchy, and in general is * easy to add to an app without weird side-effects. * * Example: * * ``` * renderButton: function() { * return ( * <TouchableOpacity onPress={this._onPressButton}> * <Image * style={styles.button} * source={require('image!myButton')} * /> * </TouchableOpacity> * ); * }, * ``` */ const DEFAULT_PROPS = { activeOpacity: 0.2, style: StyleSheet.create({ cursor: 'pointer' }) } class TouchableOpacity extends React.Component { static propTypes = { ...TouchableWithoutFeedback.propTypes, /** * Determines what the opacity of the wrapped view should be when touch is * active. */ activeOpacity: React.PropTypes.number, }; static defaultProps = DEFAULT_PROPS; state = { ...this.touchableGetInitialState(), anim: new Animated.Value(1), } // componentDidMount: function() { // // ensurePositiveDelayProps(this.props); // }, componentWillReceiveProps(nextProps) { // ensurePositiveDelayProps(nextProps); } setOpacityTo(value) { Animated.timing( this.state.anim, {toValue: value, duration: 150} ).start(); } /** * `Touchable.Mixin` self callbacks. The mixin will invoke these if they are * defined on your component. */ touchableHandleActivePressIn(e: Event) { this.clearTimeout(this._hideTimeout); this._hideTimeout = null; this._opacityActive(); this.props.onPressIn && this.props.onPressIn(e); } touchableHandleActivePressOut(e: Event) { if (!this._hideTimeout) { this._opacityInactive(); } this.props.onPressOut && this.props.onPressOut(e); } touchableHandlePress(e: Event) { this.clearTimeout(this._hideTimeout); this._opacityActive(); this._hideTimeout = this.setTimeout( this._opacityInactive, this.props.delayPressOut || 100 ); var touchBank = e.touchHistory.touchBank[e.touchHistory.indexOfSingleActiveTouch]; if (touchBank) { var offset = Math.sqrt(Math.pow(touchBank.startPageX - touchBank.currentPageX, 2) + Math.pow(touchBank.startPageY - touchBank.currentPageY, 2)); var velocity = (offset / (touchBank.currentTimeStamp - touchBank.startTimeStamp)) * 1000; if (velocity < 100) this.props.onPress && this.props.onPress(e); } else { this.props.onPress && this.props.onPress(e); } } touchableHandleLongPress(e: Event) { this.props.onLongPress && this.props.onLongPress(e); } touchableGetPressRectOffset() { return PRESS_RECT_OFFSET; // Always make sure to predeclare a constant! } touchableGetHighlightDelayMS() { return this.props.delayPressIn || 0; } touchableGetLongPressDelayMS() { return this.props.delayLongPress === 0 ? 0 : this.props.delayLongPress || 500; } touchableGetPressOutDelayMS() { return this.props.delayPressOut; } _opacityActive() { this.setOpacityTo(this.props.activeOpacity); } _opacityInactive() { this.clearTimeout(this._hideTimeout); this._hideTimeout = null; var childStyle = flattenStyle(this.props.style) || {}; this.setOpacityTo( childStyle.opacity === undefined ? 1 : childStyle.opacity ); } render() { return ( <Animated.View accessible={true} accessibilityComponentType={this.props.accessibilityComponentType} accessibilityTraits={this.props.accessibilityTraits} style={[DEFAULT_PROPS.style, this.props.style, {opacity: this.state.anim}]} testID={this.props.testID} onLayout={this.props.onLayout} onStartShouldSetResponder={this.touchableHandleStartShouldSetResponder} onResponderTerminationRequest={this.touchableHandleResponderTerminationRequest} onResponderGrant={this.touchableHandleResponderGrant} onResponderMove={this.touchableHandleResponderMove} onResponderRelease={this.touchableHandleResponderRelease} onResponderTerminate={this.touchableHandleResponderTerminate}> {this.props.children} </Animated.View> ); } }; /** * 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}; mixin.onClass(TouchableOpacity, TimerMixin); mixin.onClass(TouchableOpacity, TouchableMixin); mixin.onClass(TouchableOpacity, NativeMethodsMixin); autobind(TouchableOpacity); module.exports = TouchableOpacity;