Column groups
Column groups render a spanning header row above the regular column headers. Useful for grouping related columns under a shared label.
Column groups
Employee and Compensation groups span their respective columns.
First name
Last name
Department
Base salary
Bonus
Employee
Compensation
import DataTable, { type TableColumn, type ColumnGroup } from 'react-data-table-component';
interface Employee {
id: number;
firstName: string;
lastName: string;
department: string;
baseSalary: number;
bonus: number;
}
const data: Employee[] = [
{ id: 1, firstName: 'Aria', lastName: 'Chen', department: 'Engineering', baseSalary: 140000, bonus: 15000 },
{ id: 2, firstName: 'Marcus', lastName: 'Webb', department: 'Product', baseSalary: 125000, bonus: 7000 },
{ id: 3, firstName: 'Priya', lastName: 'Kapoor', department: 'Design', baseSalary: 110000, bonus: 8000 },
{ id: 4, firstName: 'Jordan', lastName: 'Ellis', department: 'Analytics', baseSalary: 135000, bonus: 12000 },
];
// Every column that belongs to a group must have a stable `id`
const columns: TableColumn<Employee>[] = [
{ id: 'first', name: 'First name', selector: r => r.firstName, sortable: true },
{ id: 'last', name: 'Last name', selector: r => r.lastName, sortable: true },
{ id: 'dept', name: 'Department', selector: r => r.department, sortable: true },
{ id: 'base', name: 'Base salary', selector: r => r.baseSalary, sortable: true, right: true,
format: r => `$${r.baseSalary.toLocaleString()}` },
{ id: 'bonus', name: 'Bonus', selector: r => r.bonus, sortable: true, right: true,
format: r => `$${r.bonus.toLocaleString()}` },
];
const columnGroups: ColumnGroup[] = [
{ name: 'Employee', columnIds: ['first', 'last', 'dept'] },
{ name: 'Compensation', columnIds: ['base', 'bonus'] },
];
export default function App() {
return (
<DataTable
columns={columns}
data={data}
columnGroups={columnGroups}
highlightOnHover
/>
);
} Drag to reorder groups
Add reorder: true to each group to make its header draggable.
Dragging moves the entire group (all member columns) as a block.
See the Column reordering page for a full example.
const columnGroups: ColumnGroup[] = [
{ name: 'Employee', columnIds: ['first', 'last', 'dept'], reorder: true },
{ name: 'Compensation', columnIds: ['base', 'bonus'], reorder: true },
];
<DataTable
columns={columns}
data={data}
columnGroups={columnGroups}
onColumnGroupOrderChange={(nextGroups, nextCols) => {
setGroups(nextGroups);
setCols(nextCols);
}}
/> Rules
- Each column that belongs to a group must have a stable
id. columnIdsmust match theidvalues exactly (string or number).- Columns not listed in any group span the full group-row height with no label.
- Groups render in the order they appear in the
columnGroupsarray.
ColumnGroup type
interface ColumnGroup {
name: ReactNode; // Header label (accepts JSX)
columnIds: (string | number)[]; // ids of columns that fall under this group
align?: 'left' | 'center' | 'right'; // Label alignment (default: 'center')
} Label alignment
Group labels are centered by default. Pass align to override per group:
const columnGroups: ColumnGroup[] = [
{ name: 'Employee', columnIds: ['first', 'last', 'dept'], align: 'left' },
{ name: 'Compensation', columnIds: ['base', 'bonus'] }, // centered (default)
]; Custom group header content
The name field accepts any ReactNode, so you can pass JSX:
const columnGroups: ColumnGroup[] = [
{
name: <span style={{ color: '#4f46e5', fontWeight: 700 }}>Compensation</span>,
columnIds: ['base', 'bonus'],
},
]; Styling group headers
Group label cells carry the CSS class rdt_groupCell. Target it directly
to override colours, font, or spacing without needing customStyles:
.rdt_groupCell {
color: #4f46e5;
font-weight: 700;
letter-spacing: 0.08em;
} Use CSS custom properties to keep overrides theme-aware:
.my-table {
--rdt-color-text-secondary: #4f46e5;
}