https://github.com/adazzle/react-data-grid
Feature-rich and customizable data grid React component
https://github.com/adazzle/react-data-grid
react react-data-grid
Last synced: 12 days ago
JSON representation
Feature-rich and customizable data grid React component
- Host: GitHub
- URL: https://github.com/adazzle/react-data-grid
- Owner: adazzle
- License: other
- Created: 2015-03-06T10:15:04.000Z (about 10 years ago)
- Default Branch: main
- Last Pushed: 2025-05-04T02:35:01.000Z (21 days ago)
- Last Synced: 2025-05-05T17:21:18.644Z (20 days ago)
- Topics: react, react-data-grid
- Language: TypeScript
- Homepage: https://adazzle.github.io/react-data-grid/
- Size: 252 MB
- Stars: 7,221
- Watchers: 135
- Forks: 2,203
- Open Issues: 69
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Codeowners: .github/CODEOWNERS
Awesome Lists containing this project
- awesome-react-cn - react-data-grid - Excel-like grid component built with React (Uncategorized / Uncategorized)
- awesome - adazzle/react-data-grid - Feature-rich and customizable data grid React component (TypeScript)
- awesome-react-components-all - react-data-grid - Excel-like grid component built with React, with editors, keyboard navigation, copy & paste, and the like. (Uncategorized / Uncategorized)
- best-of-react - GitHub - 11% open · ⏱️ 03.06.2024): (Data Tables & Grids)
- best-of-react - GitHub - 11% open · ⏱️ 03.06.2024): (Data Tables & Grids)
- awesome-react-components - react-data-grid - Excel-like grid. (UI Components / Editable data grid / spreadsheet)
- awesome-web - react-data-grid - handsontable](https://github.com/handsontable/react-handsontable)| ([React](https://github.com/facebook/react/))
- awesome-react - react-data-grid - Excel-like grid component built with React (Uncategorized / Uncategorized)
- awesome-react - react-data-grid - Excel-like grid.  (UI Components / Editable data grid / spreadsheet)
- awesome-faker - react-data-grid - Feature-rich and customizable data grid React component. (Projects using `@faker-js/faker`)
- awesome-web-editor - react-data-grid - Excel-like grid component built with React, with editors, keyboard navigation, copy & paste, and the like. (Table editor)
- awesome-learning-resources - react-data-grid - Excel-like grid component built with React (Uncategorized / Uncategorized)
- awesome-list - react-data-grid - Excel-like grid component built with React, with editors, keyboard navigation, copy & paste, and the like. (Demos / Openshift)
- awesome-react-components - react-data-grid - Excel-like grid. (UI Components / Table / Data Grid)
- awesome-react-components - react-data-grid - Excel-like grid. (UI Components / Editable data grid / spreadsheet)
- awesome-react-components - react-data-grid - Excel-like grid. (UI Components / Editable data grid / spreadsheet)
- fucking-awesome-react-components - react-data-grid - Excel-like grid. (UI Components / Editable data grid / spreadsheet)
- awesome-react - react-data-grid - Excel-like grid component built with React, with editors, keyboard navigation, copy & paste, and the like ` 📝 8 days ago` (React [🔝](#readme))
- awesome-react - react-data-grid - Feature-rich and customizable data grid React component (**Awesome React** [](https://github.com/sindresorhus/awesome) / React)
- awesome - react-data-grid - Excel-like grid component built with React, with editors, keyboard navigation, copy & paste, and the like http://adazzle.github.io/react-data-grid/ (TypeScript)
- best-of-react - GitHub - 11% open · ⏱️ 03.06.2024): (Data Tables & Grids)
- awesome-react-components - react-data-grid - Excel-like grid. (UI Components / Editable data grid / spreadsheet)
- awesome-react-components - react-data-grid - Excel-like grid. (UI Components / Editable data grid / spreadsheet)
README
# react-data-grid
[![npm-badge]][npm-url]
[![type-badge]][npm-url]
[![size-badge]][size-url]
[![codecov-badge]][codecov-url]
[![ci-badge]][ci-url][npm-badge]: https://img.shields.io/npm/v/react-data-grid
[npm-url]: https://www.npmjs.com/package/react-data-grid
[size-badge]: https://img.shields.io/bundlephobia/minzip/react-data-grid
[size-url]: https://bundlephobia.com/package/react-data-grid
[type-badge]: https://img.shields.io/npm/types/react-data-grid
[codecov-badge]: https://codecov.io/gh/adazzle/react-data-grid/branch/main/graph/badge.svg?token=cvrRSWiz0Q
[codecov-url]: https://app.codecov.io/gh/adazzle/react-data-grid
[ci-badge]: https://github.com/adazzle/react-data-grid/workflows/CI/badge.svg
[ci-url]: https://github.com/adazzle/react-data-grid/actionsThe DataGrid component is designed to handle large datasets efficiently while offering a rich set of features for customization and interactivity.
## Features
- [React 19.0+](package.json) support
- [Evergreen browsers and server-side rendering](browserslist) support
- Tree-shaking support and only [one npm dependency](package.json) to keep your bundles slim
- Great performance thanks to virtualization: columns and rows outside the viewport are not rendered
- Strictly typed with TypeScript
- [Keyboard accessibility](https://adazzle.github.io/react-data-grid/#/CommonFeatures)
- Light and dark mode support out of the box. The light or dark themes can be enforced using the `rdg-light` or `rdg-dark` classes.
- [Frozen columns](https://adazzle.github.io/react-data-grid/#/CommonFeatures): Freeze columns to keep them visible during horizontal scrolling.
- [Column resizing](https://adazzle.github.io/react-data-grid/#/CommonFeatures)
- [Multi-column sorting](https://adazzle.github.io/react-data-grid/#/CommonFeatures)
- Click on a sortable column header to toggle between its ascending/descending sort order
- Ctrl+Click / Meta+Click to sort an additional column
- [Column spanning](https://adazzle.github.io/react-data-grid/#/ColumnSpanning)
- [Column grouping](https://adazzle.github.io/react-data-grid/#/ColumnGrouping)
- [Row selection](https://adazzle.github.io/react-data-grid/#/CommonFeatures)
- [Row grouping](https://adazzle.github.io/react-data-grid/#/RowGrouping)
- [Summary rows](https://adazzle.github.io/react-data-grid/#/CommonFeatures)
- [Dynamic row heights](https://adazzle.github.io/react-data-grid/#/VariableRowHeight)
- [No rows fallback](https://adazzle.github.io/react-data-grid/#/NoRows)
- [Cell formatting](https://adazzle.github.io/react-data-grid/#/CommonFeatures)
- [Cell editing](https://adazzle.github.io/react-data-grid/#/CommonFeatures)
- [Cell copy / pasting](https://adazzle.github.io/react-data-grid/#/AllFeatures)
- [Cell value dragging / filling](https://adazzle.github.io/react-data-grid/#/AllFeatures)
- [Customizable Renderers](https://adazzle.github.io/react-data-grid/#/CustomizableRenderers)
- Right-to-left (RTL) support.## Links
- [Examples website](https://adazzle.github.io/react-data-grid/)
- [Source code](website)
- [Changelog](CHANGELOG.md)
- [Contributing](CONTRIBUTING.md)## Installation
Install `react-data-grid` using your favorite package manager:
```sh
npm i react-data-grid
``````sh
pnpm add react-data-grid
``````sh
yarn add react-data-grid
``````sh
bun add react-data-grid
```Additionally, import the default styles in your application:
```tsx
import 'react-data-grid/lib/styles.css';
````react-data-grid` is published as ECMAScript modules for evergreen browsers, bundlers, and server-side rendering.
## Getting started
Here is a basic example of how to use `react-data-grid` in your React application:
```tsx
import 'react-data-grid/lib/styles.css';import { DataGrid, type Column } from 'react-data-grid';
interface Row {
id: number;
title: string;
}const columns: Column[] = [
{ key: 'id', name: 'ID' },
{ key: 'title', name: 'Title' }
];const rows: Row[] = [
{ id: 0, title: 'Example' },
{ id: 1, title: 'Demo' }
];function App() {
return ;
}
```## API Reference
### Components
#### ``
##### DataGridProps
###### `columns: readonly Column[]`
See [`Column`](#column).
An array of column definitions. Each column should have a key and name.
:warning: Passing a new `columns` array will trigger a re-render for the whole grid, avoid changing it as much as possible for optimal performance.
###### `rows: readonly R[]`
An array of rows, the rows data can be of any type.
###### `topSummaryRows?: Maybe`
Rows pinned at the top of the grid for summary purposes.
###### `bottomSummaryRows?: Maybe`
Rows pinned at the bottom of the grid for summary purposes.
###### `rowKeyGetter?: Maybe<(row: R) => K>`
Function to return a unique key/identifier for each row. `rowKeyGetter` is required for row selection to work.
```tsx
import { DataGrid } from 'react-data-grid';interface Row {
id: number;
name: string;
}function rowKeyGetter(row: Row) {
return row.id;
}function MyGrid() {
return ;
}
```:bulb: While optional, setting this prop is recommended for optimal performance as the returned value is used to set the `key` prop on the row elements.
###### `onRowsChange?: Maybe<(rows: R[], data: RowsChangeData) => void>`
Callback triggered when rows are changed.
The first parameter is a new rows array with both the updated rows and the other untouched rows.
The second parameter is an object with an `indexes` array highlighting which rows have changed by their index, and the `column` where the change happened.```tsx
import { useState } from 'react';
import { DataGrid } from 'react-data-grid';function MyGrid() {
const [rows, setRows] = useState(initialRows);return ;
}
```###### `rowHeight?: Maybe number)>`
**Default:** `35` pixels
Height of each row in pixels. A function can be used to set different row heights.
###### `headerRowHeight?: Maybe`
**Default:** `35` pixels
Height of the header row in pixels.
###### `summaryRowHeight?: Maybe`
**Default:** `35` pixels
Height of each summary row in pixels.
###### `columnWidths?: Maybe`
A map of column widths containing both measured and resized widths. If not provided then an internal state is used.
```tsx
const [columnWidths, setColumnWidths] = useState((): ColumnWidths => new Map());function addNewRow() {
setRows(...);
// reset column widths after adding a new row
setColumnWidths(new Map());
}return
```###### `onColumnWidthsChange?: Maybe<(columnWidths: ColumnWidths) => void>`
Callback triggered when column widths change. If not provided then an internal state is used.
###### `selectedRows?: Maybe>`
A set of selected row keys. `rowKeyGetter` is required for row selection to work.
###### `isRowSelectionDisabled?: Maybe<(row: NoInfer) => boolean>`
Function to determine if row selection is disabled for a specific row.
###### `onSelectedRowsChange?: Maybe<(selectedRows: Set) => void>`
Callback triggered when the selection changes.
```tsx
import { useState } from 'react';
import { DataGrid, SelectColumn } from 'react-data-grid';const rows: readonly Rows[] = [...];
const columns: readonly Column[] = [
SelectColumn,
// other columns
];function MyGrid() {
const [selectedRows, setSelectedRows] = useState((): ReadonlySet => new Set());return (
);
}function rowKeyGetter(row: Row) {
return row.id;
}function isRowSelectionDisabled(row: Row) {
return !row.isActive;
}
```###### `sortColumns?: Maybe`
An array of sorted columns.
###### `onSortColumnsChange?: Maybe<(sortColumns: SortColumn[]) => void>`
Callback triggered when sorting changes.
```tsx
import { useState } from 'react';
import { DataGrid, SelectColumn } from 'react-data-grid';const rows: readonly Rows[] = [...];
const columns: readonly Column[] = [
{
key: 'name',
name: 'Name',
sortable: true
},
// other columns
];function MyGrid() {
const [sortColumns, setSortColumns] = useState([]);return (
);
}
```More than one column can be sorted via `ctrl (command) + click`. To disable multiple column sorting, change the `onSortColumnsChange` function to
```tsx
function onSortColumnsChange(sortColumns: SortColumn[]) {
setSortColumns(sortColumns.slice(-1));
}
```###### `defaultColumnOptions?: Maybe>`
Default options applied to all columns.
```tsx
function MyGrid() {
return (
);
}
```###### `onFill?: Maybe<(event: FillEvent) => R>`
###### `onCellMouseDown: Maybe<(args: CellMouseArgs, event: CellMouseEvent) => void>`
Callback triggered when a pointer becomes active in a cell. The default behavior is to select the cell. Call `preventGridDefault` to prevent the default behavior.
```tsx
function onCellMouseDown(args: CellMouseDownArgs, event: CellMouseEvent) {
if (args.column.key === 'id') {
event.preventGridDefault();
}
};
```See [`CellMouseArgs`](#cellmouseargs) and [`CellMouseEvent`](#cellmouseevent)
###### `onCellClick?: Maybe<(args: CellMouseArgs, event: CellMouseEvent) => void>`
Callback triggered when a cell is clicked.
```tsx
function onCellClick(args: CellMouseArgs, event: CellMouseEvent) {
if (args.column.key === 'id') {
event.preventGridDefault();
}
};
```This event can be used to open cell editor on single click
```tsx
function onCellClick(args: CellMouseArgs, event: CellMouseEvent) {
if (args.column.key === 'id') {
args.selectCell(true);
}
}
```See [`CellMouseArgs`](#cellmouseargs) and [`CellMouseEvent`](#cellmouseevent)
###### `onCellDoubleClick?: Maybe<(args: CellMouseArgs, event: CellMouseEvent) => void>`
Callback triggered when a cell is double-clicked. The default behavior is to open the editor if the cell is editable. Call `preventGridDefault` to prevent the default behavior.
```tsx
function onCellDoubleClick(args: CellMouseArgs, event: CellMouseEvent) {
if (args.column.key === 'id') {
event.preventGridDefault();
}
};
```See [`CellMouseArgs`](#cellmouseargs) and [`CellMouseEvent`](#cellmouseevent)
###### `onCellContextMenu?: Maybe<(args: CellMouseArgs, event: CellMouseEvent) => void>`
Callback triggered when a cell is right-clicked.
```tsx
function onCellContextMenu(args: CellMouseArgs, event: CellMouseEvent) {
if (args.column.key === 'id') {
event.preventDefault();
// open custom context menu
}
};
```See [`CellMouseArgs`](#cellmouseargs) and [`CellMouseEvent`](#cellmouseevent)
###### `onCellKeyDown?: Maybe<(args: CellKeyDownArgs, event: CellKeyboardEvent) => void>`
A function called when keydown event is triggered on a cell. This event can be used to customize cell navigation and editing behavior.
**Examples**
- Prevent editing on `Enter`
```tsx
function onCellKeyDown(args: CellKeyDownArgs, event: CellKeyboardEvent) {
if (args.mode === 'SELECT' && event.key === 'Enter') {
event.preventGridDefault();
}
}
```- Prevent navigation on `Tab`
```tsx
function onCellKeyDown(args: CellKeyDownArgs, event: CellKeyboardEvent) {
if (args.mode === 'SELECT' && event.key === 'Tab') {
event.preventGridDefault();
}
}
```Check [more examples](website/routes/CellNavigation.tsx)
###### `onCellCopy?: Maybe<(args: CellCopyArgs, NoInfer>, event: CellClipboardEvent) => void>`
Callback triggered when a cell's content is copied.
###### `onCellPaste?: Maybe<(args: CellPasteArgs, NoInfer>, event: CellClipboardEvent) => void>`
Callback triggered when content is pasted into a cell.
###### `onSelectedCellChange?: Maybe<(args: CellSelectArgs) => void>;`
Triggered when the selected cell is changed.
Arguments:
- `args.rowIdx`: `number` - row index
- `args.row`: `R` - row object of the currently selected cell
- `args.column`: `CalculatedColumn` - column object of the currently selected cell###### `onScroll?: Maybe<(event: React.UIEvent) => void>`
Callback triggered when the grid is scrolled.
###### `onColumnResize?: Maybe<(column: CalculatedColumn, width: number) => void>`
Callback triggered when column is resized.
###### `onColumnsReorder?: Maybe<(sourceColumnKey: string, targetColumnKey: string) => void>`
Callback triggered when columns are reordered.
###### `enableVirtualization?: Maybe`
**Default:** `true`
This prop can be used to disable virtualization.
###### `renderers?: Maybe>`
Custom renderers for cells, rows, and other components.
```tsx
interface Renderers {
renderCell?: Maybe<(key: Key, props: CellRendererProps) => ReactNode>;
renderCheckbox?: Maybe<(props: RenderCheckboxProps) => ReactNode>;
renderRow?: Maybe<(key: Key, props: RenderRowProps) => ReactNode>;
renderSortStatus?: Maybe<(props: RenderSortStatusProps) => ReactNode>;
noRowsFallback?: Maybe;
}
```For example, the default `` component can be wrapped via the `renderRow` prop to add contexts or tweak props
```tsx
import { DataGrid, RenderRowProps, Row } from 'react-data-grid';function myRowRenderer(key: React.Key, props: RenderRowProps) {
return (
);
}function MyGrid() {
return ;
}
```:warning: To prevent all rows from being unmounted on re-renders, make sure to pass a static or memoized render function to `renderRow`.
###### `rowClass?: Maybe<(row: R, rowIdx: number) => Maybe>`
Function to apply custom class names to rows.
```tsx
import { DataGrid } from 'react-data-grid';function MyGrid() {
return ;
}function rowClass(row: Row, rowIdx: number) {
return rowIdx % 2 === 0 ? 'even' : 'odd';
}
```###### `headerRowClass?: Maybe>`
Custom class name for the header row.
###### `direction?: Maybe<'ltr' | 'rtl'>`
This property sets the text direction of the grid, it defaults to `'ltr'` (left-to-right). Setting `direction` to `'rtl'` has the following effects:
- Columns flow from right to left
- Frozen columns are pinned on the right
- Column resize cursor is shown on the left edge of the column
- Scrollbar is moved to the left###### `className?: string | undefined`
Custom class name for the grid.
###### `style?: CSSProperties | undefined`
Custom styles for the grid.
###### `'aria-label'?: string | undefined`
The label of the grid. We recommend providing a label using `aria-label` or `aria-labelledby`
###### `'aria-labelledby'?: string | undefined`
The id of the element containing a label for the grid. We recommend providing a label using `aria-label` or `aria-labelledby`
###### `'aria-description'?: string | undefined`
###### `'aria-describedby'?: string | undefined`
If the grid has a caption or description, `aria-describedby` can be set on the grid element with a value referring to the element containing the description.
###### `'data-testid'?: Maybe`
This prop can be used to add a testid for testing. We recommend querying the grid by by its `role` and `name`.
```tsx
function MyGrid() {
return ;
}test('grid', () => {
render();
const grid = screen.getByRole('grid', { name: 'my-grid' });
});
```#### ``
`TreeDataGrid` is component built on top of `DataGrid` to add row grouping. This implements the [Treegrid pattern](https://www.w3.org/WAI/ARIA/apg/patterns/treegrid/). At the moment `TreeDataGrid` does not support `onFill` and `isRowSelectionDisabled` props
##### TreeDataGridProps
###### `groupBy?: Maybe`
###### `rowGrouper?: Maybe<(rows: readonly R[], columnKey: string) => Record>`
###### `expandedGroupIds?: Maybe>`
###### `onExpandedGroupIdsChange?: Maybe<(expandedGroupIds: Set) => void>`
###### `groupIdGetter?: Maybe<(groupKey: string, parentId?: string) => string>`
#### ``
##### Props
See [`RenderEditCellProps`](#rendereditcellprops)
#### ``
See [`renderers`](#renderers-mayberenderersr-sr)
##### Props
See [`RenderRowProps`](#renderrowprops)
The `ref` prop is supported.
#### ``
##### Props
###### `onSort: (ctrlClick: boolean) => void`
###### `sortDirection: SortDirection | undefined`
###### `priority: number | undefined`
###### `tabIndex: number`
###### `children: React.ReactNode`
#### ``
##### Props
See [`FormatterProps`](#formatterprops)
#### ``
##### Props
###### `value: boolean`
###### `tabIndex: number`
###### `disabled?: boolean | undefined`
###### `onChange: (value: boolean, isShiftClick: boolean) => void`
###### `onClick?: MouseEventHandler | undefined`
###### `'aria-label'?: string | undefined`
###### `'aria-labelledby'?: string | undefined`
#### ``
##### Props
See [`RenderGroupCellProps`](#rendergroupcellprops)
### Hooks
#### `useHeaderRowSelection(): { isIndeterminate, isRowSelected, onRowSelectionChange }`
#### `useRowSelection(): { isRowSelectionDisabled, isRowSelected, onRowSelectionChange }`
### Other
#### `SelectColumn: Column`
#### `SELECT_COLUMN_KEY = 'rdg-select-column'`
### Types
#### `Column`
##### `name: string | ReactElement`
The name of the column. Displayed in the header cell by default.
##### `key: string`
A unique key to distinguish each column
##### `width?: Maybe`
**Default** `auto`
Width can be any valid css grid column value. If not specified, it will be determined automatically based on grid width and specified widths of other columns.
```tsx
width: 80, // pixels
width: '25%',
width: 'max-content',
width: 'minmax(100px, max-content)',
````max-content` can be used to expand the column to show all the content. Note that the grid is only able to calculate column width for visible rows.
##### `minWidth?: Maybe`
**Default**: `50` pixels
Minimum column width in pixels.
##### `maxWidth?: Maybe`
Maximum column width in pixels.
##### `cellClass?: Maybe Maybe)>`
Class name(s) for the cell
##### `headerCellClass?: Maybe`
Class name(s) for the header cell.
##### `summaryCellClass?: Maybe Maybe)>`
Class name(s) for the summary cell.
##### `renderCell?: Maybe<(props: RenderCellProps) => ReactNode>`
Render function to render the content of cells.
##### `renderHeaderCell?: Maybe<(props: RenderHeaderCellProps) => ReactNode>`
Render function to render the content of the header cell.
##### `renderSummaryCell?: Maybe<(props: RenderSummaryCellProps) => ReactNode>`
Render function to render the content of summary cells
##### `renderEditCell?: Maybe<(props: RenderEditCellProps) => ReactNode>`
Render function to render the content of edit cells. When set, the column is automatically set to be editable
##### `editable?: Maybe boolean)>`
Enables cell editing. If set and no editor property specified, then a text input will be used as the cell editor.
##### `colSpan?: Maybe<(args: ColSpanArgs) => Maybe>`
##### `frozen?: Maybe`
**Default**: `false`
Determines whether column is frozen. Frozen columns are pinned on the left. At the moment we do not support pinning columns on the right.
##### `resizable?: Maybe`
**Default**: `false`
Enable resizing of the column
##### `sortable?: Maybe`
**Default**: `false`
Enable sorting of the column
##### `draggable?: Maybe`
**Default**: `false`
Enable dragging of the column
##### `sortDescendingFirst?: Maybe`
**Default**: `false`
Sets the column sort order to be descending instead of ascending the first time the column is sorted
##### `editorOptions`
Options for cell editing.
###### `displayCellContent?: Maybe`
**Default**: `false`
Render the cell content in addition to the edit cell. Enable this option when the editor is rendered outside the grid, like a modal for example.
###### `commitOnOutsideClick?: Maybe`
**Default**: `true`
Commit changes when clicking outside the cell.
###### `closeOnExternalRowChange?: Maybe`
**Default**: `true`
Close the editor when the row changes externally.
#### `CellMouseArgs`
##### `rowIdx: number`
Row index of the currently selected cell
##### `row: TRow`
row object of the currently selected cell
##### `column: CalculatedColumn`
column object of the currently selected cell
##### `selectCell: (enableEditor?: boolean) => void`
function to manually select the cell and optionally pass `true` to start editing
#### `CellMouseEvent`
Extends `React.MouseEvent`
##### `event.preventGridDefault: () => void`
##### `event.isGridDefaultPrevented: boolean`
#### `DataGridHandle`
#### `RenderEditCellProps`
#### `RenderCellProps`
#### `RenderGroupCellProps`
#### `RenderRowProps`
### Generics
- `R`, `TRow`: Row type
- `SR`, `TSummaryRow`: Summary row type
- `K`: Row key type