StatCard
ImplementedKPI metric card — 40×40 colored icon + trend pill + 28px/800 value + 12px muted label. White card with 1px border, hover lift -2px + card shadow.
patterns/molecules/statcard.htmlA labelled metric card with optional trend arrow, icon, and unit suffix. Renders as a <div role="article"> or as an <a> wrapper when href is provided.
StatCard
Charts / Stats — Family 5 (Tier 1)
A self-contained KPI tile. Owns its label, value, unit, optional trend (up / down / flat with a directional arrow), and optional leading icon. Forwarded ref lands on the outer wrapper, and the component exposes aria-labelledby / aria-busy for assistive tech and loading-state hooks.
This component supports light and dark mode.
Usage
StatCard is a small, opinionated KPI tile. Pass a label for the caption and a value for the headline number. Numbers go through toLocaleString(); pass a pre-formatted string when you need a currency symbol or a unit that does not belong to unit.
import { StatCard } from '@epasslive/design-system'
<StatCard
label="Tickets sold"
value={12480}
unit="tickets"
trend={{ direction: 'up', value: '+12.4%', label: 'vs last week' }}
/>
<StatCard
label="Avg. order value"
value={68.4}
trend={{ direction: 'flat', value: 'unchanged' }}
/>Trends
The trend prop is an object with a direction ("up" | "down" | "flat") and a value string that is rendered verbatim (so format it the way you want it to read). Direction drives both the arrow glyph and the color — emerald for up, rose for down, muted for flat. An optional label is appended in muted text and included in the aria-label ("Trend increased by +12.4% vs last week").
Loading state
Set loading to swap the body for a three-line shimmer skeleton and expose aria-busy="true" on the wrapper. The skeleton cycles through three opacity phases every 600 ms; the current phase is also exposed as data-skeleton-phase on the skeleton root for end-to-end testing.
Clickable card
Pass href to render the body inside an <a>. The wrapper stays role="article" so the announcement does not change, and the link picks up a teal focus ring (ep-teal) with a 2px offset. Use it for dashboard tiles that drill into a detail page.
Dark mode
The card uses bg-ep-surface-card and border-ep-border, which flip automatically with the active theme. Trend colors stay semantic (emerald = good, rose = bad) on both themes — the icons themselves are inline SVGs using currentColor, so the contrast tracks the surrounding text.
Props
label*stringCaption above the value. Wired to the wrapper via aria-labelledby.
value*string | numberPrimary metric. Numbers are formatted via toLocaleString(); pass a pre-formatted string for non-numeric metrics.
unitstringSuffix appended to the value with muted styling (e.g. "USD", "%", "tickets").
trendStatCardTrendTrend indicator. { direction: "up" | "down" | "flat", value: string, label?: string }. Direction drives the arrow glyph and the color (emerald / rose / muted).
iconReact.ReactNodeLeading icon rendered to the right of the label. Marked aria-hidden so it does not duplicate the label for screen readers.
loadingbooleanfalseWhen true, replaces the body with a three-line shimmer skeleton and sets aria-busy on the wrapper.
classNamestringAdditional classes appended to the inner card container (or the outer wrapper when href is set).
idstringExplicit id. Defaults to "statcard-<react.useId()>". When set, the component generates per-part ids (label/value/trend) by appending "-label", "-value", and "-trend".
hrefstringWhen provided, the body is wrapped in an <a> and the card becomes focusable with a teal focus ring. The card keeps role="article" so it stays announceable.
Props
StatCard
labelstring—valuestring—iconReact.ReactNode—unitstring—Synced from source — no interface JSDoc yet; document on `StatCard.tsx`.
trendStatCardTrend—Synced from source — no interface JSDoc yet; document on `StatCard.tsx`.
loadingbooleanfalseShows the busy state.
hrefstring—Link target URL.
classNamestring—Additional classes on the card container.
idstring'statcard-{useId()}'Explicit id; derives -label/-value/-trend ids.
hintstring—Optional muted hint line under the value (e.g. 'Set the venue capacity' when a metric is unset). Localized by the consumer.
<StatCard />Accessibility
Type
1 ruleARIA
1 ruleUsage
Import
import { StatCard } from "@epasslive/design-system"Example 1
<Card title="Event" body="Description" />Anti-patterns
— Do not hardcode data in molecules
— Avoid complex business logic in molecules