UNPKG

ignite-router-flux

Version:

Infinite Red's hot boilerplate for React Native.

232 lines (199 loc) 5.81 kB
import React, { Component } from 'react' import { Text, Animated, View, TouchableOpacity, TouchableWithoutFeedback, ActivityIndicator, BackAndroid, BackHandler } from 'react-native' import PropTypes from 'prop-types' import styles from './AlertStyle' const HwBackHandler = BackHandler || BackAndroid const HW_BACK_EVENT = 'hardwareBackPress' export default class Alert extends Component { constructor (props) { super(props) const { show } = this.props this.springValue = new Animated.Value(0.3) this.state = { showSelf: false } if (show) this._springShow(true) } componentDidMount () { HwBackHandler.addEventListener(HW_BACK_EVENT, this._handleHwBackEvent) } _springShow = fromConstructor => { this._toggleAlert(fromConstructor) Animated.spring(this.springValue, { toValue: 1, bounciness: 10 }).start() }; _springHide = () => { if (this.state.showSelf === true) { Animated.spring(this.springValue, { toValue: 0, tension: 10 }).start() setTimeout(() => { this._toggleAlert() this._onDismiss() }, 70) } }; _toggleAlert = fromConstructor => { if (fromConstructor) this.state = { showSelf: true } else this.setState({ showSelf: !this.state.showSelf }) }; _handleHwBackEvent = () => { const { closeOnHardwareBackPress } = this.props if (this.state.showSelf && closeOnHardwareBackPress) { this._springHide() return true } else if (!closeOnHardwareBackPress && this.state.showSelf) { return true } return false }; _onTapOutside = () => { const { closeOnTouchOutside } = this.props if (closeOnTouchOutside) this._springHide() }; _onDismiss = () => { const { onDismiss } = this.props onDismiss && onDismiss() }; _renderButton = data => { const { text, backgroundColor, buttonStyle, buttonTextStyle, onPress } = data return ( <TouchableOpacity activeOpacity={0.7} onPress={onPress} style={[styles.button, { backgroundColor }, buttonStyle]}> <Text style={[styles.buttonText, buttonTextStyle]}>{text}</Text> </TouchableOpacity> ) }; _renderAlert = () => { const animation = { transform: [{ scale: this.springValue }] } const { showProgress } = this.props const { title, message, customView = null } = this.props const { showCancelButton, cancelText, cancelButtonColor, cancelButtonStyle, cancelButtonTextStyle, onCancelPressed } = this.props const { showConfirmButton, confirmText, confirmButtonColor, confirmButtonStyle, confirmButtonTextStyle, onConfirmPressed } = this.props const { alertContainerStyle, overlayStyle, progressSize, progressColor, contentContainerStyle, titleStyle, messageStyle } = this.props const cancelButtonData = { text: cancelText, backgroundColor: cancelButtonColor, buttonStyle: [styles.buttonCancel, cancelButtonStyle], buttonTextStyle: cancelButtonTextStyle, onPress: onCancelPressed } const confirmButtonData = { text: confirmText, backgroundColor: confirmButtonColor, buttonStyle: confirmButtonStyle, buttonTextStyle: confirmButtonTextStyle, onPress: onConfirmPressed } return ( <View style={[styles.container, alertContainerStyle]}> <TouchableWithoutFeedback onPress={this._onTapOutside}> <View style={[styles.overlay, overlayStyle]} /> </TouchableWithoutFeedback> <Animated.View style={[styles.contentContainer, animation, contentContainerStyle]} > <View style={styles.content}> {showProgress ? ( <ActivityIndicator size={progressSize} color={progressColor} /> ) : null} {title ? ( <Text style={[styles.title, titleStyle]}>{title}</Text> ) : null} {message ? ( <Text style={[styles.message, messageStyle]}>{message}</Text> ) : null} {customView} </View> <View style={styles.action}> {showCancelButton ? this._renderButton(cancelButtonData) : null} {showConfirmButton ? this._renderButton(confirmButtonData) : null} </View> </Animated.View> </View> ) }; render () { const { showSelf } = this.state if (showSelf) return this._renderAlert() return null } componentWillReceiveProps (nextProps) { const { show } = nextProps const { showSelf } = this.state if (show && !showSelf) this._springShow() else if (show === false && showSelf) this._springHide() } componentWillUnmount () { HwBackHandler.removeEventListener(HW_BACK_EVENT, this._handleHwBackEvent) } } Alert.propTypes = { show: PropTypes.bool, showProgress: PropTypes.bool, title: PropTypes.string, message: PropTypes.string, closeOnTouchOutside: PropTypes.bool, closeOnHardwareBackPress: PropTypes.bool, showCancelButton: PropTypes.bool, showConfirmButton: PropTypes.bool, cancelText: PropTypes.string, confirmText: PropTypes.string, cancelButtonColor: PropTypes.string, confirmButtonColor: PropTypes.string, onCancelPressed: PropTypes.func, onConfirmPressed: PropTypes.func, customView: PropTypes.object } Alert.defaultProps = { show: false, showProgress: false, closeOnTouchOutside: true, closeOnHardwareBackPress: true, showCancelButton: false, showConfirmButton: false, cancelText: 'Cancel', confirmText: 'OK', cancelButtonColor: 'transparent', confirmButtonColor: 'transparent', customView: null }