Files
web/app/components/snackbar/SnackBar.vue
2026-05-22 09:57:12 +07:00

92 lines
2.2 KiB
Vue

<script setup>
import { defineAsyncComponent } from "vue";
import { useStore } from "@/stores/index";
import Info from "@/components/snackbar/Info.vue";
import Success from "@/components/snackbar/Success.vue";
import Error from "@/components/snackbar/Error.vue";
const props = defineProps({
component: String,
vbind: Object,
});
const store = useStore();
const componentFiles = import.meta.glob("@/components/**/*.vue");
const resolvedComponent = shallowRef(null);
function loadDynamicComponent() {
if (!props.component) {
resolvedComponent.value = null;
return;
}
const fullPath = `/components/snackbar/${props.component}.vue`;
const componentPath = Object.keys(componentFiles).find((path) => path.endsWith(fullPath));
if (componentPath) {
resolvedComponent.value = defineAsyncComponent(componentFiles[componentPath]);
} else {
console.error(`Không tìm thấy component tại: ${fullPath}`);
resolvedComponent.value = null;
}
}
// Theo dõi sự thay đổi của props.component để load lại nếu cần
watchEffect(() => {
loadDynamicComponent();
});
// setTimeout(() => store.commit("snackbar", undefined), 3900);
</script>
<template>
<div class="snackbar is-flex is-align-items-center is-gap-3 pl-3 pr-1.5 py-2 rounded-md has-text-white">
<Info
v-if="component === 'Info'"
v-bind="vbind"
@close="$emit('close')"
/>
<Success
v-if="component === 'Success'"
v-bind="vbind"
@close="$emit('close')"
/>
<Error
v-if="component === 'Error'"
v-bind="vbind"
@close="$emit('close')"
/>
<button
@click="$emit('close')"
class="button is-ghost is-small"
>
<span class="icon">
<Icon
name="material-symbols:close-rounded"
:size="18"
/>
</span>
</button>
</div>
</template>
<style scoped>
.snackbar {
position: fixed;
z-index: 999;
top: 50px;
left: 0;
right: 0;
margin-inline: auto;
width: fit-content;
max-width: 500px;
background-color: hsl(from var(--bulma-grey-darker) h s l / 0.9);
}
.button.is-ghost {
color: white;
}
.button.is-ghost:hover,
.button.is-ghost.is-hovered {
color: hsl(from white h s l / 0.6);
}
</style>