All files / src/shared/ui AsyncState.vue

60% Statements 3/5
53.84% Branches 14/26
0% Functions 0/2
60% Lines 3/5

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43                                            17x           5x               5x            
<script setup lang="ts">
import { PjButton } from "@plain-journal/ui";
 
defineProps<{
  loading?: boolean;
  loadingMessage?: string;
  error?: string | null;
  errorEyebrow?: string;
  errorTitle?: string;
  retryLabel?: string;
  empty?: boolean;
  emptyEyebrow?: string;
  emptyTitle?: string;
  emptyMessage?: string;
}>();
 
defineEmits<{
  retry: [];
}>();
</script>
 
<template>
  <div v-if="loading" class="async-state" role="status" aria-live="polite">
    <span class="loading-line" />
    <span class="loading-line loading-line--short" />
    <p>{{ loadingMessage ?? "正在读取信息…" }}</p>
  </div>
  <div v-else-if="error" class="async-state async-state--error" role="alert">
    <p class="eyebrow">{{ errorEyebrow ?? "暂时无法继续" }}</p>
    <h2>{{ errorTitle ?? "信息没有被加载为成功。" }}</h2>
    <p>{{ error }}</p>
    <PjButton variant="text" @click="$emit('retry')">
      {{ retryLabel ?? "重新读取 →" }}
    </PjButton>
  </div>
  <div v-else-if="empty" class="async-state">
    <p class="eyebrow">{{ emptyEyebrow ?? "没有匹配结果" }}</p>
    <h2>{{ emptyTitle ?? "这里暂时没有商品。" }}</h2>
    <p>{{ emptyMessage ?? "可以调整查找词或返回全部商品。" }}</p>
  </div>
  <slot v-else />
</template>