节点在线、应用在线、配置在线使用令牌查询
大石头 authored at 2021-12-16 19:49:30
2.25 KiB
Stardust
<script setup lang="ts">
/**
 * KPI 指标卡 KpiStat(盒装卡片 + 大号彩色数值 + 图标 + 下方标签)
 * 样式纪律:颜色一律 --el-* 令牌,禁止自定义 CSS 变量与硬编码色值。
 */
import { computed } from 'vue'
import GlassCard from './GlassCard.vue'

type Accent = 'primary' | 'success' | 'warning' | 'danger'

const props = defineProps<{
  label: string
  value: string | number
  unit?: string
  accent?: Accent
  icon?: string
}>()

const valueColor = computed(() => {
  switch (props.accent) {
    case 'primary': return 'var(--el-color-primary)'
    case 'success': return 'var(--el-color-success)'
    case 'warning': return 'var(--el-color-warning)'
    case 'danger': return 'var(--el-color-danger)'
    default: return 'var(--el-text-color-primary)'
  }
})

const iconBg = computed(() => {
  switch (props.accent) {
    case 'primary': return 'var(--el-color-primary-light-9)'
    case 'success': return 'var(--el-color-success-light-9)'
    case 'warning': return 'var(--el-color-warning-light-9)'
    case 'danger': return 'var(--el-color-danger-light-9)'
    default: return 'var(--el-fill-color-light)'
  }
})
</script>

<template>
  <GlassCard class="flex items-center justify-between gap-3 px-4 py-3 transition-shadow hover:shadow-[var(--el-box-shadow)]">
    <div class="flex min-w-0 flex-col justify-center gap-1">
      <div class="flex items-baseline gap-1">
        <span
          data-spec="kpi-value"
          class="text-[30px] font-bold tabular-nums leading-none"
          :style="{ color: valueColor }"
        >{{ value }}</span>
        <span
          v-if="unit"
          class="text-xs text-[var(--el-text-color-regular)]"
        >{{ unit }}</span>
      </div>
      <span class="text-xs text-[var(--el-text-color-regular)]">{{ label }}</span>
    </div>
    <div
      v-if="icon"
      class="flex h-9 w-9 shrink-0 items-center justify-center rounded-lg"
      :style="{ backgroundColor: iconBg }"
    >
      <svg
        class="h-5 w-5"
        viewBox="0 0 24 24"
        fill="none"
        stroke="currentColor"
        stroke-width="1.7"
        stroke-linecap="round"
        stroke-linejoin="round"
        :style="{ color: valueColor }"
      >
        <path :d="icon" />
      </svg>
    </div>
  </GlassCard>
</template>