AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
다양한 기능과 맞춤 설정이 가능한 데이터 그리드 React 컴포넌트
Feature-rich and customizable data grid React component
개발 도구TypeScript · CSSGitHub @Comcast직접 설치운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
설치형 프로젝트는 배포 도메인 없이도 확인할 수 있습니다. 개인 저장소는 GitHub 로그인으로, 조직 저장소는 위의 저장소 확인 파일로 직접 확인해 주세요.
메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗The DataGrid component is designed to handle large datasets efficiently while offering a rich set of features for customization and interactivity.
color-schemeInstall react-data-grid using your favorite package manager:
# npm
npm install react-data-grid
# Vite+
vp add react-data-grid
# pnpm
pnpm add react-data-grid
# Yarn
yarn add react-data-grid
# Bun
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.
Important
Vite 8+ uses Lightning CSS by default to minify CSS, and Lightning CSS has a bug minifying thelight-dark()syntax. You can tweak thecssMinifyorcssTargetsettings as a workaround.
build: {
cssMinify: 'esbuild', // requires the `esbuild` package to be installed
// or
cssTarget: 'esnext'
}
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} />;
}
The DataGrid provides multiple ways to customize its appearance and behavior.
The DataGrid supports both light and dark color schemes out of the box using the light-dark() CSS function. The theme automatically adapts based on the user's system preference when color-scheme: light dark; is set.
To enforce a specific theme, we recommend setting the standard color-scheme CSS property on the :root:
:root {
color-scheme: light; /* or 'dark', or 'light dark' for auto */
}
Alternatively, you can add the rdg-light or rdg-dark class to individual grids:
// Force light theme
<DataGrid className="rdg-light" columns={columns} rows={rows} />
// Force dark theme
<DataGrid className="rdg-dark" columns={columns} rows={rows} />
In forced colors mode, such as Windows contrast themes, the DataGrid uses system colors for the active cell, row selection, and the drag handle, so they follow the user's palette. Overriding --rdg-selection-color or --rdg-checkbox-focus-color in your own styles also overrides their forced colors values outside selected rows, so wrap such overrides in @media not (forced-colors: active).
The DataGrid supports the following CSS variables for customization:
.rdg {
/* Selection */
--rdg-selection-width: 2px;
--rdg-selection-color: hsl(207, 75%, 66%);
/* Typography */
--rdg-font-size: 14px;
/* Colors (using light-dark() for automatic theme switching) */
--rdg-color: light-dark(#000, #ddd);
--rdg-background-color: light-dark(hsl(0deg 0% 100%), hsl(0deg 0% 13%));
/* Header */
--rdg-header-background-color: light-dark(hsl(0deg 0% 97.5%), hsl(0deg 0% 10.5%));
--rdg-header-draggable-background-color: light-dark(hsl(0deg 0% 90.5%), hsl(0deg 0% 17.5%));
/* Rows */
--rdg-row-hover-background-color: light-dark(hsl(0deg 0% 96%), hsl(0deg 0% 9%));
--rdg-row-selected-background-color: light-dark(hsl(207deg 76% 92%), hsl(207deg 76% 42%));
--rdg-row-selected-hover-background-color: light-dark(hsl(207deg 76% 88%), hsl(207deg 76% 38%));
/* Borders */
--rdg-border-width: 1px;
--rdg-border-color: light-dark(#ddd, #444);
--rdg-summary-border-width: calc(var(--rdg-border-width) * 2);
--rdg-summary-border-color: light-dark(#aaa, #555);
/* Checkboxes */
--rdg-checkbox-focus-color: hsl(207deg 100% 69%);
/* Frozen columns */
--rdg-frozen-column-shadow-color: light-dark(rgb(0 0 0 / 15%), rgb(0 0 0 / 40%));
}
Example of customizing colors:
.my-custom-grid {
--rdg-background-color: #f0f0f0;
--rdg-selection-color: #ff6b6b;
--rdg-font-size: 16px;
}
<DataGrid className="my-custom-grid" columns={columns} rows={rows} />
The DataGrid accepts standard className and style props:
<DataGrid
columns={columns}
rows={rows}
className="my-grid custom-theme"
style={{ width: 800, height: 600 }}
/>
Control row heights using the rowHeight, headerRowHeight, and summaryRowHeight props. The rowHeight prop supports both fixed heights and dynamic heights per row.
Apply custom CSS classes to rows using the rowClass prop, and to header rows using the headerRowClass prop.
Apply custom CSS classes to cells using the cellClass property in column definitions. You can also use headerCellClass and summaryCellClass for header and summary cells, respectively.
Control column widths using the width, minWidth, and maxWidth properties in column definitions. Enable column resizing using the resizable property, or use defaultColumnOptions to apply it to all columns.
Replace default components with custom implementations using the renderers prop. Columns can also have custom renderers using the renderCell, renderHeaderCell, renderSummaryCell, renderGroupCell, and renderEditCell properties.
Ctrl also accepts ⌘, as macOS uses Ctrl+←/→ to switch desktops. In right-to-left grids, ← and → are swapped. See onCellKeyDown to customize them.
| Keys | Action |
|---|---|
| ← → ↑ ↓ | Move to the adjacent cell |
| Tab / Shift+Tab | Move to the next or previous cell. Focus leaves the grid from the last or first cell |
| Home / End | Move to the first or last cell of the row |
| Ctrl+Home / Ctrl+End | Move to the first header cell or the last cell of the last row |
| Page Up / Page Down | Move up or down by one page of rows |
| Keys | Action |
|---|---|
| Typing or Enter | Open the editor |
| Enter / Escape | Commit or discard the changes and close the editor |
| Tab / Shift+Tab | Commit the changes and move to the next or previous cell |
| Ctrl+C / Ctrl+V | Copy or paste, with onCellCopy and onCellPaste |
| Keys | Action |
|---|---|
| Shift+Space | Select or deselect the row of the active cell |
| Keys | Action |
|---|---|
| Enter / Space | Sort by the column |
| Ctrl+Enter / Ctrl+Space | Add the column to the sort, keeping the other sorted columns |
| Ctrl+← / Ctrl+→ | Resize the column |
See TreeDataGrid for the keys that expand and collapse groups.
<DataGrid />columns: readonly ColumnOrColumnGroup<R, SR>[]An array of column definitions and/or column groups. See the ColumnOrColumnGroup 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 row 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:
// ✅ Good: Only the 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 })));
ref?: Maybe<React.Ref<DataGridHandle>>Optional ref for imperative APIs like scrolling to or focusing a cell. See DataGridHandle.
topSummaryRows?: Maybe<readonly SR[]>Rows pinned at the top of the grid for summary purposes.
:warning: Performance: Memoize this array to prevent internal memoization invalidation.
bottomSummaryRows?: Maybe<readonly SR[]>Rows pinned at the bottom of the grid for summary purposes.
:warning: Performance: Memoize this array to prevent internal memoization invalidation.
getRowKey?: Maybe<(row: R) => K>Function to get a unique key for each row. Required for row selection.
import { DataGrid } from 'react-data-grid';
interface Row {
id: number;
name: string;
}
function getRowKey(row: Row) {
return row.id;
}
function MyGrid() {
return <DataGrid columns={columns} rows={rows} getRowKey={getRowKey} />;
}
: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. See the RowsChangeData type.
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.
// Fixed height for all rows
<DataGrid columns={columns} rows={rows} rowHeight={50} />;
// Dynamic height per row
function getRowHeight(row) {
return row.isExpanded ? 100 : 35;
}
<DataGrid columns={columns} rows={rows} rowHeight={getRowHeight} />;
:warning: Performance: When using a function, the heights of all rows are processed upfront. For large datasets (1000+ rows), this can cause performance issues if the identity of the function changes and invalidates internal memoization. Consider using a static function when possible, or memoize the rowHeight function.
headerRowHeight?: Maybe<number>Default: rowHeight when it is a number, otherwise 35 pixels
Height of the header row in pixels.
summaryRowHeight?: Maybe<number>Default: rowHeight when it is a number, otherwise 35 pixels
Height of each summary row in pixels.
<DataGrid
columns={columns}
rows={rows}
rowHeight={35}
headerRowHeight={45}
summaryRowHeight={40}
topSummaryRows={topSummaryRows}
/>
columnWidths?: Maybe<ColumnWidths>A map of column widths containing both measured and resized widths. If not provided, an internal state is used. See the ColumnWidths type.
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, an internal state is used. See the ColumnWidths type.
selectedRows?: Maybe<ReadonlySet<K>>A set of selected row keys. getRowKey is required for row selection to work.
isRowSelectionDisabled?: Maybe<(row: 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, type Column } from 'react-data-grid';
const rows: readonly Row[] = [...];
const columns: readonly Column<Row>[] = [
SelectColumn,
// other columns
];
function getRowKey(row: Row) {
return row.id;
}
function isRowSelectionDisabled(row: Row) {
return !row.isActive;
}
function MyGrid() {
const [selectedRows, setSelectedRows] = useState((): ReadonlySet<number> => new Set());
return (
<DataGrid
getRowKey={getRowKey}
columns={columns}
rows={rows}
selectedRows={selectedRows}
isRowSelectionDisabled={isRowSelectionDisabled}
onSelectedRowsChange={setSelectedRows}
/>
);
}
sortColumns?: Maybe<readonly SortColumn[]>An array of sorted columns. See the SortColumn type.
Sorting is controlled: the grid does not reorder rows for you. Apply the sorting to your rows state (or derived rows) based on sortColumns.
onSortColumnsChange?: Maybe<(sortColumns: SortColumn[]) => void>Callback triggered when sorting changes.
import { useState } from 'react';
import { DataGrid, type Column, type SortColumn } from 'react-data-grid';
const rows: readonly Row[] = [...];
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+Click (Cmd+Click on macOS). To disable multi-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. See the DefaultColumnOptions type.
function MyGrid() {
return (
<DataGrid
columns={columns}
rows={rows}
defaultColumnOptions={{
minWidth: 100,
resizable: true,
sortable: true,
draggable: true
}}
/>
);
}
onCellMouseDown?: CellMouseEventHandler<R, SR>Callback triggered when a pointer becomes active in a cell. The default behavior is to focus the cell. Call preventGridDefault to prevent the default behavior. See the CellMouseArgs and CellMouseEvent types.
function onCellMouseDown(args: CellMouseArgs<R, SR>, event: CellMouseEvent) {
if (args.column.key === 'id') {
event.preventGridDefault();
}
}
<DataGrid rows={rows} columns={columns} onCellMouseDown={onCellMouseDown} />;
onCellClick?: CellMouseEventHandler<R, SR>Callback triggered when a cell is clicked. See the CellMouseArgs and CellMouseEvent types.
This event can be used to open the cell editor on a single click:
function onCellClick(args: CellMouseArgs<R, SR>, event: CellMouseEvent) {
if (args.column.key === 'id') {
args.setActivePosition(true);
}
}
<DataGrid rows={rows} columns={columns} onCellClick={onCellClick} />;
onCellDoubleClick?: CellMouseEventHandler<R, SR>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. See the CellMouseArgs and CellMouseEvent types.
function onCellDoubleClick(args: CellMouseArgs<R, SR>, event: CellMouseEvent) {
if (args.column.key === 'id') {
event.preventGridDefault();
}
}
<DataGrid rows={rows} columns={columns} onCellDoubleClick={onCellDoubleClick} />;
onCellContextMenu?: CellMouseEventHandler<R, SR>Callback triggered when a cell is right-clicked. See the CellMouseArgs and CellMouseEvent types.
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>Callback triggered when a key is pressed in a cell. This event can be used to customize cell navigation and editing behavior. See the CellKeyDownArgs and CellKeyboardEvent types.
It is not called for keydown events triggered in a :modal editor, see renderEditCell.
Examples
Enterfunction onCellKeyDown(args: CellKeyDownArgs<R, SR>, event: CellKeyboardEvent) {
if (args.mode === 'ACTIVE' && event.key === 'Enter') {
event.preventGridDefault();
}
}
Tabfunction onCellKeyDown(args: CellKeyDownArgs<R, SR>, event: CellKeyboardEvent) {
if (args.mode === 'ACTIVE' && event.key === 'Tab') {
event.preventGridDefault();
}
}
See more examples.
onCellCopy?: Maybe<(args: CellCopyArgs<R, SR>, event: CellClipboardEvent) => void>Callback triggered when a cell's content is copied. See the CellCopyArgs type.
onCellPaste?: Maybe<(args: CellPasteArgs<R, SR>, event: CellClipboardEvent) => R>Callback triggered when content is pasted into a cell. See the CellPasteArgs type.
Return the updated row; the grid will call onRowsChange with it.
onActivePositionChange?: Maybe<(args: PositionChangeArgs<R, SR>) => void>Callback triggered when the active position changes. See the PositionChangeArgs type.
onFill?: Maybe<(event: FillEvent<R>) => R>Callback triggered when the value of the active cell is dragged to fill other cells. When this prop is set, a drag handle is shown on the active cell if it is editable. Drag the handle up or down to fill the cells it passes over, or double-click it to fill all the cells below.
The grid calls onFill for each editable target cell. Return the updated target row; the grid will call onRowsChange with the updated rows. See the FillEvent type.
function onFill({ columnKey, sourceRow, targetRow }: FillEvent<Row>): Row {
return { ...targetRow, [columnKey]: sourceRow[columnKey as keyof Row] };
}
<DataGrid columns={columns} rows={rows} onRowsChange={setRows} onFill={onFill} />;
onScroll?: React.UIEventHandler<HTMLDivElement> | undefinedNative DOM onScroll prop.
onColumnResize?: Maybe<(column: CalculatedColumn<R, SR>, width: number) => void>Callback triggered when a column is resized. The column parameter is the full CalculatedColumn object, and width is the new width in pixels.
onColumnsReorder?: Maybe<(sourceColumnKey: string, targetColumnKey: string) => void>Callback triggered when columns are reordered. The parameters are the key values of the source and target columns.
enableVirtualization?: Maybe<boolean>Default: true
This prop can be used to disable virtualization.
renderers?: Maybe<Renderers<R, SR>>Custom renderers for cells, rows, and other components.
See the Renderers type for the full shape.
Example of replacing default components:
import { DataGrid, type Renderers } from 'react-data-grid';
const customRenderers: Renderers<Row, SummaryRow> = {
// Custom row render function
renderRow(key, props) {
return <CustomRow key={key} {...props} />;
},
// Custom cell render function
renderCell(key, props) {
return <CustomCell key={key} {...props} />;
},
// Custom checkbox render function
renderCheckbox(props) {
return <CustomCheckbox {...props} />;
},
// Custom sort status indicator
renderSortStatus(props) {
return <CustomSortIcon {...props} />;
},
// Custom empty state
noRowsFallback: <div>No data available</div>
};
<DataGrid columns={columns} rows={rows} renderers={customRenderers} />;
The default <Row /> component can be wrapped via renderers.renderRow to add contexts or tweak props:
import { DataGrid, Row, type RenderRowProps } from 'react-data-grid';
interface MyRow {
id: number;
}
function myRowRenderer(key: React.Key, props: RenderRowProps<MyRow>) {
return (
<MyContext key={key} value={123}>
<Row {...props} />
</MyContext>
);
}
function MyGrid() {
return <DataGrid columns={columns} rows={rows} renderers={{ renderRow: myRowRenderer }} />;
}
rowClass?: Maybe<(row: R, rowIdx: number) => Maybe<string>>Function to apply custom class names to rows.
import { DataGrid } from 'react-data-grid';
function rowClass(row: Row, rowIdx: number) {
return rowIdx % 2 === 0 ? 'even' : 'odd';
}
function MyGrid() {
return <DataGrid columns={columns} rows={rows} rowClass={rowClass} />;
}
:warning: Performance: Define this function outside your component or memoize it with useCallback to avoid re-rendering all rows on every render.
headerRowClass?: Maybe<string>Custom class name for the header row.
<DataGrid columns={columns} rows={rows} headerRowClass="sticky-header" />
direction?: Maybe<'ltr' | 'rtl'>This property sets the text direction of the grid. It defaults to 'ltr' (left-to-right). See the Direction type.
Setting direction to 'rtl' has the following effects:
className?: string | undefinedCustom class name for the grid.
style?: CSSProperties | undefinedCustom styles for the grid.
role?: string | undefinedARIA role for the grid container. Defaults to grid.
'aria-label'?: string | undefinedThe label of the grid. We recommend providing a label using aria-label or aria-labelledby.
'aria-labelledby'?: string | undefinedThe id of the element containing a label for the grid. We recommend providing a label using aria-label or aria-labelledby.
'aria-rowcount'?: number | undefinedTotal number of rows for assistive technologies.
'aria-description'?: string | undefinedA human-readable description of the grid.
'aria-describedby'?: string | undefinedIf 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<string>This prop can be used to add a test ID for testing. We recommend querying the grid by its role and name.
function MyGrid() {
return <DataGrid aria-label="my-grid" columns={columns} rows={rows} />;
}
test('grid', async () => {
await page.render(<MyGrid />);
const grid = page.getByRole('grid', { name: 'my-grid' });
});
'data-cy'?: Maybe<string>Optional attribute to help with Cypress (or similar) selectors.
<TreeDataGrid />TreeDataGrid is a component built on top of DataGrid to add hierarchical row grouping. This implements the Treegrid pattern.
How it works:
groupBy prop specifies which columns should be used for groupinggetRowGroupKey when providedKeyboard Navigation:
Unsupported Props:
The following DataGrid props are not supported in TreeDataGrid:
onFill - Drag-fill is disabled for tree gridsisRowSelectionDisabled - Row selection disabling is not availablerole - TreeDataGrid manages the ARIA rolearia-rowcount - TreeDataGrid manages the ARIA row countCaveats:
columns must be Column[]Group rows in callbacks:
Callbacks that receive the active row receive group rows too: onCellKeyDown and onActivePositionChange. Their arguments are typed with TreeCellKeyDownArgs and TreePositionChangeArgs; use isGroupRow to tell group rows apart from regular rows.
import { isGroupRow, type CellKeyboardEvent, type TreeCellKeyDownArgs } from 'react-data-grid';
function onCellKeyDown(args: TreeCellKeyDownArgs<Row>, event: CellKeyboardEvent) {
if (args.mode !== 'ACTIVE') return;
if (isGroupRow(args.row)) {
console.log(`Group ${args.row.groupKey} with ${args.row.childRows.length} rows`);
return;
}
console.log(args.row.name);
}
All DataGridProps are supported except those listed above. The columns prop only supports Column[] (no column groups). When rowHeight is a function, it receives RowHeightArgs instead of just the row, and onCellKeyDown and onActivePositionChange receive group rows too. Additional props are listed below:
groupBy: readonly string[]Required. An array of column keys to group by. The order determines the grouping hierarchy (first key is the top level, second key is nested under the first, etc.).
import { TreeDataGrid, type Column } from 'react-data-grid';
interface Row {
id: number;
country: string;
city: string;
name: string;
}
const columns: readonly Column<Row>[] = [
{ key: 'country', name: 'Country' },
{ key: 'city', name: 'City' },
{ key: 'name', name: 'Name' }
];
const groupBy = ['country', 'city'];
function MyGrid() {
return (
<TreeDataGrid
columns={columns}
rows={rows}
groupBy={groupBy}
// ... other props
/>
);
}
:warning: Performance: Define this array outside your component or memoize it with useMemo, otherwise all the rows are grouped again on every render.
expandedGroupIds: ReadonlySet<string>Required. A set of group IDs that are currently expanded. Group IDs are generated by getGroupId.
import { useState } from 'react';
import { TreeDataGrid } from 'react-data-grid';
function MyGrid() {
const [expandedGroupIds, setExpandedGroupIds] = useState((): ReadonlySet<string> => new Set());
return (
<TreeDataGrid
expandedGroupIds={expandedGroupIds}
onExpandedGroupIdsChange={setExpandedGroupIds}
// ... other props
/>
);
}
onExpandedGroupIdsChange: (expandedGroupIds: Set<string>) => voidRequired. Callback triggered when groups are expanded or collapsed.
getRowGroupKey?: Maybe<(row: R, columnKey: string) => string>A function that returns the key of the group a row belongs to, for the specified column key. Rows sharing the same group key are grouped together, and groups are ordered by the first row that belongs to them. If not provided, a default implementation is used that stringifies the row's value for that column, i.e., String(row[columnKey]).
Provide your own to group on something other than the raw cell value:
function getRowGroupKey(row: Row, columnKey: string): string {
if (columnKey === 'date') {
return row.date.getFullYear().toString();
}
return String(row[columnKey]);
}
:warning: Performance: Define this function outside your component or memoize it with useCallback, otherwise all the rows are grouped again on every render.
getGroupId?: Maybe<(groupKey: string, parentId?: string) => string>Function to generate unique IDs for group rows. If not provided, a default implementation is used that concatenates parent and group keys with __.
:warning: Performance: Define this function outside your component or memoize it with useCallback to prevent unnecessary re-renders.
rowHeight?: Maybe<number | ((args: RowHeightArgs<R>) => number)>Note: Unlike DataGrid, the rowHeight function receives RowHeightArgs<R>, which includes a type property to distinguish between regular rows and group rows:
function getRowHeight(args: RowHeightArgs<Row>): number {
if (args.type === 'GROUP') {
return 50; // Custom height for group rows
}
return 35; // Height for regular rows
}
<TreeDataGrid rowHeight={getRowHeight} ... />
onCellKeyDown?: Maybe<(args: TreeCellKeyDownArgs<R, SR>, event: CellKeyboardEvent) => void>Callback triggered when a key is pressed in a cell or a row, including group rows. Unlike DataGrid, the active row in ACTIVE mode can be a group row: use isGroupRow to narrow it. See the TreeCellKeyDownArgs type and the onCellKeyDown prop on <DataGrid />.
onActivePositionChange?: Maybe<(args: TreePositionChangeArgs<R, SR>) => void>Callback triggered when the active position changes, including to a group row or a cell of one: use isGroupRow to narrow the row. See the TreePositionChangeArgs type.
<Row />The default row component. Can be wrapped via the renderers.renderRow prop.
RenderRowProps<TRow, TSummaryRow>
<Cell />The default cell component. Can be wrapped via the renderers.renderCell prop.
RenderCellProps<TRow, TSummaryRow>
<SelectCheckbox />A component for rendering row selection checkboxes.
The same props as RenderCheckboxProps, with checked required.
<ToggleGroup />Low-level component used by renderToggleGroup to render the expand/collapse control. Useful if you build a custom group cell renderer.
RenderGroupCellContentProps<TRow, TSummaryRow>
useHeaderRowSelection()Hook for managing header row selection state. Used within custom header cell renderers to implement custom "select all" functionality.
Returns:
isIndeterminate: boolean - Whether some (but not all) rows are selectedisRowSelected: boolean - Whether all rows are selectedonRowSelectionChange: (event: SelectHeaderRowEvent) => void - Callback to change selection stateExample:
import { useLayoutEffect, useRef } from 'react';
function CustomHeaderCell() {
const { isIndeterminate, isRowSelected, onRowSelectionChange } = useHeaderRowSelection();
const checkboxRef = useRef<HTMLInputElement>(null);
useLayoutEffect(() => {
if (checkboxRef.current) {
checkboxRef.current.indeterminate = isIndeterminate && !isRowSelected;
}
}, [isIndeterminate, isRowSelected]);
return (
<input
ref={checkboxRef}
type="checkbox"
checked={isRowSelected}
onChange={(event) => onRowSelectionChange({ checked: event.target.checked })}
/>
);
}
useRowSelection()Hook for managing row selection state. Used within custom cell renderers to implement custom row selection.
Returns:
isRowSelectionDisabled: boolean - Whether selection is disabled for this rowisRowSelected: boolean - Whether this row is selectedonRowSelectionChange: (event: SelectRowEvent<R>) => void - Callback to change selection stateExample:
function CustomSelectCell({ row }: RenderCellContentProps<Row>) {
const { isRowSelectionDisabled, isRowSelected, onRowSelectionChange } = useRowSelection();
return (
<input
type="checkbox"
disabled={isRowSelectionDisabled}
checked={isRowSelected}
onChange={(event) =>
onRowSelectionChange({
row,
checked: event.currentTarget.checked,
isShiftClick: event.nativeEvent.shiftKey
})
}
/>
);
}
renderHeaderCell<R, SR>(props: RenderHeaderCellContentProps<R, SR>)The default header cell content renderer. Renders sortable columns with sort indicators.
Props: RenderHeaderCellContentProps<TRow, TSummaryRow>
Example:
import { renderHeaderCell, type Column } from 'react-data-grid';
const columns: readonly Column<Row>[] = [
{
key: 'name',
name: 'Name',
sortable: true,
renderHeaderCell
}
];
renderTextEditor<TRow, TSummaryRow>(props: RenderEditCellContentProps<TRow, TSummaryRow>)A basic text editor provided for convenience.
Props: RenderEditCellContentProps<TRow, TSummaryRow>
Example:
import { renderTextEditor, type Column } from 'react-data-grid';
const columns: readonly Column<Row>[] = [
{
key: 'title',
name: 'Title',
renderEditCell: renderTextEditor
}
];
renderSortIcon(props: RenderSortIconProps)Renders the sort direction arrow icon.
Props: RenderSortIconProps
renderSortPriority(props: RenderSortPriorityProps)Renders the sort priority number for multi-column sorting.
Props: RenderSortPriorityProps
renderCheckbox(props: RenderCheckboxProps)Renders a checkbox input with proper styling and accessibility.
Props: RenderCheckboxProps
Example:
import { DataGrid, renderCheckbox } from 'react-data-grid';
<DataGrid
renderers={{
renderCheckbox: (props) => renderCheckbox({ ...props, 'aria-label': 'Select row' })
}}
/>;
renderToggleGroup<R, SR>(props: RenderGroupCellContentProps<R, SR>)The default group cell content renderer for the columns used for grouping (groupBy prop). This renders the group key, row.groupKey, and the expand/collapse toggle.
Props: RenderGroupCellContentProps<TRow, TSummaryRow>
Example:
import { renderToggleGroup, type Column } from 'react-data-grid';
const columns: readonly Column<Row>[] = [
{
key: 'group',
name: 'Group',
renderGroupCell: renderToggleGroup
}
];
renderValue<R, SR>(props: RenderCellContentProps<R, SR>)The default cell content renderer that renders the value of row[column.key].
Props: RenderCellContentProps<TRow, TSummaryRow>
Example:
import { renderValue, type Column } from 'react-data-grid';
const columns: readonly Column<Row>[] = [
{
key: 'title',
name: 'Title',
renderCell: renderValue
}
];
DataGridRenderersContextContext for providing default renderers to DataGrids in your app.
Example:
import {
DataGridRenderersContext,
renderCheckbox,
renderSortIcon,
renderSortPriority,
type Renderers
} from 'react-data-grid';
// custom implementations of renderers
const defaultGridRenderers: Renderers<unknown, unknown> = {
renderCheckbox,
renderSortStatus(props) {
return (
<>
{renderSortIcon(props)}
{renderSortPriority(props)}
</>
);
}
};
function AppProvider({ children }) {
return (
<DataGridRenderersContext value={defaultGridRenderers}>{children}</DataGridRenderersContext>
);
}
SelectColumn: Column<any, any>A pre-configured column for row selection. Includes checkbox renderers for the header row, regular rows, and group rows.
Example:
import { DataGrid, SelectColumn, type Column } from 'react-data-grid';
const columns: readonly Column<Row>[] = [SelectColumn, ...otherColumns];
function getRowKey(row: Row) {
return row.id;
}
function MyGrid() {
return (
<DataGrid
columns={columns}
rows={rows}
getRowKey={getRowKey}
selectedRows={selectedRows}
onSelectedRowsChange={setSelectedRows}
/>
);
}
SELECT_COLUMN_KEY = 'rdg-select-column'The key used for the SelectColumn. Useful for identifying or filtering the select column.
Example:
import { SELECT_COLUMN_KEY } from 'react-data-grid';
const nonSelectColumns = columns.filter((column) => column.key !== SELECT_COLUMN_KEY);
isGroupRow<TRow>(row: TRow | GroupRow<TRow>): row is GroupRow<TRow>Returns whether a row of a TreeDataGrid is a group row, e.g., the active row passed to onCellKeyDown or onActivePositionChange.
Example:
import { isGroupRow, type TreePositionChangeArgs } from 'react-data-grid';
function onActivePositionChange({ row }: TreePositionChangeArgs<Row>) {
if (row === undefined || isGroupRow(row)) return;
console.log(row.name);
}
See also: GroupRow, TreeCellKeyDownArgs, TreePositionChangeArgs
Column<TRow, TSummaryRow>Defines the configuration for a column in the grid.
See also: columns prop on <DataGrid />
name: string | ReactElementThe name of the column. Displayed in the header cell by default.
key: stringA unique key to distinguish each column.
width?: Maybe<number | string>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.
const columns: Column<Row>[] = [
{
key: 'id',
name: 'ID',
width: 80, // Fixed width in pixels
resizable: false
},
{
key: 'name',
name: 'Name',
width: '30%', // Percentage width
minWidth: 100,
maxWidth: 400
},
{
key: 'description',
name: 'Description'
// No width specified - automatically sized
}
];
Other examples:
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<number>Default: 50 pixels
Minimum column width in pixels.
maxWidth?: Maybe<number>Maximum column width in pixels.
cellClass?: Maybe<string | ((row: TRow) => Maybe<string>)>Class name(s) for cells. Can be a string or a function that returns a class name based on the row.
const columns: Column<Row>[] = [
{
key: 'status',
name: 'Status',
cellClass: (row) => `status-${row.status}`
},
{
key: 'price',
name: 'Price',
cellClass: 'text-right' // Static class
}
];
.status-active {
color: green;
font-weight: bold;
}
.status-inactive {
color: gray;
}
.text-right {
text-align: right;
}
headerCellClass?: Maybe<string>Class name(s) for the header cell.
summaryCellClass?: Maybe<string | ((row: TSummaryRow) => Maybe<string>)>Class name(s) for summary cells. Can be a string or a function that returns a class name based on the summary row.
renderCell?: Maybe<(props: RenderCellContentProps<TRow, TSummaryRow>) => ReactNode>Render function to render the content of cells.
renderHeaderCell?: Maybe<(props: RenderHeaderCellContentProps<TRow, TSummaryRow>) => ReactNode>Render function to render the content of the header cell.
renderSummaryCell?: Maybe<(props: RenderSummaryCellContentProps<TSummaryRow, TRow>) => ReactNode>Render function to render the content of summary cells.
renderGroupCell?: Maybe<(props: RenderGroupCellContentProps<TRow, TSummaryRow>) => ReactNode>Render function to render the content of group cells when using TreeDataGrid. The group row is passed as row, a GroupRow with the group's key, rows, and expanded state.
const columns: readonly Column<Row>[] = [
{
key: 'gold',
name: 'Gold',
renderGroupCell({ row }) {
return row.childRows.reduce((sum, childRow) => sum + childRow.gold, 0);
}
}
];
renderEditCell?: Maybe<(props: RenderEditCellContentProps<TRow, TSummaryRow>) => ReactNode>Render function to render the content of edit cells. When set, the column is automatically set to be editable.
Editors can render a :modal element, like a <dialog> opened with showModal(), either in the cell or in a portal. Keydown events triggered in the modal are left to the editor: onCellKeyDown is not called, and the grid does not close the editor on Escape/Enter or navigate on Tab, so the editor must call onClose itself, for example in the dialog's onClose handler.
editable?: Maybe<boolean | ((row: TRow) => boolean)>Control whether cells can be edited with renderEditCell.
colSpan?: Maybe<(args: ColSpanArgs<TRow, TSummaryRow>) => Maybe<number>>Function to determine how many columns this cell should span. Returns the number of columns to span, or undefined for no spanning. The span is clamped to the start-frozen, unfrozen, or end-frozen columns, whichever the column is part of. See the ColSpanArgs type.
Example:
import type { Column } from 'react-data-grid';
const columns: readonly Column<Row>[] = [
{
key: 'title',
name: 'Title',
colSpan(args) {
if (args.type === 'ROW' && args.row.isFullWidth) {
return 5; // Span 5 columns for full-width rows
}
return undefined;
}
}
];
frozen?: Maybe<ColumnFrozen | true>Default: false
Determines whether the column is frozen, and on which edge. Frozen columns stay in place when the grid is scrolled horizontally. See the ColumnFrozen type.
'start' (or true for backward compatibility) — pins the column to the start edge (left in LTR, right in RTL).'end' — pins the column to the end edge (right in LTR, left in RTL).false (default) — the column scrolls with the rest of the grid.const columns: readonly Column<Row>[] = [
{ key: 'id', name: 'ID', frozen: 'start' },
{ key: 'name', name: 'Name' },
{ key: 'actions', name: 'Actions', frozen: 'end' }
];
resizable?: Maybe<boolean>Default: false
Enable resizing of the column.
sortable?: Maybe<boolean>Default: false
Enable sorting of the column.
draggable?: Maybe<boolean>Default: false
Enable dragging of the column.
sortDescendingFirst?: Maybe<boolean>Default: false
Sets the column sort order to be descending instead of ascending the first time the column is sorted.
editorOptionsOptions for cell editing.
displayCellContent?: Maybe<boolean>Default: false
Render the cell content in addition to the edit cell content. Enable this option when the editor is rendered outside the grid, like a modal for example.
commitOnOutsideClick?: Maybe<boolean>Default: true
Commit changes when clicking outside the cell.
closeOnExternalRowChange?: Maybe<boolean>Default: true
Close the editor when the row value changes externally.
ColumnGroup<TRow, TSummaryRow>Defines a group of columns that share a common header.
interface ColumnGroup<R, SR = unknown> {
/** The name of the column group. It will be displayed in the header cell */
readonly name: string | ReactElement;
readonly headerCellClass?: Maybe<string>;
readonly children: readonly ColumnOrColumnGroup<R, SR>[];
}
Example:
import type { ColumnOrColumnGroup } from 'react-data-grid';
const columns: readonly ColumnOrColumnGroup<Row>[] = [
{
name: 'Personal Info',
children: [
{ key: 'firstName', name: 'First Name' },
{ key: 'lastName', name: 'Last Name' }
]
}
];
See also: ColumnOrColumnGroup
ColumnOrColumnGroup<TRow, TSummaryRow>Union type representing either a Column or a ColumnGroup.
See also: columns prop on <DataGrid />
CalculatedColumn<TRow, TSummaryRow>Extends Column with additional computed properties used internally by the grid. This is the type passed to render functions. Every Column property is set: the ones with a default value, like width and renderCell, are resolved to their default value when not set, and the others are undefined when not set.
interface CalculatedColumn<TRow, TSummaryRow = unknown> extends Column<TRow, TSummaryRow> {
/** The column group that contains the column, or `undefined` if the column is not in a group */
readonly parent: CalculatedColumnParent<TRow, TSummaryRow> | undefined;
/** The index of the column in the grid. Column groups are flattened and frozen columns are moved to their edge, so it can differ from the column's index in `columns` */
readonly idx: number;
/** Header row level, counted from the bottom header row: always `0` for columns, and negative for column groups */
readonly level: number;
readonly width: number | string;
readonly minWidth: number;
readonly maxWidth: number | undefined;
readonly resizable: boolean;
readonly sortable: boolean;
readonly draggable: boolean;
readonly frozen: ColumnFrozen;
readonly renderCell: (props: RenderCellContentProps<TRow, TSummaryRow>) => ReactNode;
readonly renderHeaderCell: (props: RenderHeaderCellContentProps<TRow, TSummaryRow>) => ReactNode;
/** Returns the number of columns that the cell spans: the clamped value returned by `colSpan`, or `1` */
readonly getColSpan: (args: ColSpanArgs<TRow, TSummaryRow> | undefined) => number;
// Always set, `undefined` when not set on the column
readonly cellClass: Column<TRow, TSummaryRow>['cellClass'];
readonly headerCellClass: Column<TRow, TSummaryRow>['headerCellClass'];
readonly summaryCellClass: Column<TRow, TSummaryRow>['summaryCellClass'];
readonly renderSummaryCell: Column<TRow, TSummaryRow>['renderSummaryCell'];
readonly renderGroupCell: Column<TRow, TSummaryRow>['renderGroupCell'];
readonly renderEditCell: Column<TRow, TSummaryRow>['renderEditCell'];
readonly editable: Column<TRow, TSummaryRow>['editable'];
readonly colSpan: Column<TRow, TSummaryRow>['colSpan'];
readonly sortDescendingFirst: Column<TRow, TSummaryRow>['sortDescendingFirst'];
readonly editorOptions: Column<TRow, TSummaryRow>['editorOptions'];
}
See also: Column, onColumnResize prop on <DataGrid />
CalculatedColumnParent<TRow, TSummaryRow>Represents a parent column group in the calculated column structure.
interface CalculatedColumnParent<R, SR> {
readonly name: string | ReactElement;
readonly parent: CalculatedColumnParent<R, SR> | undefined;
readonly idx: number;
readonly colSpan: number;
readonly level: number;
readonly headerCellClass?: Maybe<string>;
}
See also: CalculatedColumn
CalculatedColumnOrColumnGroup<TRow, TSummaryRow>Union type representing either a CalculatedColumnParent or a CalculatedColumn.
type CalculatedColumnOrColumnGroup<R, SR> = CalculatedColumnParent<R, SR> | CalculatedColumn<R, SR>;
See also: CalculatedColumn, CalculatedColumnParent
DefaultColumnOptions<TRow, TSummaryRow>Default options applied to all columns.
type DefaultColumnOptions<TRow, TSummaryRow> = Pick<
Column<TRow, TSummaryRow>,
| 'renderCell'
| 'renderHeaderCell'
| 'width'
| 'minWidth'
| 'maxWidth'
| 'resizable'
| 'sortable'
| 'draggable'
>;
See also: defaultColumnOptions prop on <DataGrid />
ColumnFrozenWhether a column is frozen, and on which edge.
type ColumnFrozen = false | 'start' | 'end';
See also: column.frozen
RenderCellContentProps<TRow, TSummaryRow>Props passed to custom cell content renderers (column.renderCell).
interface RenderCellContentProps<TRow, TSummaryRow = unknown> {
column: CalculatedColumn<TRow, TSummaryRow>;
row: TRow;
rowIdx: number;
isCellEditable: boolean;
tabIndex: number;
onRowChange: (row: TRow) => void;
}
Example:
import type { RenderCellContentProps } from 'react-data-grid';
function renderCell({ row, column, onRowChange }: RenderCellContentProps<MyRow>) {
return (
<div>
{row[column.key]}
<button onClick={() => onRowChange({ ...row, updated: true })}>Update</button>
</div>
);
}
See also: column.renderCell, renderValue function
RenderHeaderCellContentProps<TRow, TSummaryRow>Props passed to custom header cell content renderers (column.renderHeaderCell).
interface RenderHeaderCellContentProps<TRow, TSummaryRow = unknown> {
column: CalculatedColumn<TRow, TSummaryRow>;
sortDirection: SortDirection | undefined;
priority: number | undefined;
tabIndex: number;
}
See also: column.renderHeaderCell, renderHeaderCell function
RenderEditCellContentProps<TRow, TSummaryRow>Props passed to custom editors (column.renderEditCell).
interface RenderEditCellContentProps<TRow, TSummaryRow = unknown> {
column: CalculatedColumn<TRow, TSummaryRow>;
row: TRow;
rowIdx: number;
onRowChange: (row: TRow, commitChanges?: boolean) => void;
onClose: (commitChanges?: boolean, shouldFocus?: boolean) => void;
}
Example:
import type { RenderEditCellContentProps } from 'react-data-grid';
function renderEditor({ row, column, onRowChange, onClose }: RenderEditCellContentProps<MyRow>) {
return (
<input
autoFocus
value={row[column.key]}
onChange={(event) => onRowChange({ ...row, [column.key]: event.target.value })}
onBlur={() => onClose(true)}
/>
);
}
See also: column.renderEditCell, renderTextEditor function
RenderSummaryCellContentProps<TSummaryRow, TRow>Props passed to summary cell content renderers (column.renderSummaryCell).
interface RenderSummaryCellContentProps<TSummaryRow, TRow = unknown> {
column: CalculatedColumn<TRow, TSummaryRow>;
row: TSummaryRow;
tabIndex: number;
}
See also: column.renderSummaryCell
RenderGroupCellContentProps<TRow, TSummaryRow>Props passed to group cell content renderers (column.renderGroupCell) when using TreeDataGrid.
interface RenderGroupCellContentProps<TRow, TSummaryRow = unknown> {
column: CalculatedColumn<TRow, TSummaryRow>;
/** The group row: its key, rows, expanded state, level, and ID */
row: GroupRow<TRow>;
tabIndex: number;
/** Expands or collapses the group */
toggleGroup: () => void;
}
See also: column.renderGroupCell, renderToggleGroup function, <ToggleGroup />, GroupRow
GroupRow<TRow>Represents a group row in TreeDataGrid.
interface GroupRow<TRow> {
/** The rows of the group, including the rows of its subgroups */
readonly childRows: readonly TRow[];
/** The group's ID, returned by `getGroupId` */
readonly id: string;
/** The ID of the parent group, or `undefined` on the first level */
readonly parentId: string | undefined;
/** The group's key, returned by `getRowGroupKey` */
readonly groupKey: string;
/** Whether the group is expanded, i.e., its ID is in `expandedGroupIds` */
readonly isExpanded: boolean;
/** The nesting level, `0` for the first level */
readonly level: number;
/** The position of the group among its sibling groups, `0` for the first one */
readonly posInSet: number;
/** The number of sibling groups, including this one */
readonly setSize: number;
/** The index of the group row among all the rows, counting every group as expanded */
readonly startRowIndex: number;
}
See also: RenderGroupCellContentProps, RowHeightArgs, <TreeDataGrid />
RenderRowProps<TRow, TSummaryRow>Props passed to custom row renderers.
interface RenderRowProps<TRow, TSummaryRow = unknown> {
row: TRow;
/**
* Calls `callback` for each cell to render in the row, and returns the results.
* `activeIdx` is the column index of the row's active cell, if any: that cell is rendered even when it is scrolled out of view.
* If virtualization would leave out the active row, it is rendered with only its active cell, if any.
* `colSpanArgs` is passed to `column.colSpan`, and the columns that a cell spans are skipped, even the active one.
* The callback receives the cell's column, whether the cell is active, its `colSpan`, and its index in the results.
*/
mapViewportColumns: MapViewportColumns<TRow, TSummaryRow>;
rowIdx: number;
activeCellIdx: number | undefined;
isRowSelectionDisabled: boolean;
isRowSelected: boolean;
gridRowStart: number;
draggedOverCellIdx: number | undefined;
activeCellEditor: ReactElement<EditCellProps<TRow, TSummaryRow>> | undefined;
onRowChange: (column: CalculatedColumn<TRow, TSummaryRow>, rowIdx: number, newRow: TRow) => void;
rowClass: Maybe<(row: TRow, rowIdx: number) => Maybe<string>>;
isTreeGrid: boolean;
setActivePosition: (position: Position, options?: SetActivePositionOptions) => void;
// ... and DOM props, cell event handlers (onCellMouseDown, onCellClick, onCellDoubleClick, onCellContextMenu)
}
See also: renderers.renderRow, <Row />, MapViewportColumns
MapViewportColumns<TRow, TSummaryRow> (internal)Type of mapViewportColumns in RenderRowProps. This helper type is not exported; the shape is shown for reference.
type MapViewportColumns<TRow, TSummaryRow> = <T>(
activeIdx: number | undefined,
colSpanArgs: ColSpanArgs<TRow, TSummaryRow> | undefined,
callback: (
column: CalculatedColumn<TRow, TSummaryRow>,
isCellActive: boolean,
colSpan: number,
index: number
) => T
) => T[];
See also: RenderRowProps, ColSpanArgs
RenderCellProps<TRow, TSummaryRow>Props passed to the cell renderer when using renderers.renderCell.
interface RenderCellProps<TRow, TSummaryRow> {
column: CalculatedColumn<TRow, TSummaryRow>;
row: TRow;
rowIdx: number;
colSpan: number;
isDraggedOver: boolean;
isCellActive: boolean;
onRowChange: (column: CalculatedColumn<TRow, TSummaryRow>, rowIdx: number, newRow: TRow) => void;
setActivePosition: (position: Position, options?: SetActivePositionOptions) => void;
// ... and DOM props, cell event handlers (onCellMouseDown, onCellClick, onCellDoubleClick, onCellContextMenu)
}
See also: renderers.renderCell, <Cell />
RenderCheckboxPropsProps for custom checkbox renderers.
interface RenderCheckboxProps {
/** Whether the checkbox is checked */
checked?: boolean | undefined;
/** Whether the checkbox is in an indeterminate state, like the select all checkbox when only some rows are selected */
indeterminate?: boolean | undefined;
/** Whether the checkbox is disabled */
disabled?: boolean | undefined;
/** Called when the checkbox is toggled. `shift` is `true` if the Shift key was held, to select a range of rows */
onChange: (checked: boolean, shift: boolean) => void;
/** `0` when the checkbox's cell is active and `-1` otherwise, so the grid can move focus from the cell to the checkbox */
tabIndex?: number | undefined;
/** Accessible label for the checkbox */
'aria-label'?: string | undefined;
/** ID of the element that labels the checkbox */
'aria-labelledby'?: string | undefined;
}
See also: renderCheckbox function, renderers.renderCheckbox, <SelectCheckbox />
RenderSortStatusPropsProps for custom sort status renderers.
interface RenderSortStatusProps extends RenderSortIconProps, RenderSortPriorityProps {}
See also: renderers.renderSortStatus
RenderSortIconPropsProps for custom sort icon renderers.
interface RenderSortIconProps {
/** The sort direction of the column, or `undefined` if it is not sorted */
sortDirection: SortDirection | undefined;
}
See also: renderSortIcon function
RenderSortPriorityPropsProps for custom sort priority renderers.
interface RenderSortPriorityProps {
/** The column's position in `sortColumns`, starting at 1, when sorting by multiple columns, or `undefined` otherwise */
priority: number | undefined;
}
See also: renderSortPriority function
Renderers<TRow, TSummaryRow>Custom renderer configuration for the grid.
interface Renderers<TRow, TSummaryRow> {
renderCell?: Maybe<(key: Key, props: RenderCellProps<TRow, TSummaryRow>) => ReactNode>;
renderCheckbox?: Maybe<(props: RenderCheckboxProps) => ReactNode>;
renderRow?: Maybe<(key: Key, props: RenderRowProps<TRow, TSummaryRow>) => ReactNode>;
renderSortStatus?: Maybe<(props: RenderSortStatusProps) => ReactNode>;
noRowsFallback?: Maybe<ReactNode>;
}
See also: renderers prop on <DataGrid />, DataGridRenderersContext
CellMouseArgs<TRow, TSummaryRow>Arguments passed to cell mouse event handlers.
interface CellMouseArgs<TRow, TSummaryRow = unknown> {
/** The column object of the cell. */
column: CalculatedColumn<TRow, TSummaryRow>;
/** The row object of the cell. */
row: TRow;
/** The row index of the cell. */
rowIdx: number;
/** Function to manually focus the cell. Pass `true` to immediately start editing. */
setActivePosition: (enableEditor?: boolean) => void;
}
Example:
import type { CellMouseArgs, CellMouseEvent } from 'react-data-grid';
function onCellClick(args: CellMouseArgs<Row>, event: CellMouseEvent) {
console.log('Clicked cell at row', args.rowIdx, 'column', args.column.key);
args.setActivePosition(true); // Focus and start editing
}
See also: onCellMouseDown, onCellClick, onCellDoubleClick, and onCellContextMenu props on <DataGrid />
CellMouseEventHandler<TRow, TSummaryRow> (internal)Handler type used by onCellMouseDown, onCellClick, onCellDoubleClick, and onCellContextMenu. This helper type is not exported; the shape is shown for reference.
type CellMouseEventHandler<TRow, TSummaryRow> = Maybe<
(args: CellMouseArgs<TRow, TSummaryRow>, event: CellMouseEvent) => void
>;
CellEvent<E> (internal)Adds grid-specific methods to a React event. This helper type is not exported; the shape is shown for reference.
type CellEvent<E extends React.SyntheticEvent<HTMLDivElement>> = E & {
/** Prevents the default grid behavior for this event */
preventGridDefault: () => void;
/** Returns whether `preventGridDefault` was called */
isGridDefaultPrevented: () => boolean;
};
See also: CellMouseEvent, CellKeyboardEvent
CellMouseEventExtends React.MouseEvent<HTMLDivElement> with grid-specific methods.
type CellMouseEvent = CellEvent<React.MouseEvent<HTMLDivElement>>;
Example:
import type { CellMouseArgs, CellMouseEvent } from 'react-data-grid';
function onCellMouseDown(args: CellMouseArgs<Row>, event: CellMouseEvent) {
if (args.column.key === 'actions') {
event.preventGridDefault(); // Prevent cell focus
}
}
See also: onCellMouseDown, onCellClick, onCellDoubleClick, and onCellContextMenu props on <DataGrid />
CellKeyDownArgs<TRow, TSummaryRow, TActiveRow>Arguments passed to the onCellKeyDown handler. The shape differs based on whether the cell is in ACTIVE or EDIT mode.
/**
* @typeParam TActiveRow - The type of the active row in `ACTIVE` mode, `TRow | GroupRow<TRow>` in `TreeDataGrid`
*/
type CellKeyDownArgs<TRow, TSummaryRow = unknown, TActiveRow = TRow> =
| ActiveCellKeyDownArgs<TRow, TSummaryRow, TActiveRow>
| EditCellKeyDownArgs<TRow, TSummaryRow>;
ACTIVE mode:
interface ActiveCellKeyDownArgs<TRow, TSummaryRow = unknown, TActiveRow = TRow> {
mode: 'ACTIVE';
/**
* column object of the active position,
* undefined if the active position is a row instead of a cell
*/
column: CalculatedColumn<TRow, TSummaryRow> | undefined;
/** The active row. In `TreeDataGrid`, it can be a `GroupRow`, see `isGroupRow` */
row: TActiveRow;
rowIdx: number;
setActivePosition: (position: Position, options?: SetActivePositionOptions) => void;
}
EDIT mode:
interface EditCellKeyDownArgs<TRow, TSummaryRow = unknown> {
mode: 'EDIT';
column: CalculatedColumn<TRow, TSummaryRow>;
row: TRow;
rowIdx: number;
navigate: () => void;
onClose: (commitChanges?: boolean, shouldFocus?: boolean) => void;
}
Example:
import type { CellKeyboardEvent, CellKeyDownArgs } from 'react-data-grid';
function onCellKeyDown(args: CellKeyDownArgs<Row>, event: CellKeyboardEvent) {
if (args.mode === 'EDIT' && event.key === 'Escape') {
args.onClose(false); // Close without committing
event.preventGridDefault();
}
}
See also: onCellKeyDown prop on <DataGrid />, TreeCellKeyDownArgs
CellKeyboardEventExtends React.KeyboardEvent<HTMLDivElement> with grid-specific methods.
type CellKeyboardEvent = CellEvent<React.KeyboardEvent<HTMLDivElement>>;
See also: onCellKeyDown prop on <DataGrid />
CellClipboardEvent (internal)Type alias for React.ClipboardEvent<HTMLDivElement>. Used for copy and paste events. This helper type is not exported; the shape is shown for reference.
type CellClipboardEvent = React.ClipboardEvent<HTMLDivElement>;
See also: onCellCopy and onCellPaste props on <DataGrid />
CellCopyArgs<TRow, TSummaryRow>Arguments passed to onCellCopy.
interface CellCopyArgs<TRow, TSummaryRow = unknown> {
column: CalculatedColumn<TRow, TSummaryRow>;
row: TRow;
}
See also: onCellCopy prop on <DataGrid />
CellPasteArgs<TRow, TSummaryRow>Arguments passed to onCellPaste.
interface CellPasteArgs<TRow, TSummaryRow = unknown> {
column: CalculatedColumn<TRow, TSummaryRow>;
row: TRow;
}
See also: onCellPaste prop on <DataGrid />
PositionChangeArgs<TRow, TSummaryRow, TActiveRow>Arguments passed to onActivePositionChange.
/**
* @typeParam TActiveRow - The type of the active row, `TRow | GroupRow<TRow>` in `TreeDataGrid`
*/
interface PositionChangeArgs<TRow, TSummaryRow = unknown, TActiveRow = TRow> {
/** row index of the active position */
rowIdx: number;
/**
* row object of the active position,
* undefined if the active position is on a header or summary row.
* In `TreeDataGrid`, it can be a `GroupRow`, see `isGroupRow`
*/
row: TActiveRow | undefined;
/**
* column object of the active position,
* undefined if the active position is a row instead of a cell
*/
column: CalculatedColumn<TRow, TSummaryRow> | undefined;
}
See also: onActivePositionChange prop on <DataGrid />, TreePositionChangeArgs
TreeCellKeyDownArgs<TRow, TSummaryRow>Arguments passed to the onCellKeyDown handler of TreeDataGrid: the active row can be a group row.
/** The arguments of `TreeDataGrid`'s `onCellKeyDown`, whose active row can be a `GroupRow` */
type TreeCellKeyDownArgs<TRow, TSummaryRow = unknown> = CellKeyDownArgs<
TRow,
TSummaryRow,
TRow | GroupRow<TRow>
>;
See also: onCellKeyDown prop on <TreeDataGrid />, CellKeyDownArgs, isGroupRow
TreePositionChangeArgs<TRow, TSummaryRow>Arguments passed to the onActivePositionChange handler of TreeDataGrid: the active row can be a group row.
/** The arguments of `TreeDataGrid`'s `onActivePositionChange`, whose row can be a `GroupRow` */
type TreePositionChangeArgs<TRow, TSummaryRow = unknown> = PositionChangeArgs<
TRow,
TSummaryRow,
TRow | GroupRow<TRow>
>;
See also: onActivePositionChange prop on <TreeDataGrid />, PositionChangeArgs, isGroupRow
ColSpanArgs<TRow, TSummaryRow>Arguments passed to the colSpan function.
type ColSpanArgs<TRow, TSummaryRow> =
| { readonly type: 'HEADER' }
| { readonly type: 'ROW'; readonly row: TRow }
| { readonly type: 'SUMMARY'; readonly row: TSummaryRow };
Example:
import type { Column } from 'react-data-grid';
const columns: readonly Column<Row>[] = [
{
key: 'title',
name: 'Title',
colSpan(args) {
if (args.type === 'ROW' && args.row.isFullWidth) {
return 3; // Span 3 columns
}
return undefined;
}
}
];
See also: column.colSpan
RowHeightArgs<TRow>Arguments passed to TreeDataGrid's rowHeight prop when it is a function.
type RowHeightArgs<TRow> = { type: 'ROW'; row: TRow } | { type: 'GROUP'; row: GroupRow<TRow> };
Example:
function getRowHeight(args: RowHeightArgs<Row>): number {
if (args.type === 'GROUP') {
return 40;
}
return args.row.isLarge ? 60 : 35;
}
<TreeDataGrid rowHeight={getRowHeight} ... />
See also: rowHeight prop on <TreeDataGrid />, GroupRow
SortColumnDescribes a sorted column.
interface SortColumn {
readonly columnKey: string;
readonly direction: SortDirection;
}
See also: sortColumns and onSortColumnsChange props on <DataGrid />
SortDirectiontype SortDirection = 'ASC' | 'DESC';
See also: SortColumn
RowsChangeData<TRow, TSummaryRow>Data provided to the onRowsChange callback.
interface RowsChangeData<R, SR = unknown> {
/** Indexes of the rows that changed */
indexes: number[];
/** The column of the cells that changed */
column: CalculatedColumn<R, SR>;
}
See also: onRowsChange prop on <DataGrid />
SelectRowEvent<TRow>Event object for row selection changes.
interface SelectRowEvent<TRow> {
row: TRow;
checked: boolean;
isShiftClick: boolean;
}
See also: useRowSelection hook
SelectHeaderRowEventEvent object for header row selection changes.
interface SelectHeaderRowEvent {
checked: boolean;
}
See also: useHeaderRowSelection hook
FillEvent<TRow>Event object for drag-fill operations.
interface FillEvent<TRow> {
columnKey: string;
sourceRow: TRow;
targetRow: TRow;
}
See also: onFill prop on <DataGrid />
DataGridHandleHandle type assigned to a grid's ref for programmatic grid control.
interface DataGridHandle {
element: HTMLDivElement | null;
scrollToCell: (position: PartialPosition) => void;
setActivePosition: (position: Position, options?: SetActivePositionOptions) => void;
}
Example:
import { useRef } from 'react';
import { DataGrid, type DataGridHandle } from 'react-data-grid';
function MyGrid() {
const gridRef = useRef<DataGridHandle>(null);
function scrollToTop() {
gridRef.current?.scrollToCell({ rowIdx: 0 });
}
return <DataGrid ref={gridRef} columns={columns} rows={rows} />;
}
See also: ref prop on <DataGrid />
Position (internal)Represents a cell position in the grid. This helper type is not exported; the shape is shown for reference.
interface Position {
/** Column index, or `-1` for the whole row in `TreeDataGrid` */
readonly idx: number;
/** Row index: `0` is the first row, header rows and top summary rows have negative indexes, and bottom summary rows come after the last row */
readonly rowIdx: number;
}
See also: DataGridHandle, CellKeyDownArgs
PartialPosition (internal)Position for scrolling to a cell. Both fields are optional: omit idx to scroll to a row, or omit rowIdx to scroll to a column. This helper type is not exported; the shape is shown for reference.
interface PartialPosition {
readonly idx?: Maybe<number>;
readonly rowIdx?: Maybe<number>;
}
See also: DataGridHandle
SetActivePositionOptionsOptions for programmatically updating the grid's active position.
interface SetActivePositionOptions {
enableEditor?: Maybe<boolean>;
shouldFocus?: Maybe<boolean>;
}
See also: DataGridHandle, CellKeyDownArgs
ColumnWidthsA map of column widths.
type ColumnWidths = ReadonlyMap<string, ColumnWidth>;
See also: columnWidths and onColumnWidthsChange props on <DataGrid />
ColumnWidthRepresents a single column's width.
interface ColumnWidth {
/** `'resized'` if the user resized the column, or `'measured'` if the grid measured it */
readonly type: 'resized' | 'measured';
/** The width in pixels */
readonly width: number;
}
See also: ColumnWidths
DirectionText direction of the grid.
type Direction = 'ltr' | 'rtl';
See also: direction prop on <DataGrid />
Maybe<T> (internal)Utility type for optional values. This helper type is not exported; the shape is shown for reference.
type Maybe<T> = T | undefined | null;
R, TRow: Row typeSR, TSummaryRow: Summary row typeK: Row key type