Documentation Index Fetch the complete documentation index at: https://mintlify.com/Comcast/react-data-grid/llms.txt
Use this file to discover all available pages before exploring further.
React Data Grid provides comprehensive keyboard navigation support, allowing users to efficiently navigate cells, edit data, and perform actions without using a mouse.
Basic Navigation
Arrow Keys
Navigate between cells using arrow keys:
import { DataGrid , type Column } from 'react-data-grid' ;
const columns : Column < Row >[] = [
{ key: 'id' , name: 'ID' },
{ key: 'name' , name: 'Name' },
{ key: 'email' , name: 'Email' }
];
function MyGrid () {
return < DataGrid columns = { columns } rows = { rows } /> ;
}
Arrow Keys
Home/End
Page Up/Down
Tab
↑ Up : Move to cell above
↓ Down : Move to cell below
← Left : Move to cell on the left
→ Right : Move to cell on the right
Home : Jump to first cell in row
End : Jump to last cell in row
Ctrl+Home : Jump to first cell in grid
Ctrl+End : Jump to last cell in grid
Page Up : Scroll up one viewport
Page Down : Scroll down one viewport
Tab : Move to next cell (wraps to next row)
Shift+Tab : Move to previous cell (wraps to previous row)
The grid automatically scrolls to keep the selected cell visible during navigation.
Editing
Enter Edit Mode
Start editing cells using keyboard:
import { renderTextEditor } from 'react-data-grid' ;
const columns : Column < Row >[] = [
{
key: 'name' ,
name: 'Name' ,
renderEditCell: renderTextEditor
}
];
Enter Key
Typing
Double Click
Press Enter to start editing the selected cell. // Default behavior
// Enter key opens editor on editable cells
Start typing to immediately edit the cell. // Any printable character opens the editor
// and replaces the current value
Double-click a cell to start editing. // Default behavior for editable cells
While Editing
Commit Changes
Cancel Changes
Navigate
Enter : Save changes and close editor
Tab : Save changes and move to next cell
Click Outside : Save changes (default behavior)
Escape : Cancel changes and close editor
Restores original cell value
Arrow Keys : Move cursor within editor
Home/End : Jump to start/end of text
Row Selection
Select rows using keyboard:
import { useState } from 'react' ;
import { DataGrid , SelectColumn } from 'react-data-grid' ;
function MyGrid () {
const [ selectedRows , setSelectedRows ] = useState < ReadonlySet < number >>( new Set ());
const columns = [
SelectColumn ,
{ key: 'name' , name: 'Name' },
{ key: 'email' , name: 'Email' }
];
return (
< DataGrid
columns = { columns }
rows = { rows }
rowKeyGetter = { ( row ) => row . id }
selectedRows = { selectedRows }
onSelectedRowsChange = { setSelectedRows }
/>
);
}
Space Key
Range Selection
Shift+Space : Toggle row selectionFrom src/DataGrid.tsx: // Select the row on Shift + Space
if ( isSelectable && shiftKey && key === ' ' ) {
const rowKey = rowKeyGetter ( row );
selectRow ({ row , checked: ! selectedRows . has ( rowKey ), isShiftClick: false });
event . preventDefault (); // prevent scrolling
}
Shift+Click : Select range of rows
Click checkbox on first row
Hold Shift and click checkbox on last row
All rows between are selected
TreeGrid Navigation
TreeDataGrid provides additional keyboard navigation:
import { useState } from 'react' ;
import { TreeDataGrid , type Column } from 'react-data-grid' ;
function MyTreeGrid () {
const [ expandedGroupIds , setExpandedGroupIds ] = useState < ReadonlySet < unknown >>( new Set ());
return (
< TreeDataGrid
columns = { columns }
rows = { rows }
groupBy = { [ 'category' ] }
rowGrouper = { rowGrouper }
expandedGroupIds = { expandedGroupIds }
onExpandedGroupIdsChange = { setExpandedGroupIds }
/>
);
}
Expand/Collapse
Parent Navigation
When a group row is focused:
→ Right Arrow : Expand collapsed group
← Left Arrow : Collapse expanded group
From src/TreeDataGrid.tsx: if (
idx === - 1 &&
(( event . key === leftKey && row . isExpanded ) ||
( event . key === rightKey && ! row . isExpanded ))
) {
event . preventDefault ();
event . preventGridDefault ();
toggleGroup ( row . id );
}
← Left Arrow : When on collapsed group, navigate to parentif ( idx === - 1 && event . key === leftKey && ! row . isExpanded && row . level !== 0 ) {
const parentRowAndIndex = getParentRowAndIndex ( row );
if ( parentRowAndIndex !== undefined ) {
event . preventGridDefault ();
selectCell ({ idx , rowIdx: parentRowAndIndex [ 1 ] });
}
}
Custom Keyboard Behavior
Prevent Default Actions
Customize keyboard behavior using onCellKeyDown:
import type { CellKeyDownArgs , CellKeyboardEvent } from 'react-data-grid' ;
function handleCellKeyDown (
args : CellKeyDownArgs < Row >,
event : CellKeyboardEvent
) {
if ( args . mode === 'SELECT' && event . key === 'Enter' ) {
// Prevent entering edit mode on Enter
event . preventGridDefault ();
// Custom action instead
console . log ( 'Custom action for' , args . row );
}
}
< DataGrid
columns = { columns }
rows = { rows }
onCellKeyDown = { handleCellKeyDown }
/>
Customize Tab key behavior: function handleCellKeyDown (
args : CellKeyDownArgs < Row >,
event : CellKeyboardEvent
) {
if ( args . mode === 'SELECT' && event . key === 'Tab' ) {
// Prevent default tab navigation
event . preventGridDefault ();
// Custom logic: skip non-editable columns
const currentIdx = args . column . idx ;
const nextEditableIdx = columns . findIndex (
( col , idx ) => idx > currentIdx && col . renderEditCell
);
if ( nextEditableIdx !== - 1 ) {
args . selectCell ({
idx: nextEditableIdx ,
rowIdx: args . rowIdx
});
}
}
}
Custom Edit Triggers
Control when cells enter edit mode:
function handleCellClick (
args : CellMouseArgs < Row >,
event : CellMouseEvent
) {
// Enter edit mode on single click
if ( args . column . renderEditCell ) {
args . selectCell ( true ); // true = enable editor
}
}
< DataGrid
columns = { columns }
rows = { rows }
onCellClick = { handleCellClick }
/>
Only allow editing under certain conditions: function handleCellKeyDown (
args : CellKeyDownArgs < Row >,
event : CellKeyboardEvent
) {
if ( args . mode === 'SELECT' && event . key === 'Enter' ) {
// Only allow editing if user has permission
if ( ! userHasEditPermission ( args . row )) {
event . preventGridDefault ();
alert ( 'You do not have permission to edit this row' );
return ;
}
// Allow default behavior (enter edit mode)
}
}
Focus Management
The grid manages focus automatically:
// From src/DataGrid.tsx
useLayoutEffect (() => {
if ( shouldFocusCell ) {
if ( selectedPosition . idx === - 1 ) {
focusRow ( gridRef . current ! );
} else {
focusCell ( gridRef . current ! );
}
setShouldFocusCell ( false );
}
}, [ shouldFocusCell , selectedPosition . idx , gridRef ]);
Programmatic Focus
Control focus programmatically:
import { useRef } from 'react' ;
import type { DataGridHandle } from 'react-data-grid' ;
function MyComponent () {
const gridRef = useRef < DataGridHandle >( null );
function focusCell ( rowIdx : number , colIdx : number ) {
gridRef . current ?. selectCell ({ rowIdx , idx: colIdx }, { shouldFocusCell: true });
}
return (
<>
< button onClick = { () => focusCell ( 0 , 0 ) } > Focus first cell </ button >
< DataGrid
ref = { gridRef }
columns = { columns }
rows = { rows }
/>
</>
);
}
RTL Navigation
In RTL mode, horizontal navigation is reversed:
< DataGrid
columns = { columns }
rows = { rows }
direction = "rtl"
/>
From src/DataGrid.tsx: const { leftKey , rightKey } = getLeftRightKey ( direction );
// In RTL mode:
// - leftKey is 'ArrowRight'
// - rightKey is 'ArrowLeft'
Arrow key behavior automatically adjusts:
→ Right : Moves left in RTL
← Left : Moves right in RTL
Accessibility
ARIA Support
The grid implements proper ARIA attributes:
< div
role = "grid"
aria-label = "Data grid"
aria-colcount = { columns . length }
aria-rowcount = { rows . length + headerRowsCount }
aria-multiselectable = { isSelectable }
tabIndex = { - 1 } // Grid container is focusable
>
< div role = "row" aria-rowindex = { 1 } >
< div role = "columnheader" aria-colindex = { 1 } tabIndex = { - 1 } >
Column 1
</ div >
</ div >
< div role = "row" aria-rowindex = { 2 } aria-selected = { false } >
< div role = "gridcell" aria-colindex = { 1 } tabIndex = { 0 } >
Cell content
</ div >
</ div >
</ div >
Screen Reader Support
Grid role : Announces as data grid
Aria attributes : Provide context about position and selection
Focus management : Maintains logical focus order
Selection state : Announces selected rows
Provide proper labels for accessibility: < DataGrid
aria-label = "Employee directory"
aria-description = "Searchable list of all employees with contact information"
columns = { columns }
rows = { rows }
/>
// Or with aria-labelledby
<>
< h2 id = "grid-title" > Employee Directory </ h2 >
< DataGrid
aria-labelledby = "grid-title"
columns = { columns }
rows = { rows }
/>
</>
API Reference
DataGrid Props
onCellKeyDown
onCellKeyDown ?: ( args : CellKeyDownArgs < R , SR >, event : CellKeyboardEvent ) => void
Description : Callback triggered when a key is pressed in a cell.
Usage : Customize keyboard behavior or add custom shortcuts.
onSelectedCellChange
onSelectedCellChange ?: ( args : CellSelectArgs < R , SR >) => void
Description : Triggered when the selected cell changes.
CellKeyDownArgs
type CellKeyDownArgs < TRow , TSummaryRow = unknown > =
| SelectCellKeyDownArgs < TRow , TSummaryRow >
| EditCellKeyDownArgs < TRow , TSummaryRow >;
interface SelectCellKeyDownArgs < TRow , TSummaryRow > {
mode : 'SELECT' ;
column : CalculatedColumn < TRow , TSummaryRow > | undefined ;
row : TRow ;
rowIdx : number ;
selectCell : ( position : Position , options ?: SelectCellOptions ) => void ;
}
interface EditCellKeyDownArgs < TRow , TSummaryRow > {
mode : 'EDIT' ;
column : CalculatedColumn < TRow , TSummaryRow >;
row : TRow ;
rowIdx : number ;
navigate : () => void ;
onClose : ( commitChanges ?: boolean , shouldFocusCell ?: boolean ) => void ;
}
CellKeyboardEvent
type CellKeyboardEvent = CellEvent < React . KeyboardEvent < HTMLDivElement >>;
interface CellEvent < E > extends E {
preventGridDefault : () => void ;
isGridDefaultPrevented : () => boolean ;
}
Methods :
preventGridDefault(): Prevent the grid’s default keyboard behavior
isGridDefaultPrevented(): Check if default was prevented
DataGridHandle
interface DataGridHandle {
element : HTMLDivElement | null ;
scrollToCell : ( position : PartialPosition ) => void ;
selectCell : ( position : Position , options ?: SelectCellOptions ) => void ;
}