Step 9: Add Cell Editing
Enable editing on the table and configure individual columns:
// columns.ts — updated with editing
export const columns = [
columnHelper.accessor('name', {
header: 'Name',
enableSorting: true,
editable: true,
editConfig: {
type: 'text',
validate: (value) => {
if (!value || String(value).trim().length === 0) return 'Name is required'
return null
},
},
}),
columnHelper.accessor('department', {
header: 'Department',
enableSorting: true,
editable: true,
editConfig: {
type: 'select',
options: [
{ label: 'Engineering', value: 'Engineering' },
{ label: 'Marketing', value: 'Marketing' },
{ label: 'Sales', value: 'Sales' },
],
},
}),
columnHelper.accessor('salary', {
header: 'Salary',
enableSorting: true,
editable: true,
editConfig: {
type: 'number',
validate: (value) => {
if (Number(value) < 0) return 'Salary must be positive'
return null
},
},
cell: ({ getValue }) => `$${getValue().toLocaleString()}`,
}),
columnHelper.accessor('startDate', {
header: 'Start Date',
enableSorting: true,
sortingFn: 'datetime',
editable: true,
editConfig: { type: 'date' },
}),
columnHelper.accessor('active', {
header: 'Active',
editable: true,
editConfig: { type: 'toggle' },
}),
]
Then handle edit commits in your component:
export function EmployeeTable() {
const [data, setData] = useState(employees)
const table = useTable({
data,
columns,
enableCellEditing: true,
onEditCommit: (changes) => {
// changes is Record<string, Partial<Employee>>
// key is the row ID, value is the changed fields
setData((prev) =>
prev.map((row, i) => {
const rowChanges = changes[String(i)]
return rowChanges ? { ...row, ...rowChanges } : row
})
)
},
})
return (
<Table table={table} striped>
<Pagination table={table} />
</Table>
)
}
Double-click a cell to enter edit mode. Press Enter to commit, Escape to cancel.