You're in the Library

Table

A semantic data table for comparing records: sortable columns, selectable rows, density-aware rows, and a focusable scroll region on narrow screens.
Stable
Edit

Preview appears after the next Storybook update.

Table example
<Table />
Rendered with the real componentFrom the code
Light
Dark

When to use

Use it for

  • Records with the same attributes that users compare, sort or act on: tokens, components, pull requests.
  • Sortable headers (sortDirection + onSort, or useTableSort) on columns users reorder by.
  • Selectable rows: a Checkbox in the first cell, selected on the row, bulk actions above the table.
  • Compact density for expert, data-heavy screens.
  • Column widths when one column should not take the space of the others: width on the header cell, as a token length (var(--size-20)), a percentage or a fraction (0.35), plus minWidth for a floor. layout fixed keeps them exact while data loads.
  • narrowLayout stack when people read the table on a phone: under about 480px each row becomes a card, every value beside its column name. Keep scroll (the default) for wide data people compare across rows.

Not for

  • Layout: never use a table to position content.
  • Fewer than three attributes per item: use a list.
  • Editing many cells inline like a spreadsheet: that needs a grid pattern, not in the system yet.

Do and don't

Every example is rendered with the real component, so it always matches what ships.

Button1,204
Badge87
Do

Right-align numbers

numeric aligns digits on the right with tabular figures, so values compare at a glance.

No pull requests yet. Changes you sync from Figma appear here.
Do

Say what to do when it is empty

TableEmpty keeps the header in place and explains how rows will appear.

color.signal.default
Don't

Color as the only row state

A tinted row alone does not say selected. Pair it with a checked Checkbox.

Accessibility

  • Native table, thead, th scope col and td: screen readers announce headers with each cell.
  • Sortable headers contain a button; the th gets aria-sort ascending or descending on the sorted column only.
  • Selected rows set aria-selected and use the selected surface plus a checked Checkbox (never color alone).
  • The scroll container is a labelled region with tabIndex 0, so keyboard users can scroll wide tables (named by the caption or aria-label).
  • Row height and cell padding follow density: 48/36px rows, both above the 24px target minimum for the controls inside.
  • Stacked rows keep their table roles (table, row, cell), so screen readers still read cell by cell; the column names shown before each value are the header texts. The header row is hidden while rows stack, so put sorting somewhere else on phones.

Content guidelines

  • Column headers are short nouns in sentence case: "Token", "Owner", "Uses".
  • Units go in the header ("Size (px)") so cells hold only values.
  • Empty cells show "None" or "n/a", never blank.

From the code Generated from the component, not editable here.

Anatomy and tokens

Read from packages/react/src/components/Table/Table.module.css at build time. Every value is a token: open one to see its alias chain in both themes.

36 tokens17 semantic or component, change with theme and brand3 density, change with comfortable or compact16 from the shared scales

Motion and interaction

Table animates on hover. Try it in the preview at the top.

WhenWhat changesDurationEasing
HoverBackgroundmotion.duration.instant75 msmotion.easing.standardsettles in place

With reduced motion turned on, every change happens at once.

From the code Generated from the component, not editable here.

Props

Parsed from the TypeScript types in packages/react/src/components/Table/Table.tsx, so this table cannot drift from the code. It also accepts every native <HTMLTableElement> attribute.

PropTypeDefaultDescription
captionReactNodenoneVisible caption above the table. Also names the scroll region.
stickyHeaderbooleanfalseAccessible name when there is no visible caption, for example "Tokens changed in this pull request". */ 'aria-label'?: string; /** Keep the header row visible while the table scrolls inside its container.
maxHeightstringnoneMax height of the scroll container (CSS length from a token, for example var(--size-120)). Enables vertical scroll.
gridLinesbooleanfalseHairlines between columns as well as rows. Default `false`.
layout'auto' | 'fixed''auto'`auto` (default) sizes columns from their content and the widths you set. `fixed` follows the widths of the header cells exactly and truncates nothing on its own: long words wrap. Use `fixed` when rows should not shift as data loads.
narrowLayout'scroll' | 'stack''scroll'In a container narrower than about 480px: `scroll` keeps the columns and scrolls sideways (default); `stack` shows each row as a card, every value beside its column name. Column names come from the header row, or from `label` on a cell.

Comes with useTableSort, each accepting native <div> attributes.

Playground

Change the props and see the real Table update. Controls are generated from the TypeScript props; nothing here changes the system.

Code for these props
<Table caption="Tokens in this release" />

layout

narrowLayout

Workbench

For contributors: every state with the accessibility panel, in the component workbench (Storybook). The stories double as visual test fixtures; the guidance on this page is the user documentation (open Table in Storybook).

Embed Storybook stories here (6)

Loads from https://bridge-storybook.floriangouloubi.com (set STORYBOOK_URL at build time). If Storybook is not running, the frames stay empty.

SortableAndSelectable

StickyHeader

ColumnWidths

StackedOnPhone

Empty

AllStates

From the code Generated from the component, not editable here.

Changelog

  • New

    Change drafts: draftRequestText(component, kind, changes) and draftPushDescription(entries, components) write a sentence-case title and a 1 or 2 sentence summary from detected changes only (no reason, no invented number, no em dash), with pushChangeRows for a change table of variable edits and cleanDraftText to strip em dashes

    v1.0.0, Nov 11, 2026

  • New

    Data display: Card restyled as a flat plate with an interactive option and padding sizes; Badge gains appearance (subtle, now the default, or solid), a dot, icons and sizes (existing solid badges must pass appearance="solid" to keep their look); new Avatar and AvatarGroup, Table (sortable headers with aria-sort, selectable rows, sticky header, focusable scroll region, useTableSort), Accordion, Tag (removable, toggleable), Divider and Kbd

    v1.0.0, Nov 11, 2026

  • New

    A new homepage at "/", ported from the validated test page: drag the bridge to keep what your exploration added; "Start it in Bridge", "Ship it everywhere at once" and "One system everyone can trust", each step drawn as an animated Field Guide illustration; "Decide in seconds" for the design system lead; "How Bridge compares" (a short table, every feature on demand); the questions teams ask; and the Horizon closing

    v1.0.0, Nov 11, 2026

  • Fix

    Cloudflare Pages previews: read the HTML table Cloudflare really posts in its check run (<strong>Preview URL:</strong> with an <a href> link, and Branch Preview URL: on preview branches), not only Markdown rows

    v1.0.0, Nov 11, 2026

  • Fix

    Component specs count height and width as the content box (a bordered table cell is its height plus its border), the Figma build draws an empty sized slot at its padding instead of 100px, and stories reach every Figma variant: a disabled control on IconButton, Input, Select, Combobox and Textarea, and Figma variant stories for AccordionItem, MenuItem, MenuCheckboxItem, MenuSubmenu and TableEmpty

    v1.0.0, Nov 11, 2026

  • Fix

    Studio: the Tokens table fills its width again

    v1.0.0, Nov 11, 2026

  • Fix

    Studio Components: the Open requests column leaves the table (teams triage requests in Jira); the component drawer still counts them with a link to GitHub

    v1.0.0, Nov 11, 2026

  • Fix

    Studio: screens no longer end with the "Updated" date and "View source" line (they show live data; Library pages keep it), and the Components table drops its note under the table

    v1.0.0, Nov 11, 2026

  • Fix

    Studio Tokens: a page header and one toolbar row (filter field "Filter N tokens", type chips with counts, one Options menu for collections, usage, brand and modes, columns and exact match, then New token), and the table at full width with Name, Light and Dark

    v1.0.0, Nov 11, 2026

All release notes