Lays out comparable records in rows and columns: claims and their states, pricing, rules.

Molecule · stable · v1.0.0 · owner: Site system lead · contract 19 of 20 points (open: figma)

Do and don't

Do: A labelled data table

Rendered by table.ts

Open example: Table · Do: A labelled data table Use the full-page example to follow page links.

Header cells with scope.

Do: Two columns

Rendered by table.ts

Open example: Table · Do: Two columns Use the full-page example to follow page links.

Key and value.

Don't: No header cells

Rendered by table.ts

Open example: Table · Don't: No header cells Use the full-page example to follow page links.

Without headers a screen reader cannot say what a cell is.

Don't: Layout table

Rendered by table.ts

Open example: Table · Don't: Layout table Use the full-page example to follow page links.

Layout belongs in the grid.

Rules

RuleWhyCheck
Tables have header cells with scope.Assistive technology reads each cell with its header.Automated: axe (tests/site/pages.spec.ts)
A table that can be wider than the screen sits in a focusable, labelled region.The page never scrolls sideways, and keyboard users can still reach every column.Automated: tests/site/pages.spec.ts (no horizontal scroll at 320 px)

API

PropTypeRequiredDefaultWhat it does
labelstringYesThe region's accessible name.
htmlhtmlYesThe table markup with header cells.

Contract details

The full contract: identity, anatomy, variants, states, tokens, layout, motion, accessibility, content, tests

Identity

AspectValue
Idtable
LayerMolecules
Categorydata
OwnerSite system lead
Statusstable
Version1.0.0
Sourceapps/showcase/site/system/molecules/table.ts (private repository; the contract and the render function are this one module)
VersionDateChange
1.0.02026-10-26Data tables in a focusable scroll wrapper.

Use when

  • Records with the same fields. Why: A table lets the reader compare down a column.

Do not use when

  • For layout. Why: Layout tables confuse screen readers.
  • For two or three facts. Why: A list reads faster.

Anatomy

PartWhat it is
rootdiv.table-wrap (focusable region, scrolls sideways)
tabletable.table with th scope

Made of: text, tokens:type.

Used in: cloth-diagram, contract-excerpt, coverage-map, layers-demo, repo-change, score-us, status-table, survey.

Variants

VariantWhenWhy
dataRecords.One style for every table.

States

StateRendered or not applicable
defaultdefault
hoverNot applicable: A table is not interactive, so it has no hover state.
focus-visibleThe wrapper is focusable for keyboard scrolling and shows the focus ring.
activeNot applicable: A table cannot be pressed.
disabledNot applicable: A table has nothing to disable.
loadingNot applicable: A table is rendered at build time and is complete when the page loads.
emptyNot applicable: A table is not rendered without content; the builder skips it.
errorNot applicable: A table shows no data that can fail.
currentNot applicable: A table has no current item.
visitedNot applicable: A table is not a link.
expandedNot applicable: A table does not open or close.

Tokens

PartToken
th.font--type-small-strong
td.font--type-small
row.border--rule-hair --line
--table-font-type-smallvar(--type-small)
--table-padding-space-4var(--space-4)
--table-padding-space-5var(--space-5)
--table-border-bottom-rule-hairvar(--rule-hair)
--table-border-bottom-linevar(--line)
--table-border-bottom-rulevar(--rule)
--table-border-bottom-inkvar(--ink)
--table-font-weight-weight-strongvar(--weight-strong)
--table-margin-top-space-8var(--space-8)
--table-background-surfacevar(--surface)
--table-border-rule-hairvar(--rule-hair)
--table-border-linevar(--line)
--table-border-radius-radiusvar(--radius)

Layout

AspectValue
breakpointsRequired review at 390, 768, 1024 and 1440 px; execution is not implied by this declaration; scrolls sideways inside its wrapper on phones (never the page).
wrappingCells wrap; the wrapper scrolls when columns cannot shrink.
textExpansionJapanese cells wrap.

Spacing and rhythm

AspectValue
internal--space-4 cell padding.
external--space-6 above and below.
rhythmInside prose.

Motion

AspectValue
NoneStatic.

Runtime and reuse

  1. Render-only element; mount any registered child enhancements separately. Preserve required Site CSS, fonts, responsive and locale rules from nativeElement.

Accessibility passport

AspectValue
roleregion (labelled) containing a table
nameThe label
keyboardTab to the region, arrows scroll.
focusOne stop for the region.
screenReaderReads headers with each cell (scope).
contrastInk on cotton.
targetNot a target.

Content

SlotLengthVoice
html7 columnsShort cells

Good: “Capability | State | What it does today”

Bad: “A table used to place two columns of prose”

Japanese: Status names and states have Japanese versions in the status page data.

Icons and illustrations

None: this element uses no icon or illustration of its own.

Decisions and exceptions

Usage

36 uses across the built pages (measured by npm run site:system).

Tests

AspectValue
unittests/unit/site-system.test.ts: renders every do and don't example through the registry and checks the classes it owns
visualNot yet: there are no screenshot baselines; the Library page is checked for sideways scroll at 1440 px by tests/site/system.spec.ts
a11ytests/site/system.spec.ts: axe (0 serious or critical) on the element's Library page in light and dark
parityscripts/site/system/check.ts: Library examples are rendered by the same render function the site imports

Figma

not-yet: The Loom Site Figma library is the last stage of the plan; this element is not mapped yet.

Open in Storybook

Start with a conversation about your system.

We read your system, show you what we found, and agree with your team what to fix first.