AI-News/frontend/app/components/FlashBanner.vue
2025-12-04 10:04:21 +08:00

52 lines
1.4 KiB
Vue

<template>
<transition name="flash-slide">
<div
v-if="state.show"
class="flash-banner"
:class="state.type"
role="status"
aria-live="polite"
>
<span class="dot" />
<span class="text">{{ state.text }}</span>
</div>
</transition>
</template>
<script setup>
const { state } = useFlash()
</script>
<style scoped>
.flash-banner{
position: fixed;
top: 16px;
left: 50%;
transform: translateX(-50%);
max-width: min(92vw, 720px);
box-shadow: 0 10px 30px rgba(2,6,23,.18);
border: 1px solid rgba(15,23,42,.06);
border-radius: 999px;
padding: 10px 16px 10px 12px;
background: #fff;
color: #0f172a;
display: inline-flex;
align-items: center;
gap: 10px;
z-index: 2147483647; /* 足够大,压过任何遮罩 */
pointer-events: none; /* 不挡页面交互 */
}
.dot{ width:10px; height:10px; border-radius:999px; background:#64748b; }
.text{ font-size:14px; line-height:1.2; }
.success .dot{ background:#16a34a; }
.error .dot{ background:#ef4444; }
.warning .dot{ background:#f59e0b; }
.info .dot{ background:#3b82f6; }
/* .flash-banner { position: fixed; inset: auto auto auto auto; } */
.flash-slide-enter-active,
.flash-slide-leave-active{ transition: all .22s ease; }
.flash-slide-enter-from{ opacity:0; transform: translate(-50%, -8px); }
.flash-slide-leave-to{ opacity:0; transform: translate(-50%, -8px); }
</style>