Files
KArtSell.Aegis/docs/Design/kbx-foundation-v36/packages/kbx-ui/src/components/KbxTemplateStateBoundary.vue
T

40 lines
1.9 KiB
Vue

<script setup lang="ts">
import type { KbxAsyncState } from '@kbx/contracts'
import KbxDataState from './KbxDataState.vue'
withDefaults(defineProps<{
state?: KbxAsyncState
refreshing?: boolean
idleTitle?: string
idleDetail?: string
idleActionLabel?: string
emptyTitle?: string
emptyDetail?: string
errorTitle?: string
errorDetail?: string
retryLabel?: string
}>(), {
state:'ready', refreshing:false,
idleTitle:'조회 전입니다.', idleDetail:'조회조건을 확인한 후 조회하세요.', idleActionLabel:'',
emptyTitle:'', emptyDetail:'', errorTitle:'', errorDetail:'', retryLabel:'다시 조회',
})
const emit=defineEmits<{ retry:[]; idleAction:[] }>()
</script>
<template>
<div class="kbx-template-state" :data-template-state="state" :aria-busy="state==='loading' || refreshing">
<KbxDataState v-if="state==='idle'" state="idle" :title="idleTitle" :detail="idleDetail" :action-label="idleActionLabel" @action="emit('idleAction')" />
<KbxDataState v-else-if="state==='loading'" state="loading" />
<KbxDataState v-else-if="state==='empty'" state="empty" :title="emptyTitle" :detail="emptyDetail" />
<KbxDataState v-else-if="state==='error'" state="error" :title="errorTitle" :detail="errorDetail" :action-label="retryLabel" @action="emit('retry')" />
<template v-else>
<div v-if="refreshing" class="kbx-template-state__refresh" role="status" aria-live="polite">최신 내용을 조회 중입니다. 현재 화면은 유지됩니다.</div>
<slot />
</template>
</div>
</template>
<style scoped>
.kbx-template-state{min-height:0;height:100%;display:flex;flex-direction:column}.kbx-template-state__refresh{min-height:var(--kbx-template-refresh-height);display:flex;align-items:center;padding:0 var(--kbx-space-2);border:var(--kbx-border-width) solid var(--kbx-color-info-border);background:var(--kbx-color-info-surface);color:var(--kbx-color-text-muted);font-size:var(--kbx-font-xs)}
</style>