Components
Table
Table is a set of styled HTML table primitives for displaying simple tabular data.
Table provides styled HTML table elements as React components. It is intentionally minimal — it has no built-in sorting, filtering, or pagination. For those features use DataTable instead.
Use Table only when your data is truly static and needs no interaction. For anything dynamic, DataTable is the right choice.
() => (<TableWrapper><TableRoot><TableCaption>Nutritional Information</TableCaption><TableHeader><TableRow><TableHeaderCell scope="col">Food Item</TableHeaderCell><TableHeaderCell scope="col">Calories</TableHeaderCell><TableHeaderCell scope="col">Total Fat</TableHeaderCell><TableHeaderCell scope="col">Protein</TableHeaderCell></TableRow></TableHeader><TableBody><TableRow><TableCell>🍔 Bacon Smokehouse Burger</TableCell><TableCell>840</TableCell><TableCell>45g</TableCell><TableCell>46g</TableCell></TableRow><TableRow><TableCell>🍔 Big Mac</TableCell><TableCell>540</TableCell><TableCell>28g</TableCell><TableCell>25g</TableCell></TableRow><TableRow><TableCell>🥗 Side Salad</TableCell><TableCell>20</TableCell><TableCell>0g</TableCell><TableCell>1g</TableCell></TableRow></TableBody></TableRoot></TableWrapper>)
Components
Table exports a set of primitives that map directly to HTML table elements. Compose them together to build a table.
| Component | HTML element | Purpose |
|---|---|---|
TableWrapper | div | Scroll container; provides accessible role="region" wrapper |
TableRoot | table | The table element |
TableCaption | caption | Accessible label; use displayCaption={false} to hide visually |
TableHeader | thead | Header section |
TableBody | tbody | Body section |
TableRow | tr | A row |
TableHeaderCell | th | A header cell |
TableCell | td | A data cell |
TableWrapper
TableWrapper wraps the table in a scrollable div with overflow-x: auto and wires up the accessible aria-labelledby relationship between the container and the caption automatically. Always use it as the outermost wrapper.
Custom Cell Content
Because cells accept React.ReactNode, you can render any content — links, badges, icons — directly inside TableCell or TableHeaderCell.
() => (<TableWrapper><TableRoot><TableCaption>Team Status</TableCaption><TableHeader><TableRow><TableHeaderCell scope="col">Name</TableHeaderCell><TableHeaderCell scope="col">Role</TableHeaderCell><TableHeaderCell scope="col">Status</TableHeaderCell></TableRow></TableHeader><TableBody><TableRow><TableCell>Alice</TableCell><TableCell>Engineer</TableCell><TableCell><Badge badgeColor="green">Active</Badge></TableCell></TableRow><TableRow><TableCell>Bob</TableCell><TableCell>Designer</TableCell><TableCell><Badge badgeColor="green">Active</Badge></TableCell></TableRow><TableRow><TableCell>Charlie</TableCell><TableCell>Manager</TableCell><TableCell><Badge badgeColor="red">Inactive</Badge></TableCell></TableRow></TableBody></TableRoot></TableWrapper>)
Row Headers
Use TableHeaderCell with scope="row" inside TableBody rows to mark a cell as the row's header. This improves screen reader navigation for tables where the first column identifies each row.
() => (<TableWrapper><TableRoot><TableCaption>Q1 Targets</TableCaption><TableHeader><TableRow><TableHeaderCell scope="col">Team</TableHeaderCell><TableHeaderCell scope="col">Target</TableHeaderCell><TableHeaderCell scope="col">Actual</TableHeaderCell></TableRow></TableHeader><TableBody><TableRow><TableHeaderCell scope="row">Engineering</TableHeaderCell><TableCell>12 features</TableCell><TableCell>14 features</TableCell></TableRow><TableRow><TableHeaderCell scope="row">Design</TableHeaderCell><TableCell>8 designs</TableCell><TableCell>7 designs</TableCell></TableRow><TableRow><TableHeaderCell scope="row">Marketing</TableHeaderCell><TableCell>4 campaigns</TableCell><TableCell>4 campaigns</TableCell></TableRow></TableBody></TableRoot></TableWrapper>)
Accessibility
- Always provide a
TableCaption. UsedisplayCaption={false}only when the table's purpose is already clear from surrounding page context. - Use
scope="col"on allTableHeaderCellelements inTableHeader. - Use
scope="row"onTableHeaderCellelements inTableBodyrows that identify each row. TableWrapperautomatically wiresaria-labelledbybetween the container and caption for scrollable table regions.
Best Practices
- Prefer DataTable for any table with dynamic data, sorting, filtering, or pagination.
- Use Table only for simple, static tabular data where no interaction is needed.
- Always wrap the table in
TableWrapperto handle overflow and accessibility correctly.