Skip to content

Selection & Navigation

WitTable provides full spreadsheet-style selection with mouse and keyboard. Click a cell to select it, Shift+click to extend a range, and Ctrl+click to add a disjoint range. Row and column selection is supported by clicking row numbers or column headers. Select all cells with Ctrl+A or by clicking the corner cell.

Live Demo
Click cells, use Shift+Click for ranges, Ctrl+Click for multi-select.
Click a cell to see selection info
View source code
SelectionDemo.tsx
import { useState, useRef } from 'react';
import { WitTable } from '@witqq/spreadsheet-react';
import type { WitTableRef } from '@witqq/spreadsheet-react';
import type { SelectionChangeEvent } from '@witqq/spreadsheet';
import { DemoWrapper } from './DemoWrapper';
import { generateEmployees, employeeColumns } from './generate-data';
import { useSiteTheme } from './useSiteTheme';
const data = generateEmployees(50);
export function SelectionDemo() {
const { witTheme } = useSiteTheme();
const [selection, setSelection] = useState('Click a cell to see selection info');
const tableRef = useRef<WitTableRef>(null);
const handleSelectionChange = (event: SelectionChangeEvent) => {
const { row, col } = event.selection.activeCell;
setSelection(`Active cell: row ${row}, col ${col}`);
};
return (
<DemoWrapper title="Live Demo" description="Click cells, use Shift+Click for ranges, Ctrl+Click for multi-select." 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 }}>
{selection}
</div>
<div style={{ flex: 1 }}>
<WitTable
theme={witTheme}
ref={tableRef}
columns={employeeColumns}
data={data}
showRowNumbers
editable={false}
onSelectionChange={handleSelectionChange}
style={{ width: '100%', height: '100%' }}
/>
</div>
</div>
</DemoWrapper>
);
}

KeyboardNavigator handles all keyboard shortcuts:

ShortcutAction
Arrow keysMove active cell
Shift+ArrowExtend selection
TabMove to next cell
EnterMove down
Home / EndFirst / last column
Ctrl+Home / Ctrl+EndFirst / last cell in grid
PageUp / PageDownScroll by viewport height
Live Demo
Click a cell, then use Arrow keys, Tab, Enter, Home/End, Ctrl+Home/End, Page Up/Down.
View source code
KeyboardNavDemo.tsx
import { WitTable } from '@witqq/spreadsheet-react';
import { DemoWrapper } from './DemoWrapper';
import { generateEmployees, employeeColumns } from './generate-data';
import { useSiteTheme } from './useSiteTheme';
const data = generateEmployees(50);
export function KeyboardNavDemo() {
const { witTheme } = useSiteTheme();
return (
<DemoWrapper title="Live Demo" description="Click a cell, then use Arrow keys, Tab, Enter, Home/End, Ctrl+Home/End, Page Up/Down.">
<WitTable
theme={witTheme}
columns={employeeColumns}
data={data}
showRowNumbers
editable={false}
style={{ width: '100%', height: '100%' }}
/>
</DemoWrapper>
);
}
import { WitTable } from '@witqq/spreadsheet-react';
function App() {
return (
<WitTable
columns={columns}
data={data}
onSelectionChange={(selection) => {
console.log('Active cell:', selection.activeCell);
console.log('Ranges:', selection.ranges);
}}
/>
);
}

Access SelectionManager through the table ref to control selection from code:

import { useRef } from 'react';
import { WitTable, WitTableRef } from '@witqq/spreadsheet-react';
function App() {
const ref = useRef<WitTableRef>(null);
const handleSelectCell = () => {
ref.current?.selectCell(0, 0);
};
const handleGetSelection = () => {
const sel = ref.current?.getSelection();
console.log(sel);
};
return (
<>
<button onClick={handleSelectCell}>Select A1</button>
<button onClick={handleGetSelection}>Get Selection</button>
<WitTable ref={ref} columns={columns} data={data} />
</>
);
}
MethodSignatureDescription
selectCell(row: number, col: number) => voidSet active cell
selectRow(row: number) => voidSelect entire row
selectColumn(col: number) => voidSelect entire column
selectAll() => voidSelect all cells
getSelection() => SelectionGet current selection state
isSelected(row: number, col: number) => booleanCheck if cell is in selection