mirror of https://github.com/mashirozx/sakura.git
112 lines
2.9 KiB
Vue
112 lines
2.9 KiB
Vue
<template>
|
|
<div class="messages__container" :style="positionControl">
|
|
<transition-group name="messages" tag="div">
|
|
<div class="message__wrapper" v-for="message in messagesCalc" :key="message.id">
|
|
<MessageNormal v-if="message.style === 'normal'" :message="message"></MessageNormal>
|
|
</div>
|
|
</transition-group>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { defineComponent, computed } from 'vue'
|
|
import { cloneDeep } from 'lodash'
|
|
import { useInjector } from '@/hooks'
|
|
import { messages } from '@/store'
|
|
import MessageNormal from './MessageNormal.vue'
|
|
|
|
export default defineComponent({
|
|
components: { MessageNormal },
|
|
props: {
|
|
positionX: { type: String, default: 'right' }, // left center right
|
|
positionY: { type: String, default: 'top' }, // top bottom
|
|
width: { type: String, default: '380px' },
|
|
},
|
|
setup(props) {
|
|
const { messageList } = useInjector(messages)
|
|
|
|
const messagesCalc = computed(() => {
|
|
if (props.positionY === 'bottom') {
|
|
return cloneDeep(messageList.value).reverse()
|
|
} else {
|
|
return cloneDeep(messageList.value)
|
|
}
|
|
})
|
|
|
|
const positionControl = computed(() => {
|
|
return {
|
|
'--from-0': props.positionY === 'bottom' ? '100%' : '-100%',
|
|
'--from-70': props.positionY === 'bottom' ? '-20px' : '20px',
|
|
'--from-100': 0,
|
|
'--to-0': 0,
|
|
'--to-30': props.positionX === 'right' ? '-20px' : '20px',
|
|
'--to-70': props.positionX === 'right' ? '100%' : '-100%',
|
|
'--to-100': props.positionX === 'right' ? '100%' : '-100%',
|
|
'--absolute-fix': props.positionY === 'bottom' ? '-100%' : '0',
|
|
'--width': props.width,
|
|
}
|
|
})
|
|
|
|
return { messagesCalc, positionControl }
|
|
},
|
|
})
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.messages__container {
|
|
width: calc(var(--width) + 12px);
|
|
.message__wrapper {
|
|
padding: 6px;
|
|
}
|
|
|
|
.messages {
|
|
&-enter-active {
|
|
animation: from 0.5s forwards;
|
|
}
|
|
&-leave-active {
|
|
position: absolute;
|
|
transform-origin: center center;
|
|
animation: to 0.5s forwards;
|
|
}
|
|
&-move {
|
|
transition: transform 0.3s ease;
|
|
transition-delay: 0.3s;
|
|
}
|
|
}
|
|
|
|
@keyframes from {
|
|
0% {
|
|
transform: translateY(var(--from-0));
|
|
opacity: 0;
|
|
}
|
|
70% {
|
|
transform: translateY(var(--from-70));
|
|
opacity: 0.8;
|
|
}
|
|
100% {
|
|
transform: translateY(var(--from-100));
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@keyframes to {
|
|
0% {
|
|
transform: translateX(var(--to-0)) translateY(var(--absolute-fix));
|
|
opacity: 1;
|
|
}
|
|
30% {
|
|
transform: translateX(var(--to-30)) translateY(var(--absolute-fix));
|
|
opacity: 0.8;
|
|
}
|
|
70% {
|
|
transform: translateX(var(--to-70)) translateY(var(--absolute-fix));
|
|
opacity: 0;
|
|
}
|
|
100% {
|
|
transform: translateX(var(--to-100)) translateY(var(--absolute-fix));
|
|
opacity: 0;
|
|
}
|
|
}
|
|
}
|
|
</style>
|