DataGrid
A virtualized alternative to Table that only renders the rows currently in view, for datasets too lg to mount all at once.
Overview
DataGrid is a real ARIA grid (role="grid"), like Table, built on
react-aria-components' Virtualizer instead of Table's own hooks — only the rows scrolled into
view are ever mounted, so a dataset with thousands of rows costs the same to render as one with a
dozen. That windowing is also why the underlying markup is <div>s carrying grid/row/gridcell
roles rather than a real <table>: native table layout can't support mounting and unmounting rows
as the user scrolls.
Composing it mirrors Table — DataGridHeader/DataGridColumn/DataGridBody/DataGridRow/
DataGridCell are read as data to build the grid's collection, not rendered as literal markup.
rowHeight is required: the virtualizer needs a height up front to compute scroll position and
total size without measuring every row first. Pass a fixed pixel number so every row renders at
that height, or "auto" (paired with estimatedRowHeight) to measure each row from its own
content — see Variable row height. Give the grid itself a bounded height
(directly, or via a className override) so its scroll viewport actually activates — a grid tall
enough to show every row scrolls nowhere.
import {
DataGrid,
DataGridHeader,
DataGridColumn,
DataGridBody,
DataGridRow,
DataGridCell
} from '@chassis-ui/react'
const rows = Array.from({ length: 200 }, (_, i) => ({
id: i,
name: `User ${i}`,
role: ['Engineer', 'Designer', 'Product'][i % 3]
}))
export const Example = () => (
<DataGrid aria-label="Users" rowHeight={40}>
<DataGridHeader>
<DataGridColumn isRowHeader>Name</DataGridColumn>
<DataGridColumn>Role</DataGridColumn>
</DataGridHeader>
<DataGridBody items={rows}>
{(row) => (
<DataGridRow id={row.id}>
<DataGridCell>{row.name}</DataGridCell>
<DataGridCell>{row.role}</DataGridCell>
</DataGridRow>
)}
</DataGridBody>
</DataGrid>
)Sorting
Add allowsSorting to a DataGridColumn to make it clickable (and keyboard-activatable) — the
same contract as Table. DataGrid doesn't sort the data itself; it reports the requested
column/direction via onSortChange, so pair it with sortDescriptor and sort the array in that
handler.
import { useMemo, useState } from 'react'
import type { SortDescriptor } from 'react-stately'
import {
DataGrid,
DataGridHeader,
DataGridColumn,
DataGridBody,
DataGridRow,
DataGridCell
} from '@chassis-ui/react'
const rows = [
{ id: 1, name: 'Mark Otto', role: 'Engineer' },
{ id: 2, name: 'Jacob Thornton', role: 'Designer' },
{ id: 3, name: 'Larry Bird', role: 'Engineer' },
{ id: 4, name: 'Ashley Grant', role: 'Product' }
]
export const Example = () => {
const [sortDescriptor, setSortDescriptor] = useState<SortDescriptor>({
column: 'name',
direction: 'ascending'
})
const sortedRows = useMemo(() => {
const key = sortDescriptor.column as keyof (typeof rows)[number]
const sorted = [...rows].sort((a, b) => (a[key] < b[key] ? -1 : a[key] > b[key] ? 1 : 0))
return sortDescriptor.direction === 'descending' ? sorted.reverse() : sorted
}, [sortDescriptor])
return (
<DataGrid
aria-label="Team"
onSortChange={setSortDescriptor}
rowHeight={40}
sortDescriptor={sortDescriptor}
>
<DataGridHeader>
<DataGridColumn allowsSorting id="name" isRowHeader>
Name
</DataGridColumn>
<DataGridColumn allowsSorting id="role">
Role
</DataGridColumn>
</DataGridHeader>
<DataGridBody items={sortedRows}>
{(row) => (
<DataGridRow id={row.id}>
<DataGridCell>{row.name}</DataGridCell>
<DataGridCell>{row.role}</DataGridCell>
</DataGridRow>
)}
</DataGridBody>
</DataGrid>
)
}Selection
Set selectionMode="multiple" or selectionMode="single" and control it with
selectedKeys/onSelectionChange, same as Table. Unlike Table, the selection checkboxes
themselves aren't automatic — place a DataGridSelectAllCell inside a DataGridColumn for the
header, and a DataGridSelectionCell inside a DataGridCell for each row. Neither takes a row
key: each reads the selection state react-aria-components already publishes for the row it's
rendered in. Both render a native checkbox wired to that state, styled the same as Table's, and
labelled by their row's row-header cells.
import { useState } from 'react'
import type { Selection } from 'react-stately'
import {
DataGrid,
DataGridHeader,
DataGridColumn,
DataGridBody,
DataGridRow,
DataGridCell,
DataGridSelectAllCell,
DataGridSelectionCell
} from '@chassis-ui/react'
const rows = [
{ id: 1, name: 'Mark Otto', role: 'Engineer' },
{ id: 2, name: 'Jacob Thornton', role: 'Designer' },
{ id: 3, name: 'Larry Bird', role: 'Engineer' }
]
export const Example = () => {
const [selectedKeys, setSelectedKeys] = useState<Selection>(new Set())
return (
<DataGrid
aria-label="Team"
onSelectionChange={setSelectedKeys}
rowHeight={40}
selectedKeys={selectedKeys}
selectionMode="multiple"
>
<DataGridHeader>
<DataGridColumn className="datagrid-selection-cell" defaultWidth={44} minWidth={44}>
<DataGridSelectAllCell />
</DataGridColumn>
<DataGridColumn isRowHeader>Name</DataGridColumn>
<DataGridColumn>Role</DataGridColumn>
</DataGridHeader>
<DataGridBody items={rows}>
{(row) => (
<DataGridRow id={row.id}>
<DataGridCell className="datagrid-selection-cell">
<DataGridSelectionCell />
</DataGridCell>
<DataGridCell>{row.name}</DataGridCell>
<DataGridCell>{row.role}</DataGridCell>
</DataGridRow>
)}
</DataGridBody>
</DataGrid>
)
}Column widths
Unlike Table, whose columns size themselves the way any native <table> does, DataGrid's
virtualized layout computes every column's width itself, splitting the grid evenly across columns
by default — a width/className rule on a cell has no effect here. Give a DataGridColumn
defaultWidth/minWidth/maxWidth to size it explicitly, e.g. a fixed pixel width for a narrow
selection/icon column (as in the Selection example above) or an '<n>fr' value to
weight it against the grid's other columns.
Variable row height
Pass rowHeight="auto" with a required estimatedRowHeight to size each row from its own rendered
content instead of a single fixed height shared by every row. estimatedRowHeight seeds the
virtualizer's scroll-position math before a row has been measured; a row's real height can end up
taller or shorter than that estimate once it renders, which can cause a visible scroll-jump for
rows the viewport hasn't reached yet. Prefer a fixed rowHeight unless rows genuinely vary — e.g.
wrapped text of unpredictable length, as below.
import {
DataGrid,
DataGridHeader,
DataGridColumn,
DataGridBody,
DataGridRow,
DataGridCell
} from '@chassis-ui/react'
const rows = [
{
id: 1,
name: 'Mark Otto',
bio: 'Co-founder, focused on design systems and component APIs.'
},
{
id: 2,
name: 'Jacob Thornton',
bio: 'Co-founder.'
},
{
id: 3,
name: 'Larry Bird',
bio: 'Handles onboarding docs and the getting-started guide — writes most of the long-form tutorial content, keeps the changelog current, and reviews every doc PR before it merges.'
}
]
export const Example = () => (
<DataGrid aria-label="Team" bordered estimatedRowHeight={48} rowHeight="auto">
<DataGridHeader>
<DataGridColumn defaultWidth={160} isRowHeader>
Name
</DataGridColumn>
<DataGridColumn>Bio</DataGridColumn>
</DataGridHeader>
<DataGridBody items={rows}>
{(row) => (
<DataGridRow id={row.id}>
<DataGridCell>{row.name}</DataGridCell>
<DataGridCell>{row.bio}</DataGridCell>
</DataGridRow>
)}
</DataGridBody>
</DataGrid>
)Pinned columns
Set pin="start" or pin="end" on a DataGridColumn to keep it visible while the grid scrolls
horizontally — start pins it to the leading edge, end to the trailing edge. Multiple pinned
columns on the same side stack in declaration order, so the first pin="start" column sits at the
very edge and each following one sits just past the previous. Pin columns at the true start or end
of the column list — a pinned column declared in the middle of the set isn't a supported
arrangement.
import {
DataGrid,
DataGridHeader,
DataGridColumn,
DataGridBody,
DataGridRow,
DataGridCell
} from '@chassis-ui/react'
const rows = [
{
id: 1,
name: 'Mark Otto',
bio: 'Co-founder, focused on design systems and component APIs.',
notes: 'Prefers async review over live meetings.',
location: 'Boston, MA',
role: 'Engineer',
status: 'Active'
},
{
id: 2,
name: 'Jacob Thornton',
bio: 'Co-founder, works across the build pipeline and tooling.',
notes: 'Owns the release process.',
location: 'San Francisco, CA',
role: 'Engineer',
status: 'Active'
},
{
id: 3,
name: 'Larry Bird',
bio: 'Handles onboarding docs and the getting-started guide.',
notes: 'Out most Fridays.',
location: 'Springfield, IL',
role: 'Writer',
status: 'Inactive'
}
]
export const Example = () => (
<DataGrid aria-label="Team" bordered rowHeight={44}>
<DataGridHeader>
<DataGridColumn defaultWidth={160} isRowHeader pin="start">
Name
</DataGridColumn>
<DataGridColumn defaultWidth={280}>Bio</DataGridColumn>
<DataGridColumn defaultWidth={220}>Notes</DataGridColumn>
<DataGridColumn defaultWidth={200}>Location</DataGridColumn>
<DataGridColumn defaultWidth={120}>Role</DataGridColumn>
<DataGridColumn defaultWidth={100} pin="end">
Status
</DataGridColumn>
</DataGridHeader>
<DataGridBody items={rows}>
{(row) => (
<DataGridRow id={row.id}>
<DataGridCell>{row.name}</DataGridCell>
<DataGridCell>{row.bio}</DataGridCell>
<DataGridCell>{row.notes}</DataGridCell>
<DataGridCell>{row.location}</DataGridCell>
<DataGridCell>{row.role}</DataGridCell>
<DataGridCell>{row.status}</DataGridCell>
</DataGridRow>
)}
</DataGridBody>
</DataGrid>
)Async loading
Pass onLoadMore to DataGridBody to fetch and append more rows as the grid scrolls near its last
one — useful for a dataset too lg to load up front. It's only available on the
items/render-function form of children, and the props are typed so that's enforced: the loading
row is generated by appending to items and rendering it through that same function, so there's
nothing for it to do alongside a hand-written list of DataGridRow elements. Pair it with isLoading (set while the fetch is in flight) and loadingContent
(the affordance shown in its place, e.g. a spinner) — onLoadMore isn't called again while
isLoading is true, so a fetch already running doesn't get triggered a second time before it
resolves. Stop passing onLoadMore once there's nothing left to load (e.g. the fetched page came
back short of a full page) to remove the loading row entirely.
import { useState } from 'react'
import {
DataGrid,
DataGridHeader,
DataGridColumn,
DataGridBody,
DataGridRow,
DataGridCell
} from '@chassis-ui/react'
interface Person {
id: number
name: string
role: string
}
const PAGE_SIZE = 20
const TOTAL = 200
const allPeople: Person[] = Array.from({ length: TOTAL }, (_, id) => ({
id,
name: `Person ${id}`,
role: ['Engineer', 'Designer', 'Manager'][id % 3]
}))
// Stands in for a real paginated API call — replace with an actual fetch of the next page.
const fetchPeoplePage = (page: number): Promise<Person[]> =>
new Promise((resolve) => {
setTimeout(() => resolve(allPeople.slice(page * PAGE_SIZE, (page + 1) * PAGE_SIZE)), 800)
})
export const Example = () => {
const [people, setPeople] = useState<Person[]>([])
const [page, setPage] = useState(0)
const [isLoading, setIsLoading] = useState(false)
const onLoadMore = () => {
setIsLoading(true)
fetchPeoplePage(page).then((nextPage) => {
setPeople((current) => [...current, ...nextPage])
setPage((current) => current + 1)
setIsLoading(false)
})
}
const hasMore = people.length < TOTAL
return (
<DataGrid aria-label="People" rowHeight={40}>
<DataGridHeader>
<DataGridColumn isRowHeader>Name</DataGridColumn>
<DataGridColumn>Role</DataGridColumn>
</DataGridHeader>
<DataGridBody
isLoading={isLoading}
items={people}
loadingContent="Loading more…"
onLoadMore={hasMore ? onLoadMore : undefined}
>
{(person) => (
<DataGridRow id={person.id}>
<DataGridCell>{person.name}</DataGridCell>
<DataGridCell>{person.role}</DataGridCell>
</DataGridRow>
)}
</DataGridBody>
</DataGrid>
)
}Header & footer pinning
The header row stays pinned to the top of the grid's scrollable area as body rows scroll
underneath it — no extra setup required. Pass footer for content pinned below the body, e.g. a
totals row or a "load more" control — like Table's footer prop, it renders as plain markup
outside the grid's own keyboard-navigable row/cell structure, and (unlike the header) it isn't part
of the scrollable region at all, so it never scrolls out of view along with the body rows.
import {
DataGrid,
DataGridHeader,
DataGridColumn,
DataGridBody,
DataGridRow,
DataGridCell
} from '@chassis-ui/react'
const rows = Array.from({ length: 200 }, (_, i) => ({
id: i,
name: `User ${i}`,
role: ['Engineer', 'Designer', 'Product'][i % 3]
}))
export const Example = () => (
<DataGrid aria-label="Users" bordered footer={`${rows.length} users total`} rowHeight={40}>
<DataGridHeader>
<DataGridColumn isRowHeader>Name</DataGridColumn>
<DataGridColumn>Role</DataGridColumn>
</DataGridHeader>
<DataGridBody items={rows}>
{(row) => (
<DataGridRow id={row.id}>
<DataGridCell>{row.name}</DataGridCell>
<DataGridCell>{row.role}</DataGridCell>
</DataGridRow>
)}
</DataGridBody>
</DataGrid>
)Keyboard navigation
Once a cell has focus, arrow keys move focus across the grid, the same as Table — no extra setup
required.
Variants
align, bordered, borderless, hover, sm, and color all apply to the grid's root
element, the same as Table's equivalent props. color also colors the footer, which is
outside that element.
import {
DataGrid,
DataGridHeader,
DataGridColumn,
DataGridBody,
DataGridRow,
DataGridCell
} from '@chassis-ui/react'
const rows = [
{ id: 1, name: 'Mark Otto', role: 'Engineer' },
{ id: 2, name: 'Jacob Thornton', role: 'Designer' },
{ id: 3, name: 'Larry Bird', role: 'Engineer' }
]
export const Example = () => (
<DataGrid aria-label="Team" bordered hover rowHeight={40} sm>
<DataGridHeader>
<DataGridColumn isRowHeader>Name</DataGridColumn>
<DataGridColumn>Role</DataGridColumn>
</DataGridHeader>
<DataGridBody items={rows}>
{(row) => (
<DataGridRow id={row.id}>
<DataGridCell>{row.name}</DataGridCell>
<DataGridCell>{row.role}</DataGridCell>
</DataGridRow>
)}
</DataGridBody>
</DataGrid>
)Scope
- Variable row height re-measures per row, not per column.
rowHeight="auto"(see Variable row height) sizes each row independently, but a column's width is still fixed up front — a cell's content wrapping to more lines only grows that one row, it doesn't reflow neighboring columns. - The header row stays a fixed height in
rowHeight="auto"mode, pinned toestimatedRowHeightrather than measured — only body rows are. A column header whose content needs more room than that visually overflows rather than growing the header. - The loader row's underlying
aria-levelattribute is invalid on arole="grid"row (it's only meaningful on atreegridrow). This comes fromreact-aria-components's ownTableLoadMoreItemimplementation, not from anythingDataGridadds — every other row's markup is unaffected. - No stacked variant.
Table'sstackedprop collapses rows into label/value blocks below a container width, using container queries to detect the switch — that check can't see how many rows the virtualizer has mounted, so a row's true height would no longer matchrowHeightonce stacked, breaking the scroll math. Tables with too many columns for a narrow viewport are better served byTable's ownstacked/responsiveprops, which don't have this constraint. - No zebra striping. CSS-only striping (
:nth-of-type) counts a row's position among currently-mounted siblings, not its logical position in the dataset — the pattern would visibly shift as the virtualizer's mounted window changes during scroll. - No interactive column resizing or reordering, no nested/expandable rows.
react-aria-componentssupports these onTable, but they're not wired up here — columns can still be given a fixed size up front (see Column widths), just not resized by the user at runtime. footerdoesn't pick up an instance-scoped color/border override. It renders outside the grid's own scrollable element (see Header & footer pinning), so it can't inherit CSS custom properties set directly on that specificDataGridinstance's own class — only a global--table-*token override reaches it. This matches every other DataGrid instance on the page, just not one re-themed individually. Thecolorprop is not such an override: the component gives the footer the same color classes as the grid.- Columns are already windowed horizontally — no extra work needed for wide grids. The
underlying
react-aria-components/react-statelylayout engine only mounts DOM for cells that intersect the horizontal viewport (the same visible-range mechanism that windows rows vertically), confirmed by rendering an 80-column grid and finding only 11columnheaderelements in the DOM regardless of total column count. Everything that has to find a specific column's cells in the DOM — pinned-column positioning, the scroll cues,fr-column measurement — therefore matches them on theiraria-colindex(which the layout engine sets from the column's position in the collection) rather than counting DOM children, whose number is the size of the mounted window. One caveat: the layout engine's own per-row cell-building pass isn't skipped for columns already scrolled past on the left (only columns past the right edge of the viewport are skipped) — the cost of computing a row's cell offsets scales with column count up to the visible window, not just the visible window's size. This is a layout-computation cost, not a DOM-rendering one, and only matters at very high column counts (100+). - No
idprop, unlikeTable.react-aria-components'Tabledoesn't accept one: it generates the grid's own id and derives every cell's and column header'sidfrom it (which is what the row/checkboxaria-labelledbywiring points at), so an overridden one would break those references. Usearia-labelledbyto point at a visible heading, oraria-label, rather than labelling via anidof your own.
API
DataGrid
| Prop | Type | Default |
|---|---|---|
align? | "bottom" | "middle" | "top" | — |
Set the vertical alignment of cell content. Mirrors Table's prop of the same name for API
parity — same as Table, this awaits chassis-css adding the matching .align-* styles. | ||
aria-label? | string | — |
| An accessible label for the grid, used when there's no visible heading. | ||
aria-labelledby? | string | — |
| Identifies a visible heading element for the grid. | ||
bordered? | boolean | — |
| Add borders on all sides of the grid and cells. | ||
borderless? | boolean | — |
| Remove borders on all sides of the grid and cells. | ||
children | [ReactElement<DataGridHeaderProps<T>, string | JSXElementConstructor<any>>, ReactElement<DataGridBodyProps<T>, string | JSXElementConstructor<...>>] | — |
A DataGridHeader and a DataGridBody, each built from DataGridColumn/DataGridRow/
DataGridCell. | ||
className? | string | — |
| A string of all className you want applied to the component. | ||
color? | ContextColor | — |
| Sets the color of the component. | ||
disabledKeys? | Iterable<Key> | — |
| A list of row keys to disable. Disabled rows cannot be selected, focused, or interacted with. | ||
estimatedRowHeight? | number | — |
Seeds the virtualizer's scroll-position math for rows that haven't been measured yet.
Required when rowHeight="auto" — pick a value close to the typical row's real height
to minimize scroll-jump on first measurement. A row's real height can still turn out far
from this estimate once it renders, which can cause a visible scroll-jump for rows the
viewport hasn't reached yet. | ||
footer? | ReactNode | — |
Content shown below the grid, e.g. a totals row or a "load more" control. Rendered as plain
markup outside the grid's own scrollable/virtualized region — not part of the
keyboard-navigable grid, and never scrolls out of view along with the body rows. Mirrors
Table's footer prop for API parity. | ||
hover? | boolean | — |
| Enable a hover state on grid rows. | ||
onSelectionChange? | ((keys: Selection) => void) | — |
| Handler that is called when the selection changes. | ||
onSortChange? | ((descriptor: SortDescriptor) => void) | — |
| Handler that is called when a column is sorted. | ||
ref? | Ref<HTMLDivElement> | — |
rowHeight | number | "auto" | — |
Row height in pixels, or "auto" to measure each row from its own rendered content
instead of a single fixed height shared by every row (pair it with a required
estimatedRowHeight, and see the docs site's "Variable row height" section for the
tradeoffs). A fixed number renders every row, including the header, at that exact
height; content taller than it visually overflows rather than growing the row. | ||
selectedKeys? | Selection | — |
| The currently selected row keys (controlled). | ||
selectionMode? | "none" | "single" | "multiple" | none |
| The type of selection that is allowed. | ||
sm? | boolean | — |
| Make the grid more compact by cutting all cell padding. | ||
sortDescriptor? | SortDescriptor | — |
| The current sort column and direction. | ||
DataGridHeader
| Prop | Type | Default |
|---|---|---|
children | ReactNode | ((column: T) => ReactElement<unknown, string | JSXElementConstructor<any>>) | — |
DataGridColumn elements, or a render function paired with columns for dynamic column
generation. | ||
className? | string | — |
| A string of all className you want applied to the header row group. | ||
columns? | Iterable<T> | — |
A list of column data objects, rendered via the function form of children. | ||
dependencies? | readonly unknown[] | — |
Values that should invalidate the column cache when using the columns/render-function form
of children — see DataGridBody's dependencies for why this matters. | ||
DataGridColumn
| Prop | Type | Default |
|---|---|---|
allowsSorting? | boolean | — |
| Whether the column allows sorting. Adds a sort indicator and makes the header clickable/keyboard-activatable. | ||
children | ReactNode | — |
| Rendered contents of the column header. | ||
className? | string | — |
| A string of all className you want applied to the column header. | ||
defaultWidth? | ColumnSize | null | — |
The initial width of the column, e.g. for a narrow selection/icon column — a plain number or
'<n>%' for a fixed size, or '<n>fr' to share remaining space with other fractional
columns in proportion (columns default to '1fr', so they split space evenly unless given
one of these). Unlike Table, which sizes a narrow column via width: 1% relying on native
<table> auto-layout, DataGrid's virtualized layout computes every column's width itself —
a CSS width rule on the cell has no effect, so this prop is the only way to size a column. | ||
id? | Key | — |
The unique id of the column, referenced by sortDescriptor.column. | ||
isRowHeader? | boolean | — |
| Whether this column is a row header, announced by assistive technology during row navigation. | ||
maxWidth? | ColumnStaticSize | null | — |
The maximum width of the column, as a fixed pixel number or '<n>%'. | ||
minWidth? | ColumnStaticSize | null | — |
The minimum width of the column, as a fixed pixel number or '<n>%'. | ||
pin? | "start" | "end" | — |
Pin the column so it stays visible while the grid scrolls horizontally: 'start' pins it to
the leading edge, 'end' to the trailing edge. Stacks correctly with other pinned columns on
the same side, in declaration order. | ||
textValue? | string | — |
A string representation of the column header, used for accessibility announcements. Defaults
to children when it's a plain string — set this explicitly when the header contains
anything else (an icon, a Tooltip, etc.). | ||
DataGridBody
| Prop | Type | Default |
|---|---|---|
children | ReactElement<unknown, string | JSXElementConstructor<any>> | ReactElement<unknown, string | JSXElementConstructor<any>>[] | ((item: T) => ReactElement<...>) | — |
DataGridRow elements.
A render function called once per item in items, returning that row's DataGridRow. | ||
className? | string | — |
| A string of all className you want applied to the body row group. | ||
dependencies? | readonly unknown[] | — |
Values that should invalidate the row cache when using the items/render-function form of
children — e.g. a value from outside items that the render function reads. Without this,
changing that outside value won't re-render already-cached rows, since dynamic rows are only
rebuilt when items or dependencies change by reference, not on every parent re-render. | ||
isLoading? | boolean | — |
Whether more items are currently being fetched. Shows loadingContent in the loader row while
true, and — until this goes back to false — suppresses further onLoadMore calls, so one
scroll-into-view doesn't fire the callback again before the in-flight fetch resolves. | ||
items? | Iterable<T> | — |
A list of row data objects, rendered via the function form of children. | ||
loadingContent? | ReactNode | — |
Content rendered inside the loader row while isLoading is true, e.g. a spinner. Only takes
effect alongside onLoadMore. | ||
onLoadMore? | (() => void) | — |
Called when the grid scrolls near its last row, so more data can be fetched and appended to
items. Pair with isLoading so a fetch already in flight isn't triggered again before it
resolves. | ||
renderEmptyState? | ((props: TableBodyRenderProps) => ReactNode) | — |
Content shown in place of rows when items is empty. | ||
DataGridRow
| Prop | Type | Default |
|---|---|---|
children | ReactNode | ((column: T) => ReactElement<unknown, string | JSXElementConstructor<any>>) | — |
DataGridCell elements, or a render function called once per column with that column's
data — required when the row's parent DataGridBody uses the items/render-function form. | ||
className? | string | — |
| A string of all className you want applied to the row. | ||
columns? | Iterable<T> | — |
A list of column data objects, rendered via the function form of children. | ||
id? | Key | — |
The unique id of the row, referenced by selectedKeys/disabledKeys. | ||
textValue? | string | — |
| A string representation of the row's contents, used for typeahead. | ||
DataGridCell
| Prop | Type | Default |
|---|---|---|
children | ReactNode | — |
| The contents of the cell. | ||
className? | string | — |
| A string of all className you want applied to the cell. | ||
colSpan? | number | — |
| Indicates how many columns the cell spans. | ||
id? | Key | — |
| The unique id of the cell. | ||
textValue? | string | — |
| A string representation of the cell's contents, used for typeahead. | ||
DataGridSelectionCell
| Prop | Type | Default |
|---|---|---|
className? | string | — |
A string of all className you want applied to the checkbox, replacing the default
check-input. | ||
DataGridSelectAllCell takes no props — it reads the grid's selection state directly.