| <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> | |