Skip to content

Stat

One key number with its label and an optional trend, shown with an arrow icon and words.

  • Free core, MIT
  • Version 2.0.0-rc.1
  • APG pattern: Static text

Examples

These are the real React components. Use them with a mouse, touch or keyboard, and switch the theme and density for every example at once.

Default

Monthly revenue

£12,480

Show the code

Default, code

<Stat label="Monthly revenue" value="£12,480" />

With a trend

Monthly revenue

£12,480

12% up on September

Show the code

With a trend, code

<Stat
  label="Monthly revenue"
  value="£12,480"
  trend={{ direction: 'up', text: '12% up on September', sentiment: 'positive' }}
/>

Row

Active members

1,204

38 more than last week

Churn

2.1%

0.4 points up

Open tickets

17

No change

Show the code

Row, code

<div className="grid grid-cols-1 gap-gap-lg sm:grid-cols-3">
  <Stat label="Active members" value="1,204" trend={{ direction: 'up', text: '38 more than last week', sentiment: 'positive' }} />
  <Stat label="Churn" value="2.1%" trend={{ direction: 'up', text: '0.4 points up', sentiment: 'negative' }} />
  <Stat label="Open tickets" value="17" trend={{ direction: 'flat', text: 'No change' }} />
</div>

Tile

Monthly revenue

£12,480

12% up on September, the best month this year

£11,140 in September

Churn

2.1%

0.4 points up

1.7% in September

Show the code

Tile, code

function Sparkline() {
  return (
    <svg viewBox="0 0 120 32" className="h-8 w-full text-chart-1" aria-hidden="true" preserveAspectRatio="none">
      <polyline points="0,26 15,22 30,24 45,16 60,18 75,10 90,12 105,6 120,4" fill="none" stroke="currentColor" strokeWidth="2" vectorEffect="non-scaling-stroke" />
    </svg>
  );
}

<div className="grid max-w-md grid-cols-2 gap-gap-md">
  <Card><CardContent>
    <Stat label="Monthly revenue" value="£12,480" trend={{ direction: 'up', text: '12% up on September, the best month this year', sentiment: 'positive' }} compare="£11,140 in September" sparkline={<Sparkline />} />
  </CardContent></Card>
  <Card><CardContent>
    <Stat label="Churn" value="2.1%" trend={{ direction: 'up', text: '0.4 points up', sentiment: 'negative' }} compare="1.7% in September" />
  </CardContent></Card>
</div>

Tokens

The 6 design tokens Stat reads, with the value each has in the theme and density chosen above. Change a token and the component follows, in Figma and in code.

Show all 6 tokens
Tokens Stat reads
TokenValue nowCSS variable
color.text.danger…--sd-color-text-danger
color.text.default…--sd-color-text-default
color.text.secondary…--sd-color-text-secondary
color.text.success…--sd-color-text-success
spacing.gap.xs…--sd-spacing-gap-xs
spacing.stack.xs…--sd-spacing-stack-xs

Install

The npm package isn’t published yet. When it is, this is the install line; until then, this page runs the same build of the package (from commit fa3abf8).

Install

npm i @superduperui/react @superduperui/tokens

Import

import { Stat } from "@superduperui/react"

Props

Stat also takes the props of the React Aria component it’s built on.

Stat props
PropTypeWhat it does
labelrequiredstringWhat the number is ("Monthly revenue").
valuerequiredReactNodeThe value, already formatted ("£12,480").
trend{ direction: 'up' | 'down' | 'flat'; text: string; /** Is this direction good? Sets the colour; the words carry the meaning. */ sentiment?: 'positive' | 'negative' | 'neutral' }Change since the last period, as text ("12% up on September"). Shown with an arrow icon and words, never colour alone.
compareReactNodeThe figure it is compared with, in words ("£11,140 in September"). Shown under the trend in the secondary colour.
sparklineReactNodeA small chart under the figures (a sparkline). Decorative, or named by itself; the trend or compare carries the same news in words.
headingLevel2 | 3 | 4 | 5 | 6Heading level of the label when the stat starts a section of the outline (2.4.10). Default: not a heading.

When to use it

Use it for

  • Dashboards and summaries
  • Usage and billing overviews

Use something else for

  • Long lists of numbers: use Table
  • Trends shown only by colour

Accessibility

Screen readers announce "Monthly revenue, £12,480, 12% up on September".

WCAG 2.2 AAA criteria the component meets in Comfortable density: 1.4.6, 1.4.9, 2.3.2.

Not interactive: density changes spacing only.

What your product still has to do

  • Write the trend as words ("12% up on September")
  • Write the comparison as words too; a sparkline only repeats them

Shared patterns it ships with: 2.4.10 (headingLevel).

This release’s test results

Test results for Stat in this release
axe-core (WCAG A, AA, AAA and best practice)100 runs across every story, theme, density and width: 0 violations
Rendered text contrast360 text runs: 0 below 7:1, lowest 8.43:1
Target size0 targets: 0 under 44px in Comfortable
Focus appearance (2.4.13)0 focus stops in 0 browser engines: all pass

Manual passes with VoiceOver and NVDA haven’t been done yet.

In Figma

The Figma component is Stat, with Trend (Up, Down, Flat); Sentiment (Positive, Negative, Neutral). The Figma library isn’t published yet.

Figma to code: Label → label; Value → value; Trend → trend.direction (Up = "up", Down = "down", Flat = "flat"); Sentiment → trend.sentiment (Positive = "positive", Negative = "negative", Neutral = "neutral"); Trend text → trend.text when Show trend; Compare → compare when Show compare; Sparkline → sparkline.