import {defineStore} from "pinia"; import {ref} from "vue"; export type ToastType = 'success' | 'error' | 'info'; export interface ToastOptions { message: string; title?: string; type?: ToastType; duration?: number; } export interface Toast { id: number; message: string; title?: string; type: ToastType; } const DEFAULT_DURATION = 5000; export const useToastStore = defineStore('toast', () => { const toasts = ref([]); let nextId = 0; const dismiss = (id: number) => { toasts.value = toasts.value.filter(toast => toast.id !== id); }; const push = (opts: ToastOptions | string): number => { const options = typeof opts === "string" ? {message: opts} : opts; const id = nextId++; toasts.value.push({ id, message: options.message, title: options.title, type: options.type ?? 'info', }); const duration = options.duration ?? DEFAULT_DURATION; if (duration > 0) { setTimeout(() => dismiss(id), duration); } return id; }; return {toasts, push, dismiss}; }); interface ToastHelper { (opts: ToastOptions | string): number; success: (message: string) => number; error: (message: string) => number; info: (message: string) => number; } export const toast: ToastHelper = Object.assign( (opts: ToastOptions | string): number => useToastStore().push(opts), { success: (message: string): number => useToastStore().push({message, type: 'success'}), error: (message: string): number => useToastStore().push({message, type: 'error'}), info: (message: string): number => useToastStore().push({message, type: 'info'}), }, );