import React, { useEffect, useState, useContext, createContext } from 'react'; import { Toast } from 'react-bootstrap'; interface IToast { header?: string; content: JSX.Element|string; delay?: number; variant?: 'success'|'danger'|'warning'|'info'; } interface IActiveToast extends IToast { id: number; } let toastID = 0; const ToastContext = createContext<(item:IToast) => void>(() => {}); export const ToastProvider: React.FC = ({children}) => { const [toasts, setToasts] = useState([]); const removeToast = (id:number) => ( setToasts(toasts.filter(item => item.id !== id)) ); const toastItems = toasts.map(toast => ( removeToast(toast.id)} className={toast.variant ?? 'success'} delay={toast.delay ?? 5000} > { toast.header ?? 'Stash' } {toast.content} )); const addToast = (toast:IToast) => ( setToasts([...toasts, { ...toast, id: toastID++ }]) ); return ( {children}
{ toastItems }
) } function createHookObject(toastFunc: (toast:IToast) => void) { return { success: toastFunc, error: (error: Error) => { // eslint-disable-next-line no-console console.error(error.message); toastFunc({ variant: 'danger', header: 'Error', content: error.message ?? error.toString() }); } } } const useToasts = () => { const setToast = useContext(ToastContext); const [hookObject, setHookObject] = useState(createHookObject(setToast)); useEffect(() => ( setHookObject(createHookObject(setToast)) ), [setToast]); return hookObject; } export default useToasts;