Skip to content
Cynosurev0.5.0
SearchStorybookGitHubnpmColour mode: System. Switch to Light

Components / Feedback and display

Stat

A figure with its label, a KPI tile: the value with an optional unit, the change since last time and a line of context, on a Card. With href the whole tile is one link to the figure's detail. For several facts about one record, use DescriptionList instead.

Default

When to useLink to "When to use"

  • Dashboards and overviews: the few numbers someone opens the page to see.
  • A figure that leads somewhere: href makes the tile a link to the report behind it.

Use something else when:

  • there are many facts about one thing (a record's details, a settings summary): DescriptionList
  • the numbers are rows to compare: Table
  • the figure is progress towards a goal: ProgressBar

UsageLink to "Usage"

tsx
Copy
import { Grid, Stat } from "@arshad-shah/cynosure";
import { users } from "@arshad-shah/cynosure/icons";

<Stat label="Revenue" value="£12,400" delta={{ value: "+12%" }} description="vs last month" />
<Stat label="p95 latency" value="184" unit="ms" delta={{ value: "-8%", tone: "success" }} />
<Stat label="Members" value="312" icon={users} href="/members" />

Change since last timeLink to "Change since last time"

delta draws an arrow and the change in a tone, and gives screen readers a sentence such as "up 12%". The direction comes from the value's sign (+ is up, - or − is down, anything else is flat) unless direction says otherwise. Up is success and down is danger; set tone when down is good news, as for costs or errors.

Delta direction tone and arrow

The spoken words are English by default. labels takes a function per direction, given the value without its sign:

tsx
Copy
<Stat
  label="Chiffre d'affaires"
  value="12 400 €"
  delta={{ value: "+12 %" }}
  labels={{ up: (v) => `en hausse de ${v}`, down: (v) => `en baisse de ${v}`, flat: (v) => `stable à ${v}` }}
/>

Units, icons and alignmentLink to "Units, icons and alignment"

unit is written after the value, smaller. icon adds a decorative IconTile at the start; align="center" puts it above and centres everything.

SizesLink to "Sizes"

size sets the value, the label, the icon tile and the card's padding together.

Sizes

Several statsLink to "Several stats"

There is no StatGroup: put the stats in a Grid. When they form a set, make it a list with as="ul" on the Grid and as="li" on each Stat; a linked stat keeps its list item and puts the link inside it.

List of stats

PropsLink to "Props"

Every prop of Stat
PropWhat it doesTypeDefault
labelRequired
What is measured ("Revenue"). Read before the value.ReactNode
valueRequired
The figure ("£12,400"). Digits are tabular, so stats in a row line up.ReactNode
unit
A unit written after the value, smaller ("ms", "users").ReactNode
description
A line under the value: what the figure covers ("Last 30 days") or how it compares ("vs last month").ReactNode
delta
The change since last time: an arrow, the value in a tone, and a spoken direction ("up 12%").StatDelta
icon
An icon on an IconTile at the start of the stat. Decorative: the label names the stat.IconData
iconTone
Colour of the icon tile. Default "accent".Tone"accent"
size
Size of the value, the text, the icon tile and the padding. Default "md".Size"md"
align
start: icon beside the text, text at the start. center: icon above, everything centred. Default "start"."start" | "center""start"
variant
The card's look, as Card's: surface raised, outline border only, soft tinted. Default "surface"."soft" | "outline" | "surface""surface"
as
Element of a static stat: li inside a list of stats, article for a stat that stands alone. Default "div"."div" | "article" | "li""div"
href
Makes the whole stat a link to the figure's detail (through Card, so unsafe schemes are not linked).string
target
With href: where it opens, e.g. _blank.string
onClick
With href: called when the link is followed, before the browser navigates.MouseEventHandler<HTMLElement>
labels
Replace the built-in English words spoken with the delta.Partial<StatLabels>
className
Added to the root element, for layout.string
style
Layout only. Restyle through --cy-stat-* tokens.CSSProperties

Generated from the type definitions in @arshad-shah/cynosure 0.5.0.

Behaviour and accessibilityLink to "Behaviour and accessibility"

Behaviour and accessibility, table 1
InputResult
Click, tap, Enter on a stat with hrefFollows the link (onClick runs first)
TabFocuses a linked stat, with Card's focus ring. A static stat is not focusable
  • Reading order: the label and the figures are a description list. The label is the term and the value, delta and description are its definitions, so a screen reader reads "Revenue, £12,400, up 12%, vs last month".
  • Delta: the visible figure is hidden from assistive technology and a visually hidden sentence is read instead, so the direction never depends on colour or the arrow.
  • Icon: decorative; the label names the stat.
  • Link: one link named by the stat's text, with nothing interactive inside. Unsafe schemes such as javascript: are not linked.
  • Digits are tabular, so figures in a row of stats line up.

TouchLink to "Touch"

A linked stat is a whole Card, well above the 44px target for coarse pointers, and a tap follows it. A static stat has nothing to press.

ThemingLink to "Theming"

Theming, table 2
TokenDefaultWhat it sets
--cy-stat-gap--cy-space-5Space between the icon tile and the text
--cy-stat-label-color--cy-color-mutedColour of the label, unit and description
--cy-stat-value-font--cy-font-displayFont family of the value
--cy-stat-value-weight--cy-font-weight-boldFont weight of the value
--cy-stat-value-size-sm--cy-font-size-xlValue size at size="sm"
--cy-stat-value-size-md--cy-font-size-2xlValue size at size="md"
--cy-stat-value-size-lg1.45 times --cy-font-size-2xlValue size at size="lg"

The frame is a Card, restyled through the --cy-card-* tokens; the icon is an IconTile (--cy-icon-tile-*).

ts
Copy
createTheme({ components: { stat: { valueWeight: "500" }, card: { radius: "8px" } } });

className and style are for layout only. Change the look through tokens so every product stays consistent.

Card · IconTile · Grid · DescriptionList · Table

These examples run Cynosure 0.5.0 (commit 50ce30b), the version on npm.

Getting started
Theming
Icons
Accessibility
Code editors and highlighters
Using Cynosure without React
Build-tool adapters
Components
Accordion
AppShell
AspectRatio
Breadcrumbs
Calendar
Card
Container
Disclosure
Divider
DocumentViewport
Grid
Inline
PageHeader
PanZoomCanvas
ScrollArea
SideNav
SortableList
SplitPane
Stack
StatusBar
Tabs
TitleBar
Toolbar
Tree
VirtualList
ZoomControls
Announcer
Avatar
Badge
CodeBlock
DescriptionList
EmptyState
ErrorBoundary
Field
Heading
IconTile
Image
Kbd
List
LoadingDots
Notice
ProgressBar
Prose
Skeleton
Stat
Steps
Table
Text
Button
Checkbox
Checklist
ColorField
ColorSwatches
Combobox
CompareSlider
CopyButton
DateField
FileDrop
IconButton
KeyValueEditor
Link
NumberField
Pagination
PathField
RadioGroup
SearchField
SegmentedControl
Select
SelectionFrame
SignaturePad
Slider
Switch
TagInput
TextArea
TextField
ThemeToggle
TimeField
ButtonBase
ChoiceBase
DialogBase
FileInputBase
HiddenValue
Icon
InputBase
LinkBase
LiveRegion
TextAreaBase
ChatMessage
Choice
DataGrid
DeviceFrame
HighlightedText
HotkeyField
ListRow
OptionList
OverlayFrame
QRCode
RowActions
Section
SiteFooter
SiteHeader
SkipLink
SortButton
VisuallyHidden
CommandPalette
ContextMenu
Dialog
FloatingToolbar
HoverCard
Menu
Menubar
Popover
ProgressOverlay
Sheet
Toast
Tooltip
Changelog