szafran98's picture
initial commit
8a1f4e2
<script setup lang="ts">
import PluginNotifications from "@plugin/components/PluginNotifications.vue";
import useSnackbar from "@plugin/composables/snackbar.ts";
import {computed} from "vue";
const theme = 'dark-theme';
const direction = 'top';
const { state, closeNotification } = useSnackbar();
const snackItems = computed(() => state.messages);
const handleNotificationClick = (clickFunc: (()=> void) | null): void => {
if (clickFunc && typeof clickFunc === 'function') {
clickFunc();
}
}
</script>
<template>
<div class="snackbar-container" :class="direction">
<div
class="snackbar-item"
v-for="(snack, idx) in snackItems"
:key="idx"
:is-closed="snack.closed"
>
<PluginNotifications
:status="snack.type"
@close="closeNotification(snack.key)"
:solid="true"
is-from-snackbar
:theme="theme"
:show-button="snack.showButton"
:button-text="snack.buttonText"
@clicked="handleNotificationClick(snack.click)"
>
<template v-slot:text>
{{ snack.message }}
</template>
</PluginNotifications>
</div>
</div>
</template>
<style scoped lang="scss">
.snackbar-container {
position: fixed;
width: 100%;
margin: auto;
z-index: 111;
&.top {
top: 30px;
animation-name: slideFromTop;
animation-duration: .5s;
}
&.bottom {
bottom: 20px;
}
> .snackbar-item {
margin-inline: 12px;
:deep(.notifications-section) {
margin-inline: auto;
}
&[is-closed="true"] {
animation-name: closeNotification;
animation-duration: .5s;
}
& + .snackbar-item {
margin-top: 20px;
}
}
@keyframes closeNotification {
from {
transform: translateY(0px);
opacity: 1;
}
to {
transform: translateY(-150px);
opacity: 0;
}
}
@keyframes slideFromTop {
from {
transform: translateY(-150px);
opacity: 0;
}
to {
transform: translateY(0px);
opacity: 1;
}
}
}
</style>