Files
web-temp/layers/components/molecules/loading/Local.vue

56 lines
1.9 KiB
Vue

<script setup lang="ts">
import { useLoadingStore } from '#layers/stores/useLoadingStore'
const loadingStore = useLoadingStore()
const localLoadings = computed(() => Object.entries(loadingStore.localLoadings))
const canTeleport = (localId: string) => {
if (!import.meta.client) {
return false
}
return !!document.getElementById(localId)
}
</script>
<template>
<template v-for="[localId, loadingInfo] in localLoadings" :key="localId">
<Teleport v-if="canTeleport(localId)" :to="`#${localId}`">
<Transition
enter-active-class="transition-opacity duration-300 ease-in-out"
enter-from-class="opacity-0"
enter-to-class="opacity-100"
leave-active-class="transition-opacity duration-300 ease-in-out"
leave-from-class="opacity-100"
leave-to-class="opacity-0"
>
<div
v-if="loadingInfo.active"
class="fixed inset-0 bg-black/80 flex items-center justify-center z-[9999]"
>
<!-- 메인 스피너 -->
<div class="relative w-16 h-16">
<!-- 외부 -->
<div
class="absolute inset-0 border-4 border-transparent border-t-blue-500 rounded-full animate-spin"
/>
<!-- 중간 -->
<div
class="absolute inset-1 border-4 border-transparent border-t-purple-500 rounded-full animate-spin"
style="animation-delay: -0.3s"
/>
<!-- 내부 -->
<div
class="absolute inset-2 border-4 border-transparent border-t-cyan-500 rounded-full animate-spin"
style="animation-delay: -0.6s"
/>
<!-- 중심 -->
<div
class="absolute inset-3 border-4 border-transparent border-t-emerald-500 rounded-full animate-spin"
style="animation-delay: -0.9s"
/>
</div>
</div>
</Transition>
</Teleport>
</template>
</template>