feat(ui) : error toasts persist until dismissed, add progress bar on auto-dismiss toasts
This commit is contained in:
@@ -13,7 +13,7 @@
|
|||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="alert toast-card shadow-md px-3 py-2 text-sm"
|
class="alert toast-card relative shadow-md px-3 py-2 text-sm overflow-hidden"
|
||||||
:class="getToastClasses(toast.type)"
|
:class="getToastClasses(toast.type)"
|
||||||
>
|
>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
@@ -54,6 +54,13 @@
|
|||||||
<IconLucideX class="w-3 h-3" aria-hidden="true" />
|
<IconLucideX class="w-3 h-3" aria-hidden="true" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Progress bar for auto-dismiss toasts -->
|
||||||
|
<div
|
||||||
|
v-if="toast.duration > 0"
|
||||||
|
class="absolute bottom-0 left-0 h-0.5 bg-current opacity-30 rounded-full"
|
||||||
|
:style="{ animation: `toast-progress ${toast.duration}ms linear forwards` }"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</TransitionGroup>
|
</TransitionGroup>
|
||||||
@@ -111,4 +118,9 @@ const getToastClasses = (type) => {
|
|||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
border-radius: 0.75rem;
|
border-radius: 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes toast-progress {
|
||||||
|
from { width: 100%; }
|
||||||
|
to { width: 0%; }
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ export interface Toast {
|
|||||||
message: string
|
message: string
|
||||||
type: ToastType
|
type: ToastType
|
||||||
visible: boolean
|
visible: boolean
|
||||||
|
duration: number
|
||||||
}
|
}
|
||||||
|
|
||||||
const toasts = ref<Toast[]>([])
|
const toasts = ref<Toast[]>([])
|
||||||
@@ -32,6 +33,7 @@ export function useToast() {
|
|||||||
message,
|
message,
|
||||||
type,
|
type,
|
||||||
visible: true,
|
visible: true,
|
||||||
|
duration: type === 'error' ? 0 : duration,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (toasts.value.length >= MAX_TOASTS) {
|
if (toasts.value.length >= MAX_TOASTS) {
|
||||||
@@ -40,10 +42,12 @@ export function useToast() {
|
|||||||
|
|
||||||
toasts.value.push(toast)
|
toasts.value.push(toast)
|
||||||
|
|
||||||
// Auto-remove after duration
|
// Only auto-dismiss non-error toasts
|
||||||
setTimeout(() => {
|
if (type !== 'error' && duration > 0) {
|
||||||
removeToast(id)
|
setTimeout(() => {
|
||||||
}, duration)
|
removeToast(id)
|
||||||
|
}, duration)
|
||||||
|
}
|
||||||
|
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user