Repository Public
1import { create } from 'zustand';23export type ToastTone = 'info' | 'success' | 'warning' | 'error';4export interface Toast {5 id: number;6 title: string;7 body?: string;8 tone: ToastTone;9 href?: string;10}11interface ToastState {12 toasts: Toast[];13 push: (t: Omit<Toast, 'id'>) => void;14 dismiss: (id: number) => void;15}16let seq = 0;17export const useToasts = create<ToastState>((set) => ({18 toasts: [],19 push: (t) => {20 const id = ++seq;21 set((s) => ({ toasts: [...s.toasts.slice(-3), { ...t, id }] }));22 setTimeout(() => set((s) => ({ toasts: s.toasts.filter((x) => x.id !== id) })), t.tone === 'error' ? 8000 : 5000);23 },24 dismiss: (id) => set((s) => ({ toasts: s.toasts.filter((x) => x.id !== id) })),25}));26export const toast = {27 info: (title: string, body?: string) => useToasts.getState().push({ title, body, tone: 'info' }),28 success: (title: string, body?: string) => useToasts.getState().push({ title, body, tone: 'success' }),29 warning: (title: string, body?: string) => useToasts.getState().push({ title, body, tone: 'warning' }),30 error: (title: string, body?: string) => useToasts.getState().push({ title, body, tone: 'error' }),31};32