Skip to main content

Stats

Overview​

The Stats component lays out a row of Stats, such as the key figures at the top of a dashboard, as one description list on Bulma's smart grid.

It's a <dl> holding a Stat for each figure, each a <div> with its label and its values, so a screen reader meets one list for the whole row. The row is Bulma's smart grid: each tile is at least minCol wide, the tiles share the width left over, and they wrap onto more lines as the row narrows, with no media queries.


Import​

import { Stats, Stat } from '@allxsmith/bestax-bulma';

Usage​

Basic Usage​

Put a Stat in it for each figure, and name the row by the heading above it with aria-labelledby, so a screen reader says what the figures are about when it gets there. Make the window narrower to see the tiles wrap.

<>
  <Title as="h2" textSize="5" id="stats-kpis">
    This month
  </Title>
  <Stats aria-labelledby="stats-kpis" minCol={8} gap={4}>
    <Stat
      label="Revenue"
      value={8456.4}
      format={{ style: 'currency', currency: 'USD' }}
      locale="en-US"
      change={0.12}
      description="since last month"
    />
    <Stat
      label="New customers"
      value={1234}
      locale="en-US"
      change={-0.019}
      description="since last month"
    />
    <Stat
      label="Churn"
      value={0.021}
      format={{ style: 'percent', maximumFractionDigits: 1 }}
      locale="en-US"
      change={0.004}
      changeColor="danger"
      description="since last month"
    />
    <Stat
      label="Requests"
      value={1234567}
      format={{ notation: 'compact' }}
      locale="en-US"
      change={0}
      description="since last month"
    />
  </Stats>
</>

Tile Width and Gap​

minCol is the narrowest a tile gets before the row wraps, 1.5rem a step, as on Grid; unset, it's Bulma's 9rem. The gap helper prop sets the space between tiles, 0.5rem a step.

<Stats minCol={5} gap={2}>
  <Stat label="Mon" value={12} />
  <Stat label="Tue" value={18} />
  <Stat label="Wed" value={9} />
  <Stat label="Thu" value={21} />
  <Stat label="Fri" value={15} />
</Stats>

Text Color​

textColor on the row puts has-text-* on the <dl>, as on Buttons, and is each Stat's textColor unless it has its own, so it colors the figures: a Stat sets its own color, which a color on the row alone wouldn't reach. The labels, the changes and the notes keep their own colors.

<Stats minCol={8} textColor="link">
  <Stat label="Revenue" value="$8,456" />
  <Stat label="Refunds" value="$312" textColor="danger" />
</Stats>

In a LocaleProvider​

A LocaleProvider around the row reaches every figure and change in it. Put it around the Stats rather than inside, since its wrapper <div> can't sit in a list.

<LocaleProvider locale="de-DE">
  <Stats minCol={8} gap={4}>
    <Stat
      label="Umsatz"
      value={8456.4}
      format={{ style: 'currency', currency: 'EUR' }}
      change={-0.019}
    />
    <Stat label="Neukunden" value={1234} change={0.12} />
  </Stats>
</LocaleProvider>

Compound (dot-notation) usage​

Stat is also available as Stats.Stat, parts included, so a row can be composed from the single Stats import.

<Stats minCol={8} gap={4}>
  <Stats.Stat label="Revenue" value="$8,456" description="this month" />
  <Stats.Stat>
    <Stats.Stat.Label>New customers</Stats.Stat.Label>
    <Stats.Stat.Value>1,234</Stats.Stat.Value>
    <Stats.Stat.Description>this month</Stats.Stat.Description>
  </Stats.Stat>
</Stats>


Accessibility​

  • One list for the row: a <dl> with a <div> for each Stat, which browsers expose as a list of terms and their definitions. Chromium, Firefox and WebKit give the same tree: each label followed by its figure, its change and its note, in the order written.
  • A name from the heading above: point aria-labelledby at it, as in Basic Usage.
  • Only Stats inside: a <dl> holds only its groups, so put nothing else in the row, and wrap no Stat in it. A LocaleProvider or a Box goes around the whole row instead. A role="status" element doesn't: it goes around one lone Stat whose figure should be announced, since announcing a whole row that refreshes would be noise.
  • Reading order is the order you write: the grid places the tiles and follows the writing direction, so in a right-to-left page the first tile sits on the right, and a screen reader reads them in the same order either way.
  • Not interactive and not live: it has no tab stop and announces nothing when a figure changes. See Stat for the one figure that should be announced.

  • Stat: One figure, its label, its change and its note.
  • Grid: Bulma's smart grid, which lays the row out.
  • Title: For the heading that names the row.
  • Helper Props: Bulma helper props for spacing, color, etc.

Additional Resources​


Props​

PropTypeDefaultDescription
classNamestring—Additional CSS classes to apply.
childrenReact.ReactNode—Stats, one per figure, and nothing else: they're the groups of its <dl>.
minColBulmaMinColValue—The narrowest a tile gets before the row wraps (is-col-min-*), as Grid's minCol: 1.5rem a step. Unset, it's Bulma's 9rem.
textColorBulma color | 'inherit' | 'current'—Text color helper: has-text-* on the <dl>, as on Buttons. Each Stat in the row without a textColor of its own takes it too, which colors its figure, since a Stat sets its own color. The labels, the changes and the notes keep theirs.
bgColorBulma color | 'inherit' | 'current'—Background color helper.
refReact.Ref<HTMLDListElement>—Ref forwarded to the <dl>.
gapBulmaGapStep—The space between tiles (is-gap-*), the helper prop with the values Grid's gap takes.
aria-labelledbystring—The id of the heading above the row, which names it.
...All standard <dl> attributes and Bulma helper props—See Helper Props

Types:

  • BulmaMinColValue: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 — Allowed minimum column values for Bulma grid.

Subcomponents:

  • Stats.Stat: The Stat component shows a figure with its name, and often a change and a note, such as a dashboard's revenue or an account's storage used. It's a label and its values in a description list: a <dt> for the label, and a <dd> each for the figure, the change and the note. On its own it renders its own <dl>; inside Stats it's a <div> in the row's. A number value is written by NumberFormatter, so it follows a LocaleProvider. A change is written with its sign ("+12%"), so the direction is in the text, beside a decorative arrow and a color.