Data Grid
A full-featured data grid with sorting, selection, column resizing, pinned columns, drag-and-drop row reorder, virtualization, and async loading — built on the Namespace UIKit Table.
Usage
| Customer | Transaction ID | Status | Amount | Fee | Net | Payment Method | Region | Description | Date | ||
|---|---|---|---|---|---|---|---|---|---|---|---|
Emma Wilsonemma@example.com | pay_1N3xDR | succeeded | $2,450.00 | $73.50 | $2,376.50 | Visa •••• 4242 | North America | Annual subscription — Enterprise plan | Dec 7, 2025 | ||
Isabella Nguyenisabella@example.com | pay_1N3x9M | succeeded | $299.00 | $8.97 | $290.03 | Visa •••• 1234 | Asia Pacific | Quarterly subscription — Team plan | Dec 3, 2025 | ||
Jackson Leejackson@example.com | pay_1N3x8L | processing | $39.00 | $1.43 | $37.57 | Mastercard •••• 5555 | North America | Monthly add-on — Extra seats | Dec 2, 2025 | ||
Liam Johnsonliam@example.com | pay_1N3xCQ | refunded | $150.00 | $4.50 | $145.50 | Mastercard •••• 6789 | Europe | Monthly subscription — Pro plan | Dec 6, 2025 | ||
Olivia Martinolivia@example.com | pay_1N3x7K | succeeded | $1,999.00 | $59.97 | $1,939.03 | Visa •••• 4242 | North America | Annual subscription — Pro plan | Dec 1, 2025 | ||
Sofia Davissofia@example.com | pay_1N3xBP | succeeded | $450.00 | $13.50 | $436.50 | Visa •••• 9012 | Europe | One-time purchase — Enterprise setup | Dec 5, 2025 | ||
William Kimwill@example.com | pay_1N3xAN | failed | $99.00 | $3.17 | $95.83 | Amex •••• 3782 | Asia Pacific | Monthly subscription — Starter plan | Dec 4, 2025 |
"use client";
import type { Selection } from "react-aria-components";
import { useState } from "react";The DataGrid component takes a flat data array, a columns definition, and a getRowId function. It renders a fully accessible table with built-in support for sorting, selection, column resizing, and more.
Anatomy
Import the DataGrid component — it is not a compound component and has no DataGrid.* sub-parts.
import { DataGrid } from "@thenamespace/uikit";
<DataGrid />;Column Definitions
Columns are defined as an array of DataGridColumn<T> objects. Each column has an id, a header, and either an accessorKey (to read a value from the row object) or a custom cell renderer.
import type { DataGridColumn } from "@thenamespace/uikit";
interface Payment {
id: string;
customer: string;
amount: number;
status: "succeeded" | "failed";
}
const columns: DataGridColumn<Payment>[] = [
{
id: "customer",
header: "Customer",
accessorKey: "customer",
isRowHeader: true,
allowsSorting: true,
},
{
id: "amount",
header: "Amount",
accessorKey: "amount",
align: "end",
cell: (item) => `$${item.amount.toFixed(2)}`,
},
{
id: "status",
header: "Status",
accessorKey: "status",
},
];Custom Cell Rendering
The cell function receives the full row item and column definition. Return any ReactNode:
{
id: "status",
header: "Status",
cell: (item) => (
<Chip color={item.status === "succeeded" ? "success" : "danger"} size="sm" variant="soft">
{item.status}
</Chip>
),
}
Custom Header Rendering
The header property accepts a string, a ReactNode, or a render function that receives { sortDirection } for sortable columns:
{
id: "amount",
header: ({ sortDirection }) => (
<span>Amount {sortDirection === "ascending" ? "↑" : sortDirection === "descending" ? "↓" : ""}</span>
),
allowsSorting: true,
}
Row Selection
Enable row selection with selectionMode and showSelectionCheckboxes. Supports both "single" and "multiple" modes with controlled or uncontrolled state.
const [selectedKeys, setSelectedKeys] = useState<Selection>(new Set());
<DataGrid
aria-label="Users"
columns={columns}
data={users}
getRowId={(item) => item.id}
selectionMode="multiple"
showSelectionCheckboxes
selectedKeys={selectedKeys}
onSelectionChange={setSelectedKeys}
/>;Sorting
Mark columns as sortable with allowsSorting: true. In uncontrolled mode, the DataGrid sorts data client-side using locale-aware string comparison (or a custom sortFn). For server-side sorting, pass a controlled sortDescriptor and handle onSortChange.
Uncontrolled (client-side)
<DataGrid
aria-label="Payments"
columns={columns}
data={payments}
getRowId={(item) => item.id}
defaultSortDescriptor={{ column: "customer", direction: "ascending" }}
/>Controlled (server-side)
const [sortDescriptor, setSortDescriptor] = useState<SortDescriptor>({
column: "date",
direction: "descending",
});
<DataGrid
aria-label="Payments"
columns={columns}
data={payments}
getRowId={(item) => item.id}
sortDescriptor={sortDescriptor}
onSortChange={setSortDescriptor}
/>;Custom Sort Function
Provide a sortFn on a column for custom comparison logic:
{
id: "priority",
header: "Priority",
allowsSorting: true,
sortFn: (a, b) => priorityOrder[a.priority] - priorityOrder[b.priority],
}
Column Resizing
Enable column resizing with allowsColumnResize on the DataGrid and allowsResizing on individual columns. Columns must have minWidth set.
<DataGrid
aria-label="Payments"
columns={columns}
data={payments}
getRowId={(item) => item.id}
allowsColumnResize
onColumnResize={(widths) => console.log("Resizing:", widths)}
onColumnResizeEnd={(widths) => console.log("Final widths:", widths)}
/>Pinned Columns
Pin columns to the start or end edge so they stay visible during horizontal scroll. Pinned columns must have a numeric width or minWidth.
const columns: DataGridColumn<Company>[] = [
{
id: "name",
header: "Company",
pinned: "start",
minWidth: 160,
// ...
},
// ... scrollable columns ...
{
id: "actions",
header: "",
pinned: "end",
width: 50,
cell: (item) => <RowActions id={item.id} />,
},
];Drag and Drop
Enable row reorder with the onReorder callback. The DataGrid provides built-in drag handles, keyboard support (Enter to grab, arrows to move, Enter to drop), and fires the callback with the reordered data array.
const [tasks, setTasks] = useState(initialTasks);
<DataGrid
aria-label="Backlog"
columns={columns}
data={tasks}
getRowId={(item) => item.id}
onReorder={(event) => setTasks(event.reorderedData)}
/>;For advanced drag-and-drop scenarios (cross-list, custom drag items), pass dragAndDropHooks directly from RAC's useDragAndDrop.
Expandable Rows
| Name | Type | Size | Date Modified |
|---|---|---|---|
| Documents | Folder | 3 items | Oct 20, 2025 |
| Project Alpha | Folder | 2 items | Aug 2, 2025 |
| Meeting Notes.md | Text | 12 KB | Sep 14, 2025 |
| Photos | Folder | 2 items | Feb 3, 2026 |
| readme.txt | Text | 4 KB | Mar 1, 2026 |
"use client";
import type { Selection } from "react-aria-components";
import { useState } from "react";Render hierarchical data by providing a getChildren function. The DataGrid recursively renders child rows, auto-generates a chevron toggle in the treeColumn, and indents each nested level by treeIndent pixels.
interface FileRow {
id: string;
name: string;
type: "Folder" | "File";
children?: FileRow[];
}
const [expandedKeys, setExpandedKeys] = useState<Selection>(new Set(["1"]));
<DataGrid
aria-label="Files"
columns={columns}
data={files}
getRowId={(item) => item.id}
getChildren={(item) => item.children}
treeColumn="name"
expandedKeys={expandedKeys}
onExpandedChange={setExpandedKeys}
/>;The treeColumn prop specifies which column displays the chevron. If omitted, it defaults to the first isRowHeader column (or the first column). Use defaultExpandedKeys for uncontrolled expansion, or pair expandedKeys with onExpandedChange for controlled behavior. Set treeIndent={0} to disable automatic per-level indentation.
Expandable rows compose with selection, drag-and-drop, sorting, pinned columns, and column resizing.
Editable Cells
Feature Flags
Edit titles, change priorities, adjust story points, and toggle features inline.
| Feature | Priority | Story Points | Enabled |
|---|---|---|---|
Dark mode | |||
CSV export | |||
Keyboard shortcuts | |||
Two-factor auth | |||
Bulk import | |||
Audit log | |||
Webhooks | |||
Custom branding |
"use client";
import { useState } from "react";
import {Use the cell render function to embed any interactive component — text fields, selects, switches, number steppers, etc.
Empty State
Projects
| Project | Owner | Files | Last Updated |
|---|---|---|---|
No Projects YetGet started by creating your first project. You can always import existing projects later. | |||
"use client";
import {
Add01Icon,
FolderOpenIcon,Provide a renderEmptyState function to display a custom empty state when data is empty.
<DataGrid
aria-label="Projects"
columns={columns}
data={[]}
getRowId={(item) => item.id}
renderEmptyState={() => (
<EmptyState size="sm">
<EmptyState.Header>
<EmptyState.Media variant="icon">
<FolderOpen />
</EmptyState.Media>
<EmptyState.Title>No Projects Yet</EmptyState.Title>
<EmptyState.Description>
Get started by creating your first project.
</EmptyState.Description>
</EmptyState.Header>
</EmptyState>
)}
/>Async Loading
Invoices
8 / 50| Invoice | Client | Amount | Status | Issued |
|---|---|---|---|---|
| INV-1000 | Cyberdyne Systems | $9,748 | overdue | Jan 6, 2025 |
| INV-1001 | Soylent Corp | $2,012 | paid | Feb 23, 2025 |
| INV-1002 | LexCorp | $9,675 | paid | Mar 1, 2025 |
| INV-1003 | Pied Piper | $8,000 | pending | Apr 7, 2025 |
| INV-1004 | Massive Dynamic | $6,901 | paid | May 18, 2025 |
| INV-1005 | Umbrella LLC | $6,263 | overdue | Jun 20, 2025 |
| INV-1006 | Umbrella LLC | $389 | overdue | Jul 1, 2025 |
| INV-1007 | Umbrella LLC | $3,059 | paid | Aug 8, 2025 |
"use client";
import { useState } from "react";
import { DataGrid, type DataGridColumn } from "@thenamespace/uikit";Use onLoadMore, isLoadingMore, and loadMoreContent to implement infinite scroll loading. The DataGrid renders a sentinel row that triggers onLoadMore when it scrolls into view.
<DataGrid
aria-label="Invoices"
columns={columns}
data={items}
getRowId={(item) => item.id}
scrollContainerClassName="max-h-[400px] overflow-y-auto"
onLoadMore={hasMore ? handleLoadMore : undefined}
isLoadingMore={isLoading}
loadMoreContent={<Spinner size="md" />}
/>Virtualization
Enable row virtualization for large datasets (1,000+ rows) with the virtualized prop. Only visible rows are rendered to the DOM. You must set rowHeight and headingHeight.
<DataGrid
virtualized
aria-label="Product inventory"
columns={columns}
data={products}
getRowId={(item) => item.id}
contentClassName="h-[400px] min-w-[900px] overflow-auto"
rowHeight={58}
headingHeight={37}
/>Bulk Actions
| Employee | Department | Status | Joined | |
|---|---|---|---|---|
AO Amara Okaforamara.okafor@company.com | Support | Pending | Jun 27, 2024 | |
ER Elena Rodriguezelena.rodriguez@company.com | HR | Active | Jan 28, 2024 | |
JO James O'Brienjames.o.brien@company.com | Finance | Active | Apr 14, 2024 | |
LB Luca Bianchiluca.bianchi@company.com | Engineering | Active | Jul 25, 2024 | |
MC Marcus Chenmarcus.chen@company.com | Design | Pending | Feb 3, 2024 | |
PP Priya Patelpriya.patel@company.com | HR | Active | Mar 4, 2024 | |
YT Yuki Tanakayuki.tanaka@company.com | Product | Inactive | May 8, 2024 |
// @ts-nocheck -- Complex demo data intentionally uses heterogeneous shapes.
"use client";
import type { Selection } from "react-aria-components";
Combine row selection with an ActionBar to provide bulk operations like export, archive, or delete.
Users
A minimal user directory using the "secondary" variant with accessorKey-only columns and a row action link — no selection, no sorting.
Team Members
A full-featured HR table with controlled sorting, multi-selection, pinned columns, column resizing, column visibility toggling, search, filters, and client-side pagination.
Servers
A server monitoring dashboard with controlled sorting, selection, column visibility toggling, search, status filtering, and rich cell renderers including sparkline charts and circular progress indicators.
Complex
Team Members
100| Worker ID | External Worker ID | Member | Country | Role | Worker Type | Status | Start Date | Teams | ||
|---|---|---|---|---|---|---|---|---|---|---|
| WRK-7293027 | EXT-O65TY0GW | AC Aaron Carteraaron.carter@example.com | Software Engineer | Contractor | Inactive | September 16, 2025 | Product | |||
| WRK-9145881 | EXT-IJWM67YO | AJ Alice Johnsonalice.johnson@example.com | Network Administrator | Contractor | Active | May 6, 2025 | ProductEngineeringDesign+1 | |||
| WRK-4113931 | EXT-VWXGQ2YR | AJ Alice Johnsonalice.johnson@example.com | Technical Support Specialist | Employee | Active | July 13, 2025 | ProductEngineeringDesign+2 | |||
| WRK-2903436 | EXT-GB2GA8CY | AJ Alice Johnsonalice.johnson@example.com | Operations Coordinator | Contractor | Vacation | April 14, 2025 | ProductEngineeringDesign | |||
| WRK-9738309 | EXT-62IGY3A9 | AJ Alice Johnsonalice.johnson@example.com | Accountant | Employee | Vacation | January 15, 2025 | Product | |||
| WRK-9876926 | EXT-CCSPUX9O | AJ Alice Johnsonalice.johnson@example.com | Graphic Designer | Contractor | Inactive | April 11, 2026 | ProductEngineeringDesign+1 | |||
| WRK-8979921 | EXT-TRXKAG0G | BB Bella Brownbella.brown@example.com | Technical Support Specialist | Employee | Active | April 24, 2026 | ProductEngineering | |||
| WRK-8443933 | EXT-B3M1WFOO | BB Bella Brownbella.brown@example.com | QA Tester | Contractor | Active | June 18, 2025 | ProductEngineeringDesign+1 | |||
| WRK-2672673 | EXT-9H1WJGWE | BB Bella Brownbella.brown@example.com | Operations Coordinator | Contractor | Vacation | January 6, 2026 | ProductEngineeringDesign+2 | |||
| WRK-4313540 | EXT-45G6B6NL | BS Bob Smithbob.smith@example.com | Environmental Scientist | Contractor | Vacation | February 10, 2025 | OtherManagementSupport |
// @ts-nocheck -- Complex demo data intentionally uses heterogeneous shapes.
"use client";
import type { Selection, SortDescriptor } from "react-aria-components";
Drag And Drop Reorder
Drag rows to reorder. Use keyboard (Enter to grab, arrows to move, Enter to drop).
| Task | Priority | Assignee | Status | |
|---|---|---|---|---|
| Design system audit | high | Olivia | In Progress | |
| API rate limiting | high | Jackson | To Do | |
| Onboarding flow redesign | medium | Isabella | In Progress | |
| Database migration script | high | William | To Do | |
| Unit test coverage report | low | Sofia | Done | |
| Performance profiling | medium | Liam | To Do | |
| Accessibility audit | medium | Emma | In Progress | |
| CI pipeline optimization | low | Noah | Done |
"use client";
import { useState } from "react";
import { DataGrid, type DataGridColumn } from "@thenamespace/uikit";Pinned Columns Compact
Companies
| Company | Categories | Last interaction | Connection strength | Twitter followers | |||
|---|---|---|---|---|---|---|---|
| LVMH | B2CConsumer Dis…E-commerce | lvmh | No contact | No communication | 198,135 | LVMH | |
| Disney | B2CE-commerce | disneymusicgroup | No contact | No communication | 10,140,332 | Disney | |
| PayPal | B2CFinanceFinancial Se…+1 | paypal | No contact | No communication | 969,425 | PayPal | |
| United Airlines | AirlinesB2CE-commerce+1 | united-airlines | No contact | No communication | 1,174,209 | united | |
| Apple | B2CConsumer Ele…E-commerce | apple | No contact | No communication | 9,119,742 | Apple | |
| Microsoft | B2BEnterpriseInformation …+1 | microsoft | No contact | No communication | 12,814,907 | Microsoft | |
| Airbnb | B2CInternetMarketplace | airbnb | No contact | No communication | 883,549 | Airbnb | |
| sweetgreen | B2CE-commerceFood+1 | sweetgreen | about 2 hours ago | Very strong | 3,200 | sweetgreen | |
| OpenPhone | B2BB2CSaaS+2 | openphone | 2 days ago | Weak | 8,400 | OpenPhone | |
| Intercom | B2BB2CE-commerce+1 | intercom | No contact | No communication | 42,427 | intercom | |
| Attio | AutomationB2BEnterprise+1 | attio | about 3 hours ago | Very weak | 1,340 | attio | |
| Opera | B2BB2CInformation …+2 | opera-software | 14 days ago | Very weak | 63,000 | opera | |
| B2BB2CBroadcasting+1 | 9 days ago | Weak | 28,946,065 |
"use client";
import type { Selection } from "react-aria-components";
import { useMemo, useState } from "react";Simple
Users
A list of all the users in your account including their name, title, email and role.
| Name | Title | Role | ||
|---|---|---|---|---|
| Lindsay Walton | Front-end Developer | lindsay.walton@example.com | Member | Edit |
| Courtney Henry | Designer | courtney.henry@example.com | Admin | Edit |
| Tom Cook | Director of Product | tom.cook@example.com | Member | Edit |
| Whitney Francis | Copywriter | whitney.francis@example.com | Admin | Edit |
| Leonard Krasner | Senior Designer | leonard.krasner@example.com | Owner | Edit |
| Floyd Miles | Principal Designer | floyd.miles@example.com | Member | Edit |
"use client";
import { DataGrid, type DataGridColumn } from "@thenamespace/uikit";
import { Button } from "@thenamespace/uikit/button";
import { Link } from "@thenamespace/uikit/link";Virtualized
// @ts-nocheck -- Complex demo data intentionally uses heterogeneous shapes.
"use client";
import type { Selection } from "react-aria-components";
With Charts
Servers
8| Cluster ID | Instances | Status | Region | Capacity | Cost | Requests | |
|---|---|---|---|---|---|---|---|
#4586930 | 25 | Active | US-West 1 | 20.01% | $830.04 | ||
#4586931 | 13 | Active | US-East 2 | 7.36% | $752.72 | ||
#4586932 | 27 | Inactive | EU-Central 1 | 48.25% | $517.60 | ||
#4586933 | 28 | Inactive | AP-South 1 | 21.15% | $544.93 | ||
#4586934 | 6 | Active | US-West 2 | 73.12% | $412.71 | ||
#4586935 | 19 | Active | EU-West 1 | 72.65% | $354.06 | ||
#4586936 | 27 | Active | CA-Central 1 | 15.19% | $775.45 | ||
#4586937 | 27 | Active | AP-Northeast 1 | 11.35% | $146.05 |
// @ts-nocheck -- Complex demo data intentionally uses heterogeneous shapes.
"use client";
import type { Selection, SortDescriptor } from "react-aria-components";
CSS Classes
Base Classes
.data-grid— Root wrapper. Setsposition: relativeandwidth: 100%. Defines--data-grid-selection-column-widthand--data-grid-drag-handle-column-widthcustom properties.
Element Classes
.data-grid__selection-column— Narrow<th>for the select-all checkbox. Fixed width from--data-grid-selection-column-width..data-grid__selection-cell— Narrow<td>for row selection checkboxes. Same fixed width..data-grid__drag-handle-column— Narrow<th>for the drag handle column. Fixed width from--data-grid-drag-handle-column-width..data-grid__drag-handle-cell— Narrow<td>for the drag handle. Same fixed width..data-grid__drag-handle— The grip button inside each row. Styled withcursor: graband subtle color..data-grid__sort-icon— Chevron indicator next to sortable column headers. Rotates 180° when descending..data-grid__empty-state— Centered container for the empty state message. Muted text, vertical padding..data-grid__tree-cell— Flex wrapper inside thetreeColumncell that holds the chevron toggle and cell content. Per-level indentation is applied inline viapadding-inline-start..data-grid__tree-toggle— Expand/collapse chevron button, rendered when a row has children. Sized via--data-grid-tree-toggle-size..data-grid__tree-toggle-icon— Chevron icon inside the toggle. Rotates 90° when the row is expanded via[data-expanded]..data-grid__tree-toggle-spacer— Invisible placeholder rendered for leaf rows so their content aligns with sibling rows that have a chevron.
Interactive States
- Drag handle hover:
&:hover/[data-hovered="true"]on.data-grid__drag-handle— text transitions toforeground. - Drag handle pressed:
&:active/[data-pressed="true"]on.data-grid__drag-handle— cursor changes tograbbing. - Drag handle focus:
[data-focus-visible="true"]on.data-grid__drag-handle— applies focus ring viastatus-focused. - Row dragging:
.table__row[data-dragging="true"]— reduced opacity (0.5). - Drop indicator:
.react-aria-DropIndicator[data-drop-target] td— accent background line.
Alignment
[data-align="end"]— Right-aligns both header and cell content.[data-align="center"]— Center-aligns both header and cell content.
Vertical Alignment
Controlled by the verticalAlign prop via [data-vertical-align] on the root:
[data-vertical-align="top"]—vertical-align: top(flexboxitems-startin virtualized mode).[data-vertical-align="middle"]—vertical-align: middle(flexboxitems-centerin virtualized mode).[data-vertical-align="bottom"]—vertical-align: bottom(flexboxitems-endin virtualized mode).
Pinned Columns
[data-pinned]— Makes the cellposition: stickywithz-index: 2.[data-pinned="start"]— Sticky toinset-inline-start.[data-pinned="end"]— Sticky toinset-inline-end.[data-pinned-edge]— Boundary column that shows a separator line when the pinned group detaches from the scrollable content.[data-pinned-start-detached]— Set on root when content has scrolled past the start-pinned columns. Shows separator via::after.[data-pinned-end-detached]— Set on root when content hasn't scrolled to the end edge. Shows separator via::after.
CSS Variables
--data-grid-selection-column-width— Width of the selection checkbox column (default:40px).--data-grid-drag-handle-column-width— Width of the drag handle column (default:32px).--data-grid-tree-toggle-size— Size of the expand/collapse chevron button and its leaf-row spacer (default:24px).--data-grid-tree-gap— Gap between the chevron/spacer and the cell content in atreeColumncell (default:4px).
API Reference
DataGrid
The root data grid component. Accepts a generic type parameter T for the row data shape.
| Prop | Type | Default | Description |
|---|---|---|---|
data | T[] | — | Row data array. |
columns | DataGridColumn<T>[] | — | Column definitions. |
getRowId | (item: T) => string | number | — | Extracts a unique key from each row item. |
aria-label | string | — | Accessible label for the table. Required. |
variant | "primary" | "secondary" | "primary" | Visual variant passed to the underlying Table. |
className | string | — | Additional className for the root wrapper. |
contentClassName | string | — | Additional className for the inner <table> element (e.g. min-w-[1200px] for horizontal scroll). |
scrollContainerClassName | string | — | Additional className for the scroll container (e.g. max-h-[400px] overflow-y-auto). |
verticalAlign | "top" | "middle" | "bottom" | "middle" | Vertical alignment of cell content within each row. |
selectionMode | "none" | "single" | "multiple" | "none" | Row selection mode. |
selectedKeys | Selection | — | Controlled selected row keys. |
defaultSelectedKeys | Selection | — | Default selected row keys (uncontrolled). |
onSelectionChange | (keys: Selection) => void | — | Callback when selection changes. |
selectionBehavior | "toggle" | "replace" | "toggle" | Selection interaction model. |
showSelectionCheckboxes | boolean | false | Auto-prepend a checkbox column for selection. |
sortDescriptor | SortDescriptor | — | Controlled sort descriptor. When provided, sorting is controlled externally. |
defaultSortDescriptor | SortDescriptor | — | Default sort descriptor (uncontrolled). |
onSortChange | (descriptor: SortDescriptor) => void | — | Callback when sort changes. Fires in both controlled and uncontrolled modes. |
allowsColumnResize | boolean | false | Enable column resizing on columns that opt in. |
onColumnResize | (widths: Map<string | number, ColumnSize>) => void | — | Callback during column resize. |
onColumnResizeEnd | (widths: Map<string | number, ColumnSize>) => void | — | Callback when resize ends. |
onReorder | (event: DataGridReorderEvent<T>) => void | — | Convenience callback for row reorder. Enables built-in drag-and-drop. Mutually exclusive with dragAndDropHooks. |
dragAndDropHooks | DragAndDropHooks | — | Advanced RAC drag-and-drop hooks for custom DnD scenarios. Overrides onReorder. |
onRowAction | (key: string | number) => void | — | Callback when a row is actioned (e.g. double-click or Enter). |
renderEmptyState | () => ReactNode | — | Render function for the empty state when data is empty. |
onLoadMore | () => void | — | Callback when the load-more sentinel scrolls into view. |
isLoadingMore | boolean | false | Whether more data is currently being fetched. |
loadMoreContent | ReactNode | — | Content to show inside the load-more sentinel row (e.g. a Spinner). |
disabledKeys | Iterable<string | number> | — | Keys of rows that should be disabled. |
virtualized | boolean | false | Enable row virtualization for large datasets. Requires rowHeight and headingHeight. |
rowHeight | number | 42 | Fixed row height in pixels. Required when virtualized is true. |
headingHeight | number | 36 | Header row height in pixels. Required when virtualized is true. |
getChildren | (item: T) => T[] | undefined | — | Return child rows for a given item. Providing this enables expandable/tree rows. |
treeColumn | string | — | Column id that displays the expand/collapse chevron. Defaults to the first isRowHeader column, or the first column. |
expandedKeys | Selection | — | Controlled set of expanded row keys. |
defaultExpandedKeys | Selection | — | Default expanded row keys (uncontrolled). |
onExpandedChange | (keys: Selection) => void | — | Callback when expanded rows change. |
treeIndent | number | 20 | Pixels of inline-start padding added per nested level on the treeColumn cell. Set to 0 to disable. |
DataGridColumn<T>
Column definition object passed to the columns prop.
| Property | Type | Default | Description |
|---|---|---|---|
id | string | — | Unique column identifier. Used as the sort key and RAC column id. Required. |
header | ReactNode | ((info: { sortDirection?: SortDirection }) => ReactNode) | — | Column header content. String, node, or render function receiving sort info. |
accessorKey | keyof T & string | — | Key on T to read the cell value from. Used for default rendering and sorting. |
cell | (item: T, column: DataGridColumn<T>) => ReactNode | — | Custom cell renderer. Receives the row item and column definition. |
isRowHeader | boolean | false | Mark this column as the row header (for accessibility). |
allowsSorting | boolean | false | Allow this column to be sorted. |
sortFn | (a: T, b: T) => number | — | Custom sort comparator. Falls back to locale-aware string comparison. |
allowsResizing | boolean | — | Allow this column to be resized. Only effective when allowsColumnResize is true on the DataGrid. |
width | ColumnSize | — | Initial/controlled column width (px, %, or fr). |
minWidth | number | — | Minimum column width when resizing. |
maxWidth | number | — | Maximum column width when resizing. |
align | "start" | "center" | "end" | "start" | Cell text alignment. |
headerClassName | string | — | Additional className appended to every <th> for this column. |
cellClassName | string | — | Additional className appended to every <td> for this column. |
pinned | "start" | "end" | — | Pin this column so it stays visible during horizontal scroll. Uses logical directions (start = left in LTR). Pinned columns must have a numeric width or minWidth. |
DataGridReorderEvent<T>
Event object passed to the onReorder callback.
| Property | Type | Description |
|---|---|---|
keys | Set<string | number> | The keys that were moved. |
target | { key: string | number; dropPosition: "before" | "after" } | The target row key and drop position. |
reorderedData | T[] | The full reordered data array after applying the move. |
Type Exports
The following types are re-exported from the DataGrid module for convenience:
| Type | Origin | Description |
|---|---|---|
DataGridSelection | react-aria-components Selection | Represents a set of selected keys, or "all". |
DataGridSortDescriptor | react-aria-components SortDescriptor | Describes the current sort column and direction. |
DataGridSortDirection | react-aria-components SortDirection | "ascending" | "descending". |
DataGridColumnSize | — | A number, a numeric string, a percentage string, or a fractional unit string. |