import type { ReactElement } from 'react'; import React, { useEffect, useLayoutEffect, useRef } from 'react'; import { Animated, LayoutAnimation } from 'react-native'; import { Container, ContentContainer, IconContainer, CTAWrapper, TextContainer, StyledBody, StyledIcon, } from './StyledToast'; import { useToastConfig } from './ToastContext'; import type { IconName } from '../Icon'; import type { IntentType, ToastProps } from './types'; const getIntentIcon = (intent: IntentType): IconName | undefined => { switch (intent) { case 'success': return 'circle-ok'; case 'warning': return 'warning'; case 'info': return 'circle-info'; case 'error': return 'circle-warning'; default: return undefined; } }; const ToastIcon = ({ themeIntent, icon, }: { icon?: IconName; themeIntent: IntentType; }) => icon ? ( ) : null; const Toast = ({ content, icon, variant = 'default', intent = 'info', style, duration = 2000, autoDismiss = true, onAction, actionLabel, onDismiss, distance = 0, }: ToastProps): ReactElement => { const animatedValue = useRef(new Animated.Value(0)).current; const toastConfig = useToastConfig(); useEffect(() => { if (autoDismiss && duration >= 0) { const id = setTimeout(() => onDismiss?.(), duration); return () => clearTimeout(id); } }, []); useEffect(() => { const animation = Animated.timing(animatedValue, { toValue: 1, useNativeDriver: true, }); animation.start(); return () => animation.stop(); }, []); useLayoutEffect(() => { LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); }); const interpolateY = animatedValue.interpolate({ inputRange: [0, 1], outputRange: toastConfig.position === 'top' ? [-20, distance] : [20, -distance], }); return ( {icon !== null ? ( ) : null} {typeof content === 'string' ? ( {content} ) : ( content )} {actionLabel ? ( { onAction?.(); onDismiss?.(); }} > {typeof actionLabel === 'string' ? ( {actionLabel} ) : ( actionLabel )} ) : null} ); }; export default Toast;