All files / components/base ToastContainer.vue

94.44% Statements 34/36
100% Branches 3/3
60% Functions 3/5
94.44% Lines 34/36

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>