UNPKG

react-native-easy-toast

Version:

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

171 lines (154 loc) 4.58 kB
/** * react-native-easy-toast * https://github.com/crazycodeboy/react-native-easy-toast * Email:crazycodeboy@gmail.com * Blog:https://www.devio.org/ * @flow */ import React, { Component } from 'react'; import { StyleSheet, View, Animated, Dimensions, Text, TouchableWithoutFeedback } from 'react-native' import PropTypes, { any } from 'prop-types'; 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, onPress) { this.duration = typeof duration === 'number' ? duration : DURATION.LENGTH_SHORT; this.callback = callback; console.log(typeof onPress) if (typeof onPress === 'function') this.onPress = onPress this.setState({ isShow: true, text: text, }); this.animation = Animated.timing( this.state.opacityValue, { toValue: this.props.opacity, duration: this.props.fadeInDuration, useNativeDriver: this.props.useNativeAnimation } ) 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, useNativeDriver: this.props.useNativeAnimation } ) 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 ? <TouchableWithoutFeedback onPress={this.onPress} > <View style={[styles.container, { top: pos }]} pointerEvents="auto" > <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> </TouchableWithoutFeedback> : 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: any, position: PropTypes.oneOf([ 'top', 'center', 'bottom', ]), textStyle: any, positionValue: PropTypes.number, fadeInDuration: PropTypes.number, fadeOutDuration: PropTypes.number, opacity: PropTypes.number, useNativeAnimation: PropTypes.bool } Toast.defaultProps = { position: 'bottom', textStyle: styles.text, positionValue: 120, fadeInDuration: 500, fadeOutDuration: 500, opacity: 1, useNativeAnimation: false }