Data table
Organising content · researchedA grid of rows and columns for scanning, sorting, selecting, expanding and acting on structured records.
organism · also called Index table, Table · contains table, pagination, table-toolbar, bulk-actions, checkbox
Each block is the real component from that system’s own package, in an isolated frame. They are live: hover, focus and press them. Frames are drawn on white so systems compare on one ground, and a font a system licenses only for its own site (GOV.UK’s Transport) falls back to what the system itself specifies.
Ant Design
Table native: yes antd 6.6.5- Variants
- —
- Sizes
- large, medium, small
- States documented
- loading
- Accessibility guidance
- no
Renders a native table (via @rc-component/table); documented sorting, filtering, row selection, expandable rows, pagination, virtual scrolling. Table.Column, Table.ColumnGroup, Table.Summary are sub-parts of it, not separate components.
1 corrected on re-read
- states_documented: null → ["loading"] Table API row: loading, "Loading status of table"
Carbon
Data table native: yes @carbon/react 1.117.0- Variants
- Default, With selection, With expansion
- Sizes
- xs, sm, md, lg, xl
- States documented
- hover, focus, active, disabled, loading
- Accessibility guidance
- yes
Table renders a native table; selection rows use InlineCheckbox or RadioButton. Sizes are the Table size prop values (default lg). The 13 index entries are all parts of DataTable; I treat the component as one.
2 corrected on re-read
- variants: null → ["Default","With selection","With expansion"] Usage 'Variants' table
- urls: {"docs_url":"https://carbondesignsystem.com/components/data-table/usage/","code_url":"https://github.com/carbon-design-system/carbon/tree/main/packages/react/src/components/DataTable"} → {"docs_url":"https://www.carbondesignsystem.com/building-blocks/core/components/data-table/guidelines","code_url":"https://github.com/carbon-design-system/carbon/tree/main/packages/react/src/components/DataTable"} docs 200 after redirect to https://www.carbondesignsystem.com/building-blocks/core/components/data-table/guidelines; code URL 200
GOV.UK
Checked: component index (https://design-system.service.gov.uk/components/ , 37 components), patterns index, styles index, repo tree src/govuk/components and objects, and installed govuk-frontend 6.5.1 components directory. Only the Table component, a plain table with caption, numeric cells and optional header cells; docs describe no sorting, selecting, expanding or row actions, and the template has no aria-sort support. Table maps to the canonical `table` component, not this one.
Material Web
Checked docs/components (20 component pages), the repo top-level dirs, labs/, labs/gb/components and the installed 2.5.0 package. docs/roadmap.md lists Data table under components not yet built.
Primer
DataTable native: yes @primer/react 38.40.1- Variants
- —
- Sizes
- —
- States documented
- loading
- Accessibility guidance
- yes
Primer React. Renders a native table/thead/tbody/tr; page status is experimental (index also says experimental). Sorting, pagination, skeleton and group subcomponents. cellPadding: condensed/normal/spacious.
1 corrected on re-read
- states_documented: null → ["loading"] Example In a loading state uses skeleton rows
Spectrum
Table native: partly @spectrum-web-components/button 1.12.4- Variants
- —
- Sizes
- small, medium, large
- States documented
- default, hover, active, focus, disabled
- Accessibility guidance
- no
Docs from the rsp page (selected and dragged rows also documented). S2 TableView is virtualized, and React Aria's Table renders divs when virtualized and a table element otherwise; SWC 1st-gen sp-table uses slotted custom elements with ARIA; spectrum-css table 8.2.0 has a table-element template. Installed SWC 1.12.4 has @spectrum-web-components/table. Index's Table body, cell, column, footer, header, row and Editable table cell entries are parts of this one component, not separate ones; pagination and toolbar are not bundled.
2 corrected on re-read
- sizes: null → ["small","medium","large"] Page: Tables come in three sizes: small, medium, and large (S2 TableView has no size prop)
- a11y_documented: "yes" → "no" rsp table accessibility fragment is the Tooltip table (tooltip keyboard/WCAG text), not about tables
USWDS
Table subset native: yes @uswds/uswds 3.14.0- Variants
- borderless, compact, scrollable (usa-table-container--scrollable), stacked, stacked-header, sticky-header, striped, sortable rows
- Sizes
- —
- States documented
- default
- Accessibility guidance
- yes
Index said not shipped. Table is a native table with a documented sortable-rows example and responsive variants. No row selection, expansion, pagination or row actions are documented, so it covers only part of the canonical job.
Platform facts
Anatomy
- table — HTML table; APG Table: container role table.
- caption optional — HTML caption element: 'the title of the table'; APG: aria-labelledby/aria-label on the table.
- row — APG: role row (HTML tr).
- column header — APG: cell containing column title has role columnheader (HTML th).
- row header optional — APG: role rowheader.
- cell — APG: role cell (HTML td).
- sort indicator optional — APG Table: aria-sort on the header cell of a sorted column or row. Not named on the HTML table or APG Table page; APG Grid lists sort in the data grid example descriptions only.
The seven states
| default | Static tabular data. |
|---|---|
| hover | Inference: row hover is a design-system CSS convention; neither APG nor HTML defines it. |
| focus | APG Table: a table is not an interactive widget, so its cells are not focusable or selectable, and all focusable elements inside it are in the page tab sequence. APG Grid: a grid is a composite widget with a single tab stop and arrow-key movement between cells. Which applies depends on the implementation. |
| active | n/a — Not defined for a table. |
| disabled | n/a — Not defined for table; individual controls inside may be disabled. |
| error | n/a — Not defined for table. |
| loading | Inference, no source: loading data is an application state; HTML and APG define none. |
Every cell was read twice, the second time from raw sources by a separate pass. 6 of 35 fields changed on the second read — open any “corrected” note to see what it said before.