Skip to content

Stat Tile

One headline number with its label, change and optional trend line.

Preview

Available balance
₹1,84,250
+6.4% bettervs last month

Installation

pnpm add @syntara/react @syntara/tokens
import { StatTile, StatTileGroup, formatDelta } from '@syntara/react';

Usage

import { StatTile } from '@syntara/react';

export function Balance() {
  return <StatTile label="Available balance" value="₹1,84,250" delta={0.064} deltaLabel="vs last month" />;
}

Examples

Grid with sparklines

A StatTileGroup where lower is better for two of the figures.

Claims paid
₹4,12,800
+11.2% bettervs last month
Avg. settlement time
3.4 days
−18% bettervs last month
Rejected claims
14
+7.5% worsevs last month

Captions, icons and variants

A caption instead of a delta, a no-change delta, and the small outline tile.

Members covered
4
2 adults, 2 children
Wallet balance
₹8,500
0%no change this month
Open requests
0
Updated 5 min ago

Editorial

Case-study figures: a large regular-weight number over a quiet label, in hairline tiles.

renewals a month
12k+
to a quote
45s
in use
2 yrs

Good and bad change

Two rises, one good and one bad (positiveIsGood={false}), and no change. Bad news shows an alert mark as well as its colour.

Revenue
₹12,48,300
+6.4% bettervs last month
Refunds
₹38,420
+3.1% worsevs last month
Active cards
1,286
0%no change

Accessibility

No keyboard interaction of its own.

  • Standalone, a tile is a <dl> (label = <dt>, value and change = <dd>); inside StatTileGroup the group is the <dl> and each tile a <div>.
  • Good or bad change is never colour alone (WCAG 1.4.1). Good news shows a trend arrow, bad news an alert mark in its place, and no change no mark; the sign shows the direction. Screen readers hear betterLabel or worseLabel after the change ("+3.1% worse").
  • The delta uses a true minus (−) and is isolated in the locale's direction, so "+6.4%" never renders as "6.4%+" on right-to-left pages.
  • The sparkline is aria-hidden; put anything that matters in the value, delta or caption. It mirrors on right-to-left pages, with the trend icon.

Guidelines

Do

  • Name the comparison period in deltaLabel.
  • Set positiveIsGood={false} for metrics where down is good.
  • Pass betterLabel and worseLabel in the page's language when it isn't English.
  • Format the value with Intl for the user's locale before passing it.

Don’t

  • Don't put more than one number in value.
  • Don't use the sparkline as the only evidence of a trend.

API reference

StatTile

labelRequired
ReactNode

What the number measures.

valueRequired
ReactNode

The figure, already formatted (currency, units, compact notation).

delta
number

Change as a fraction: 0.064 → +6.4%. Shown as a signed pill: good news with a trend arrow, bad news with an alert mark, no change with no mark.

deltaLabel
ReactNode

What the change is measured against, e.g. "vs last month".

positiveIsGood
boolean

Whether an increase is good news. false for costs, churn, wait times.

Default true

betterLabel
string

Read by screen readers after a change that is good news ("+6.4% better"). Translate it with the page.

Default 'better'

worseLabel
string

Read by screen readers after a change that is bad news ("+3.1% worse"). Translate it with the page.

Default 'worse'

deltaFormatOptions
Intl.NumberFormatOptions

Overrides the delta format.

Default { style: 'percent', maximumFractionDigits: 1, signDisplay: 'exceptZero' }

caption
ReactNode

A quiet line under the value, used instead of a delta.

icon
ReactNode

Decorative icon at the top inline-end.

sparkline
number[]

Recent values, oldest first (≥2 finite points). Decorative line with a 12% area fill and an end dot.

size
  • sm
  • mddefault
  • lg

Value size: xl, 2xl or 3xl.

variant
  • defaultdefault
  • outline
  • ghost
  • editorial

Same chrome options as Card; ghost for tiles inside a card. editorial = a quiet inset figure for a card (a showcase card's results): the number first, large and regular weight, the label beneath, a hairline edge on a slightly lifted face (surface.canvas light, surface.default dark), no shadow; its corner follows the card's.

StatTileGroup

children
ReactNode

StatTiles. Rendered as one <dl> in a responsive grid (~224px minimum per column).

Tokens

The semantic tokens this component reads, grouped by what they control. Swatches show this site’s theme; change a tenant’s brand and the component follows with no code change.

Colour9
border.defaultborder.subtlefeedback.danger.bgsurface.defaultsurface.raisedtext.brandtext.defaulttext.subtlesurface.canvas
Type17
font.bodyfont.headingfont.size.2xlfont.size.3xlfont.size.4xlfont.size.mdfont.size.smfont.tracking.2xlfont.tracking.3xlfont.tracking.4xlfont.tracking.mdfont.tracking.smfont.weight.mediumfont.weight.regularline-height.normalline-height.snugline-height.tight
Space and size8
card-insetsection-gapspace.1space.16space.2space.4space.8space.3
Shape1
radius.container
Depth2
hairlineshadow.raised
Motion5
motion.duration.fastmotion.duration.slowmotion.duration.springmotion.easingOutmotion.spring
Other2
sheenrim