MetricCard
A dashboard tile showing one number, its trend, and an optional sparkline.
Active repositories
4,820
43%vs. previous 24 hours
<template> <MetricCard label="Active repositories" :value="activeRepoCount.toLocaleString()" :trend="repoTrend" /></template>Props
| Name | Type | Default |
|---|---|---|
| label | string | - |
| value | string | number | - |
| valueSuffix | string | - |
| tooltip | string | - |
| tooltipLabel | string | "More info" |
| subtitle | string | - |
| trend | number | null | - |
| trendGoodWhen | "up" | "down" | "up" |
| muted | boolean | false |
| trendFormat | (trend: number) => string | unsigned en-US percent, e.g. "12%" |
| trendLabel | string | - |
| isLoading | boolean | false |
Slots
| Name | Description |
|---|---|
| chart | Optional sparkline or other small chart, rendered below the value/subtitle. |
Guidelines
Do
- Use for a single at-a-glance KPI in a dashboard grid - a count, a rate, a cost.
- Set
trendGoodWhen="down"for metrics where a decrease is the good outcome (open critical findings, MTTR). - Pass an already-formatted
value(toLocaleString(),formatUsd(), etc.) - this component doesn't format numbers itself. UsevalueSuffixfor a unit that reads dimmer than the number ("/100" on a score).
- Put a
Sparklinein the#chartslot for a cost or volume whose recent shape matters more than one more number. - From an i18n'd app, also pass
tooltipLabel(the translated "More info") so the tooltip trigger's accessible name is localized. - From an i18n'd app, pass
trendFormat(a locale-aware percent formatter) andtrendLabel(a translated "12% up"/"12% down") - the built-in badge text is an unsigned en-US percent, and withouttrendLabela screen reader hears only the number, not the direction.
Don't
- Don't drop it standalone outside a stat grid - like Table's cell renderers, it's meant to render alongside its siblings, not on its own.
- Don't pass a signed/labelled trend string (
"+12%") - pass the raw ratio (0.12) and let the component format and color it. - Don't look for a horizontal layout, a leading icon or a header link - a MetricCard is one vertical block. A linked or icon-led summary is a Card with
title/icon, or a LinkCard.
Examples
Minimal
Label, value and the trend badge. The badge hides itself for a null, zero or non-finite trend.
Active repositories
128
12%<template> <MetricCard label="Active repositories" :value="activeRepoCount.toLocaleString()" :trend="repoTrend" /></template>With tooltip and sparkline
tooltip explains the metric beside its label; subtitle names the comparison period; the chart slot takes a Sparkline. trend-good-when flips the badge color for a metric where less is better.
Total cost
$2,310
8%Last 30 days
<template> <MetricCard label="Total cost" :value="formatUsd(totals.costUsd)" tooltip="Spend across every scan type in the selected range." subtitle="Last 30 days" :trend="costTrend" trend-good-when="down" > <template #chart> <Sparkline :data="daily" :value="(d) => d.costUsd" /> </template> </MetricCard></template>Value suffix and point delta
value-suffix renders a dimmed unit after the number; trend-format turns a raw point delta into the badge text instead of the default percent.
Security score
82/100
3vs. last 30 days
<template> <MetricCard label="Security score" :value="score ?? '-'" :muted="score === null" value-suffix="/100" :trend="scoreDelta" :trend-format="(delta) => String(Math.abs(delta))" /></template>Loading
is-loading swaps the value and subtitle for skeletons and reserves a band where the sparkline will be, so the card keeps its size when data lands.
Total cost
<template> <MetricCard label="Total cost" :value="formatUsd(totals.costUsd)" subtitle="Last 30 days" :is-loading="isPending" > <template #chart> <Sparkline :data="daily" :value="(d) => d.costUsd" /> </template> </MetricCard></template>