Upgrading from pre-v10? Check out our upgrade guide for help on how to migrate to the updated API.
The Table component displays data in rows and columns and optionally supports row selection, sorting, and other features.
The LeafyGreen Table wraps TanStack's react-table's hooks and types. Although all react-table features are supported using LeafyGreen Table, only the following features are styled according to design system guidelines:
- Virtualized scrolling
- Nested rows
- Expandable rows
- Selectable rows
- Sortable rows
- Sticky headers
Although other features from react-table are supported, we discourage developers from utilizing them as they would not align with MongoDB design systems guidelines.
yarn add @leafygreen-ui/tablenpm install @leafygreen-ui/tableimport {
Table,
TableHead,
HeaderRow,
TableBody,
Row,
Cell,
} from '@leafygreen-ui/table';
<Table {...args}>
<TableHead>
<HeaderRow>
{columns.map((columnName: string) => (
<HeaderCell key={columnName}>{columnName}</HeaderCell>
))}
</HeaderRow>
</TableHead>
<TableBody>
{data.map((row: { [key: string]: any }) => (
<Row key={row.id}>
{Object.keys(row).map((cellKey: string, index: number) => {
return <Cell key={`${cellKey}-${index}`}>{row[cellKey]}</Cell>;
})}
</Row>
))}
</TableBody>
</Table>;import {
Table,
TableHead,
HeaderRow,
TableBody,
Row,
Cell,
} from '@leafygreen-ui/table';
const tableContainerRef = React.useRef<HTMLDivElement>(null);
const data = React.useState(() => makeData(false, 10_000))[0];
const columns = React.useMemo<Array<ColumnDef<Person>>>(
() => [
{
accessorKey: 'id',
header: 'ID',
size: 60,
},
{
accessorKey: 'firstName',
header: 'First Name',
cell: info => info.getValue(),
},
],
[],
);
const table = useLeafyGreenTable<Person>({
containerRef: tableContainerRef,
data,
columns,
});
const { rows } = table.getRowModel();
<Table
{...args}
table={table}
ref={tableContainerRef}
>
<TableHead>
{table.getHeaderGroups().map((headerGroup: HeaderGroup<Person>) => (
<HeaderRow key={headerGroup.id}>
{headerGroup.headers.map(header => {
return (
<HeaderCell key={header.id} header={header}>
{flexRender(
header.column.columnDef.header,
header.getContext(),
)}
</HeaderCell>
);
})}
</HeaderRow>
))}
</TableHead>
<TableBody>
{rows.map((row: LeafyGreenTableRow<Person>) => (
<Row key={row.id}>
{row.getVisibleCells().map((cell: LeafyGreenTableCell<Person>) => {
return (
<Cell key={cell.id}>
{flexRender(
cell.column.columnDef.cell,
cell.getContext(),
)}
</Cell>
);
})}
</Row>
)}
</TableBody>
</Table>More specific code samples are available below pertaining to each documented feature.
useLeafygreenTable wraps react-table and react-virtual to support advanced table functionalities and virtual scrolling.
useLeafygreenTable takes an options object and returns a table.
useLeafygreenTable exposes all options used in react-table, with the following exceptions:
Setting this prop will inject checkbox cells into all rows. Refer to our Storybook deployment to find examples.
This prop controls whether a 'select all' checkbox will be rendered in the header row. This will be set to true by default.
Setting this prop will indicate that the Table component is being used with the Pagination component. This will expose various pagination utilities from table.getState().pagination. Find an example of how this prop should be used on our Storybook deployment.
react-virtual's useVirtual hook will be called if this option is set. When this option is set, the object returned by useLeafygreenTable will include virtualRows, totalSize and scrollToIndex. Refer to our Storybook deployment to find examples.
Note that the number of virtual rows rendered depends on the height passed to the
Tablecomponent. For a reasonably performant use of virtual scrolling, ensure that there is a height set on the component to reduce the number of virtual rows rendered.
useLeafygreenTable extends react-table's data option to allow a renderExpandedContent prop to be passed to the table's data type.
This option determines how the row's expanded content will be rendered. Refer to Storybook deployment for an example.
useLeafygreenTable extends react-table's data option to allow a subRows prop to be passed to the table's data type.
This option defines the data displayed in nested rows and expects an array of objects with the same shape as other rows. Rows can be nested multiple times. Refer to Storybook deployment for an example.
useLeafygreenTable extends react-table's columns option to allow a align prop to be passed to the column's data.
This option determines the alignment of the column. Refer to Storybook deployment for an example.
| Name | Description | Type | Default |
|---|---|---|---|
shouldAlternateRowColor |
Determines whether alternating rows will have dark backgrounds | boolean | false |
disableAnimations |
Disables all transition animations for smoother rendering of tall content where appropriate | boolean | false |
baseFontSize |
The base font size of the title and text rendered in children | 13 | 16 | 13 |
darkMode |
Render the component in dark mode. | boolean | false |
+ other HTML table element props
| Name | Description | Type | Default |
|---|---|---|---|
isSticky |
Determines whether the table head will stick as the user scrolls down. | boolean | false |
+ other HTML thead element props
If
isStickyis set totrue, theTablecomponent will need to have a CSSheightvalue set in pixels.
All HTML tr element props
| Name | Description | Type | Default |
|---|---|---|---|
| sortState | Determines the current sorting direction. | SortState |
'asc' 'desc' 'off' 'none' |
| header | Header object returned from the useLeafygreenTable hook. |
Header<T, any> | - |
+ other HTML th element props
TableBody accepts HTML tbody element props.
The
TableBodywill render as aReact.Fragmentwhen Tables have expandable or nested rows to support virtualized scrolling on rows with unknown heights.This is done to ensure that dynamic heights of rows with expandable content can be measured using a
refusing atbodyelement. In lieu of arowgroupHTML element, expandable content relies ontbodyto track groups of rows. This means theTableBodyneeds to render as aReact.Fragmentto ensure there aren'ttbodyelements insidetbodyelements.
| Name | Description | Type | Default |
|---|---|---|---|
| disabled | Determines whether the row is disabled | boolean |
false |
| row | Row object passed from the useLeafygreenTable hook. |
LeafygreenTableRow<T> |
- |
| virtualRow | Virtual row object passed from the useLeafygreenTable hook. |
VirtualItem |
- |
+ other HTML tr element props
Cell accepts HTML td element props.
All nested row animations are set at the Cell level, with a
max-heightset to 40vh, which should cover most cases with a relatively smooth animation. For taller content, setdisableAnimation={true}or override the max-height with a& > div { max-height: ... }CSS selector on theCellcomponent.
Note that the number of virtual rows rendered depends on the height passed to the
Tablecomponent. For a reasonably performant use of virtual scrolling, ensure that there is a height set on the component to reduce the number of virtual rows rendered.
Demo with virtualized scrolling
Demo with virtualized scrolling
Demo with virtualized scrolling
To add expandable content to your Table, ensure the renderExpandedContent prop is passed to the row's data through useLeafygreenTable's data prop.
For cases where you anticipate having more than 20 rows with nested rows, it is advisable to opt for virtual scrolling to improve performance of row transitions.