import { createContext , memo , ReactNode , useCallback , useContext , useMemo , useState } from 'react' ; import { AnimatedToast } from './Toast' ; type DismissToastHandler = ( ) => void ; type ToastActions = { pushToast : ( message : string , onDismiss ? : DismissToastHandler ) => void ; dismissToast : ( ) => void ; dismissAllToasts : ( ) => void ; } ; const ToastActionsContext = createContext < ToastActions | undefined > ( undefined ) ; export const useToastActions = ( ) : ToastActions => { const context = useContext ( ToastActionsContext ) ; if ( ! context ) { throw new Error ( 'Attempted to use ToastActionsContext without a provider!' ) ; } return context ; } ; const noop = ( ) => { } ; type ToastType = { message : string ; onDismiss : DismissToastHandler ; } ; type Props = { children : ReactNode ; } ; const ToastProvider = memo ( ( { children } ) => { const [ toasts , setToasts ] = useState < ToastType [ ] > ( [ ] ) ; const pushToast = useCallback ( ( message , onDismiss = noop ) => { setToasts ( ( previousMessages ) => [ ... previousMessages , { message , onDismiss } ] ) ; } , [ ] ) ; const dismissToast = useCallback ( ( ) => { setToasts ( ( previousMessages ) => { if ( previousMessages . length === 0 ) { return previousMessages ; } const toastToDismiss = previousMessages [ previousMessages . length - 1 ] ; toastToDismiss . onDismiss ( ) ; return previousMessages . slice ( 0 , - 1 ) ; } ) ; } , [ ] ) ; const dismissAllToasts = useCallback ( ( ) => { setToasts ( [ ] ) ; } , [ ] ) ; const value = useMemo ( ( ) => ( { pushToast , dismissToast , dismissAllToasts , } ) , [ pushToast , dismissToast , dismissAllToasts ] ) ; return ( < ToastActionsContext . Provider value = { value } > { toasts . map ( ( { message , onDismiss } ) => ( < AnimatedToast key = { message } message = { message } onClose = { onDismiss } / > ) ) } { children } < /ToastActionsContext.Provider>); } ) ; export default ToastProvider ;