Inline Editing
Spreadsheet uses an InlineEditor — a textarea overlay positioned over the active cell. Double-click a cell or press F2 to open the editor. Press Enter to commit the value, Escape to cancel, and Tab to commit and move to the next cell. Scrolling while editing auto-commits and closes the editor.
View source code
import { useState } from 'react';import { Spreadsheet } from '@witqq/spreadsheet-react';import type { CellChangeEvent } from '@witqq/spreadsheet';import { DemoWrapper } from './DemoWrapper';import { generateEmployees, employeeColumns } from './generate-data';import { useSiteTheme } from './useSiteTheme';
const data = generateEmployees(30);const editableColumns = employeeColumns.map((col) => ({ ...col, editable: true }));
export function EditingDemo() { const { witTheme } = useSiteTheme(); const [lastEdit, setLastEdit] = useState('Double-click or press F2 to edit a cell');
const handleCellChange = (event: CellChangeEvent) => { setLastEdit( `Edited row ${event.row}, col ${event.col}: "${event.oldValue}" → "${event.value}"`, ); };
return ( <DemoWrapper title="Live Demo" description="Double-click or press F2 to edit. Enter to commit, Escape to cancel." height={440} > <div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}> <div style={{ padding: '0.5rem 0.75rem', fontSize: '0.8rem', color: '#64748b', borderBottom: '1px solid #e2e8f0', flexShrink: 0, }} > {lastEdit} </div> <div style={{ flex: 1 }}> <Spreadsheet theme={witTheme} columns={editableColumns} data={data} showRowNumbers editable onCellChange={handleCellChange} style={{ width: '100%', height: '100%' }} /> </div> </div> </DemoWrapper> );}Editable Table
Section titled “Editable Table”Enable editing on the entire table and listen for changes:
import { Spreadsheet } from '@witqq/spreadsheet-react';
function App() { const [data, setData] = useState(initialData);
return ( <Spreadsheet columns={columns} data={data} editable={true} onCellChange={(event) => { console.log(`Cell [${event.row},${event.col}]: ${event.oldValue} → ${event.newValue}`); // Update your data source }} /> );}Per-Column Editability
Section titled “Per-Column Editability”Control which columns are editable through ColumnDef.editable:
const columns: ColumnDef[] = [ { key: 'id', title: 'ID', editable: false }, { key: 'name', title: 'Name', editable: true }, { key: 'email', title: 'Email', editable: true }, { key: 'role', title: 'Role', editable: false },];Editor Close Reasons
Section titled “Editor Close Reasons”When the editor closes, the reason is provided as EditorCloseReason:
type EditorCloseReason = 'enter' | 'shift-enter' | 'tab' | 'shift-tab' | 'escape' | 'blur' | 'scroll' | 'programmatic';enter— User pressed Enter (commits value, moves down)shift-enter— User pressed Shift+Enter (commits value, moves up)tab— User pressed Tab (commits value, moves to next cell)shift-tab— User pressed Shift+Tab (commits value, moves to previous cell)escape— User pressed Escape (cancels edit, restores original)blur— Editor lost focus (commits value)scroll— User scrolled while editing (auto-commits value)programmatic— Closed by code via API call
API Reference
Section titled “API Reference”InlineEditor
Section titled “InlineEditor”| Method | Signature | Description |
|---|---|---|
open | (row: number, col: number, initialText?: string) => void | Open editor on cell |
commitAndClose | (reason: EditorCloseReason) => void | Commit current value and close |
cancelAndClose | () => void | Discard changes and close |
isEditing | boolean (getter) | Whether editor is currently open |
See Also
Section titled “See Also”- Date & DateTime Editors — calendar overlay for date and datetime cells
- Cell Editor Registry — register custom editors and control editor selection