diff --git a/src/runtime/composables/useToast.ts b/src/runtime/composables/useToast.ts index 14abd58a3f..3c42786e2c 100644 --- a/src/runtime/composables/useToast.ts +++ b/src/runtime/composables/useToast.ts @@ -1,3 +1,4 @@ +import { ref, nextTick, readonly } from 'vue' import { useState } from '#imports' import type { ToastProps } from '../types' @@ -8,20 +9,40 @@ export interface Toast extends Omit { export function useToast() { const toasts = useState('toasts', () => []) + const maxToasts = 5 + const running = ref(false) + const queue: Toast[] = [] - function add(toast: Partial): Toast { + const generateId = () => `${Date.now()}-${Math.random().toString(36).slice(2, 9)}` + + async function processQueue() { + if (running.value || queue.length === 0) { + return + } + + running.value = true + + while (queue.length > 0) { + const toast = queue.shift()! + + await nextTick() + + toasts.value = [...toasts.value, toast].slice(-maxToasts) + } + + running.value = false + } + + async function add(toast: Partial): Promise { const body = { - id: new Date().getTime().toString(), + id: generateId(), open: true, ...toast } - const index = toasts.value.findIndex((t: Toast) => t.id === body.id) - if (index === -1) { - toasts.value.push(body) - } + queue.push(body) - toasts.value = toasts.value.slice(-5) + await processQueue() return body } @@ -55,7 +76,7 @@ export function useToast() { } return { - toasts, + toasts: readonly(toasts), add, update, remove,