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.

Name
Role
Department
Salary
Aria Chen
Engineering Lead
Engineering
$155,000
Marcus Webb
Product Manager
Product
$132,000
Priya Kapoor
Senior Designer
Design
$118,000
Jordan Ellis
Data Scientist
Analytics
$143,000
Sam Rivera
DevOps Engineer
Engineering
$128,000

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.

PropTypeDescription
initialColumnWidthsRecord<string | number, number>Seed column widths (px) by column id on mount.
onColumnResize(columnId, width, allWidths) => voidCalled 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

PropTypeDefaultDescription
resizablebooleanfalseShow drag handles on column headers for resizing.
initialColumnWidthsRecord<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 propTypeDefaultDescription
column.widthstring-Initial width (e.g. "180px").
column.minWidthstring"100px"Minimum width the user can resize to. Hard floor of 40 px applies regardless.