UNPKG

popup-ui-custom

Version:

Rafael Augusto's React Native Popup UI base project with some updates to be compliant with React 0.70 (fixes deprecated-react-native-prop-types error)

251 lines (235 loc) 5.29 kB
import React, { Component } from 'react' import { View, Text, TouchableOpacity, StyleSheet, Image, Animated, Dimensions, Alert } from 'react-native' const WIDTH = Dimensions.get('screen').width const HEIGHT = Dimensions.get('screen').height class Popup extends Component { static popupInstance static show({ ...config }) { this.popupInstance.start(config) } static hide() { this.popupInstance.hidePopup() } state = { positionView: new Animated.Value(HEIGHT), opacity: new Animated.Value(0), positionPopup: new Animated.Value(HEIGHT), popupHeight: 0 } start({ ...config }) { this.setState({ title: config.title, type: config.type, icon: config.icon !== undefined ? config.icon : false, textBody: config.textBody, button: config.button !== undefined ? config.button : true, buttonText: config.buttonText || 'Ok', callback: config.callback !== undefined ? config.callback : this.defaultCallback(), background: config.background || 'rgba(0, 0, 0, 0.5)', timing: config.timing, autoClose: config.autoClose !== undefined ? config.autoClose : false }) Animated.sequence([ Animated.timing(this.state.positionView, { toValue: 0, duration: 100, useNativeDriver: false }), Animated.timing(this.state.opacity, { toValue: 1, duration: 300, useNativeDriver: false }), Animated.spring(this.state.positionPopup, { toValue: (HEIGHT / 2) - (this.state.popupHeight / 2), bounciness: 15, useNativeDriver: true }) ]).start() if (config.autoClose && config.timing !== 0) { const duration = config.timing > 0 ? config.timing : 5000 setTimeout(() => { this.hidePopup() }, duration) } } hidePopup() { Animated.sequence([ Animated.timing(this.state.positionPopup, { toValue: HEIGHT, duration: 250, useNativeDriver: true }), Animated.timing(this.state.opacity, { toValue: 0, duration: 300, useNativeDriver: false }), Animated.timing(this.state.positionView, { toValue: HEIGHT, duration: 100, useNativeDriver: false }) ]).start() } defaultCallback() { return Alert.alert( 'Callback!', 'Callback complete!', [ { text: 'Ok', onPress: () => this.hidePopup() } ] ) } handleImage(type) { switch (type) { case 'Success': return require('../../assets/Success.png') case 'Danger': return require('../../assets/Error.png') case 'Warning': return require('../../assets/Warning.png') } } render() { const { title, type, textBody, button, buttonText, callback, background } = this.state let el = null; if (this.state.button) { el = <TouchableOpacity style={[styles.Button, styles[type]]} onPress={callback}> <Text style={styles.TextButton}>{buttonText}</Text> </TouchableOpacity> } else { el = <Text></Text> } return ( <Animated.View ref={c => this._root = c} style={[styles.Container, { backgroundColor: background || 'transparent', opacity: this.state.opacity, transform: [ { translateY: this.state.positionView } ] }]}> <Animated.View onLayout={event => { this.setState({ popupHeight: event.nativeEvent.layout.height }) }} style={[styles.Message, { transform: [ { translateY: this.state.positionPopup } ] }]} > <View style={styles.Header} /> { this.state.icon ? (this.state.icon) : <Image source={this.handleImage(type)} resizeMode="contain" style={styles.Image} /> } <View style={styles.Content}> <Text style={styles.Title}>{title}</Text> <Text style={styles.Desc}>{textBody}</Text> {el} </View> </Animated.View> </Animated.View> ) } } const styles = StyleSheet.create({ Container: { position: 'absolute', zIndex: 99999, width: WIDTH, height: HEIGHT, backgroundColor: 'rgba(0, 0, 0, 0.5)', alignItems: 'center', top: 0, left: 0 }, Message: { maxWidth: 300, width: 230, minHeight: 300, backgroundColor: '#fff', borderRadius: 30, alignItems: 'center', overflow: 'hidden', position: 'absolute', }, Content: { padding: 20, alignItems: 'center' }, Header: { height: 230, width: 230, backgroundColor: '#FBFBFB', borderRadius: 100, marginTop: -120 }, Image: { width: 150, height: 80, position: 'absolute', top: 20 }, Title: { fontWeight: 'bold', fontSize: 18, color: '#333' }, Desc: { textAlign: 'center', color: '#666', marginTop: 10 }, Button: { borderRadius: 50, height: 40, width: 130, justifyContent: 'center', alignItems: 'center', marginTop: 30 }, TextButton: { color: '#fff', fontWeight: 'bold' }, Success: { backgroundColor: '#AAF577', shadowColor: "#AAF577", shadowOffset: { width: 0, height: 5, }, shadowOpacity: 0.36, shadowRadius: 6.68, elevation: 11 }, Danger: { backgroundColor: '#F29091', shadowColor: "#F29091", shadowOffset: { width: 0, height: 5, }, shadowOpacity: 0.36, shadowRadius: 6.68, elevation: 11 }, Warning: { backgroundColor: '#fbd10d', shadowColor: "#fbd10d", shadowOffset: { width: 0, height: 5, }, shadowOpacity: 0.36, shadowRadius: 6.68, elevation: 11 } }) export default Popup