Stat tile
A label, a large value and an optional detail line, on a card. The app lays tiles out in its own grid. With onClick the tile is a button; with render, a link. Then the whole tile takes the hover fill and the focus ring. Its accessible name is its text, in order. Set aria-label for a shorter one.
Profiles saved1,284of 1,402 profiles
PendingDid not load
import { type CSSProperties } from "react";
import { StatTile } from "@etched/reticle/stat-tile";
/** The app's grid: as many 12 rem columns as fit. Reticle does not lay tiles out. */
const tiles: CSSProperties = { display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(12rem, 1fr))", gap: "var(--et-space-4)" };
export function Preview() {
return (
<div style={{ ...tiles, gridTemplateColumns: "repeat(2, minmax(0, 1fr))", inlineSize: "100%" }}>
<StatTile label="Profiles saved" value="1,284" detail="of 1,402 profiles" />
<StatTile label="Pending" value={null} detail="Did not load" />
</div>
);
}Installation
import { StatTile } from "@etched/reticle/stat-tile";Examples
In a grid
Orbit's profile enrichment. The app sets the grid; tiles in a row take the same height.
Profiles saved1,2841,402 unique LinkedIn profiles
Pending37Waiting or collecting
Needs attention8152 failed · 21 uncertain · 8 cancelled
Awaiting profile resolution0Missing or unresolved LinkedIn identity
import { type CSSProperties } from "react";
import { StatTile } from "@etched/reticle/stat-tile";
/** The app's grid: as many 12 rem columns as fit. Reticle does not lay tiles out. */
const tiles: CSSProperties = { display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(12rem, 1fr))", gap: "var(--et-space-4)" };
export function InAGrid() {
return (
<div style={tiles}>
<StatTile label="Profiles saved" value="1,284" detail="1,402 unique LinkedIn profiles" />
<StatTile label="Pending" value="37" detail="Waiting or collecting" />
<StatTile label="Needs attention" value="81" detail="52 failed · 21 uncertain · 8 cancelled" />
<StatTile label="Awaiting profile resolution" value="0" detail="Missing or unresolved LinkedIn identity" />
</div>
);
}Not available
With no value, the tile shows a dash, and screen readers read "Not available". A count of 0 still shows 0.
Lots testedThe count did not load
Chips binned0This week
import { type CSSProperties } from "react";
import { StatTile } from "@etched/reticle/stat-tile";
/** The app's grid: as many 12 rem columns as fit. Reticle does not lay tiles out. */
const tiles: CSSProperties = { display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(12rem, 1fr))", gap: "var(--et-space-4)" };
export function NotAvailable() {
return (
<div style={tiles}>
<StatTile label="Lots tested" value={null} detail="The count did not load" />
<StatTile label="Chips binned" value={0} detail="This week" />
</div>
);
}Links
With render, the whole tile is a link (or a router link) to the filtered list. Tracer's role summary.
import { type CSSProperties } from "react";
import { StatTile } from "@etched/reticle/stat-tile";
/** The app's grid: as many 12 rem columns as fit. Reticle does not lay tiles out. */
const tiles: CSSProperties = { display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(12rem, 1fr))", gap: "var(--et-space-4)" };
export function Links() {
return (
<div style={tiles}>
<StatTile render={<a href="#interviewing" />} label="Interviewing" value="12" detail="Avg 9 days in stage" />
<StatTile render={<a href="#offer" />} label="Offer" value="3" detail="Avg 4 days in stage" />
<StatTile render={<a href="#hired" />} label="Hired" value="2" detail="This quarter" />
</div>
);
}API reference
| Prop | Type | Default | Description |
|---|---|---|---|
| label * | ReactNode | – | What the value counts, for example "Profiles saved". |
| value * | ReactNode | – | The value, formatted by the app, for example count.toLocaleString(). Figures are tabular. null, undefined or "" shows "—", which screen readers read as "Not available". 0 shows 0. |
| detail | ReactNode | – | A line under the value, such as a breakdown or a share of the total. |
| onClick | MouseEventHandler<HTMLElement> | – | Makes the whole tile a button that calls this, for example to filter the table below. |
| render | ReactElement<{ className?: string }> | – | Makes the whole tile another element with the tile's look, such as a link: render={<a href="/candidates?status=offer" />} or a router link. |