Data display
Ten ways to show the same rows. The choice is decided by what the reader does next — compares, scans, or looks up one thing.
What it solves
Rows of data can be shown ten different ways, and the argument about which is usually an argument about taste. It does not have to be: the right shape follows from what the reader is about to do.
Comparing values across records needs columns. Finding one record needs search and a scannable list. Understanding a single record needs pairs of label and value. Watching one number needs that number to be large and alone.
Anatomy
The library states the condition for each, and the conditions do not overlap:
- Rows get sorted —
GrDataTable. Sorting, filtering, column order; the heaviest component in the library and the right one when the reader compares. - The consumer formats the cells —
GrTable. A plain table when the data is already prepared and nothing needs to be computed for it. - Rows are uniform —
GrList. A list, not a table: one column of the same kind of thing. - A record card —
GrDescriptionList. Label-value pairs as a real description list, values aligned in a column. - Content needs a surface —
GrCard. A container, not a layout: it says «this belongs together», nothing more. - One metric is the point —
GrStatistic. Large, with a caption and a trend. - A signed number inside a sentence —
GrDelta. Sign, tone and arrow inline, where a whole statistic block would be too much. - Events happen over time —
GrTimeline. An axis and day headings, because «when» is the question being asked. - The data is nested —
GrTree. Expansion and selection over a hierarchy.
Example
Do and don’t
Do — A table when values are compared down a column
Comparison is what columns are for: the eye runs down one and finds the outlier. If the reader will do that, the table earns its weight.
Don’t — A table for a single record
A two-column table of «field / value» for one object is a description list
wearing a grid: the header row says nothing, and every screen reader announces a
table with one meaningful row. GrDescriptionList is the shape that fits.
Do — Sort on the server when the data is large
GrDataTable takes controlled sorting: the component shows the state, the data
comes back already ordered. Sorting a page of a hundred rows inside a set of ten
thousand sorts the page, not the data — and the reader cannot tell.
Don’t — Load everything to make it feel fast
Ten thousand rows in the DOM is a fast table on a fast machine and an unusable page on a phone. The reader wanted the first twenty and a way to find the rest.
Do — One number large, the rest in a sentence
GrStatistic for the metric the screen is about; GrDelta for the change
mentioned inside a line of text. Two statistic blocks side by side compete, and
the one that matters loses.
Don’t — Colour as the only carrier of a trend
Green and red say «up» and «down» to some readers and nothing to others.
GrDelta carries sign and arrow with the tone — the colour repeats the meaning
rather than holding it alone.
Accessibility
A table must be a table. Headers marked as headers, and each column header tied to its column: that is what lets a screen reader say «Price, 240» instead of just «240» in a cell somewhere.
Sorting is a control, not a decoration. In GrDataTable a sortable header is
an ordinary button — reachable by keyboard, activated by Enter or Space, and its
current direction announced rather than only drawn as an arrow.
A tree is a keyboard pattern, not a nesting of lists. GrTree implements the
APG contract in full: arrows walk and expand, Home and End jump to the edges.
Half of that pattern is worse than none — the role is announced and the behaviour
does not match it.
The heavier the component, the more of its accessibility is already decided for you — and the more of the rest is not. Column headers that say «#» or «···» defeat a correct table just as thoroughly as wrong markup.
Components in this pattern
The list is built from frontmatter, not from links in the prose: renaming a slug does not lose it.
GrDataTabledataGrTabledataGrListdataGrDescriptionListdataGrCarddataGrStatisticdataGrDeltadataGrTimelinedataGrTreedata
Keyboard
Contracts come from the library. The pattern does not restate them — it points at them.
GrDataTableComponent contractGrTableComponent contractGrListComponent contractGrTimelineComponent contractGrTreeComponent contract