2024-04-04 22:20:42 +00:00
|
|
|
<template>
|
|
|
|
<article
|
|
|
|
:class="message.type"
|
|
|
|
class="group rounded-l-md cursor-pointer flex items-stretch opacity-90 transition-transform duration-300 origin-right
|
|
|
|
hover:opacity-100 hover:scale-110"
|
|
|
|
title="Click to dismiss"
|
2024-04-23 21:01:27 +00:00
|
|
|
@click="dismiss"
|
2024-04-04 22:20:42 +00:00
|
|
|
@mouseenter="cancelAutoDismiss"
|
|
|
|
@mouseleave="setAutoDismiss"
|
|
|
|
>
|
|
|
|
<aside class="flex items-center px-3 py-0 bg-black/10">
|
|
|
|
<Icon :icon="typeIcon" class="group-hover:hidden" />
|
|
|
|
<Icon :icon="faTimesCircle" class="hidden group-hover:block" />
|
|
|
|
</aside>
|
|
|
|
<main class="flex-1 py-2 pl-3 pr-4">{{ message.content }}</main>
|
|
|
|
</article>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
|
import { computed, onMounted, toRefs } from 'vue'
|
|
|
|
import {
|
|
|
|
faCircleCheck,
|
|
|
|
faCircleExclamation,
|
|
|
|
faCircleInfo,
|
|
|
|
faTimesCircle,
|
|
|
|
faTriangleExclamation
|
|
|
|
} from '@fortawesome/free-solid-svg-icons'
|
|
|
|
|
|
|
|
const props = defineProps<{ message: ToastMessage }>()
|
|
|
|
const { message } = toRefs(props)
|
|
|
|
|
|
|
|
const typeIcon = computed(() => {
|
|
|
|
switch (message.value.type) {
|
|
|
|
case 'info':
|
|
|
|
return faCircleInfo
|
|
|
|
case 'success':
|
|
|
|
return faCircleCheck
|
|
|
|
case 'warning':
|
|
|
|
return faTriangleExclamation
|
|
|
|
default:
|
|
|
|
return faCircleExclamation
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
let timeoutHandler: number
|
|
|
|
|
|
|
|
const emit = defineEmits<{ (e: 'dismiss', message: ToastMessage): void }>()
|
|
|
|
|
|
|
|
const dismiss = () => {
|
|
|
|
emit('dismiss', message.value)
|
|
|
|
window.clearTimeout(timeoutHandler)
|
|
|
|
}
|
|
|
|
|
|
|
|
const cancelAutoDismiss = () => window.clearTimeout(timeoutHandler)
|
|
|
|
const setAutoDismiss = () => (timeoutHandler = window.setTimeout(() => dismiss(), message.value.timeout * 1000))
|
|
|
|
|
|
|
|
onMounted(() => setAutoDismiss())
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="postcss" scoped>
|
|
|
|
.info {
|
|
|
|
@apply bg-blue-600 text-blue-100;
|
|
|
|
}
|
|
|
|
|
|
|
|
.danger {
|
|
|
|
@apply bg-red-700 text-red-100;
|
|
|
|
}
|
|
|
|
|
|
|
|
.success {
|
|
|
|
@apply bg-green-600 text-green-100;
|
|
|
|
}
|
|
|
|
|
|
|
|
.warning {
|
|
|
|
@apply bg-orange-600 text-orange-100;
|
|
|
|
}
|
|
|
|
</style>
|