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
JavaScript
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,
},
});