Excel-like grid component built with React, with editors, keyboard navigation, copy & paste, and the like
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
The ReactDataGrid component is the primary interface for creating Excel-like data grids with virtual rendering, editing capabilities, and comprehensive user interaction support.
Main grid component that renders tabular data with virtual scrolling, editing, sorting, and filtering capabilities.
/**
* Main data grid component with Excel-like functionality
* @param props - Configuration object for the grid
* @returns JSX.Element representing the data grid
*/
function ReactDataGrid(props: ReactDataGridProps): JSX.Element;
interface ReactDataGridProps {
// Required Configuration
/** Array of column definitions */
columns: Column[];
/** Function to retrieve row data by index */
rowGetter: (index: number) => any;
/** Total number of rows to display */
rowsCount: number;
/** Minimum height of the grid in pixels */
minHeight: number;
// Layout Configuration
/** Height of each data row in pixels (default: 35) */
rowHeight?: number;
/** Height of the header row in pixels */
headerRowHeight?: number;
/** Height of the filter row in pixels (default: 45) */
headerFiltersHeight?: number;
/** Minimum width of the grid in pixels */
minWidth?: number;
/** Minimum column width in pixels (default: 80) */
minColumnWidth?: number;
// Interaction Configuration
/** Enable cell selection functionality (default: false) */
enableCellSelect?: boolean;
/** Cell navigation behavior mode (default: 'none') */
cellNavigationMode?: 'none' | 'loopOverRow' | 'changeRow';
/** Enable drag and drop functionality */
enableDragAndDrop?: boolean;
/** Enable automatic cell focus (default: true) */
enableCellAutoFocus?: boolean;
// Row Configuration
/** Primary key property name for rows (default: 'id') */
rowKey?: string;
/** Row index to scroll to on render (default: 0) */
scrollToRowIndex?: number;
// Event Handlers - Data Updates
/** Called when grid data is updated via editing, copy/paste, or drag */
onGridRowsUpdated?: (event: GridRowsUpdatedEvent) => void;
/** Called before a cell becomes editable */
onCheckCellIsEditable?: (event: CheckCellEditableEvent) => boolean;
/** Called just before a cell editing begins */
onBeforeEdit?: (event: BeforeEditEvent) => void;
// Event Handlers - Selection
/** Called when a row is selected */
onRowSelect?: (rowIdx: number, row: any) => void;
/** Called when a cell is selected */
onCellSelected?: (position: Position) => void;
/** Called when a cell is deselected */
onCellDeSelected?: (position: Position) => void;
/** Called when a cell is expanded */
onCellExpand?: (args: CellExpandArgs) => void;
// Event Handlers - User Interaction
/** Called when a row is clicked */
onRowClick?: (rowIdx: number, row: any, column: Column) => void;
/** Called when a row is double-clicked */
onRowDoubleClick?: (rowIdx: number, row: any, column: Column) => void;
/** Called on keyboard key down events */
onGridKeyDown?: (event: GridKeyboardEvent) => void;
/** Called on keyboard key up events */
onGridKeyUp?: (event: GridKeyboardEvent) => void;
// Event Handlers - Sorting and Filtering
/** Called when grid is sorted */
onGridSort?: (sortColumn: string, sortDirection: SortDirection) => void;
/** Called when grid is filtered via FilterableHeaderCell */
onFilter?: (filter: Filter) => void;
/** Called when all filters are cleared */
onClearFilters?: () => void;
/** Called when a filter is added */
onAddFilter?: (filter: Filter) => void;
// Event Handlers - Layout
/** Called when a column is resized */
onColumnResize?: (idx: number, width: number) => void;
/** Called when the grid is scrolled */
onScroll?: (scrollState: ScrollState) => void;
// Sorting Configuration
/** Key of the currently sorted column */
sortColumn?: string;
/** Direction of the current sort */
sortDirection?: SortDirection;
// Selection Configuration
/** Row selection configuration */
rowSelection?: RowSelection;
/** Cell range selection configuration */
cellRangeSelection?: CellRangeSelection;
// Custom Components
/** Toolbar component to display above the grid */
toolbar?: React.ReactElement;
/** Context menu component */
contextMenu?: React.ReactElement;
/** Custom draggable header cell component */
draggableHeaderCell?: React.ComponentType<any>;
/** Custom row group renderer */
rowGroupRenderer?: React.ComponentType<any>;
/** Custom row actions cell renderer */
rowActionsCell?: React.ComponentType<any>;
/** Custom select all renderer */
selectAllRenderer?: React.ComponentType<any>;
// Advanced Configuration
/** Function to get cell actions for rendering action buttons */
getCellActions?: (column: Column, row: any) => CellAction[];
/** Function to get valid filter values */
getValidFilterValues?: (column: Column) => any[];
/** DOM element where editor portals should mount (default: document.body) */
editorPortalTarget?: Element;
/** Called when row expand/collapse is toggled */
onRowExpandToggle?: (args: RowExpandToggleArgs) => void;
/** Called when a sub-row is deleted */
onDeleteSubRow?: (args: DeleteSubRowArgs) => void;
/** Called when a sub-row is added */
onAddSubRow?: (args: AddSubRowArgs) => void;
}Configuration object that defines how each column behaves and appears in the grid.
interface Column {
/** Unique identifier for the column */
key: string;
/** Display name shown in the header */
name: string;
// Layout Properties
/** Column width in pixels */
width?: number;
/** Whether the column can be resized */
resizable?: boolean;
/** Whether the column is frozen (non-scrollable) */
frozen?: boolean;
// Interaction Properties
/** Whether the column can be sorted */
sortable?: boolean;
/** Sort descending first instead of ascending */
sortDescendingFirst?: boolean;
/** Whether the column can be filtered */
filterable?: boolean;
/** Whether the column can be dragged to reorder */
draggable?: boolean;
// Editing Properties
/** Whether cells in this column are editable */
editable?: boolean;
/** Custom editor component for this column */
editor?: React.ComponentType<EditorProps>;
// Display Properties
/** Custom formatter component for cell display */
formatter?: React.ComponentType<FormatterProps>;
/** Custom header renderer component */
headerRenderer?: React.ComponentType<HeaderRendererProps>;
/** Custom filter renderer component */
filterRenderer?: React.ComponentType<FilterRendererProps>;
// Event Configuration
/** Event handlers specific to this column */
events?: {
[eventName: string]: (event: any, args: any) => void;
};
}Type definitions for grid events and callbacks.
interface GridRowsUpdatedEvent {
fromRow: number;
toRow: number;
updated: { [key: string]: any };
action: 'CELL_UPDATE' | 'COLUMN_FILL' | 'COPY_PASTE' | 'CELL_DRAG';
}
interface Position {
idx: number;
rowIdx: number;
}
interface CheckCellEditableEvent {
row: any;
column: Column;
rowIdx: number;
}
interface BeforeEditEvent {
rowIdx: number;
column: Column;
row: any;
}
interface CellExpandArgs {
rowIdx: number;
idx: number;
rowData: any;
expandArgs: any;
}
interface GridKeyboardEvent {
rowIdx: number;
idx: number;
key: string;
}
type SortDirection = 'ASC' | 'DESC' | 'NONE';
interface Filter {
columnKey: string;
filterTerm: string;
}
interface ScrollState {
scrollTop: number;
scrollLeft: number;
}Usage Examples:
import ReactDataGrid from 'react-data-grid';
// Basic configuration with required props
const BasicGrid = () => {
const columns = [
{ key: 'id', name: 'ID', width: 80 },
{ key: 'name', name: 'Name', width: 200 },
{ key: 'email', name: 'Email', width: 250 }
];
const rows = [
{ id: 1, name: 'John Doe', email: 'john@example.com' },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com' }
];
return (
<ReactDataGrid
columns={columns}
rowGetter={i => rows[i]}
rowsCount={rows.length}
minHeight={400}
/>
);
};
// Grid with editing and event handling
const EditableGrid = () => {
const [rows, setRows] = useState(initialRows);
const handleGridRowsUpdated = ({ fromRow, toRow, updated }) => {
const newRows = rows.slice();
for (let i = fromRow; i <= toRow; i++) {
newRows[i] = { ...newRows[i], ...updated };
}
setRows(newRows);
};
const editableColumns = [
{ key: 'id', name: 'ID' },
{ key: 'name', name: 'Name', editable: true },
{ key: 'active', name: 'Active', editable: true }
];
return (
<ReactDataGrid
columns={editableColumns}
rowGetter={i => rows[i]}
rowsCount={rows.length}
minHeight={500}
enableCellSelect={true}
onGridRowsUpdated={handleGridRowsUpdated}
onRowClick={(rowIdx, row) => console.log('Row clicked:', row)}
/>
);
};
// Grid with sorting and filtering
const AdvancedGrid = () => {
const [sortColumn, setSortColumn] = useState('');
const [sortDirection, setSortDirection] = useState('NONE');
const handleGridSort = (columnKey, direction) => {
setSortColumn(columnKey);
setSortDirection(direction);
// Implement sorting logic
};
const sortableColumns = [
{ key: 'id', name: 'ID', sortable: true },
{ key: 'name', name: 'Name', sortable: true, filterable: true },
{ key: 'date', name: 'Date', sortable: true }
];
return (
<ReactDataGrid
columns={sortableColumns}
rowGetter={i => sortedRows[i]}
rowsCount={sortedRows.length}
minHeight={600}
sortColumn={sortColumn}
sortDirection={sortDirection}
onGridSort={handleGridSort}
onFilter={handleFilter}
/>
);
};Install with Tessl CLI
npx tessl i tessl/npm-react-data-grid@6.1.1