DataGridComponent
The grid component: columns, data, borders, resizing, reordering, and selection.
Last updated August 30, 2026
DataGridComponent takes a set of columns and a data source and renders a grid. Resizing, reordering, and selection are all opt-in — enable them per grid with resizableColumns, reorderableColumns, and selectable, or per column via each column's own resizable and reorderable fields.
Resizable, reorderable columns#
DataGridComponent
Live exampleimport { useState } from "react";
import { defineColumnsFromRows } from "@gridkitjs/core";
import {
DataGridComponent,
type ColumnDefinition,
type ResizeMode,
} from "@gridkitjs/react";
const columns: readonly ColumnDefinition<Row>[] = [
...defineColumnsFromRows(rows),
{
field: "Cost",
id: "Cost.currency",
type: "currency",
headerTemplate: <span className="italic">Cost</span>,
cellTemplate: ({ value, row }) => (
<span className={row.Cost > 500 ? "font-semibold text-red-600" : ""}>
{currency.format(Number(value))}
</span>
),
},
];
const [resizeMode, setResizeMode] = useState<ResizeMode>("fit");
<DataGridComponent
columns={columns}
dataSource={rows}
borders="all"
resizableColumns
reorderableColumns
resizeMode={resizeMode}
/>;Props#
| Prop | Type | Default | Description |
|---|---|---|---|
columns | readonly ColumnDefinition<Row>[] | Columns to render. Falls back to defineColumnsFromRows(dataSource) when omitted. See column definition for every field. | |
dataSource | readonly Row[] | The rows to render. | |
getRowId | (row: Row, index: number) => string | row position | A row's stable identity, for state keyed by it. Give one for data that sorts, filters, or pages. |
label | string | The grid's accessible name, announced when it takes focus — without one a screen reader announces only "grid". | |
labelledBy | string | The id of an element naming the grid, for a heading already on the page. Takes precedence over label. | |
height | number | string | Bounds the row area's height, independently scrollable — the grid's own chrome stays outside it and always visible. A number is pixels; a string is a CSS length (e.g. "60vh"). Omitted, the row area's height stays content-driven. | |
virtualized | boolean | false | Renders only the rows near the current scroll position rather than every row at once. Requires height. See row virtualization. |
overscan | number | 4 | Rows rendered outside the visible range on each side. Only meaningful with virtualized on. |
estimatedRowHeight | number | 40 | Assumed height for a row never yet measured. Only meaningful with virtualized on. |
borders | Borders ("horizontal" | "vertical" | "all" | "none") | Which cell borders to draw. | |
hoverable | HoverableConfig ({ rows?, columns?, cells? }) | all true | Which hover highlighting to enable — the opposite polarity of selectable, below: hover is on by default, so set a member to false to turn it off. |
resizableColumns | boolean | false | Whether columns can be dragged wider, unless a column says otherwise. |
reorderableColumns | boolean | false | Whether columns can be dragged into a new position. |
resizeMode | "fit" | "fixed" | "fit" | Whether columns fill the grid's width or sit at their own. |
defaultColumnSizing | ColumnSizingState | Column widths to start from, keyed by column id. Uncontrolled. | |
defaultColumnOrder | readonly string[] | Column ids in the order to start in. Uncontrolled. | |
columnSizeDefaults | Partial<ColumnSizeDefaults> | Sizes applied to columns that do not set their own. | |
onColumnResize | (event: ColumnResizeEvent) => void | Called as the user resizes a column: continuously with phase "move", once with "end". | |
onColumnOrderChange | (event: ColumnOrderEvent) => void | Called once when the user drops a column somewhere new. | |
sortableColumns | boolean | false | Whether columns can be sorted by clicking their header toggle, unless a column says otherwise. Shift-click stacks a column into the sort instead of replacing it. |
defaultColumnSort | readonly { columnId, direction }[] | The sort to start with, in priority order. Uncontrolled. | |
onColumnSortChange | (event: ColumnSortEvent) => void | Called once when the user changes the sort — a toggle, a stack, or a clear back to "none". | |
groupableColumns | boolean | false | Whether a column's header shows a click/Alt+ArrowDown group toggle. See row grouping. |
groupToggleIconColumns | boolean | true | Whether a groupable header shows its group-toggle icon. Purely a rendering choice. |
groupByDraggableColumns | boolean | false | Whether a column's header may be dragged into the group-by bar. |
groupByBarVisibility | "always" | "auto" | "never" | "auto" | How the group-by bar's visibility follows the active grouping. |
defaultGroupBy | GroupByState | The group-by stack to start with, outer to inner. Uncontrolled. | |
onGroupByChange | (event: GroupByEvent) => void | Called once when the user adds, removes, or reorders a group-by level. | |
defaultGroupExpansion | GroupExpansionState | Group ids collapsed to start with. Uncontrolled. | |
onGroupExpansionChange | (event: GroupExpansionEvent) => void | Called once when the user expands or collapses a group, or every group at once. | |
defaultFilter | FilterState<Row> | The filter to start with — every applied entry, ANDed together. Uncontrolled. See column filtering. | |
paginated | boolean | false | Whether the grid's rows are split into pages. See pagination. |
defaultPagination | PaginationState | { pageIndex: 0, pageSize: 25 } | The page and page size to start on, once paginated is on. Uncontrolled. |
pager | PagerConfig | Presentation options for the built-in pager. See pagination. | |
onPaginationChange | (event: PaginationChangeEvent) => void | Called once when the user changes the page or the page size. | |
aggregates | AggregateState<Row> | Aggregates to compute — a subtotal per group and a grand total. Controlled. See aggregate functions. | |
groupAggregateDisplay | "inline" | "row" | "inline" | Where a group's own subtotal renders. See aggregate functions. |
selectable | { rows?, columns?, cells? } | all off | Which parts of the grid the user may select, and how many of each. Off by default: selection claims the click. |
defaultRowSelection / defaultColumnSelection | SelectionState | Row / column ids selected to start with. Uncontrolled. | |
defaultCellSelection | CellSelectionState | The cell selected to start with. Uncontrolled. | |
ref | Ref<DataGridApi<Row>> | Imperative handle for reading live grid state and triggering focus/scroll/selection actions. See Imperative handle. |
Scrollable layout#
Set height to bound the row area to a fixed size, independently scrollable, while the group-by bar, header, footer, and pager stay outside it and always visible:
<DataGridComponent columns={columns} dataSource={rows} height={400} />Under the hood, the header, the rows, and (when aggregates is active) the grand-total footer each render as their own <table> — .gridkit-data-grid-header, .gridkit-data-grid-body (the one height applies to), and .gridkit-data-grid-footer — rather than sharing one. That's what keeps the header and footer out of the region that scrolls: they're never inside it to begin with, so there's nothing to pin in place with position: sticky. A consumer who wants a divider or shadow at the seam adds their own CSS targeting one of those classes directly, for example:
.gridkit-data-grid-header {
box-shadow: 0 1px 0 var(--gridkit-line);
}Keyboard & pointer interactions#
- Drag a header's trailing edge to resize; double-click it to size the column to its content.
- With the trailing edge focused, Alt+ArrowLeft / Alt+ArrowRight nudge the width; Escape cancels an in-progress resize.
- Drag a header to reorder columns.
- With a header focused, Ctrl+ArrowLeft / Ctrl+ArrowRight reorders it via keyboard; Escape cancels an in-progress drag.
- Click a row, column, or cell to select it; Ctrl+click toggles, Shift+click takes a range.
- Ctrl+A selects every row; Escape clears every selection.
- Click a groupable header's group icon, or focus the header and press Alt+ArrowDown, to add or remove it from the group-by stack — or drag the header into the group-by bar, for a column that sets
groupByDraggable. - Drag a chip in the group-by bar to reorder the stack; with a chip focused, Ctrl+ArrowLeft / Ctrl+ArrowRight moves it via keyboard.
- Click a group header, or focus it and press Space/Enter, to expand or collapse it.
See also#
- Column definition for the full
ColumnDefinition<Row>field reference. - Column resizing, reordering, sorting, and filtering, each in depth.
- Row, column, and cell selection, each on its own page.
- Row grouping for
groupableColumns/groupBy, in depth. - Pagination for
paginated/pagination, and how it composes with grouping. - Aggregate functions for
aggregatesandfooterTemplate, in depth. - Accessibility for the keyboard model, ARIA attributes, and live announcements.
- Events for every callback prop, firing live.
- Imperative handle for the
ref, in depth.