# Stat strip

A row of stats in one frame, or none, that wraps to fewer columns as its space narrows.

A block: a ready-made arrangement of components, to copy into a project. Its own classes carry the `site-` prefix; rename it to your project's own. Status: experimental. Figma: the Figma file, https://www.figma.com/community/file/1688324308358870630. Built from: Stat, Status dot.

## Examples

### Usage

Three stats in one raised frame, with thin lines between them.

```html
<div class="site-stat-strip site-stat-strip--look-framed" role="group" aria-label="This week">
  <dl class="smbk-stat smbk-stat--size-sm smbk-stat--type-static site-stat-strip__stat">
    <dt class="smbk-stat__name" id="stat-strip-1-name">Waiting on you</dt>
    <dd class="smbk-stat__figure">4</dd>
    <dd class="smbk-stat__description">Pull requests to approve</dd>
  </dl>
  <dl class="smbk-stat smbk-stat--size-sm smbk-stat--type-static site-stat-strip__stat">
    <dt class="smbk-stat__name" id="stat-strip-2-name">Deploys</dt>
    <dd class="smbk-stat__figure">12</dd>
    <dd class="smbk-stat__description">All passed</dd>
  </dl>
  <dl class="smbk-stat smbk-stat--size-sm smbk-stat--type-static site-stat-strip__stat">
    <dt class="smbk-stat__name" id="stat-strip-3-name">Open issues</dt>
    <dd class="smbk-stat__figure">3</dd>
    <dd class="smbk-stat__description">Two due this week</dd>
  </dl>
</div>
```

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

<div className="site-stat-strip site-stat-strip--look-framed" role="group" aria-label="This week">
  <Stat className="site-stat-strip__stat" size="sm" name="Waiting on you" figure={4} description="Pull requests to approve" />
  <Stat className="site-stat-strip__stat" size="sm" name="Deploys" figure={12} description="All passed" />
  <Stat className="site-stat-strip__stat" size="sm" name="Open issues" figure={3} description="Two due this week" />
</div>
```

### Four stats

Four across where there is room for them; with less, they wrap, and a row that is not full lets its stats grow.

```html
<div class="site-stat-strip site-stat-strip--look-framed" role="group" aria-label="This month">
  <dl class="smbk-stat smbk-stat--size-sm smbk-stat--type-static site-stat-strip__stat">
    <dt class="smbk-stat__name" id="stat-strip-1-name">Visitors</dt>
    <dd class="smbk-stat__figure">8,240</dd>
    <dd class="smbk-stat__description">Up 12% on last month</dd>
  </dl>
  <dl class="smbk-stat smbk-stat--size-sm smbk-stat--type-static site-stat-strip__stat">
    <dt class="smbk-stat__name" id="stat-strip-2-name">Sign-ups</dt>
    <dd class="smbk-stat__figure">312</dd>
    <dd class="smbk-stat__description">From 4 campaigns</dd>
  </dl>
  <dl class="smbk-stat smbk-stat--size-sm smbk-stat--type-static site-stat-strip__stat">
    <dt class="smbk-stat__name" id="stat-strip-3-name">Refunds</dt>
    <dd class="smbk-stat__figure">2</dd>
    <dd class="smbk-stat__description">Both under $20</dd>
  </dl>
  <dl class="smbk-stat smbk-stat--size-sm smbk-stat--type-static site-stat-strip__stat">
    <dt class="smbk-stat__name" id="stat-strip-4-name">Uptime</dt>
    <dd class="smbk-stat__figure">98%</dd>
    <dd class="smbk-stat__description">Last 30 days</dd>
  </dl>
</div>
```

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

<div className="site-stat-strip site-stat-strip--look-framed" role="group" aria-label="This month">
  <Stat className="site-stat-strip__stat" size="sm" name="Visitors" figure="8,240" description="Up 12% on last month" />
  <Stat className="site-stat-strip__stat" size="sm" name="Sign-ups" figure={312} description="From 4 campaigns" />
  <Stat className="site-stat-strip__stat" size="sm" name="Refunds" figure={2} description="Both under $20" />
  <Stat className="site-stat-strip__stat" size="sm" name="Uptime" figure="98%" description="Last 30 days" />
</div>
```

### Two by two

Room for two columns: the stats wrap into two rows, with a line between the rows.

```html
<div class="site-stat-strip site-stat-strip--look-framed" role="group" aria-label="Today">
  <dl class="smbk-stat smbk-stat--size-sm smbk-stat--type-static site-stat-strip__stat">
    <dt class="smbk-stat__name" id="stat-strip-1-name">Orders</dt>
    <dd class="smbk-stat__figure">46</dd>
    <dd class="smbk-stat__description">9 still to ship</dd>
  </dl>
  <dl class="smbk-stat smbk-stat--size-sm smbk-stat--type-static site-stat-strip__stat">
    <dt class="smbk-stat__name" id="stat-strip-2-name">Returns</dt>
    <dd class="smbk-stat__figure">1</dd>
    <dd class="smbk-stat__description">Waiting for the parcel</dd>
  </dl>
  <dl class="smbk-stat smbk-stat--size-sm smbk-stat--type-static site-stat-strip__stat">
    <dt class="smbk-stat__name" id="stat-strip-3-name">Messages</dt>
    <dd class="smbk-stat__figure">7</dd>
    <dd class="smbk-stat__description">3 without a reply</dd>
  </dl>
  <dl class="smbk-stat smbk-stat--size-sm smbk-stat--type-static site-stat-strip__stat">
    <dt class="smbk-stat__name" id="stat-strip-4-name">Stock alerts</dt>
    <dd class="smbk-stat__figure">2</dd>
    <dd class="smbk-stat__description">Below 10 left</dd>
  </dl>
</div>
```

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

<div className="site-stat-strip site-stat-strip--look-framed" role="group" aria-label="Today">
  <Stat className="site-stat-strip__stat" size="sm" name="Orders" figure={46} description="9 still to ship" />
  <Stat className="site-stat-strip__stat" size="sm" name="Returns" figure={1} description="Waiting for the parcel" />
  <Stat className="site-stat-strip__stat" size="sm" name="Messages" figure={7} description="3 without a reply" />
  <Stat className="site-stat-strip__stat" size="sm" name="Stock alerts" figure={2} description="Below 10 left" />
</div>
```

### Plain

No frame and no lines, for a card or a panel that already has an edge.

```html
<div class="site-stat-strip site-stat-strip--look-plain" role="group" aria-label="This quarter">
  <dl class="smbk-stat smbk-stat--size-sm smbk-stat--type-static site-stat-strip__stat">
    <dt class="smbk-stat__name" id="stat-strip-1-name">Revenue</dt>
    <dd class="smbk-stat__figure">$48,200</dd>
    <dd class="smbk-stat__description">Up 8% on last quarter</dd>
  </dl>
  <dl class="smbk-stat smbk-stat--size-sm smbk-stat--type-static site-stat-strip__stat">
    <dt class="smbk-stat__name" id="stat-strip-2-name">New customers</dt>
    <dd class="smbk-stat__figure">86</dd>
    <dd class="smbk-stat__description">21 on a yearly plan</dd>
  </dl>
  <dl class="smbk-stat smbk-stat--size-sm smbk-stat--type-static site-stat-strip__stat">
    <dt class="smbk-stat__name" id="stat-strip-3-name">Churn</dt>
    <dd class="smbk-stat__figure">1.4%</dd>
    <dd class="smbk-stat__description">Lowest this year</dd>
  </dl>
</div>
```

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

<div className="site-stat-strip site-stat-strip--look-plain" role="group" aria-label="This quarter">
  <Stat className="site-stat-strip__stat" size="sm" name="Revenue" figure="$48,200" description="Up 8% on last quarter" />
  <Stat className="site-stat-strip__stat" size="sm" name="New customers" figure={86} description="21 on a yearly plan" />
  <Stat className="site-stat-strip__stat" size="sm" name="Churn" figure="1.4%" description="Lowest this year" />
</div>
```

### Linked, with a dot

Each figure links to its list; the dot says in words that the first needs you.

```html
<div class="site-stat-strip site-stat-strip--look-framed" role="group" aria-label="Your work">
  <dl class="smbk-stat smbk-stat--size-sm smbk-stat--type-link site-stat-strip__stat">
    <dt
      class="smbk-stat__name"
      id="stat-strip-1-name"
    ><span class="smbk-status-dot smbk-status-dot--tone-warning smbk-stat__dot" role="img" aria-label="Needs you"><span class="smbk-status-dot__dot"></span></span>Waiting on you</dt>
    <dd class="smbk-stat__figure">
      <a
        class="smbk-stat__link"
        href="#reviews"
        id="stat-strip-1-figure"
        aria-labelledby="stat-strip-1-name stat-strip-1-figure"
      >4</a>
    </dd>
    <dd class="smbk-stat__description">Pull requests to approve</dd>
  </dl>
  <dl class="smbk-stat smbk-stat--size-sm smbk-stat--type-link site-stat-strip__stat">
    <dt class="smbk-stat__name" id="stat-strip-2-name">Assigned to you</dt>
    <dd class="smbk-stat__figure">
      <a
        class="smbk-stat__link"
        href="#assigned"
        id="stat-strip-2-figure"
        aria-labelledby="stat-strip-2-name stat-strip-2-figure"
      >9</a>
    </dd>
    <dd class="smbk-stat__description">3 due this week</dd>
  </dl>
  <dl class="smbk-stat smbk-stat--size-sm smbk-stat--type-link site-stat-strip__stat">
    <dt class="smbk-stat__name" id="stat-strip-3-name">Mentions</dt>
    <dd class="smbk-stat__figure">
      <a
        class="smbk-stat__link"
        href="#mentions"
        id="stat-strip-3-figure"
        aria-labelledby="stat-strip-3-name stat-strip-3-figure"
      >2</a>
    </dd>
    <dd class="smbk-stat__description">Since yesterday</dd>
  </dl>
</div>
```

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

<div className="site-stat-strip site-stat-strip--look-framed" role="group" aria-label="Your work">
  <Stat className="site-stat-strip__stat" size="sm" name="Waiting on you" figure={4} description="Pull requests to approve" href="#reviews" dot="warning" dotLabel="Needs you" />
  <Stat className="site-stat-strip__stat" size="sm" name="Assigned to you" figure={9} description="3 due this week" href="#assigned" />
  <Stat className="site-stat-strip__stat" size="sm" name="Mentions" figure={2} description="Since yesterday" href="#mentions" />
</div>
```

### On a phone

At a phone's width the strip is one column.

```html
<div
  class="site-stat-strip site-stat-strip--look-framed"
  role="group"
  aria-label="This week, on a phone"
>
  <dl class="smbk-stat smbk-stat--size-sm smbk-stat--type-static site-stat-strip__stat">
    <dt class="smbk-stat__name" id="stat-strip-1-name">Waiting on you</dt>
    <dd class="smbk-stat__figure">4</dd>
    <dd class="smbk-stat__description">Pull requests to approve</dd>
  </dl>
  <dl class="smbk-stat smbk-stat--size-sm smbk-stat--type-static site-stat-strip__stat">
    <dt class="smbk-stat__name" id="stat-strip-2-name">Deploys</dt>
    <dd class="smbk-stat__figure">12</dd>
    <dd class="smbk-stat__description">All passed</dd>
  </dl>
  <dl class="smbk-stat smbk-stat--size-sm smbk-stat--type-static site-stat-strip__stat">
    <dt class="smbk-stat__name" id="stat-strip-3-name">Open issues</dt>
    <dd class="smbk-stat__figure">3</dd>
    <dd class="smbk-stat__description">Two due this week</dd>
  </dl>
</div>
```

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

<div className="site-stat-strip site-stat-strip--look-framed" role="group" aria-label="This week, on a phone">
  <Stat className="site-stat-strip__stat" size="sm" name="Waiting on you" figure={4} description="Pull requests to approve" />
  <Stat className="site-stat-strip__stat" size="sm" name="Deploys" figure={12} description="All passed" />
  <Stat className="site-stat-strip__stat" size="sm" name="Open issues" figure={3} description="Two due this week" />
</div>
```

## Purpose

Lines up a few key figures at the top of a dashboard or a section, such as what waits for a reader, what ran this week and how a service is doing. Each figure is a stat; the strip only arranges them.

## Anatomy

- The block, a row of stats that wraps.
- The framed look puts them in one raised frame with thin lines between the stats and between rows; the plain look has no frame and no lines, and keeps its rows apart.
- Each stat is the Stat component, at its small size, carrying the block's stat class beside its own.

## When to use

- For two to four figures a reader checks first, each with its name and a line of what it means.
- Framed at the top of a dashboard; plain inside a card or a panel that already has an edge.

## When not to use

- For one figure. Use a stat on its own.
- For figures a reader compares across many rows. Use a table.

## Behavior

Every stat is at least the small column width and shares what is left, so the strip shows four, three, two or one column by the room it is given, and one at a phone's width. A row that is not full lets its stats grow to fill it. The strip takes no focus; a linked stat is one Tab stop of its own.

## Accessibility

### What it does for you

- Each stat is a description list, so a screen reader hears its name, then its figure and what it means.
- A linked stat is one stop for the Tab key; a plain one takes no focus.

### What you must do

- Name the strip with `role="group"` and an `aria-label`, such as "This week", when a page has more than one.
- Say a dot's meaning in words through the stat's dot label.

### How to test

- With a screen reader, each stat reads its name, then its figure and what it means, and a dot by its words.
- With text at 200% and the page 320 pixels wide, the strip is one column.

### Keyboard

| Key | What it does |
|---|---|
| Tab | Moves focus to each linked stat in turn. |
| Enter | Follows the focused stat's link. |

## Usage rules

### Do

- Keep the figures short, and say what each means in its line.
- Use the same size for every stat in a strip.

### Don't

- Fill it with more figures than a reader takes in at a glance.
- Mix linked and plain stats without a reason a reader can see.

## Stylesheet

```css
/* site-stat-strip — Stat strip, a block: stats lined up in rows that wrap. Copy it into your project and rename
 * site- to your project's own prefix. Each stat is the Stat component, given this block's stat class beside its
 * own; the strip draws only the rows and the frame. Every stat fills its row and is at least the small column
 * width, so the strip has one to four columns by the room it is given, and one at a phone's width. */

.site-stat-strip {
  display: flex;
  flex-wrap: wrap;
  gap: var(--smbk-border-width-hairline);
}

/* Framed: one raised frame; the subtle border color shows through the hairline gaps between stats and rows. */
.site-stat-strip--look-framed {
  overflow: hidden;
  border-radius: var(--smbk-radius-container-md);
  background: var(--smbk-color-border-subtle);
  box-shadow: var(--smbk-elevation-raised);
}

/* Plain: no frame and no lines; the rows sit apart. */
.site-stat-strip--look-plain {
  row-gap: var(--smbk-space-stack-lg);
}

.site-stat-strip__stat {
  flex: 1 1 var(--smbk-size-column-min-sm);
  min-width: min(100%, var(--smbk-size-column-min-sm));
}

/* ---- high contrast (forced colors) ---- */
/* The fill that draws the lines is dropped: the frame and each stat get an outline in the text color instead. */

@media (forced-colors: active) {
  .site-stat-strip--look-framed {
    outline: var(--smbk-border-width-hairline) solid CanvasText;
  }

  .site-stat-strip--look-framed .site-stat-strip__stat {
    outline: var(--smbk-border-width-hairline) solid CanvasText;
  }
}
```
