2022-07-26 09:51:19 +00:00
|
|
|
<template>
|
|
|
|
<div
|
|
|
|
class="message"
|
|
|
|
:class="message.type"
|
|
|
|
title="Click to dismiss"
|
2022-12-02 16:17:37 +00:00
|
|
|
@click="dismiss"
|
2022-07-26 09:51:19 +00:00
|
|
|
>
|
|
|
|
<aside>
|
2022-12-02 16:17:37 +00:00
|
|
|
<icon :icon="typeIcon" class="icon" />
|
|
|
|
<icon :icon="faTimesCircle" class="icon-dismiss" />
|
2022-07-26 09:51:19 +00:00
|
|
|
</aside>
|
|
|
|
<main>{{ message.content }}</main>
|
|
|
|
</div>
|
|
|
|
</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
|
2022-12-02 16:17:37 +00:00
|
|
|
default:
|
2022-07-26 09:51:19 +00:00
|
|
|
return faCircleExclamation
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
let timeoutHandler: number
|
|
|
|
|
2022-11-13 15:18:24 +00:00
|
|
|
const emit = defineEmits<{ (e: 'dismiss', message: ToastMessage): void }>()
|
2022-07-26 09:51:19 +00:00
|
|
|
|
|
|
|
const dismiss = () => {
|
|
|
|
emit('dismiss', message.value)
|
|
|
|
window.clearTimeout(timeoutHandler)
|
|
|
|
}
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
timeoutHandler = window.setTimeout(() => dismiss(), message.value.timeout * 1000)
|
|
|
|
})
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
.message {
|
|
|
|
border-radius: 4px 0 0 4px;
|
|
|
|
cursor: pointer;
|
|
|
|
display: flex;
|
|
|
|
align-items: stretch;
|
|
|
|
opacity: .9;
|
|
|
|
transition: transform .3s;
|
|
|
|
|
|
|
|
.icon-dismiss {
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
opacity: 1;
|
|
|
|
transform: scale(1.1);
|
|
|
|
transform-origin: right;
|
|
|
|
|
|
|
|
.icon {
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
|
|
|
|
.icon-dismiss {
|
|
|
|
display: block;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
aside {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
padding: 0 8px;
|
|
|
|
background: rgba(0, 0, 0, .1)
|
|
|
|
}
|
|
|
|
|
|
|
|
main {
|
|
|
|
flex: 1;
|
|
|
|
padding: 7px 14px 7px 10px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.info {
|
|
|
|
background-color: rgb(12 74 110);
|
|
|
|
color: rgb(224 242 254);
|
|
|
|
}
|
|
|
|
|
|
|
|
.danger {
|
|
|
|
background-color: rgb(185 28 28);
|
|
|
|
color: rgb(254 226 226);
|
|
|
|
}
|
|
|
|
|
|
|
|
.success {
|
|
|
|
background-color: rgb(5 150 105);
|
|
|
|
color: rgb(209 250 229);
|
|
|
|
}
|
|
|
|
|
|
|
|
.warning {
|
|
|
|
background-color: rgb(249 115 22);
|
|
|
|
color: rgb(255 237 213);
|
|
|
|
}
|
|
|
|
</style>
|