Components/StatCard
Universal Component

StatCard

Metric card for values, insights, and progress summaries.

This page was migrated by AI, please review carefully

Migration is complete, but please validate against source code and manual review.

StatCard

TxStatCard displays a primary metric with optional icon decoration, insight comparison, or progress ring. Use the default variant for simple metrics, insight for trend deltas, and variant="progress" or progress for bounded percentage summaries.

Basic Usage

Default Variant

Base card layout without trend/progress enhancement.

Demo will load when visible.
<template>
  <TxStatCard
    :value="2847"
    label="Total Plugins"
    icon-class="i-carbon-download text-6xl text-[var(--tx-color-primary)]"
    clickable
  />
</template>

Insight Variant

Shows trend/compare information by passing the insight object.

Demo will load when visible.
<script setup lang="ts">
import NumberFlow from '@number-flow/vue'
import { ref } from 'vue'

const activeUsers = ref(18200)
const activeInsight = ref({
  from: 16800,
  to: activeUsers.value,
  type: 'delta',
  color: 'success',
  iconClass: 'i-carbon-growth',
})

const resourceLoad = ref(42)
const resourceInsight = ref({
  from: 35,
  to: resourceLoad.value,
  type: 'percent',
  color: 'danger',
  iconClass: 'i-carbon-arrow-up-right',
  precision: 1,
})

function bump() {
  const nextUsers = Math.floor(Math.random() * 8000) + 14000
  const nextLoad = Math.floor(Math.random() * 50) + 30

  activeInsight.value = {
    ...activeInsight.value,
    from: activeUsers.value,
    to: nextUsers,
  }
  activeUsers.value = nextUsers

  resourceInsight.value = {
    ...resourceInsight.value,
    from: resourceLoad.value,
    to: nextLoad,
  }
  resourceLoad.value = nextLoad
}
</script>

<template>
  <div style="display: flex; flex-direction: column; gap: 12px;">
    <div style="display: flex; gap: 8px;">
      <TxButton @click="bump">
        Shuffle
      </TxButton>
    </div>

    <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px;">
      <TxStatCard
        :value="activeUsers"
        label="Active Users"
        icon-class="i-carbon-task text-6xl text-[var(--tx-color-success)]"
        :insight="activeInsight"
      />
      <TxStatCard
        :value="resourceLoad"
        label="Resource Load"
        icon-class="i-carbon-chip text-6xl text-[var(--tx-color-warning)]"
        :insight="resourceInsight"
      >
        <template #value>
          <div style="display: flex; align-items: baseline; gap: 6px;">
            <NumberFlow :value="resourceLoad" />
            <span style="font-size: 16px;">%</span>
          </div>
        </template>
      </TxStatCard>
    </div>
  </div>
</template>

Progress Variant

Switches to progress layout and supports shuffle updates.

Demo will load when visible.
<script setup lang="ts">
import NumberFlow from '@number-flow/vue'
import { computed, ref } from 'vue'

const healthProgress = ref(78)
const healthDelay = ref(2)

const healthStatus = computed(() => {
  if (healthProgress.value > 85) {
    return 'Synced'
  }
  return 'Syncing'
})

const healthMeta = computed(() => `${healthStatus.value} · Last sync: ${healthDelay.value}s ago (v2.4.0)`)

function bump() {
  healthProgress.value = Math.floor(Math.random() * 50) + 40
  healthDelay.value = Math.floor(Math.random() * 16) + 2
}
</script>

<template>
  <div style="display: flex; flex-direction: column; gap: 12px;">
    <div style="display: flex; gap: 8px;">
      <TxButton @click="bump">
        Shuffle
      </TxButton>
    </div>

    <TxStatCard
      variant="progress"
      :value="healthProgress"
      label="Cloud Sync"
      :meta="healthMeta"
      :progress="healthProgress"
      icon-class="i-carbon-cloud text-[var(--tx-color-primary)]"
    >
      <template #value>
        <div style="display: flex; align-items: baseline; gap: 6px;">
          <NumberFlow :value="healthProgress" />
          <span style="font-size: 16px;">%</span>
        </div>
      </template>
    </TxStatCard>
  </div>
</template>

API

Props

PropTypeDefaultDescription
valuenumber | string-Primary value shown in the card; numeric values can animate through NumberFlow when available.
labelstring-Metric label shown below the value or at the top for insight/progress layouts.
iconClassstring''Icon class (UnoCSS Icones).
clickablebooleanfalseEnables hover/press states.
insightStatCardInsight-Change indicator object (moves label to top).
variantStatCardVariant'default'Layout variant (default | progress).
progressnumber-Progress percent (0-100). Passing this enables the progress variant.
metastring-Bottom meta line for progress variant.

StatCardInsight

FieldTypeDefaultDescription
fromnumber-Baseline value.
tonumber-Current value.
type'percent' | 'delta''percent'Percent change or absolute delta.
color'success' | 'danger' | 'warning' | 'info' | string-Overrides indicator color.
iconClassstring-Custom indicator icon.
suffixstring-Overrides suffix (default % for percent).
precisionnumber-Decimal precision.

Slots

SlotDescription
valueCustom value area.
labelCustom label area.
metaMeta line for progress variant.