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;