import { atom } from 'jotai'; import type { ToastInstance } from '../components/Toasts'; import { generateId } from './generateId'; import { jotaiStore } from './jotai'; export const toastsAtom = atom([]); export function showToast({ id, timeout = 5000, ...props }: Omit & { id?: ToastInstance['id']; timeout?: ToastInstance['timeout']; }) { id = id ?? generateId(); const uniqueKey = generateId(); const toasts = jotaiStore.get(toastsAtom); const toastWithSameId = toasts.find((t) => t.id === id); let delay = 0; if (toastWithSameId) { hideToast(toastWithSameId); // Allow enough time for old toast to animate out delay = 200; } setTimeout(() => { const newToast: ToastInstance = { id, uniqueKey, timeout, ...props }; if (timeout != null) { setTimeout(() => hideToast(newToast), timeout); } jotaiStore.set(toastsAtom, (prev) => [...prev, newToast]); }, delay); return id; } export function hideToast(toHide: ToastInstance) { jotaiStore.set(toastsAtom, (all) => { const t = all.find((t) => t.uniqueKey === toHide.uniqueKey); t?.onClose?.(); return all.filter((t) => t.uniqueKey !== toHide.uniqueKey); }); } export function showErrorToast({ id, title, message, }: { id: string; title: string; message: T; }) { return showToast({ id, color: 'danger', timeout: null, message: (

{title}

{String(message)}
), }); }