Columns
Columns are defined as an array of TableColumn<T> objects.
Each column controls its header label, data accessor, sort behavior, rendering, and layout.
Column features
Toggle column visibility with omit, enable per-column filtering, and see custom cell renderers and conditional cell styles in action.
import { useState } from 'react';
import DataTable, { type TableColumn, type ConditionalStyles } from 'react-data-table-component';
interface Employee {
id: number;
name: string;
department: string;
salary: number;
status: 'Active' | 'Remote' | 'Contractor' | 'On Leave';
startDate: string;
}
const StatusBadge = ({ status }: { status: Employee['status'] }) => (
<span
style={{
padding: '2px 8px',
borderRadius: 12,
fontSize: 11,
fontWeight: 600,
background: status === 'Active' ? '#dcfce7' : '#f3f4f6',
color: status === 'Active' ? '#15803d' : '#6b7280',
}}
>
{status}
</span>
);
export default function App() {
const [showDept, setShowDept] = useState(true);
const [showSalary, setShowSalary] = useState(true);
const [filterable, setFilterable] = useState(false);
const columns: TableColumn<Employee>[] = [
{
id: 'name',
name: 'Name',
selector: r => r.name,
sortable: true,
filterable, // filterable toggles a filter input in the header
},
{
id: 'department',
name: 'Department',
selector: r => r.department,
sortable: true,
omit: !showDept,
},
{
id: 'salary',
name: 'Salary',
selector: r => r.salary,
sortable: true,
right: true,
format: r => `$${r.salary.toLocaleString()}`,
omit: !showSalary,
conditionalCellStyles: [{ when: r => r.salary > 150000, style: { fontWeight: 700 } }],
},
{
id: 'status',
name: 'Status',
selector: r => r.status,
center: true,
cell: r => <StatusBadge status={r.status} />,
},
{
id: 'start',
name: 'Start date',
selector: r => r.startDate,
sortable: true,
format: r => new Date(r.startDate).toLocaleDateString(),
},
];
return (
<div>
<div>
<button onClick={() => setShowDept(p => !p)}>Toggle Department</button>
<button onClick={() => setShowSalary(p => !p)}>Toggle Salary</button>
<button onClick={() => setFilterable(p => !p)}>Toggle filterable</button>
</div>
<DataTable columns={columns} data={data} defaultSortFieldId="name" />
</div>
);
}
Basic column definition
import { type TableColumn } from 'react-data-table-component';
interface Row {
id: number;
name: string;
salary: number;
}
const columns: TableColumn<Row>[] = [
{
name: 'Name',
selector: row => row.name,
sortable: true,
},
{
name: 'Salary',
selector: row => row.salary,
format: row => `$${row.salary.toLocaleString()}`,
right: true,
},
];
Column properties
| Prop | Type | Description |
|---|---|---|
id | string | number | Stable identity used by defaultSortFieldId, columnGroups, and filterValues. |
name | ReactNode | Column header label. |
selector | (row, index?) => Primitive | ReactNode | Data accessor used for sorting and default display. |
cell | (row, index, column, id) => ReactNode | Custom cell renderer. Overrides the selector display value. |
format | (row, index) => ReactNode | Format the selector value for display without changing the sort key. |
sortable | boolean | Enable sorting on this column. |
sortFunction | (a: T, b: T) => number | Custom comparator for this column. Takes priority over the table-level sortFunction. |
sortField | string | Backend field name passed to onSort for server-side sorting, when it differs from id. |
filterable | boolean | Show a filter popup for this column. |
filterType | "text" | "number" | "date" | "datetime" | "time" | "set" | Filter operator set and input widget. Defaults to "text". See Filtering. |
filterFunction | (row, filter: FilterState) => boolean | Custom filter predicate. Overrides built-in operator logic. Receives the full FilterState including both conditions. |
filterOptions | { values?: string[] | ((rows: T[]) => string[]); separator?: string | RegExp } | Per-column set filter settings. values supplies the checklist, separator splits multi-value cells. |
width | string | Fixed column width, e.g. "120px". With resizable, this is the starting width. |
minWidth | string | Minimum width. Defaults to "100px" when neither width nor minWidth is set. With resizable, the user cannot drag narrower than this, with a hard floor of 40px. |
maxWidth | string | Maximum width. |
grow | number | Flex-grow factor (default 1). Set to 0 to prevent growing. |
right | boolean | Right-align cell content. |
center | boolean | Center cell content. |
wrap | boolean | Allow cell text to wrap. |
compact | boolean | Remove this column's cell padding. Independent of the table-level dense prop, which shrinks row height instead. |
button | boolean | Center content and suppress row click propagation. |
allowOverflow | boolean | Allow cell content to overflow (useful for dropdowns and popovers). |
ignoreRowClick | boolean | Prevent clicks in this cell from firing onRowClicked. |
hide | Media | Hide the column below the given breakpoint (Media.SM = 599px, MD = 959px, LG = 1280px). |
omit | boolean | Exclude the column entirely. Toggle this to show/hide a column. |
reorder | boolean | Allow drag-to-reorder for this column (requires reorder on at least two columns). |
pinned | 'left' | 'right' | Freeze the column to an edge during horizontal scroll. Only visible when the table overflows its container, so give columns explicit widths. |
style | CSSProperties | Inline styles applied to every cell in this column. |
conditionalCellStyles | ConditionalStyles<T>[] | Per-cell conditional styles. |
footer | ReactNode | (rows: T[]) => ReactNode | Footer cell for this column: a static node or a function of the filtered and sorted rows. See Footer. |
The inline editing fields (editable, editor, validate,
onCellEdit) are covered on the Inline editing page.
Custom cell renderer
{
name: 'Actions',
button: true,
cell: row => (
<button onClick={() => handleDelete(row.id)}>Delete</button>
),
}
Column filtering
Add filterable: true to any column to render a filter icon in the header.
Clicking the icon opens a filter panel; rows are filtered client-side by default.
{ name: 'Name', selector: r => r.name, filterable: true }
// Custom filter logic:
{
name: 'Status',
selector: r => r.status,
filterable: true,
filterFunction: (row, filter) => row.status.startsWith(filter.condition1.value ?? ''),
}
For controlled filter state, pass filterValues and onFilterChange to
DataTable. See Column filtering for filter types,
operators, and server-side filtering.
Column reordering
Mark columns with reorder: true and pass onColumnOrderChange to
DataTable to enable drag-to-reorder handles. The callback receives the new column array
in order.
const [cols, setCols] = React.useState(columns);
<DataTable columns={cols} data={data} onColumnOrderChange={setCols} />;
Hiding columns
Toggle a column's visibility by setting omit dynamically:
const [showSalary, setShowSalary] = React.useState(true);
const columns = [
{ name: 'Name', selector: r => r.name },
{ name: 'Salary', selector: r => r.salary, omit: !showSalary },
];