UNPKG

rn-poptoast

Version:

A zero-config, provider-free popup toast library for React Native — fast, lightweight, and beautiful

133 lines (123 loc) 3.36 kB
import React, { useEffect, useState } from "react"; import { Modal, StyleSheet, Text, View } from "react-native"; import LottieView from "lottie-react-native"; import error from "../../../assets/animations/Error.json"; import success from "../../../assets/animations/Success.json"; import warning from "../../../assets/animations/Warning.json"; import { Feather } from "@expo/vector-icons"; import { fonts } from "../../config/fonts"; import { colors } from "../../config/colors"; let showToast; const ToastContainer = () => { const [visible, setVisible] = useState(false); const [toastData, setToastData] = useState({ title: "error", message: "" }); useEffect(() => { showToast = ({ title, message }) => { setToastData({ title, message }); setVisible(true); }; }, []); useEffect(() => { if (visible) { const timer = setTimeout(() => { setVisible(false); }, 3000); return () => clearTimeout(timer); } }, [visible]); const getIcon = () => { switch (toastData.title) { case "success": return success; case "warning": return warning; default: return error; } }; return ( <Modal visible={visible} animationType="slide" transparent> <View style={styles.overlay}> <View style={[styles.content, styles.categoryShadow]}> <View style={styles.titleCont}> <Text style={styles.modaltitle}>{toastData.title}</Text> </View> <LottieView source={getIcon()} autoPlay loop resizeMode="cover" style={styles.jsonIcon} /> <Text style={styles.title}>{toastData.message}</Text> <View style={styles.iconCont}> <Feather onPress={() => setVisible(false)} name="x-circle" size={32} color={colors.white} /> </View> </View> </View> </Modal> ); }; export const triggerToast = (message, options = {}) => { if (typeof showToast === "function") { showToast({ title: options.title || "error", message, }); } else { console.warn("Toast is not mounted yet."); } }; export default ToastContainer; const styles = StyleSheet.create({ overlay: { flex: 1, backgroundColor: "#00000099", justifyContent: "center", alignItems: "center", }, titleCont: { backgroundColor: colors.black, height: 50, width: "100%", borderTopLeftRadius: 20, borderTopRightRadius: 20, justifyContent: "center", alignItems: "center", paddingHorizontal: 16, }, modaltitle: { fontSize: 18, fontFamily: fonts.dmSansBold, color: colors.white, textTransform: "capitalize", }, content: { width: 300, backgroundColor: colors.white, borderRadius: 20, alignItems: "center", paddingBottom: 20, position: "relative", }, jsonIcon: { height: 120, width: 120, }, title: { fontSize: 18, fontFamily: fonts.dmSansBold, color: colors.black500, paddingHorizontal: 16, textAlign: "center", textTransform: "capitalize", }, categoryShadow: { shadowColor: colors.black, shadowOffset: { width: 0, height: 1 }, shadowOpacity: 0.16, shadowRadius: 1.51, elevation: 2, }, iconCont: { alignItems: "center", justifyContent: "center", position: "absolute", bottom: -40, left: 130, }, });