Skip to content
LogoLogo

Data Table

Loading...

Overview

Resources

Loading...

Loading...

Loading...

Loading...

Install

yarn add @camp/data-table

Variations

Basic Table

A simple data table with basic column definitions and data display.

import { Table, createColumnHelper, useReadOnlyTable, flexRender } from '@camp/data-table';
 
const columnHelper = createColumnHelper<{
  name: string;
  email: string;
  role: string;
}>();
 
const columns = [
  columnHelper.accessor('name', {
    header: 'Name',
    cell: (info) => info.getValue(),
  }),
  columnHelper.accessor('email', {
    header: 'Email',
    cell: (info) => info.getValue(),
  }),
  columnHelper.accessor('role', {
    header: 'Role',
    cell: (info) => info.getValue(),
  }),
];
 
const data = [
  { name: 'John Doe', email: 'john@example.com', role: 'Admin' },
  { name: 'Jane Smith', email: 'jane@example.com', role: 'User' },
];
 
function MyDataTable() {
  const table = useReadOnlyTable({ data, columns });
 
  return (
    <Table.Container>
      <Table.Head>
        {table.getHeaderGroups().map((headerGroup) => (
          <Table.HeaderRow key={headerGroup.id}>
            {headerGroup.headers.map((header) => (
              <Table.HeaderCell key={header.id}>
                {flexRender(header.column.columnDef.header, header.getContext())}
              </Table.HeaderCell>
            ))}
          </Table.HeaderRow>
        ))}
      </Table.Head>
      <Table.Body>
        {table.getRowModel().rows.map((row) => (
          <Table.Row key={row.id}>
            {row.getVisibleCells().map((cell) => (
              <Table.Cell key={cell.id}>
                {flexRender(cell.column.columnDef.cell, cell.getContext())}
              </Table.Cell>
            ))}
          </Table.Row>
        ))}
      </Table.Body>
    </Table.Container>
  );
}

Usage

Best practices

  • Use clear, descriptive column headers that accurately represent the data
  • Keep table rows concise and avoid overwhelming users with too many columns
  • Implement proper empty states when no data is available
  • Use custom cell rendering to enhance data presentation and user experience
  • Ensure tables are accessible with proper semantic markup and keyboard navigation
  • Consider pagination for large datasets to improve performance

Content guidelines

✅ DO

  • Use descriptive column headers that clearly indicate the data type
  • Implement empty states with helpful messaging when no data is available
  • Use custom cell rendering to format data appropriately (dates, status indicators, etc.)

🚫 DON’T

  • Use vague or technical column names that confuse users
  • Leave empty tables without any indication of why they're empty
  • Display raw data without any formatting or context

Accessibility

Keyboard support

  • Tables support standard keyboard navigation for screen readers
  • Users can navigate through table cells using Tab key
  • Arrow keys can be used to move between cells in supported implementations
  • Table headers are properly associated with their corresponding data cells

Breaking changes

  • Import path changes from @/components/table to @camp/data-table
  • Requires using the createColumnHelper and useReadOnlyTable hooks for table configuration
  • Data must be structured as an array of objects with consistent properties
  • Column definitions must be created using the column helper pattern
  • Table rendering requires using the flexRender function for dynamic content
Copyright © 2026 ActiveCampaign