Skip to content

Table

Github icon-storybook-square Storybook Markdown Copy for LLM

A table displays data in rows and columns, with support for sorting, selection, and keyboard navigation.

Import

import { Table } from "@cfa/react-core";

Live Editor

Guidelines

When to use

  • Table is for data with comparable columns, such as when people compare, sort, filter, or bulk-edit.

Do

  • On narrow viewports, keep tabular data in a Table. Prefer horizontal scroll over turning rows into Cards.
  • Scroll wide tables horizontally in a contained area. Keep column headers and the row identifier visible where the component supports it.
  • When the table is selectable, always include a selection column (SelectionColumn in the header and SelectionCell in each row), typically first. Do not rely on selected row color alone.
  • For multi-select, include select-all in the header. For single-select, still include a per-row control. Do not include select-all.
  • Name each row’s selection checkbox from that row, such as the row header, not a generic Select.
  • For container empty, loading, error, and filtered-empty states, see Empty State.

Avoid

  • Using Table when selection is a single attribute without columns. Use ListBox.

Examples

Dynamic Collections

Use the items prop to pass an array of objects to Table.Body with a render function. This works like .map() but is more performant because it only re-renders rows that have changed, rather than the entire list.

Striped Variant

Use the variant="striped" prop to alternate row background colors for better readability.

Compact

Use the compact prop to reduce row height and cell padding.

Text Alignment

Use the alignment prop on Table.Cell or Table.Column to align cell content. Supported values are "start" (default), "center", and "end".

Use the href prop on Table.Row to make entire rows navigable. This is useful for tables where each row represents a resource the user can navigate to.

Single Selection

Enable single row selection by setting selectionMode="single".

Multiple Selection

Enable multiple row selection by setting selectionMode="multiple".

Replace Selection Behavior

By default, selection uses selectionBehavior="toggle" which renders checkboxes and allows additive selection. Set selectionBehavior="replace" to select rows on click. Hold Shift to select a range or Ctrl/Cmd to add individual rows.

Disabled Rows

Use the disabledKeys prop to prevent interaction with specific rows. Disabled rows are excluded from selection.

Sortable Columns

Use sortDescriptor and onSortChange to control sorting. Mark sortable columns with allowsSorting and add sort indicator icons to show direction.

Note: This approach sorts data that is already loaded into the table, which works well for small datasets. For more complex patterns like server-side sorting, pagination, or filtering, consider using an external library such as TanStack Table to manage table state.

Embedded Components

Table cells can contain interactive components like menus, buttons, or links. This is useful for adding row-level actions.

Empty State

Use the renderEmptyState prop to display a message or custom component when there are no items to display.

Async Loading

Use renderEmptyState to show a loading indicator while fetching data. Once the data resolves, the table automatically renders the rows.

Use Table.Footer to display summary rows such as totals below the table body. Place one or more Table.Row elements inside the footer, using colSpan on cells when a label should span multiple columns.

Load More

Use Table.LoadMoreItem to enable infinite scrolling. Place it as the last child of Table.Body alongside a Collection. It calls onLoadMore when scrolled into view and displays its children (e.g., a loading indicator) while loading.