72 lines
1.4 KiB
Vue
72 lines
1.4 KiB
Vue
<!-- 媒体加载状态组件,统一展示加载中和加载失败反馈。 -->
|
||
<script setup lang="ts">
|
||
import { CircleAlert, LoaderCircle } from "@/icons";
|
||
|
||
withDefaults(defineProps<{ failed?: boolean; compact?: boolean; label?: string; errorLabel?: string }>(), {
|
||
failed: false,
|
||
compact: false,
|
||
label: "媒体加载中",
|
||
errorLabel: "媒体加载失败",
|
||
});
|
||
</script>
|
||
|
||
<template>
|
||
<div
|
||
class="media-loading-state"
|
||
:class="{ failed, compact }"
|
||
>
|
||
<CircleAlert
|
||
v-if="failed"
|
||
:size="24"
|
||
:stroke-width="1.7"
|
||
/>
|
||
<LoaderCircle
|
||
v-else
|
||
class="media-loading-spinner"
|
||
:size="26"
|
||
:stroke-width="1.8"
|
||
/>
|
||
<span>{{ failed ? errorLabel : label }}</span>
|
||
</div>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.media-loading-state {
|
||
position: absolute;
|
||
inset: 0;
|
||
z-index: 3;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 9px;
|
||
color: var(--web-media-loading-text);
|
||
background: var(--web-media-state-mask);
|
||
font-size: 12px;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.media-loading-state.failed {
|
||
color: var(--web-media-error-text);
|
||
}
|
||
|
||
.media-loading-state.compact span {
|
||
display: none;
|
||
}
|
||
|
||
.media-loading-state.compact svg {
|
||
width: 19px;
|
||
height: 19px;
|
||
}
|
||
|
||
.media-loading-spinner {
|
||
animation: media-loading-spin 0.9s linear infinite;
|
||
}
|
||
|
||
@keyframes media-loading-spin {
|
||
to {
|
||
transform: rotate(360deg);
|
||
}
|
||
}
|
||
</style>
|