Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | <template>
<div
class="fixed top-4 right-4 z-50 flex flex-col gap-3 pointer-events-none"
aria-live="polite"
aria-atomic="false"
>
<div
v-for="toast in toasts"
:key="toast.id"
class="pointer-events-auto"
>
<BaseToast
:variant="toast.variant"
:message="toast.message"
:action-label="toast.actionLabel"
:duration="toast.duration"
:model-value="toast.visible"
@update:model-value="(value) => handleUpdate(toast.id, value)"
@dismiss="handleDismiss(toast.id)"
@action="handleAction(toast.id)"
/>
</div>
</div>
</template>
<script setup lang="ts">
/**
* ToastContainer
* @description Container component that renders all active toasts
* Should be placed in the layout to be available app-wide
*/
import { useToast, getToastAction } from '~/composables/useToast'
const { toasts, dismiss } = useToast()
function handleUpdate(id: string, visible: boolean) {
if (!visible) {
dismiss(id)
}
}
function handleDismiss(id: string) {
dismiss(id)
}
function handleAction(id: string) {
const action = getToastAction(id)
if (action) {
action()
}
dismiss(id)
}
</script>
|