2026-07-02 14:34:19 +05:30

83 lines
2.2 KiB
TypeScript

import React, { createContext, useContext, useState, useCallback } from 'react';
import { Animated, Text } from 'react-native';
import { useAppTheme } from '@theme';
import { getStyles } from './toast.styles';
export type ToastType = 'success' | 'error' | 'info';
interface ToastOptions {
message: string;
type?: ToastType;
duration?: number;
}
interface ToastContextType {
showToast: (options: ToastOptions) => void;
}
const ToastContext = createContext<ToastContextType | undefined>(undefined);
export const ToastProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const { colors } = useAppTheme();
const styles = getStyles(colors);
const [toast, setToast] = useState<{ message: string; type: ToastType } | null>(null);
const [fadeAnim] = useState(new Animated.Value(0));
const showToast = useCallback(
({ message, type = 'info', duration = 3000 }: ToastOptions) => {
setToast({ message, type });
// Animate In
Animated.timing(fadeAnim, {
toValue: 1,
duration: 300,
useNativeDriver: true,
}).start();
// Dismiss after duration
setTimeout(() => {
Animated.timing(fadeAnim, {
toValue: 0,
duration: 300,
useNativeDriver: true,
}).start(() => setToast(null));
}, duration);
},
[fadeAnim]
);
const getStyleConfig = () => {
if (!toast) return { bg: null, text: null };
switch (toast.type) {
case 'success':
return { bg: styles.successBg, text: styles.successText };
case 'error':
return { bg: styles.errorBg, text: styles.errorText };
case 'info':
return { bg: styles.infoBg, text: styles.infoText };
}
};
const config = getStyleConfig();
return (
<ToastContext.Provider value={{ showToast }}>
{children}
{toast ? (
<Animated.View style={[styles.container, config.bg, { opacity: fadeAnim }]}>
<Text style={[styles.message, config.text]}>{toast.message}</Text>
</Animated.View>
) : null}
</ToastContext.Provider>
);
};
export const useToast = () => {
const context = useContext(ToastContext);
if (!context) {
throw new Error('useToast must be used within a ToastProvider');
}
return context;
};