UNPKG

react-native-toastier

Version:

React Native Toast message library for Android and iOS with animated and customizable toast notifications.

143 lines (132 loc) 3.26 kB
import React, { useEffect } from 'react'; import { Animated, Text, TouchableOpacity, View } from 'react-native'; import theme from '../theme'; import styled from './styles'; import { Theme, ToastProps } from '../types'; import useToastState from '../hooks/useToastState'; export const defaultDuration = 15000; interface Props { open?: boolean; onClose?: () => void; theme?: Theme offset?: number; } const Toast = ({ message, children, duration: timing, theme: toastTheme, type = 'default', open, onClose, onOpen, left, right, contentContainerStyle, textContainerStyle, messageStyle, titleStyle, offset, title, animation = 'zoomIn', position = 'bottom', }: ToastProps & Props) => { const {state, action} = useToastState({ position, animation, offset, onClose, }); const { showToast, animation: Animation } = state; const { startAnimations, finishAnimations } = action; const Theme = { toast: toastTheme }; const duration = timing || defaultDuration; useEffect(() => { let timeout: NodeJS.Timeout; if (open) { onOpen?.(); startAnimations(); timeout = setTimeout(() => { hideToast(); }, duration); } else { hideToast(); } return () => clearTimeout(timeout); }, [open, duration, showToast]); const hideToast = () => { finishAnimations(); }; const getPositionStyle = () => { switch (position) { case 'top': return { top: 0 }; case 'bottom': return { bottom: 0 }; default: return { bottom: 0 }; } }; if (!open) { return null; } return ( <Animated.View style={[ styled.styles.container, getPositionStyle(), {opacity: showToast}, Animation, ]}> <View style={[ styled.styles.toastContainer, theme?.toast?.[type], Theme?.toast?.[type], contentContainerStyle, ].flat()}> {left ?? null} {children ?? ( <> <View style={[styled.styles.textContainer, textContainerStyle].flat()}> {title && ( <Text style={[ styled.styles.title, {color: Theme?.toast?.[type]?.color}, titleStyle, ].flat()}> {title} </Text> )} {message && ( <Text style={[ styled.styles.message, {color: Theme?.toast?.[type]?.color || theme?.toast?.[type]?.color}, messageStyle, ].flat()}> {message} </Text> )} </View> </> )} {right ?? ( <TouchableOpacity onPress={hideToast}> <Text style={[ styled.styles.iconStyle, {color: Theme?.toast?.[type]?.color || theme?.toast?.[type]?.color}, titleStyle, ].flat()}> x </Text> </TouchableOpacity> )} </View> </Animated.View> ); }; export default Toast;