koel/resources/assets/js/components/ui/MessageToast.vue
2023-11-10 14:16:06 +01:00

110 lines
2 KiB
Vue

<template>
<div :class="message.type" class="message" title="Click to dismiss" @click="dismiss">
<aside>
<Icon :icon="typeIcon" class="icon" />
<Icon :icon="faTimesCircle" class="icon-dismiss" />
</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
default:
return faCircleExclamation
}
})
let timeoutHandler: number
const emit = defineEmits<{ (e: 'dismiss', message: ToastMessage): void }>()
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>