Theme studio

Design a theme, preview it live, then export it. Saved in this browser.

Quick picks #10b981
Generated scale
50100200300400500600700800900
Some text is below AA

MetricCard

  • Needs review
  • WCAG 2.2 evidence
  • RTL

A headline number with its label and context: type picks the layout, simple, trend, sparkline, progress, comparison or icon, and isLoading shows the Figma loading placeholder. Presentational: no state and no "use client", so it renders in React Server Components. The card is a labelled group (label, value, delta, caption in reading order). The delta badge says whether the figure went up or down and whether that is good or bad in an arrow and in hidden text, never by colour alone (WCAG 1.1.1, 1.4.1); the progress bar is a named progressbar with the figure as its text (4.1.2); the loading state is aria-busy with hidden text (4.1.3). The layout adapts to the card's own width through a container query, and long or translated text wraps (1.4.10, 1.4.12). Use at most four to six cards in a row; use a chart for analysis. Consumer duties: formatting numbers for the locale, the label and caption wording, the text alternative of a sparkline, and announcing when loaded data replaces the placeholder.

import { MetricCard } from "@nexera-ui/react";
Loading example…
13
examples
15
props
3
live controls
1
platform
8
WCAG criteria
5
blocks use it

Try every prop. Copy the code.

Change the props and the code updates. Check light and dark, LTR and RTL, and phone width.

Loading…
label
trend
isLoading
Generated code
import { MetricCard } from "@nexera-ui/react";

<MetricCard />

Examples 12

The same examples as Storybook, rendered live. Open Code to copy one.

Trend

Type=Trend: a delta badge after the value.

Loading example…

With sparkline

Type=Sparkline: pass a Sparkline chart in the sparkline slot; it drops below the value when the card is narrow.

Loading example…

Progress

Type=Progress: a named progress bar that reads the figure.

Loading example…

Comparison

Type=Comparison: a delta against the previous period; here a fall is good news (trend="down-good").

Loading example…

With icon

Type=Icon: an icon tile before the label.

Loading example…

With info

info puts a control or icon at the end of the header, for example a tooltip that explains the metric.

Loading example…

Loading

State=Loading (isLoading): three pulsing bars, aria-busy and visually hidden text.

Loading example…

Kpi row

The Figma Chart/KPI/* family (Headcount, Attrition, Open roles, Time to hire) folded into MetricCard type="trend" (owner decision D1): the same layout with different data.

Loading example…

Long content

Long and translated text wraps; the figure wraps rather than truncating.

Loading example…

Right to left

Right-to-left: the text aligns to the start, the delta keeps its arrow, numbers stay left-to-right.

Loading example…

Narrow container

A 14 rem container: the card keeps its padding and the value row wraps.

Loading example…

Props 15

Press "Try it" on a card to load that prop into the playground.

15 props shown

typeNexera
"icon" | "trend" | "sparkline" | "simple" | "progress" | "comparison"

Layout of the card: simple (value and caption), trend (value, delta badge, caption), sparkline (value, delta badge and a sparkline), progress (value and a bar), comparison (value, delta badge against the previous period) and icon (an icon tile before the label). The Figma Chart/KPI/* components (Headcount, Attrition, Open roles, Time to hire) are type="trend" cards: the same layout with different data. Progress card.

Default simple
progressNexera
number

Only with type="progress". How far along, 0 to 100. The bar is a progressbar named by the label and announcing value ("86%") as its text.

Default –
progressLabelNexera
string

Only with type="progress". Replaces the label as the accessible name of the bar, for example "Profile completion, employees with a complete profile". Translate it.

Default –
label*Nexera
ReactNode

What is measured. Short noun phrase. It names the card for assistive technology (the card is a labelled group), and wraps instead of truncating.

Default –
value*Nexera
string

The headline figure. Format numbers, currency and dates for the reader's locale (Intl.NumberFormat) and include the unit.

Default –
captionNexera
ReactNode

Context under the figure. Shown when provided.

Default –
iconNexera
ReactNode

Icon in the tile before the label, shown with type="icon". 18 px, decorative.

Default –
infoNexera
ReactNode

Content at the end of the header. Pass an IconButton inside a Tooltip that explains how the metric is calculated, or a plain decorative icon. Nothing is drawn by default: a bare icon would look like a control that does nothing.

Default –
deltaNexera
string

The change since the comparison period, for example "+4.2%", shown after the value with type trend, sparkline or comparison. Format it for the locale and include the sign.

Default –
trendNexera
"up-good" | "up-bad" | "down-good" | "down-bad" | "flat"

Direction and meaning of delta: an arrow for the direction and a green, red or grey badge for good, bad or no change, plus hidden text, so neither relies on colour alone for assistive technology. Figma's samples use up-good for trend and sparkline and down-good for comparison.

Default up-good
deltaLabelsNexera
Partial<Record<DeltaBadgeTrend, string>>

Texts read after delta, per trend ("Increase, good"); see DeltaBadge. Translate all five for your locale.

Default –
sparklineNexera
ReactNode

The sparkline for type="sparkline": pass a Sparkline chart with its own text alternative. It sits after the value on the same row from a 20 rem container, below it in a narrower card. Replaces nothing when type is another value.

Default –
isLoadingNexera
boolean

Shows a placeholder instead of the content: three pulsing bars. The card is aria-busy and carries visually hidden text (loadingLabel), so assistive technology knows the figure is not there yet (WCAG 4.1.3). Announce the result when the data arrives if it matters.

Default false
loadingLabelNexera
string

Visually hidden text of the loading state. Translate it.

Default Loading
classNameNexera
string

Extra classes, merged last so they win over the defaults.

Default –

* Required. React Aria props shown are the ones most apps use; the component accepts the rest of its React Aria props too.

Accessible by default.

Built on React Aria, and covered by the WCAG 2.2 evidence generated on every build.

WCAG 2.2 evidence

5 direct · 3 supporting
  • 1.1.1Non-text ContentLevel A · tested directly
  • 1.3.1Info and RelationshipsLevel A · tested directly
  • 1.4.1Use of ColorLevel A · tested directly
  • 1.4.10ReflowLevel AA · supporting test
  • 1.4.12Text SpacingLevel AA · supporting test
  • 2.3.3Animation from InteractionsLevel AAA · supporting test
  • 4.1.2Name, Role, ValueLevel A · tested directly
  • 4.1.3Status MessagesLevel AA · tested directly

Fits any width.

Nexera components respond to the space they are given. Drag the corner of the frame, or pick a width.

0 px · drag the corner

Styling hooks

Pass className to add Tailwind classes (merged last). State is exposed as data attributes, so you can style it with variants like data-pressed:.

Usage
<MetricCard className="shadow-sm" />

Used in blocks

Related components