Resizable columns
Enable drag-to-resize handles on column headers by setting resizable. Users drag the right edge of any header cell to adjust its width, by mouse or touch. Resize is fully compatible with sorting, pagination, filtering, pinning, and column reordering.
Resizable columns
Drag the right edge of any column header to resize it.
Drag the right edge of any column header to resize it.
import DataTable, { type TableColumn } from 'react-data-table-component';
const columns: TableColumn<Employee>[] = [
{ name: 'Name', selector: r => r.name, width: '180px', minWidth: '100px' },
{ name: 'Role', selector: r => r.role, minWidth: '120px' },
{ name: 'Department', selector: r => r.department, width: '140px', minWidth: '80px' },
{
name: 'Salary',
selector: r => r.salary,
width: '110px',
right: true,
format: r => `$${r.salary.toLocaleString()}`,
},
];
<DataTable columns={columns} data={data} resizable highlightOnHover />;How it works
The resize handle sits straddling the right edge of each header cell, a 6 px hit area centered on the column boundary so it aligns with the column separator. Onmousedown, a global mousemove listener tracks the delta and writes the new width to component state; the affected column receives an inlinewidth style. Only the resized column re-renders.
Initial and minimum widths
width sets the starting width; minWidth clamps how small a user can drag the column. Columns without a fixed width start at their natural flex width and remain resizable.
const columns: TableColumn<Employee>[] = [
{ name: 'Name', selector: r => r.name, width: '200px', minWidth: '120px' },
{ name: 'Status', selector: r => r.status, width: '100px' },
{ name: 'Notes', selector: r => r.notes /* grows to fill remaining space */ },
];
<DataTable columns={columns} data={data} resizable />;The hard floor is 40 px. DataTable won't allow narrower than that regardless of minWidth.
Visual indicator
The handle is invisible until hover. On hover or active drag, a 2 px center line appears in your primary color (--rdt-color-primary). The line sits exactly on the column boundary so it visually replaces the separator while resizing.
Persisting widths
Pass onColumnResize to receive the settled width after every drag, andinitialColumnWidths to hydrate saved widths on mount. Both are keyed by the id you set on each column:
import { useState } from 'react';
import DataTable, { type TableColumn } from 'react-data-table-component';
const STORAGE_KEY = 'employees-table-widths';
function loadWidths(): Record<string, number> {
try {
return JSON.parse(localStorage.getItem(STORAGE_KEY) ?? '{}');
} catch {
return {};
}
}
export default function App() {
const [initialWidths] = useState(loadWidths);
const columns: TableColumn<Employee>[] = [
{ id: 'name', name: 'Name', selector: r => r.name },
{ id: 'salary', name: 'Salary', selector: r => r.salary, right: true },
];
return (
<DataTable
columns={columns}
data={data}
resizable
initialColumnWidths={initialWidths}
onColumnResize={(_id, _width, allWidths) =>
localStorage.setItem(STORAGE_KEY, JSON.stringify(allWidths))
}
/>
);
}See the Persist column widths recipe for a live demo, including saving to a back-end API instead of localStorage.
| Prop | Type | Description |
|---|---|---|
initialColumnWidths | Record<string | number, number> | Seed column widths (px) by column id on mount. |
onColumnResize | (columnId, width, allWidths) => void | Called with the column id, final width (px), and full widths map after a resize. |
With column pinning
Resize works on pinned columns. When a pinned column's width changes, the sticky offsets for columns pinned further from the edge update automatically. The pin band shifts to stay aligned.
Resetting widths
Force a remount of DataTable to clear all resize state. The simplest approach is a React key bump:
const [resetKey, setResetKey] = useState(0);
<button onClick={() => {
localStorage.removeItem(STORAGE_KEY);
setResetKey(k => k + 1);
}}>Reset column widths</button>
<DataTable key={resetKey} columns={columns} data={data} resizable />Accessibility
The resize handle is pointer-only (mouse and touch). Keyboard users cannot drag-resize. If keyboard-accessible resizing matters for your audience, provide a settings UI (a popover with width inputs per column) as an alternative.
Prop reference
| Prop | Type | Default | Description |
|---|---|---|---|
resizable | boolean | false | Show drag handles on column headers for resizing. |
initialColumnWidths | Record<string | number, number> | - | Seed column widths (px) by column id on mount. |
onColumnResize | (columnId, width, allWidths) => void | - | Called with the column id, final width (px), and full widths map after a resize. |
| Column prop | Type | Default | Description |
|---|---|---|---|
column.width | string | - | Initial width (e.g. "180px"). |
column.minWidth | string | "100px" | Minimum width the user can resize to. Hard floor of 40 px applies regardless. |