MCPcopy
hub / github.com/Comcast/react-data-grid

github.com/Comcast/react-data-grid @v7.0.0-beta.59 sqlite

repository ↗ · DeepWiki ↗ · release v7.0.0-beta.59 ↗
519 symbols 1,122 edges 120 files 2 documented · 0%
README

react-data-grid

npm-badge type-badge size-badge codecov-badge ci-badge

The DataGrid component is designed to handle large datasets efficiently while offering a rich set of features for customization and interactivity.

Features

Links

Important

rolldown-vite by default uses lightningcss to minify css which has a bug minifying light-dark syntax. You can switch to esbuild as a workaround

build: {
  ....,
  cssMinify: 'esbuild'
}

Installation

Install react-data-grid using your favorite package manager:

npm i react-data-grid
pnpm add react-data-grid
yarn add react-data-grid
bun add react-data-grid

Additionally, import the default styles in your application:

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:

import 'react-data-grid/lib/styles.css';

import { DataGrid, type Column } from 'react-data-grid';

interface Row {
  id: number;
  title: string;
}

const columns: readonly Column<Row>[] = [
  { key: 'id', name: 'ID' },
  { key: 'title', name: 'Title' }
];

const rows: readonly Row[] = [
  { id: 0, title: 'Example' },
  { id: 1, title: 'Demo' }
];

function App() {
  return <DataGrid columns={columns} rows={rows} />;
}

Theming

Set --rdg-color-scheme: light/dark at the :root to control the color theme. The light or dark themes can be enforced using the rdg-light or rdg-dark classes.

API Reference

Components

<DataGrid />

DataGridProps
columns: readonly Column<R, SR>[]

An array of column definitions. Each column should have a key and name. See the Column type for all available options.

:warning: Performance: Passing a new columns array will trigger a re-render and recalculation for the entire grid. Always memoize this prop using useMemo or define it outside the component to avoid unnecessary re-renders.

rows: readonly R[]

An array of rows, the rows data can be of any type.

:bulb: Performance: The grid is optimized for efficient rendering:

  • Virtualization: Only visible rows are rendered in the DOM
  • Individual row updates: Row components are memoized, so updating a single row object will only re-render that specific row, not all rows
  • Array reference matters: Changing the array reference itself (e.g., setRows([...rows])) triggers viewport and layout recalculations, even if the row objects are unchanged
  • Best practice: When updating rows, create a new array but reuse unchanged row objects. For example:

```tsx // ✅ Good: Only changed row is re-rendered setRows(rows.map((row, idx) => (idx === targetIdx ? { ...row, updated: true } : row)));

// ❌ Avoid: Creates new references for all rows, causing all visible rows to re-render setRows(rows.map((row) => ({ ...row }))); ```

topSummaryRows?: Maybe<readonly SR[]>

Rows pinned at the top of the grid for summary purposes.

bottomSummaryRows?: Maybe<readonly SR[]>

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.

import { DataGrid } from 'react-data-grid';

interface Row {
  id: number;
  name: string;
}

function rowKeyGetter(row: Row) {
  return row.id;
}

function MyGrid() {
  return <DataGrid columns={columns} rows={rows} rowKeyGetter={rowKeyGetter} />;
}

: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.

:warning: Performance: Define this function outside your component or memoize it with useCallback to prevent unnecessary re-renders.

onRowsChange?: Maybe<(rows: R[], data: RowsChangeData<R, SR>) => 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.

import { useState } from 'react';
import { DataGrid } from 'react-data-grid';

function MyGrid() {
  const [rows, setRows] = useState(initialRows);

  return <DataGrid columns={columns} rows={rows} onRowsChange={setRows} />;
}
rowHeight?: Maybe<number | ((row: R) => number)>

Default: 35 pixels

Height of each row in pixels. A function can be used to set different row heights.

:warning: Performance: When using a function, the height of all rows is calculated upfront on every render. For large datasets (1000+ rows), this can cause performance issues. Consider using a fixed height when possible, or memoize the rowHeight function.

headerRowHeight?: Maybe<number>

Default: 35 pixels

Height of the header row in pixels.

summaryRowHeight?: Maybe<number>

Default: 35 pixels

Height of each summary row in pixels.

columnWidths?: Maybe<ColumnWidths>

A map of column widths containing both measured and resized widths. If not provided then an internal state is used.

const [columnWidths, setColumnWidths] = useState((): ColumnWidths => new Map());

function addNewRow() {
  setRows(...);
  // reset column widths after adding a new row
  setColumnWidths(new Map());
}

return <DataGrid columnWidths={columnWidths} onColumnWidthsChange={setColumnWidths} ... />
onColumnWidthsChange?: Maybe<(columnWidths: ColumnWidths) => void>

Callback triggered when column widths change. If not provided then an internal state is used.

selectedRows?: Maybe<ReadonlySet<K>>

A set of selected row keys. rowKeyGetter is required for row selection to work.

isRowSelectionDisabled?: Maybe<(row: NoInfer<R>) => boolean>

Function to determine if row selection is disabled for a specific row.

onSelectedRowsChange?: Maybe<(selectedRows: Set<K>) => void>

Callback triggered when the selection changes.

import { useState } from 'react';
import { DataGrid, SelectColumn } from 'react-data-grid';

const rows: readonly Rows[] = [...];

const columns: readonly Column<Row>[] = [
  SelectColumn,
  // other columns
];

function rowKeyGetter(row: Row) {
  return row.id;
}

function isRowSelectionDisabled(row: Row) {
  return !row.isActive;
}

function MyGrid() {
  const [selectedRows, setSelectedRows] = useState((): ReadonlySet<number> => new Set());

  return (
    <DataGrid
      rowKeyGetter={rowKeyGetter}
      columns={columns}
      rows={rows}
      selectedRows={selectedRows}
      isRowSelectionDisabled={isRowSelectionDisabled}
      onSelectedRowsChange={setSelectedRows}
    />
  );
}
sortColumns?: Maybe<readonly SortColumn[]>

An array of sorted columns.

onSortColumnsChange?: Maybe<(sortColumns: SortColumn[]) => void>

Callback triggered when sorting changes.

import { useState } from 'react';
import { DataGrid, SelectColumn } from 'react-data-grid';

const rows: readonly Rows[] = [...];

const columns: readonly Column<Row>[] = [
  {
    key: 'name',
    name: 'Name',
    sortable: true
  },
  // other columns
];

function MyGrid() {
  const [sortColumns, setSortColumns] = useState<readonly SortColumn[]>([]);

  return (
    <DataGrid
      columns={columns}
      rows={rows}
      sortColumns={sortColumns}
      onSortColumnsChange={setSortColumns}
    />
  );
}

More than one column can be sorted via ctrl (command) + click. To disable multiple column sorting, change the onSortColumnsChange function to

function onSortColumnsChange(sortColumns: SortColumn[]) {
  setSortColumns(sortColumns.slice(-1));
}
defaultColumnOptions?: Maybe<DefaultColumnOptions<R, SR>>

Default options applied to all columns.

function MyGrid() {
  return (
    <DataGrid
      columns={columns}
      rows={rows}
      defaultColumnOptions={{
        minWidth: 100,
        resizable: true,
        sortable: true,
        draggable: true
      }}
    />
  );
}
onFill?: Maybe<(event: FillEvent<R>) => R>
onCellMouseDown: Maybe<(args: CellMouseArgs<R, SR>, 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.

function onCellMouseDown(args: CellMouseDownArgs<R, SR>, event: CellMouseEvent) {
  if (args.column.key === 'id') {
    event.preventGridDefault();
  }
}

<DataGrid rows={rows} columns={columns} onCellMouseDown={onCellMouseDown} />;
onCellClick?: Maybe<(args: CellMouseArgs<R, SR>, event: CellMouseEvent) => void>

Callback triggered when a cell is clicked.

function onCellClick(args: CellMouseArgs<R, SR>, event: CellMouseEvent) {
  if (args.column.key === 'id') {
    event.preventGridDefault();
  }
}

<DataGrid rows={rows} columns={columns} onCellClick={onCellClick} />;

This event can be used to open cell editor on single click

function onCellClick(args: CellMouseArgs<R, SR>, event: CellMouseEvent) {
  if (args.column.key === 'id') {
    args.selectCell(true);
  }
}
onCellDoubleClick?: Maybe<(args: CellMouseArgs<R, SR>, 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.

function onCellDoubleClick(args: CellMouseArgs<R, SR>, event: CellMouseEvent) {
  if (args.column.key === 'id') {
    event.preventGridDefault();
  }
}

<DataGrid rows={rows} columns={columns} onCellDoubleClick={onCellDoubleClick} />;
onCellContextMenu?: Maybe<(args: CellMouseArgs<R, SR>, event: CellMouseEvent) => void>

Callback triggered when a cell is right-clicked.

function onCellContextMenu(args: CellMouseArgs<R, SR>, event: CellMouseEvent) {
  if (args.column.key === 'id') {
    event.preventDefault();
    // open custom context menu
  }
}

<DataGrid rows={rows} columns={columns} onCellContextMenu={onCellContextMenu} />;
onCellKeyDown?: Maybe<(args: CellKeyDownArgs<R, SR>, 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
function onCellKeyDown(args: CellKeyDownArgs<R, SR>, event: CellKeyboardEvent) {
  if (args.mode === 'SELECT' && event.key === 'Enter') {
    event.preventGridDefault();
  }
}
  • Prevent navigation on Tab
function onCellKeyDown(args: CellKeyDownArgs<R, SR>, event: CellKeyboardEvent) {
  if (args.mode === 'SELECT' && event.key === 'Tab') {
    event.preventGridDefault();
  }
}

Check more examples

`onCell

Extension points exported contracts — how you extend this code

BrowserCommands (Interface)
(no doc)
test/globals.d.ts
Row (Interface)
(no doc)
test/browser/TreeDataGrid.test.tsx
Row (Interface)
(no doc)
test/visual/basicGrid.test.tsx
Row (Interface)
(no doc)
test/node/ssr.test.tsx
GroupedColumnHeaderRowProps (Interface)
(no doc)
src/GroupedColumnHeaderRow.tsx
GroupCellProps (Interface)
(no doc)
src/GroupCell.tsx
SelectCellState (Interface)
(no doc)
src/DataGrid.tsx
Scheduler (Interface)
(no doc)
src/EditCell.tsx

Core symbols most depended-on inside this repo

validateCellPosition
called by 128
test/browser/utils.tsx
getCellsAtRowIndex
called by 81
test/browser/utils.tsx
setup
called by 43
test/browser/utils.tsx
getCell
called by 40
test/browser/utils.tsx
testRowCount
called by 33
test/browser/utils.tsx
getSelectedCell
called by 24
test/browser/utils.tsx
testCount
called by 24
test/browser/utils.tsx
getGrid
called by 23
test/browser/utils.tsx

Shape

Function 408
Interface 111

Languages

TypeScript100%

Modules by API surface

src/DataGrid.tsx41 symbols
src/types.ts32 symbols
test/browser/utils.tsx21 symbols
src/HeaderCell.tsx19 symbols
src/TreeDataGrid.tsx14 symbols
test/browser/renderers.test.tsx13 symbols
website/routes/CommonFeatures.tsx12 symbols
src/utils/selectedCellUtils.ts11 symbols
website/routes/MasterDetail.tsx10 symbols
website/routes/CustomizableRenderers.tsx10 symbols
website/routes/AllFeatures.tsx10 symbols
src/EditCell.tsx10 symbols

Dependencies from manifests, versioned

@biomejs/biome2.3.8 · 1×
@eslint-react/eslint-plugin2.3.12 · 1×
@eslint/markdown7.5.1 · 1×
@faker-js/faker10.0.0 · 1×
@tanstack/react-router1.132.31 · 1×
@tanstack/router-plugin1.132.31 · 1×
@types/node24.8.0 · 1×
@types/react19.2.0 · 1×
@types/react-dom19.2.0 · 1×
@typescript-eslint/eslint-plugin8.48.1 · 1×
@typescript-eslint/parser8.48.1 · 1×

For agents

$ claude mcp add react-data-grid \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact