All files / packages/design-system-2-site/src/components/ui DataTable.tsx

100% Statements 4/4
100% Branches 0/0
100% Functions 4/4
100% Lines 4/4

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52                                                979x           3103x               10186x   32350x                      
import type { ReactNode } from 'react';
 
export interface DataTableColumn<T> {
  header: string;
  align?: 'start' | 'center' | 'end';
  /** Optional fixed column width, e.g. "4rem". */
  width?: string;
  cell: (row: T) => ReactNode;
}
 
interface DataTableProps<T> {
  columns: DataTableColumn<T>[];
  rows: T[];
  getRowKey: (row: T, index: number) => string;
  /** Id of the heading that names the table. */
  labelledBy?: string;
}
 
/**
 * Bordered data grid with a header band and row hover. Distinct from the prose
 * `.content-blocks table`, though it shares its type, border and spacing tokens.
 * Styling lives in globals.css (`.data-table*`).
 */
export function DataTable<T>({ columns, rows, getRowKey, labelledBy }: DataTableProps<T>) {
  return (
    <div className="data-table">
      <table className="data-table__table" aria-labelledby={labelledBy}>
        <thead>
          <tr>
            {columns.map((col, i) => (
              <th key={i} style={{ textAlign: col.align, width: col.width }}>
                {col.header}
              </th>
            ))}
          </tr>
        </thead>
        <tbody>
          {rows.map((row, r) => (
            <tr key={getRowKey(row, r)}>
              {columns.map((col, c) => (
                <td key={c} style={{ textAlign: col.align }}>
                  {col.cell(row)}
                </td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}