# Stat

One figure with its name and a line of what it means, plain or as a link to where the figure comes from.

Block: `smbk-stat`. Status: experimental. Figma: the Figma file, https://www.figma.com/community/file/1688324308358870630. Desktop and mobile: differ by presentation only.

## Options

| Axis | Values | Default | Meaning |
|---|---|---|---|
| `size` | `lg`, `sm` | `lg` | Small sits closer to its edges and sets the figure a heading step smaller, for a row of many stats. |
| `type` | `static`, `link` | `static` | A link takes the link colors and underline on its figure, and the whole tile follows it. The wrapper sets it when it is given an address. |

Parts: `smbk-stat__name`, `smbk-stat__dot`, `smbk-stat__figure`, `smbk-stat__link`, `smbk-stat__trend`, `smbk-stat__description`, `smbk-stat__chart`

## Markup

```html
<dl class="smbk-stat smbk-stat--size-lg smbk-stat--type-static">
  <dt class="smbk-stat__name" id="stat-1-name">Waiting on you</dt>
  <dd class="smbk-stat__figure">4</dd>
  <dd class="smbk-stat__description">Pull requests to approve</dd>
</dl>
```

## React

```tsx
import { Stat } from './design-system/components/stat/stat.js';

<Stat size="lg" name="Waiting on you" figure={4} description="Pull requests to approve" dotLabel="Needs you" />
```

## Stylesheet

```css
/* smbk-stat — Stat. Figma "Stat" 7118:401 (Size × Type × State; Dot and Description booleans).
 * One figure with its name above it and a line under it, on the default surface with square corners:
 * the name in Label SM, the figure in a heading style with tabular digits, the line in Body SM, the
 * extra small stack step apart; an optional change badge after the figure and a small chart under the line.
 * As wide as its content in running text; a grid or a row it sits in stretches it. In a card's slot the
 * card drops its padding and fill (card.css), so it lines up with the card's other parts. A linked figure takes the link colors and underline, and its link covers the whole
 * tile, so the tile is the one place to press and the focus ring goes round it. */

.smbk-stat {
  box-sizing: border-box;
  position: relative;
  display: inline-flex;
  flex-direction: column;
  gap: var(--smbk-space-stack-xs);
  margin: 0;
  padding: var(--smbk-space-inset-xl);
  vertical-align: top;
  background: var(--smbk-color-surface-default);
}

.smbk-stat__name {
  display: flex;
  align-items: center;
  gap: var(--smbk-space-inline-xs);
  margin: 0;
  color: var(--smbk-color-text-subtle);
  font-family: var(--smbk-typography-label-sm-font-family);
  font-size: var(--smbk-typography-label-sm-font-size);
  font-weight: var(--smbk-typography-label-sm-font-weight);
  line-height: var(--smbk-typography-label-sm-line-height);
  letter-spacing: var(--smbk-typography-label-sm-letter-spacing);
  text-transform: var(--smbk-typography-label-sm-text-transform);
}

.smbk-stat__figure {
  margin: 0;
  color: var(--smbk-color-text-default);
  font-family: var(--smbk-typography-heading-md-font-family);
  font-size: var(--smbk-typography-heading-md-font-size);
  font-weight: var(--smbk-typography-heading-md-font-weight);
  line-height: var(--smbk-typography-heading-md-line-height);
  letter-spacing: var(--smbk-typography-heading-md-letter-spacing);
  text-transform: var(--smbk-typography-heading-md-text-transform);
  font-variant-numeric: tabular-nums;
}

.smbk-stat__description {
  margin: 0;
  color: var(--smbk-color-text-subtle);
  font-family: var(--smbk-typography-body-sm-font-family);
  font-size: var(--smbk-typography-body-sm-font-size);
  font-weight: var(--smbk-typography-body-sm-font-weight);
  line-height: var(--smbk-typography-body-sm-line-height);
  letter-spacing: var(--smbk-typography-body-sm-letter-spacing);
}

.smbk-stat__figure:has(> .smbk-stat__trend) {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--smbk-space-inline-sm);
}

/* The change after the figure, such as a small badge. A flex box, so the figure's line height leaves no
   room around it. */
.smbk-stat__trend {
  display: flex;
  align-items: center;
}

/* A small chart under the line, such as a sparkline or a meter, as wide as the stat. */
.smbk-stat__chart {
  min-width: 0;
  margin: 0;
}

/* ---- link: the figure is the link, in the link colors and underlined; its box is stretched over the
   whole tile, so pressing anywhere on the tile follows it and the ring is drawn round the tile. ---- */

.smbk-stat__link {
  color: var(--smbk-color-text-link);
  text-decoration: underline;
  outline: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

.smbk-stat__link::after {
  content: "";
  position: absolute;
  inset: 0;
}

@media (hover: hover) {
  .smbk-stat__link:hover {
    color: var(--smbk-color-text-link-hover);
  }
}

.smbk-stat__link:active {
  color: var(--smbk-color-text-link-pressed);
}

.smbk-stat__link:focus-visible::after {
  outline: var(--smbk-focus-ring-width) solid var(--smbk-color-border-focus);
  outline-offset: var(--smbk-focus-ring-offset);
}

/* ---- small: closer to its edges, the figure a step smaller ---- */

.smbk-stat--size-sm {
  padding: var(--smbk-space-inset-lg);
}

.smbk-stat--size-sm .smbk-stat__figure {
  font-family: var(--smbk-typography-heading-sm-font-family);
  font-size: var(--smbk-typography-heading-sm-font-size);
  font-weight: var(--smbk-typography-heading-sm-font-weight);
  line-height: var(--smbk-typography-heading-sm-line-height);
  letter-spacing: var(--smbk-typography-heading-sm-letter-spacing);
  text-transform: var(--smbk-typography-heading-sm-text-transform);
}

/* ---- high contrast (forced colors) ---- */
/* In Windows high-contrast mode the browser drops fills and shadows; this puts the meaning back with the
   user's own colors. Nothing here applies outside that mode. */

@media (forced-colors: active) {
  /* The ring round the tile is drawn in the palette's highlight. */
  .smbk-stat__link:focus-visible::after {
    outline-color: Highlight;
  }
}
```

## Tokens it reads

```json
{
  "space": {
    "stack": {
      "xs": {
        "$type": "dimension",
        "$value": "{{space.4}}",
        "$description": "Gap between things stacked one above another, extra small."
      }
    },
    "inset": {
      "xl": {
        "$type": "dimension",
        "$value": "{{space.16}}",
        "$description": "Padding inside a component, extra large."
      },
      "lg": {
        "$type": "dimension",
        "$value": "{{space.12}}",
        "$description": "Padding inside a component, large."
      }
    },
    "inline": {
      "xs": {
        "$type": "dimension",
        "$value": "{{space.4}}",
        "$description": "Gap between things side by side, extra small."
      },
      "sm": {
        "$type": "dimension",
        "$value": "{{space.6}}",
        "$description": "Gap between things side by side, small."
      }
    }
  },
  "color": {
    "surface": {
      "default": {
        "$type": "color",
        "$value": "{{color.grey.100}}",
        "$description": "Standard surface: cards, panels, the header."
      }
    },
    "text": {
      "subtle": {
        "$type": "color",
        "$value": "{{color.grey.700}}",
        "$description": "Secondary text: descriptions, metadata."
      },
      "default": {
        "$type": "color",
        "$value": "{{color.grey.900}}",
        "$description": "Main text."
      },
      "link": {
        "$type": "color",
        "$value": "{{color.grey.900}}",
        "$description": "Link text."
      },
      "link-hover": {
        "$type": "color",
        "$value": "{{color.grey.950}}",
        "$description": "Link text on hover."
      },
      "link-pressed": {
        "$type": "color",
        "$value": "{{color.grey.800}}",
        "$description": "Link text while pressed."
      }
    },
    "border": {
      "focus": {
        "$type": "color",
        "$value": "{{color.red.600}}",
        "$description": "Keyboard focus ring on controls."
      }
    }
  },
  "typography": {
    "label-sm": {
      "$type": "typography",
      "$value": {
        "fontFamily": "Geist, Geist Fallback, system-ui, sans-serif",
        "fontSize": "12px",
        "fontWeight": 500,
        "lineHeight": 1.4,
        "letterSpacing": "0px"
      },
      "$description": "Label SM: labels on controls and short UI text (buttons, chips, tabs, menu headings). Geist Medium, sentence case. Code and keys use Code SM and Code MD."
    },
    "heading-md": {
      "$type": "typography",
      "$value": {
        "fontFamily": "Funnel Display, Funnel Display Fallback, system-ui, sans-serif",
        "fontSize": {
          "min": "28px",
          "max": "40px"
        },
        "fontWeight": 400,
        "lineHeight": 1.2,
        "letterSpacing": "0px"
      }
    },
    "body-sm": {
      "$type": "typography",
      "$value": {
        "fontFamily": "Geist, Geist Fallback, system-ui, sans-serif",
        "fontSize": "14px",
        "fontWeight": 400,
        "lineHeight": 1.5,
        "letterSpacing": "0px"
      }
    },
    "heading-sm": {
      "$type": "typography",
      "$value": {
        "fontFamily": "Funnel Display, Funnel Display Fallback, system-ui, sans-serif",
        "fontSize": {
          "min": "24px",
          "max": "32px"
        },
        "fontWeight": 400,
        "lineHeight": 1.2,
        "letterSpacing": "0px"
      }
    }
  },
  "focus": {
    "ring": {
      "width": {
        "$type": "dimension",
        "$value": "{{border-width.2}}",
        "$description": "Thickness of the focus ring."
      },
      "offset": {
        "$type": "dimension",
        "$value": "{{space.2}}",
        "$description": "Gap between a control and its focus ring."
      }
    }
  }
}
```

## Purpose

Shows one figure that matters, with its name above it and a line under it that says what the figure means: the open pull requests waiting for a review, the uptime of the last thirty days. A stat can link to where its figure comes from.

## Anatomy

- The block, a description list of its own, on the default surface with square corners.
- The name part, the term: what the figure counts, in a small label style and the subtle text color.
- The dot part, an optional status dot before the name, for a figure that needs attention.
- The figure part, the value in a heading style with digits of equal width, so figures line up and do not jump as they change.
- The link part, the figure as a link, in the link colors and underlined, when the stat has an address.
- The trend part, an optional mark of the change after the figure, such as a small badge.
- The description part, an optional line under the figure in a small body style and the subtle text color.
- The chart part, an optional small chart under the line, such as a sparkline or a meter, as wide as the stat.

## When to use

- At the top of a dashboard or an overview, for the few figures a reader comes to check.
- For a figure that leads somewhere: the list of what it counts, the report behind it.

## When not to use

- For a value over time. Use a chart or a [sparkline](sparkline.md).
- For a long row of equally weighted figures with no question or action behind them. Pick the few that matter.
- For a pair of a term and its value inside a page of details. Use a [description list](description-list.md).

## Behavior

A stat is as wide as its content in running text; a grid or a row it sits in stretches it, so a row of stats can share its width equally. The description wraps, and the trend moves under the figure when there is no room beside it.

In a card's slot the stat is one of the card's parts: it drops its own padding and surface, so its name starts on the card's inset and lines up with the card's header.

A linked stat is one link. Its figure shows the link, and the whole tile follows it: pressing anywhere on the tile goes to the address. On hover and press the figure takes the link's hover and pressed colors; with the keyboard, the focus ring goes round the whole tile. The trend and the chart sit under the link's target, so a chart in a linked stat takes no pointer of its own.

## Accessibility
### What it does for you

- Each stat is a description list: the name is the term, the figure and the description are its details. A screen reader says the name with the figure.
- A linked stat is one Tab stop, named by the name and the figure together, such as "Waiting on you 4".
- The dot's label is read as part of the name.
- The tile is the link's target, so it is far larger than the smallest size a finger can press.

### What you must do

- Say the dot's meaning in words: give it a label such as "Needs you". Never let the dot's color be the only sign.
- Write the trend in words and signs, such as "+12%" or "3 fewer", not as a color or an arrow alone.
- Give a chart its summary in words, as the sparkline asks.

### How to test

- Tab through a linked stat: it is one stop, with the focus ring round the whole tile, and Enter follows its address.
- With a screen reader, a stat is read as the name with the figure and its trend, then the description and the chart's summary; a linked one as a link by the name and the figure together; a dot's label is read as part of the name.
- On a touch screen, a press anywhere on the tile goes to the address.
- With text at 200% and the page 320 pixels wide, the description wraps and the figure stays whole.

### Keyboard

| Key | What it does |
|---|---|
| Tab | Moves focus to a linked stat, which is one stop. A stat with no address takes no keys. |
| Enter | Follows the linked stat's address. |

## Usage rules

### Do

- Say what the figure means, and whether it is good or bad, in the description.
- Link the figure to the list or report it comes from, when there is one.
- Keep the name short: two or three words.

### Don't

- Put a chart with axes, or a long sentence, in a stat. The chart part is for a small line or bar.
- Use the dot without its words.
- Line up more figures than a reader can take in at a glance.
