You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

206 lines
7.6 KiB

import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
import _createClass from 'babel-runtime/helpers/createClass';
import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
import _inherits from 'babel-runtime/helpers/inherits';
import React from 'react';
import { View, Modal, Animated, TouchableWithoutFeedback, StyleSheet, Dimensions, Easing } from 'react-native';
var styles = StyleSheet.create({
wrap: {
flex: 1,
backgroundColor: 'rgba(0,0,0,0)'
},
mask: {
backgroundColor: 'black',
opacity: .5
},
content: {
backgroundColor: 'white'
},
absolute: {
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0
}
});
var screen = Dimensions.get('window');
var RCModal = function (_React$Component) {
_inherits(RCModal, _React$Component);
function RCModal(props) {
_classCallCheck(this, RCModal);
var _this = _possibleConstructorReturn(this, (RCModal.__proto__ || Object.getPrototypeOf(RCModal)).call(this, props));
_this.animateMask = function (visible) {
_this.stopMaskAnim();
_this.state.opacity.setValue(_this.getOpacity(!visible));
_this.animMask = Animated.timing(_this.state.opacity, {
toValue: _this.getOpacity(visible),
duration: _this.props.animationDuration
});
_this.animMask.start(function () {
_this.animMask = null;
});
};
_this.stopMaskAnim = function () {
if (_this.animMask) {
_this.animMask.stop();
_this.animMask = null;
}
};
_this.stopDialogAnim = function () {
if (_this.animDialog) {
_this.animDialog.stop();
_this.animDialog = null;
}
};
_this.animateDialog = function (visible) {
_this.stopDialogAnim();
_this.animateMask(visible);
var _this$props = _this.props,
animationType = _this$props.animationType,
animationDuration = _this$props.animationDuration;
animationDuration = animationDuration;
if (animationType !== 'none') {
if (animationType === 'slide-up' || animationType === 'slide-down') {
_this.state.position.setValue(_this.getPosition(!visible));
_this.animDialog = Animated.timing(_this.state.position, {
toValue: _this.getPosition(visible),
duration: animationDuration,
easing: visible ? Easing.elastic(0.8) : undefined
});
} else if (animationType === 'fade') {
_this.animDialog = Animated.parallel([Animated.timing(_this.state.opacity, {
toValue: _this.getOpacity(visible),
duration: animationDuration,
easing: visible ? Easing.elastic(0.8) : undefined
}), Animated.spring(_this.state.scale, {
toValue: _this.getScale(visible)
})]);
}
_this.animDialog.start(function () {
_this.animDialog = null;
if (!visible) {
_this.setState({
modalVisible: false
});
}
if (_this.props.onAnimationEnd) {
_this.props.onAnimationEnd(visible);
}
});
} else {
if (!visible) {
_this.setState({
modalVisible: false
});
}
}
};
_this.close = function () {
_this.animateDialog(false);
};
_this.onMaskClose = function () {
if (_this.props.maskClosable && _this.props.onClose) {
_this.props.onClose();
}
};
_this.getPosition = function (visible) {
if (visible) {
return 0;
}
return _this.props.animationType === 'slide-down' ? -screen.height : screen.height;
};
_this.getScale = function (visible) {
return visible ? 1 : 1.05;
};
_this.getOpacity = function (visible) {
return visible ? 1 : 0;
};
var visible = props.visible;
_this.state = {
position: new Animated.Value(_this.getPosition(visible)),
scale: new Animated.Value(_this.getScale(visible)),
opacity: new Animated.Value(_this.getOpacity(visible)),
modalVisible: visible
};
return _this;
}
_createClass(RCModal, [{
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
if (this.shouldComponentUpdate(nextProps, null)) {
this.setState({
modalVisible: true
});
}
}
}, {
key: 'shouldComponentUpdate',
value: function shouldComponentUpdate(nextProps, nextState) {
if (this.props.visible || this.props.visible !== nextProps.visible) {
return true;
}
if (nextState) {
if (nextState.modalVisible !== this.state.modalVisible) {
return true;
}
}
return false;
}
}, {
key: 'componentDidMount',
value: function componentDidMount() {
if (this.props.animateAppear && this.props.animationType !== 'none') {
this.componentDidUpdate({});
}
}
}, {
key: 'componentDidUpdate',
value: function componentDidUpdate(prevProps) {
var props = this.props;
if (prevProps.visible !== props.visible) {
this.animateDialog(props.visible);
}
}
}, {
key: 'render',
value: function render() {
var props = this.props;
if (!this.state.modalVisible) {
return null;
}
var animationStyleMap = {
none: {},
'slide-up': { transform: [{ translateY: this.state.position }] },
'slide-down': { transform: [{ translateY: this.state.position }] },
fade: { transform: [{ scale: this.state.scale }], opacity: this.state.opacity }
};
return React.createElement(Modal, { visible: true, transparent: true, onRequestClose: this.props.onClose, supportedOrientations: ['portrait', 'landscape'] }, React.createElement(View, { style: [styles.wrap, props.wrapStyle] }, React.createElement(TouchableWithoutFeedback, { onPress: this.onMaskClose }, React.createElement(Animated.View, { style: [styles.absolute, { opacity: this.state.opacity }] }, React.createElement(View, { style: [styles.absolute, props.maskStyle] }))), React.createElement(Animated.View, { style: [styles.content, props.style, animationStyleMap[props.animationType]] }, this.props.children)));
}
}]);
return RCModal;
}(React.Component);
export default RCModal;
RCModal.defaultProps = {
wrapStyle: styles.wrap,
maskStyle: styles.mask,
animationType: 'slide-up',
animateAppear: false,
animationDuration: 300,
visible: false,
maskClosable: true,
onClose: function onClose() {},
onAnimationEnd: function onAnimationEnd(_visible) {}
};