useToast.ts
970 bytes
| 1 | import { ref } from 'vue' |
|---|---|
| 2 | |
| 3 | export interface Toast { |
| 4 | id: number |
| 5 | message: string |
| 6 | type: 'success' | 'error' | 'warning' | 'info' |
| 7 | dismissing?: boolean |
| 8 | } |
| 9 | |
| 10 | const toasts = ref<Toast[]>([]) |
| 11 | let nextId = 0 |
| 12 | |
| 13 | function addToast(message: string, type: Toast['type'], duration = 4000) { |
| 14 | const id = nextId++ |
| 15 | toasts.value.push({ id, message, type }) |
| 16 | |
| 17 | setTimeout(() => dismissToast(id), duration) |
| 18 | } |
| 19 | |
| 20 | function dismissToast(id: number) { |
| 21 | const toast = toasts.value.find((t) => t.id === id) |
| 22 | if (toast) { |
| 23 | toast.dismissing = true |
| 24 | setTimeout(() => { |
| 25 | toasts.value = toasts.value.filter((t) => t.id !== id) |
| 26 | }, 300) |
| 27 | } |
| 28 | } |
| 29 | |
| 30 | export function useToast() { |
| 31 | return { |
| 32 | toasts, |
| 33 | success: (message: string) => addToast(message, 'success'), |
| 34 | error: (message: string) => addToast(message, 'error', 6000), |
| 35 | warning: (message: string) => addToast(message, 'warning'), |
| 36 | info: (message: string) => addToast(message, 'info'), |
| 37 | dismiss: dismissToast, |
| 38 | } |
| 39 | } |
| 40 | |