rafaelaugustos / react-native-popup-ui

A simple and fully customizable React Native component that implements a popup UI.
Apache License 2.0
401 stars 64 forks source link

Update Toast #24

Open njavilas2015 opened 3 years ago

njavilas2015 commented 3 years ago

hi sorry for my short contribution, i updated the toast to hooks good night

`import React, { useState, useRef } from 'react'; import { View, Animated, Text, StyleSheet, Dimensions, Image, Button } from 'react-native';

const { width, height } = Dimensions.get('screen');

const Toast = ({ title, text, icon, color, duration }) => {

const [toast, setToast] = useState(new Animated.Value(height));
const [time, setTime] = useState(new Animated.Value((90 * width) / 100));
const [currentTime, setCurrentTime] = useState(0);

const viewAnimation = useRef(null);

const styles = StyleSheet.create({
    toast: {
        position: 'absolute',
        width: '90%',
        alignSelf: 'center',
        borderRadius: 5,
        minHeight: 100,
        shadowColor: '#ccc',
        alignItems: 'center',
        shadowOffset: { width: 0, height: 2 },
        shadowOpacity: 0.25,
        shadowRadius: 3.84,
        elevation: 5,
        flexDirection: 'row',
    },
    timing: {
        borderBottomRightRadius: 5,
        borderBottomLeftRadius: 5,
        height: 10,
        width: '100%',
        backgroundColor: 'rgba(255, 255, 255, 0.5)',
        position: 'absolute',
        bottom: 0,
        left: 0,
    },
    content: {
        flex: 1,
        paddingLeft: 20,
        paddingRight: 20,
    },
    title: {
        color: '#fff',
        fontWeight: 'bold',
        fontSize: 16,
    },
    subtitle: {
        marginTop: 5,
        fontSize: 13,
        color: '#fff',
        fontWeight: '400',
    },
    img: {
        resizeMode: 'contain',
        width: 20,
        height: 20,
    },
    iconStatus: {
        width: 40,
        height: 40,
        // backgroundColor: '#fff',
        borderRadius: 50,
        marginLeft: 20,
        justifyContent: 'center',
        alignItems: 'center',
    },
});

const getPercentage = (percentage, value) => (percentage * value) / 100;

const start = () => {
    console.log('comenzo');
    Animated.spring(toast, { toValue: height - 190, bounciness: 15, useNativeDriver: true }).start();
    setTimeout(() => {hideToast(); console.log('ha terminado');}, duration);
};

const runCurrentTime = () => {
    let interval = setInterval(() => {
        if (currentTime >= 5) { clearInterval(interval); }
        else {
            setCurrentTime(currentTime + 1);
            runTiming();
        }
    }, 1000);
};

const runTiming = () => Animated.timing(time, { toValue: getPercentage(90, width) - getPercentage(90, width) / currentTime }).start();

const hideToast = () => Animated.timing(toast, { toValue: height + 500, duration: 300, useNativeDriver: true }).start();

return (
    <>
        <Animated.View
            ref={viewAnimation}
            style={[
                styles.toast,
                { backgroundColor: color, transform: [{ translateY: toast }] },
            ]}
        >
            <View style={[styles.iconStatus]}>
                <Image source={icon} />
            </View>
            <View style={styles.content}>
                <Text style={[styles.title]}>{title}</Text>
                <Text style={styles.subtitle}>{text}</Text>
            </View>

            <Animated.View style={[styles.timing, { width: time }]} />
        </Animated.View>
        <Button title={'iniciar evento'} onPress={() => start()}/>
    </>
);

};

export default Toast; `

njavilas2015 commented 3 years ago

popup.js

import React, { useState } from 'react'; import { View, Text, TouchableOpacity, StyleSheet, Image, Animated, Dimensions, Button } from 'react-native';

import { useTheme } from 'react-native-paper';

const { height, width } = Dimensions.get('screen');

const Popup = ({ title, type, icon, textBody, button, buttonText, callback, background, duration, autoClose }) => { const { colors } = useTheme();

const [positionView, setPositionView] = useState(new Animated.Value(height));
const [opacity, setOpacity] = useState(new Animated.Value(0));
const [positionPopup, setPositionPopup] = useState(new Animated.Value(height));
const [popupHeight, setPopupHeight] = useState(0);

const styles = StyleSheet.create({
    Container: {
        position: 'absolute',
        zIndex: 99999,
        width: width,
        height: height,
        backgroundColor: 'rgba(0, 0, 0, 0.5)',
        alignItems: 'center',
        top: -70,
        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,
    },
});

const start = () => {

    Animated.sequence([
        Animated.timing(positionView, { toValue: 0, duration: 100, useNativeDriver: false }),
        Animated.timing(opacity, { toValue: 1, duration: 300, useNativeDriver: false }),
        Animated.spring(positionPopup, {
            toValue: (height / 2) - (popupHeight / 2),
            bounciness: 15, useNativeDriver: true,
        }),
    ]).start();

    if (autoClose && duration !== 0) { setTimeout(() => hidePopup(), duration); }
};

const hidePopup = () => Animated.sequence([
    Animated.timing(positionPopup, { toValue: height, duration: 250, useNativeDriver: true }),
    Animated.timing(opacity, { toValue: 0, duration: 300, useNativeDriver: false }),
    Animated.timing(positionView, { toValue: height, duration: 100, useNativeDriver: false }),
]).start();

return (
    <>
        <Animated.View
            style={[styles.Container, {
                backgroundColor: background || 'transparent',
                opacity: opacity,
                transform: [{ translateY: positionView }],
            }]}>
            <Animated.View
                onLayout={event => setPopupHeight(event.nativeEvent.layout.height)}
                style={[styles.Message, { transform: [{ translateY: positionPopup }] }]}
            >
                <View style={styles.Header} />

                <Image source={icon} resizeMode="contain" style={styles.Image} />

                <View style={styles.Content}>
                    <Text style={styles.Title}>{title}</Text>
                    <Text style={styles.Desc}>{textBody}</Text>
                    {
                        button ?
                            <TouchableOpacity style={[styles.Button, styles[type]]} onPress={() => callback()}>
                                <Text style={styles.TextButton}>{buttonText}</Text>
                            </TouchableOpacity> : null
                    }
                </View>
            </Animated.View>
        </Animated.View>
        <Button title={'open animated'} onPress={() => start()} />
    </>
);

};

export default Popup;