UNPKG

react-native-easy-toast-types

Version:

A react native module to show toast like android, it works on iOS and Android.

162 lines (145 loc) 4.19 kB
/** * react-native-easy-toast * https://github.com/crazycodeboy/react-native-easy-toast * Email:crazycodeboy@gmail.com * Blog:http://jiapenghui.com * @flow */ import React, {Component} from 'react'; import { StyleSheet, View, ViewPropTypes as RNViewPropTypes, Animated, Dimensions, Text, } from 'react-native' import PropTypes from 'prop-types'; const ViewPropTypes = RNViewPropTypes || View.propTypes; export const DURATION = { LENGTH_SHORT: 500, FOREVER: 0, }; const {height, width} = Dimensions.get('window'); export default class Toast extends Component { constructor(props) { super(props); this.state = { isShow: false, text: '', opacityValue: new Animated.Value(this.props.opacity), } } show(text, duration, callback) { this.duration = typeof duration === 'number' ? duration : DURATION.LENGTH_SHORT; this.callback = callback; this.setState({ isShow: true, text: text, }); this.animation = Animated.timing( this.state.opacityValue, { toValue: this.props.opacity, duration: this.props.fadeInDuration, } ) this.animation.start(() => { this.isShow = true; if(duration !== DURATION.FOREVER) this.close(); }); } close( duration ) { let delay = typeof duration === 'undefined' ? this.duration : duration; if(delay === DURATION.FOREVER) delay = this.props.defaultCloseDelay || 250; if (!this.isShow && !this.state.isShow) return; this.timer && clearTimeout(this.timer); this.timer = setTimeout(() => { this.animation = Animated.timing( this.state.opacityValue, { toValue: 0.0, duration: this.props.fadeOutDuration, } ) this.animation.start(() => { this.setState({ isShow: false, }); this.isShow = false; if(typeof this.callback === 'function') { this.callback(); } }); }, delay); } componentWillUnmount() { this.animation && this.animation.stop() this.timer && clearTimeout(this.timer); } render() { let pos; switch (this.props.position) { case 'top': pos = this.props.positionValue; break; case 'center': pos = height / 2; break; case 'bottom': pos = height - this.props.positionValue; break; } const view = this.state.isShow ? <View style={[styles.container, { top: pos }]} pointerEvents="none" > <Animated.View style={[styles.content, { opacity: this.state.opacityValue }, this.props.style]} > {React.isValidElement(this.state.text) ? this.state.text : <Text style={this.props.textStyle}>{this.state.text}</Text>} </Animated.View> </View> : null; return view; } } const styles = StyleSheet.create({ container: { position: 'absolute', left: 0, right: 0, elevation: 999, alignItems: 'center', zIndex: 10000, }, content: { backgroundColor: 'black', borderRadius: 5, padding: 10, }, text: { color: 'white' } }); Toast.propTypes = { style: ViewPropTypes.style, position: PropTypes.oneOf([ 'top', 'center', 'bottom', ]), textStyle: Text.propTypes.style, positionValue:PropTypes.number, fadeInDuration:PropTypes.number, fadeOutDuration:PropTypes.number, opacity:PropTypes.number } Toast.defaultProps = { position: 'bottom', textStyle: styles.text, positionValue: 120, fadeInDuration: 500, fadeOutDuration: 500, opacity: 1 }