Files
client-web/src/components/common/LoadErrorState.vue
T

49 lines
2.0 KiB
Vue

<script setup lang="ts">
import { CircleAlert } from '@lucide/vue'
withDefaults(defineProps<{
title: string
message?: string
loading?: boolean
retryText?: string
showRetry?: boolean
compact?: boolean
}>(), {
message: '',
loading: false,
retryText: '重新加载',
showRetry: true,
compact: false,
})
defineEmits<{ retry: [] }>()
</script>
<template>
<section class="load-error-state" :class="{ 'is-compact': compact }" role="alert">
<CircleAlert class="load-error-state__icon" :size="20" aria-hidden="true" />
<div class="load-error-state__content">
<strong>{{ title }}</strong>
<p v-if="message">{{ message }}</p>
<slot name="details" />
</div>
<div v-if="showRetry || $slots.actions" class="load-error-state__actions">
<slot name="actions">
<el-button type="primary" plain :loading="loading" @click="$emit('retry')">{{ retryText }}</el-button>
</slot>
</div>
</section>
</template>
<style scoped>
.load-error-state { display: flex; min-width: 0; align-items: flex-start; gap: 12px; padding: 16px; border: 1px solid var(--el-color-danger-light-7); border-radius: 8px; background: var(--el-color-danger-light-9); color: var(--el-text-color-primary); }
.load-error-state.is-compact { padding: 12px; }
.load-error-state__icon { flex: 0 0 auto; margin-top: 1px; color: var(--el-color-danger); }
.load-error-state__content { min-width: 0; flex: 1; }
.load-error-state__content strong { display: block; font-size: 14px; line-height: 1.5; }
.load-error-state__content p { margin: 4px 0 0; color: var(--el-text-color-secondary); font-size: 13px; line-height: 1.6; overflow-wrap: anywhere; }
.load-error-state__actions { display: flex; flex: 0 0 auto; flex-wrap: wrap; gap: 8px; }
.load-error-state__actions :deep(.el-button) { margin-left: 0; }
@media (max-width: 720px) { .load-error-state { flex-wrap: wrap; } .load-error-state__content { flex-basis: calc(100% - 36px); } .load-error-state__actions { width: 100%; padding-left: 32px; } .load-error-state__actions :deep(.el-button) { min-height: 44px; } }
</style>