Skip to content

Documentation

neelam-ui

Search documentation

Getting Started
Forms
Overlays
Navigation
Data Display
Layout
AI & Chat
Blocks
GitHub repository

Stat Card

The “big number, and which way it's going” tile a dashboard overview is built from — label, value, an optional signed delta, and an optional sparkline.

Active users
12.9KIncreased by+12.4%vs. previous 30 days
Avg. response time
248 msIncreased by+6.2%vs. previous 30 days

Usage#

import { StatCard } from "neelam-ui";
 
<StatCard
  label="Active users"
  value="12.9K"
  delta={0.124}
  deltaLabel="vs. previous 30 days"
  trend={[180, 190, 210, 240, 290, 340]}
/>

value is pre-formatted by you — 12.9K, $4.2M, 3.4 hrs. delta is a signed ratio, so 0.124 renders as +12.4%; override the rendering with formatDelta.

It wraps Card rather than restyling a bare div, so a KPI row and the cards around it share one surface, border, and shadow.

Up is not always good#

deltaDirection decides the delta's colour, because a rise is not universally good news:

  • "up-is-good" (the default) — active users, revenue.
  • "down-is-good" — response time, error rate, churn.
  • "neutral" — no judgement, rendered muted.

Hard-coding green-for-up colours half a dashboard wrong

A 6% rise in average response time is bad news shown in green if you leave the default in place. Set deltaDirection on every metric where falling is the win — the demo above does exactly this for response time.

The delta never relies on colour alone#

An arrow icon carries the direction visually, and an sr-only "increased"/"decreased" carries it to assistive tech. The green or red is reinforcement, not the signal (WCAG 1.4.1).

Trend#

trend renders a Sparkline under the value. Ten to fifteen points reads best; the sparkline is decorative, since the number it trends is already stated right above it.

Typography#

The value uses the font's default proportional figures, deliberately not tabular-nums: tabular figures give every digit a zero's width, which reads loose at display sizes. Tabular figures belong in Table's columns, where digits must line up between rows.

Loading#

StatCard is presentation only — no fetching, polling, or loading state. Show one before its data arrives by composing a Skeleton into the value slot:

<StatCard label="Active users" value={<Skeleton className="h-8 w-20" />} />

Keyboard#

Keyboard shortcuts
KeyBehaviour
TabNot focusable. A stat card is a readout — wrap it in a link yourself if it should drill through.

Accessibility#

  • The delta's direction is available three ways: the arrow's shape, the sr-only "increased"/"decreased" text, and the sign in the formatted percentage. Colour is the fourth, not the first.
  • icon is decorative and hidden from assistive tech — it always duplicates the label beside it.
  • The sparkline is aria-hidden, since the headline value states the same thing in words.
  • deltaLabel names the comparison period. A delta without one is a number the reader cannot interpret — always say what it is measured against.

API reference#

Props for StatCard
PropTypeDefault
labelrequired

What the number measures, in sentence case and without a trailing colon.

ReactNode
valuerequired

The headline number, pre-formatted by the caller (`12.9K`, `$4.2M`, `3.4 hrs`).

ReactNode
delta

Signed change over the comparison period, as a ratio — `0.124` is a 12.4% rise.

number
deltaDirection

Which way is good news, deciding the delta's color. Defaults to `"up-is-good"`.

enumup-is-good
deltaLabel

Names the period the delta is measured against, e.g. `"vs. previous 30 days"`.

ReactNode
formatDelta

Overrides the default signed-percentage rendering of `delta`.

((delta: number) => string)
icon

A leading icon for the metric. Decorative — it's hidden from assistive tech.

ReactNode
trend

A short series rendered as a `Sparkline` under the value. Ten to fifteen points reads best.

number[]

Also accepts every native <div> attribute except title, which is replaced by label.