Skip to content

Column & Row Resize

WitTable supports resizing columns and rows by dragging borders. Drag the right border of a column header to resize the column, or drag the bottom border of a row number cell to resize the row. Both operations are undoable via ResizeColumnCommand and ResizeRowCommand.

Live Demo
Drag column header borders to resize. ID column is locked. Row borders in the row-number gutter can also be dragged.
View source code
ResizeDemo.tsx
import { WitTable } from '@witqq/spreadsheet-react';
import type { ColumnDef } from '@witqq/spreadsheet';
import { DemoWrapper } from './DemoWrapper';
import { generateEmployees } from './generate-data';
import { useSiteTheme } from './useSiteTheme';
const data = generateEmployees(50);
const resizableColumns: ColumnDef[] = [
{ key: 'id', title: 'ID', width: 60, type: 'number', resizable: false },
{ key: 'name', title: 'Name (resizable)', width: 160, minWidth: 80, maxWidth: 400, resizable: true },
{ key: 'department', title: 'Department', width: 130, minWidth: 60, resizable: true },
{ key: 'salary', title: 'Salary', width: 100, type: 'number', minWidth: 60, resizable: true },
{ key: 'city', title: 'City', width: 120, minWidth: 60, maxWidth: 300, resizable: true },
{ key: 'startDate', title: 'Start Date', width: 110, type: 'date', resizable: true },
{ key: 'active', title: 'Active', width: 70, type: 'boolean', resizable: true },
];
export function ResizeDemo() {
const { witTheme } = useSiteTheme();
return (
<DemoWrapper title="Live Demo" description="Drag column header borders to resize. ID column is locked. Row borders in the row-number gutter can also be dragged." height={440}>
<WitTable
theme={witTheme}
columns={resizableColumns}
data={data}
showRowNumbers
style={{ width: '100%', height: '100%' }}
/>
</DemoWrapper>
);
}

Column resize respects ColumnDef.minWidth and ColumnDef.maxWidth constraints. Row resize is bounded between 12px minimum and 400px maximum.

Enable resize per-column through ColumnDef.resizable:

import { WitTable } from '@witqq/spreadsheet-react';
const columns: ColumnDef[] = [
{ key: 'id', title: 'ID', width: 60, resizable: false },
{ key: 'name', title: 'Name', width: 200, minWidth: 100, maxWidth: 400, resizable: true },
{ key: 'email', title: 'Email', width: 250, minWidth: 150, resizable: true },
];
function App() {
return (
<WitTable
columns={columns}
data={data}
onColumnResize={(col, width) => {
console.log(`Column ${col} resized to ${width}px`);
}}
/>
);
}

Listen to resize lifecycle events for custom behavior:

<WitTable
columns={columns}
data={data}
onColumnResizeStart={(col, startWidth) => {
console.log('Resize started:', col);
}}
onColumnResizeEnd={(col, newWidth) => {
// Persist new width to backend
saveColumnWidth(col, newWidth);
}}
onRowResizeStart={(row, startHeight) => {
console.log('Row resize started:', row);
}}
onRowResizeEnd={(row, newHeight) => {
saveRowHeight(row, newHeight);
}}
/>

Handles column width changes with constraints from ColumnDef:

  • minWidth — Minimum column width in pixels (default: 30)
  • maxWidth — Maximum column width in pixels (default: unlimited)
  • resizable — Whether the column can be resized (default: true)

Handles row height changes:

  • Minimum height: 12px
  • Maximum height: 400px

Both managers create undoable commands, so Ctrl+Z reverts a resize operation.