Cell rendering
Every column has three ways to control what renders in its cells: selector for plain data access, format for display transforms, and cell for full custom React renderers.
selector, format, and cell
| Prop | Returns | Affects sort? | Use for |
|---|---|---|---|
selector | Primitive | ReactNode | Yes | Simple data access. Source of truth for sorting. |
format | ReactNode | No | Formatting (currency, dates) without breaking sort order. |
cell | ReactNode | No | Full custom renderers: badges, avatars, action buttons. |
When cell is provided it takes priority over selector and formatfor rendering. For sortable columns with a custom cell, always provide selectorreturning a Primitive so sorting has a value to compare.
// ✅ Sortable column with a custom badge cell
{
name: 'Status',
selector: row => row.status, // sort key
cell: row => <StatusBadge status={row.status} />, // display
sortable: true,
}
// ✅ Currency column — format preserves sort order
{
name: 'Salary',
selector: row => row.salary, // sort on raw number
format: row => `$${row.salary.toLocaleString()}`, // display formatted
sortable: true,
right: true,
}Action button cells
Set button: true on a column to center the content and prevent clicks from bubbling to onRowClicked. Use this for edit / delete / view action columns.
{
name: '',
cell: row => <button onClick={() => openProfile(row)}>View</button>,
button: true,
width: '100px',
}Alignment and sizing
| Prop | Effect |
|---|---|
right | Right-align cell content. |
center | Center cell content. |
width | Fixed column width, e.g. "120px". Overrides flex sizing. |
minWidth | Minimum width before shrinking. |
maxWidth | Maximum width before growing stops. |
grow | Flex-grow factor. Default 1. Set to 0 to prevent growing. |
wrap | Allow text to wrap inside the cell. |
compact | Remove this column's cell padding. Independent of the table-level dense prop, which shrinks row height instead. |
Overflow and portals
By default DataTable clips cell overflow so rows stay a consistent height. If a cell contains a dropdown menu or popover that needs to break out, set allowOverflow: true on that column.
{
name: 'Actions',
cell: row => <ActionsMenu row={row} />,
allowOverflow: true,
button: true,
}Suppressing row click in a cell
ignoreRowClick: true prevents clicks in the cell from firing onRowClicked. Useful for inline controls (toggles, links) inside a clickable row.
Custom cells — avatar, currency format, status badge, action button
Each column demonstrates a different cell technique: a composite avatar+name renderer, format() for currency and dates, a status badge via cell(), and an action button column.
import DataTable, { type TableColumn } from 'react-data-table-component';
const columns: TableColumn<Employee>[] = [
{
name: 'Employee',
cell: row => (
<div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
<div
style={{
width: 32,
height: 32,
borderRadius: '50%',
background: '#dbeafe',
color: '#1d4ed8',
fontWeight: 700,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
{row.name
.split(' ')
.map(n => n[0])
.join('')}
</div>
<div>
<div style={{ fontWeight: 600 }}>{row.name}</div>
<div style={{ fontSize: 12, color: '#6b7280' }}>{row.department}</div>
</div>
</div>
),
minWidth: '200px',
grow: 2,
},
{
name: 'Salary',
selector: row => row.salary,
format: row =>
new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
maximumFractionDigits: 0,
}).format(row.salary),
sortable: true,
right: true,
},
{
name: 'Status',
cell: row => (
<span
style={{ padding: '2px 10px', borderRadius: 999, fontSize: 12, fontWeight: 600, ...statusStyle(row.status) }}
>
{row.status}
</span>
),
center: true,
width: '130px',
},
{
name: '',
cell: row => <button onClick={() => alert(`Viewing ${row.name}`)}>View profile</button>,
button: true,
width: '120px',
},
];See it combined with other features in the Inline row actions recipe.