import React, { useEffect, useRef } from 'react'; import { Animated, StyleSheet, Text } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; export type ToastVariant = 'error' | 'success' | 'warning'; interface ToastProps { message: string; variant: ToastVariant; visible: boolean; } const VARIANT_COLORS: Record = { error: '#EF4444', success: '#22c55e', warning: '#F97316', }; export function Toast({ message, variant, visible }: ToastProps) { const insets = useSafeAreaInsets(); const translateY = useRef(new Animated.Value(-120)).current; const opacity = useRef(new Animated.Value(0)).current; useEffect(() => { if (visible) { Animated.parallel([ Animated.spring(translateY, { toValue: 0, useNativeDriver: true, tension: 80, friction: 10, }), Animated.timing(opacity, { toValue: 1, duration: 200, useNativeDriver: true, }), ]).start(); } else { Animated.parallel([ Animated.timing(translateY, { toValue: -120, duration: 250, useNativeDriver: true, }), Animated.timing(opacity, { toValue: 0, duration: 200, useNativeDriver: true, }), ]).start(); } }, [visible]); return ( {message} ); } const styles = StyleSheet.create({ container: { position: 'absolute', left: 16, right: 16, zIndex: 9999, borderRadius: 10, paddingHorizontal: 16, paddingVertical: 12, shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.15, shadowRadius: 8, elevation: 8, }, message: { color: '#fff', fontSize: 14, fontWeight: '500', lineHeight: 20, }, });