Files
klatab/common/Toast.tsx

89 lines
2.3 KiB
TypeScript

import * as React from "react";
import { Animated, StyleSheet, Text, View } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { ToastType, useToast } from "./ToastProvider";
const fadeDuration = 300;
export const Toast: React.FC = () => {
const insets = useSafeAreaInsets();
const { toastConfig, hideToast } = useToast();
const opacity = React.useRef(new Animated.Value(0)).current;
const fadeIn = React.useCallback(() => {
Animated.timing(opacity, {
toValue: 1,
duration: fadeDuration,
useNativeDriver: true,
}).start();
}, [opacity]);
const fadeOut = React.useCallback(() => {
Animated.timing(opacity, {
toValue: 0,
duration: fadeDuration,
useNativeDriver: true,
}).start(() => {
hideToast();
});
}, [opacity, hideToast]);
React.useEffect(() => {
if (!toastConfig) {
return;
}
fadeIn();
if (toastConfig.duration > 0) {
const timer = setTimeout(fadeOut, toastConfig.duration);
return () => clearTimeout(timer);
}
}, [toastConfig, fadeIn, fadeOut]);
if (!toastConfig) {
return null;
}
const { type, message } = toastConfig;
const toastTypeColors: { [key in ToastType]: string } = {
[ToastType.Info]: "#17a2b8",
[ToastType.Error]: "#dc3545",
[ToastType.Success]: "#28a745",
[ToastType.Warn]: "#ffc107",
};
let backgroundColor = toastTypeColors[type];
return (
<Animated.View
style={[
styles.container,
{ top: insets.top + 20, opacity }, // Positioning at the top
]}
>
<View style={[styles.toast, { backgroundColor }]}>
<Text style={styles.message}>{message}</Text>
</View>
</Animated.View>
);
};
const styles = StyleSheet.create({
container: {
alignSelf: "center",
position: "absolute",
marginHorizontal: 20,
maxWidth: 480,
},
toast: {
borderRadius: 6,
padding: 16,
},
message: {
fontSize: 16,
textAlign: "center",
color: '#fff',
},
});