Files
ppeasy_vg12/resources/js/components/ui/ToastHost.vue
T
2026-10-09 08:21:06 +02:00

39 lines
1.7 KiB
Vue

<script setup lang="ts">
import { ToastClose, ToastProvider, ToastRoot, ToastTitle, ToastViewport } from 'reka-ui';
import { useToast, type ToastSeverity } from '@/composables/useToast';
import { useTranslations } from '@/composables/useVanguard';
const { messages, remove } = useToast();
const { __ } = useTranslations();
const styles: Record<ToastSeverity, { container: string; icon: string }> = {
success: { container: 'border-green-200 bg-green-50 text-green-800', icon: 'fas fa-check-circle' },
info: { container: 'border-sky-200 bg-sky-50 text-sky-800', icon: 'fas fa-info-circle' },
warn: { container: 'border-amber-200 bg-amber-50 text-amber-800', icon: 'fas fa-exclamation-triangle' },
error: { container: 'border-red-200 bg-red-50 text-red-800', icon: 'fas fa-times-circle' },
};
</script>
<template>
<ToastProvider>
<ToastRoot
v-for="message in messages"
:key="message.id"
:duration="message.life"
class="flex items-start gap-2 rounded-md border px-4 py-3 shadow-md data-[state=closed]:opacity-0"
:class="styles[message.severity].container"
@update:open="(open: boolean) => !open && remove(message.id)"
>
<i :class="styles[message.severity].icon" class="mt-1 shrink-0" aria-hidden="true" />
<ToastTitle class="flex-1">{{ message.summary }}</ToastTitle>
<ToastClose class="cursor-pointer opacity-60 hover:opacity-100" :aria-label="__('Close')">
<i class="fas fa-times" aria-hidden="true" />
</ToastClose>
</ToastRoot>
<ToastViewport class="fixed top-4 left-1/2 -translate-x-1/2 z-100 flex w-96 max-w-[calc(100vw-2rem)] flex-col gap-2" />
</ToastProvider>
</template>