+
{columns}
);
@@ -274,12 +295,14 @@ export function Grid<
CellComponent,
cellProps,
columnCount,
+ columnKey,
columnStartIndexOverscan,
columnStopIndexOverscan,
getColumnBounds,
getRowBounds,
isRtl,
rowCount,
+ rowKey,
rowStartIndexOverscan,
rowStopIndexOverscan
]);
diff --git a/lib/components/grid/types.ts b/lib/components/grid/types.ts
index 395053c7..2c9e09e6 100644
--- a/lib/components/grid/types.ts
+++ b/lib/components/grid/types.ts
@@ -61,6 +61,23 @@ export type GridProps<
*/
columnCount: number;
+ /**
+ * Grids use the column index as a `key` by default.
+ * This prop can be used along with the `rowKey` prop to provide a custom `key` value.
+ *
+ * ℹ️ Custom keys can ensure better UX for sortable or filterable grids,
+ * particularly if your cell components are stateful.
+ * Refer to the [React documentation](https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key) for more info.
+ *
+ * ⚠️ This prop cannot be auto-memoized because it is called during render.
+ * It is important to always `useCallback` for this prop; do not use an inline function.
+ */
+ columnKey?: (args: {
+ columnIndex: number;
+ data: CellProps;
+ rowIndex: number;
+ }) => React.Key;
+
/**
* Column width; the following formats are supported:
* - number of pixels (number)
@@ -201,6 +218,19 @@ export type GridProps<
| string
| ((index: number, cellProps: CellProps) => number);
+ /**
+ * Grids use the row index as a `key` by default.
+ * This prop can be used along with the `columnKey` prop to provide a custom `key` value.
+ *
+ * ℹ️ Custom keys can ensure better UX for sortable or filterable grids,
+ * particularly if your cell components are stateful.
+ * Refer to the [React documentation](https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key) for more info.
+ *
+ * ⚠️ This prop cannot be auto-memoized because it is called during render.
+ * It is important to always `useCallback` for this prop; do not use an inline function.
+ */
+ rowKey?: (args: { data: CellProps; rowIndex: number }) => React.Key;
+
/**
* Optional CSS properties.
* The grid of cells will fill the height and width defined by this style.
diff --git a/lib/components/list/List.test.tsx b/lib/components/list/List.test.tsx
index f226209b..f4424924 100644
--- a/lib/components/list/List.test.tsx
+++ b/lib/components/list/List.test.tsx
@@ -1,5 +1,5 @@
import { act, render, screen } from "@testing-library/react";
-import { createRef, useLayoutEffect } from "react";
+import { createRef, useEffect, useLayoutEffect, useRef } from "react";
import { beforeEach, describe, expect, test, vi } from "vitest";
import { EMPTY_OBJECT } from "../../../src/constants";
import { assert } from "../../utils/assert";
@@ -865,6 +865,117 @@ describe("List", () => {
});
});
+ describe("rowKey", () => {
+ test("is used for every rendered row", () => {
+ const rowKey = vi.fn((index) => index);
+
+ render(
+
+ );
+
+ const items = screen.queryAllByRole("listitem");
+ expect(items).toHaveLength(7);
+ expect(rowKey).toHaveBeenCalledWith(0, EMPTY_OBJECT);
+ expect(rowKey).toHaveBeenCalledWith(1, EMPTY_OBJECT);
+ expect(rowKey).toHaveBeenCalledWith(2, EMPTY_OBJECT);
+ expect(rowKey).toHaveBeenCalledWith(3, EMPTY_OBJECT);
+ expect(rowKey).toHaveBeenCalledWith(4, EMPTY_OBJECT);
+ expect(rowKey).toHaveBeenCalledWith(5, EMPTY_OBJECT);
+ expect(rowKey).toHaveBeenCalledWith(6, EMPTY_OBJECT);
+ });
+
+ test("preserves state when list order changes", async () => {
+ let data = new Array(5).fill(true).map((_, index) => index);
+
+ const rowKey = vi.fn((index) => data[index]);
+ const renderLog: string[] = [];
+
+ function LocalRowComponent({
+ data,
+ index,
+ style
+ }: RowComponentProps<{ data: number[] }>) {
+ const id = data[index];
+
+ const idDuringMountRef = useRef(id);
+
+ useEffect(() => {
+ if (idDuringMountRef.current === id) {
+ renderLog.push(`index: ${index}, id: ${id}`);
+ return;
+ }
+
+ throw Error(
+ `Expected id "${idDuringMountRef.current}" but was "${id}"`
+ );
+ });
+
+ return (
+
+ Index {index}, id {id}
+
+ );
+ }
+
+ const { rerender } = render(
+
+ );
+
+ const items = screen.queryAllByRole("listitem");
+ expect(items).toHaveLength(5);
+ expect(rowKey).toHaveBeenCalled();
+ expect(renderLog).toMatchInlineSnapshot(`
+ [
+ "index: 0, id: 0",
+ "index: 1, id: 1",
+ "index: 2, id: 2",
+ "index: 3, id: 3",
+ "index: 4, id: 4",
+ ]
+ `);
+
+ renderLog.splice(0);
+ rowKey.mockReset();
+
+ await act(async () => {
+ data = [...data.reverse()];
+
+ rerender(
+
+ );
+ });
+
+ expect(rowKey).toHaveBeenCalled();
+ expect(renderLog).toMatchInlineSnapshot(`
+ [
+ "index: 0, id: 4",
+ "index: 1, id: 3",
+ "index: 2, id: 2",
+ "index: 3, id: 1",
+ "index: 4, id: 0",
+ ]
+ `);
+ });
+ });
+
describe("aria attributes", () => {
test("should be set by default", () => {
render(
diff --git a/lib/components/list/List.tsx b/lib/components/list/List.tsx
index ae150296..00903077 100644
--- a/lib/components/list/List.tsx
+++ b/lib/components/list/List.tsx
@@ -37,6 +37,7 @@ export function List<
rowComponent: RowComponentProp,
rowCount,
rowHeight: rowHeightProp,
+ rowKey,
rowProps: rowPropsUnstable,
tagName = "div" as TagName,
style,
@@ -185,7 +186,7 @@ export function List<
"aria-setsize": rowCount,
role: "listitem"
}}
- key={index}
+ key={rowKey ? rowKey(index, rowProps) : index}
index={index}
style={{
position: "absolute",
@@ -206,6 +207,7 @@ export function List<
getCellBounds,
isDynamicRowHeight,
rowCount,
+ rowKey,
rowProps,
startIndexOverscan,
stopIndexOverscan
diff --git a/lib/components/list/types.ts b/lib/components/list/types.ts
index ebcbbc1a..92fcc18d 100644
--- a/lib/components/list/types.ts
+++ b/lib/components/list/types.ts
@@ -134,6 +134,19 @@ export type ListProps<
| ((index: number, cellProps: RowProps) => number)
| DynamicRowHeight;
+ /**
+ * Lists use the row index as a `key` by default.
+ * This prop can provide a custom `key` value.
+ *
+ * ℹ️ Custom keys can ensure better UX for sortable or filterable lists,
+ * particularly if your row components are stateful.
+ * Refer to the [React documentation](https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key) for more info.
+ *
+ * ⚠️ This prop cannot be auto-memoized because it is called during render.
+ * It is important to always `useCallback` for this prop; do not use an inline function.
+ */
+ rowKey?: (index: number, data: RowProps) => React.Key;
+
/**
* Additional props to be passed to the row-rendering component.
* List will automatically re-render rows when values in this object change.
diff --git a/lib/hooks/useStableCallback.ts b/lib/hooks/useStableCallback.ts
index 954cbb1d..d009f388 100644
--- a/lib/hooks/useStableCallback.ts
+++ b/lib/hooks/useStableCallback.ts
@@ -2,18 +2,25 @@ import { useCallback, useRef } from "react";
import { useIsomorphicLayoutEffect } from "./useIsomorphicLayoutEffect";
// Forked from useEventCallback (usehooks-ts)
-export function useStableCallback
(
- fn: (args: Args) => Return
-): (args: Args) => Return {
+export function useStableCallback(
+ fn: (...args: Args) => Return
+): (...args: Args) => Return;
+export function useStableCallback(
+ fn: ((...args: Args) => Return) | undefined
+): ((...args: Args) => Return) | undefined;
+export function useStableCallback(
+ fn: ((...args: Args) => Return) | undefined
+): ((...args: Args) => Return) | undefined {
const ref = useRef(() => {
- throw new Error("Cannot call during render.");
+ // This error ensures components don't render with previous/stale function
+ throw new Error("Cannot call an event handler while rendering.");
});
useIsomorphicLayoutEffect(() => {
ref.current = fn;
}, [fn]);
- return useCallback((args: Args) => ref.current?.(args), [ref]) as (
- args: Args
+ return useCallback((...args: Args) => ref.current?.(...args), [ref]) as (
+ ...args: Args
) => Return;
}
diff --git a/package.json b/package.json
index f04cde7e..5fbc4f46 100644
--- a/package.json
+++ b/package.json
@@ -89,7 +89,7 @@
"react-docgen-typescript": "^2.4.0",
"react-dom": "^19.2.3",
"react-error-boundary": "^6.0.0",
- "react-lib-tools": "0.0.52",
+ "react-lib-tools": "0.0.53",
"react-router-dom": "^7.6.3",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-visualizer": "^6.0.3",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 61f6e414..b60163a7 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -119,8 +119,8 @@ importers:
specifier: ^6.0.0
version: 6.0.0(react@19.2.3)
react-lib-tools:
- specifier: 0.0.52
- version: 0.0.52(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.8.3)
+ specifier: 0.0.53
+ version: 0.0.53(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.8.3)
react-router-dom:
specifier: ^7.6.3
version: 7.6.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
@@ -6664,10 +6664,10 @@ packages:
integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
}
- react-lib-tools@0.0.52:
+ react-lib-tools@0.0.53:
resolution:
{
- integrity: sha512-UabOEVqBSNQOV7YJuA+V/Tg2GXDiAzk7ukPqUuPlmvnerX4ri1qZr3t34RdnnD9Y5Ovm29HvuKdw/tImb6qBHg==
+ integrity: sha512-0KSuuryin8JbehtPtW9D9KMScWKWdE+GwDZC2SZIN9g7/7YzmoXcUxT6v+3GQ1jV3Bh7z+TJcOYY00XaeV5b8w==
}
peerDependencies:
react: ^18.0.0 || ^19.0.0
@@ -12067,7 +12067,7 @@ snapshots:
react-is@17.0.2: {}
- react-lib-tools@0.0.52(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.8.3):
+ react-lib-tools@0.0.53(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.8.3):
dependencies:
"@codemirror/lang-css": 6.3.1
"@codemirror/lang-html": 6.4.11
diff --git a/public/generated/docs/Grid.json b/public/generated/docs/Grid.json
index e4858156..d2717ce2 100644
--- a/public/generated/docs/Grid.json
+++ b/public/generated/docs/Grid.json
@@ -96,6 +96,24 @@
"name": "columnCount",
"required": true
},
+ "columnKey": {
+ "description": [
+ {
+ "content": "Grids use the column index as a key by default.\nThis prop can be used along with the rowKey prop to provide a custom key value.
\n"
+ },
+ {
+ "content": "Custom keys can ensure better UX for sortable or filterable grids,\nparticularly if your cell components are stateful.\nRefer to the React documentation for more info.
\n",
+ "intent": "primary"
+ },
+ {
+ "content": "This prop cannot be auto-memoized because it is called during render.\nIt is important to always useCallback for this prop; do not use an inline function.
\n",
+ "intent": "warning"
+ }
+ ],
+ "html": "columnKey?: (args: { columnIndex: number; data: CellProps; rowIndex: number; }) => Key
",
+ "name": "columnKey",
+ "required": false
+ },
"columnWidth": {
"description": [
{
@@ -190,6 +208,24 @@
"name": "rowHeight",
"required": true
},
+ "rowKey": {
+ "description": [
+ {
+ "content": "Grids use the row index as a key by default.\nThis prop can be used along with the columnKey prop to provide a custom key value.
\n"
+ },
+ {
+ "content": "Custom keys can ensure better UX for sortable or filterable grids,\nparticularly if your cell components are stateful.\nRefer to the React documentation for more info.
\n",
+ "intent": "primary"
+ },
+ {
+ "content": "This prop cannot be auto-memoized because it is called during render.\nIt is important to always useCallback for this prop; do not use an inline function.
\n",
+ "intent": "warning"
+ }
+ ],
+ "html": "rowKey?: (args: { data: CellProps; rowIndex: number; }) => Key
",
+ "name": "rowKey",
+ "required": false
+ },
"tagName": {
"description": [
{
diff --git a/public/generated/docs/List.json b/public/generated/docs/List.json
index 9b414ca7..6c157eac 100644
--- a/public/generated/docs/List.json
+++ b/public/generated/docs/List.json
@@ -135,6 +135,24 @@
"name": "rowHeight",
"required": true
},
+ "rowKey": {
+ "description": [
+ {
+ "content": "Lists use the row index as a key by default.\nThis prop can provide a custom key value.
\n"
+ },
+ {
+ "content": "Custom keys can ensure better UX for sortable or filterable lists,\nparticularly if your row components are stateful.\nRefer to the React documentation for more info.
\n",
+ "intent": "primary"
+ },
+ {
+ "content": "This prop cannot be auto-memoized because it is called during render.\nIt is important to always useCallback for this prop; do not use an inline function.
\n",
+ "intent": "warning"
+ }
+ ],
+ "html": "rowKey?: (index: number, data: RowProps) => Key
",
+ "name": "rowKey",
+ "required": false
+ },
"rowProps": {
"description": [
{
diff --git a/public/generated/site-map.json b/public/generated/site-map.json
index 7ef76570..df3e6fd8 100644
--- a/public/generated/site-map.json
+++ b/public/generated/site-map.json
@@ -47,7 +47,7 @@
{
"path": "/list/props",
"section": "Lists",
- "text": " Renders data with many rows.\n Required props rowComponent: (props: { ariaAttributes: { \"aria-posinset\": number; \"aria-setsize\": number; role: \"listitem\"; }; index: number; style: CSSProperties; } & RowProps) => ReactNode | null React component responsible for rendering a row.\n This component will receive an index and style prop by default.\nAdditionally it will receive prop values passed to rowProps.\n The prop types for this component are exported as RowComponentProps \n rowCount: number Number of items to be rendered in the list.\n rowHeight: string | number | DynamicRowHeight | ((index: number, cellProps: RowProps) => number) Row height; the following formats are supported:\n\nnumber of pixels (number)\npercentage of the grid's current height (string)\nfunction that returns the row height (in pixels) given an index and cellProps \ndynamic row height cache returned by the useDynamicRowHeight hook\n\n Dynamic row heights are not as efficient as predetermined sizes.\nIt's recommended to provide your own height values if they can be determined ahead of time.\n rowProps: RowProps Additional props to be passed to the row-rendering component.\nList will automatically re-render rows when values in this object change.\n This object must not contain ariaAttributes, index, or style props.\n Optional props children?: ReactNode Additional content to be rendered within the list (above cells).\nThis property can be used to render things like overlays or tooltips.\n className?: string CSS class name.\n defaultHeight?: number = 0 Default height of list for initial render.\nThis value is important for server rendering.\n listRef?: Ref<{ readonly element: HTMLDivElement | null; scrollToRow(config: { align?: \"auto\" | \"center\" | \"end\" | \"smart\" | \"start\"; behavior?: \"auto\" | \"instant\" | \"smooth\"; index: number; }): void; }> Ref used to interact with this component's imperative API.\n This API has imperative methods for scrolling and a getter for the outermost DOM element.\n The useListRef and useListCallbackRef hooks are exported for convenience use in TypeScript projects.\n onResize?: (size: { height: number; width: number; }, prevSize: { height: number; width: number; }) => void Callback notified when the List's outermost HTMLElement resizes.\nThis may be used to (re)scroll a row into view.\n onRowsRendered?: (visibleRows: { startIndex: number; stopIndex: number; }, allRows: { startIndex: number; stopIndex: number; }) => void Callback notified when the range of visible rows changes.\n overscanCount?: number = 3 How many additional rows to render outside of the visible area.\nThis can reduce visual flickering near the edges of a list when scrolling.\n style?: CSSProperties Optional CSS properties.\nThe list of rows will fill the height defined by this style.\n tagName?: keyof IntrinsicElements = \"div\" as TagName Can be used to override the root HTML element rendered by the List component.\nThe default value is \"div\", meaning that List renders an HTMLDivElement as its root.\n In most use cases the default ARIA roles are sufficient and this prop is not needed.\n ",
+ "text": " Renders data with many rows.\n Required props rowComponent: (props: { ariaAttributes: { \"aria-posinset\": number; \"aria-setsize\": number; role: \"listitem\"; }; index: number; style: CSSProperties; } & RowProps) => ReactNode | null React component responsible for rendering a row.\n This component will receive an index and style prop by default.\nAdditionally it will receive prop values passed to rowProps.\n The prop types for this component are exported as RowComponentProps \n rowCount: number Number of items to be rendered in the list.\n rowHeight: string | number | DynamicRowHeight | ((index: number, cellProps: RowProps) => number) Row height; the following formats are supported:\n\nnumber of pixels (number)\npercentage of the grid's current height (string)\nfunction that returns the row height (in pixels) given an index and cellProps \ndynamic row height cache returned by the useDynamicRowHeight hook\n\n Dynamic row heights are not as efficient as predetermined sizes.\nIt's recommended to provide your own height values if they can be determined ahead of time.\n rowProps: RowProps Additional props to be passed to the row-rendering component.\nList will automatically re-render rows when values in this object change.\n This object must not contain ariaAttributes, index, or style props.\n Optional props children?: ReactNode Additional content to be rendered within the list (above cells).\nThis property can be used to render things like overlays or tooltips.\n className?: string CSS class name.\n defaultHeight?: number = 0 Default height of list for initial render.\nThis value is important for server rendering.\n listRef?: Ref<{ readonly element: HTMLDivElement | null; scrollToRow(config: { align?: \"auto\" | \"center\" | \"end\" | \"smart\" | \"start\"; behavior?: \"auto\" | \"instant\" | \"smooth\"; index: number; }): void; }> Ref used to interact with this component's imperative API.\n This API has imperative methods for scrolling and a getter for the outermost DOM element.\n The useListRef and useListCallbackRef hooks are exported for convenience use in TypeScript projects.\n onResize?: (size: { height: number; width: number; }, prevSize: { height: number; width: number; }) => void Callback notified when the List's outermost HTMLElement resizes.\nThis may be used to (re)scroll a row into view.\n onRowsRendered?: (visibleRows: { startIndex: number; stopIndex: number; }, allRows: { startIndex: number; stopIndex: number; }) => void Callback notified when the range of visible rows changes.\n overscanCount?: number = 3 How many additional rows to render outside of the visible area.\nThis can reduce visual flickering near the edges of a list when scrolling.\n rowKey?: (index: number, data: RowProps) => Key Lists use the row index as a key by default.\nThis prop can provide a custom key value.\n Custom keys can ensure better UX for sortable or filterable lists,\nparticularly if your row components are stateful.\nRefer to the React documentation for more info.\n This prop cannot be auto-memoized because it is called during render.\nIt is important to always useCallback for this prop; do not use an inline function.\n style?: CSSProperties Optional CSS properties.\nThe list of rows will fill the height defined by this style.\n tagName?: keyof IntrinsicElements = \"div\" as TagName Can be used to override the root HTML element rendered by the List component.\nThe default value is \"div\", meaning that List renders an HTMLDivElement as its root.\n In most use cases the default ARIA roles are sufficient and this prop is not needed.\n ",
"title": "List component props"
},
{
@@ -89,7 +89,7 @@
{
"path": "/grid/props",
"section": "Grids",
- "text": " Renders data with many rows and columns.\n Unlike List rows, Grid cell sizes must be known ahead of time.\nEither static sizes or something that can be derived (from the data in CellProps) without rendering.\n Required props cellComponent: (props: { ariaAttributes: { \"aria-colindex\": number; role: \"gridcell\"; }; columnIndex: number; rowIndex: number; style: CSSProperties; } & CellProps) => ReactNode | null React component responsible for rendering a cell.\n This component will receive an index and style prop by default.\nAdditionally it will receive prop values passed to cellProps.\n The prop types for this component are exported as CellComponentProps \n cellProps: CellProps Additional props to be passed to the cell-rendering component.\nGrid will automatically re-render cells when values in this object change.\n This object must not contain ariaAttributes, columnIndex, rowIndex, or style props.\n columnCount: number Number of columns to be rendered in the grid.\n columnWidth: string | number | ((index: number, cellProps: CellProps) => number) Column width; the following formats are supported:\n\nnumber of pixels (number)\npercentage of the grid's current width (string)\nfunction that returns the column width (in pixels) given an index and cellProps \n\n rowCount: number Number of rows to be rendered in the grid.\n rowHeight: string | number | ((index: number, cellProps: CellProps) => number) Row height; the following formats are supported:\n\nnumber of pixels (number)\npercentage of the grid's current height (string)\nfunction that returns the row height (in pixels) given an index and cellProps \n\n Optional props children?: ReactNode Additional content to be rendered within the grid (above cells).\nThis property can be used to render things like overlays or tooltips.\n className?: string CSS class name.\n defaultHeight?: number = 0 Default height of grid for initial render.\nThis value is important for server rendering.\n defaultWidth?: number = 0 Default width of grid for initial render.\nThis value is important for server rendering.\n dir?: string Indicates the directionality of grid cells.\n See HTML dir global attribute for more information.\n gridRef?: Ref<{ readonly element: HTMLDivElement | null; scrollToCell(config: { behavior?: \"auto\" | \"instant\" | \"smooth\"; columnAlign?: \"auto\" | \"center\" | \"end\" | \"smart\" | \"start\"; columnIndex: number; rowAlign?: \"auto\" | ... 3 more ... | \"start\"; rowIndex: number; }): void; scrollToColumn(config: { ...; }): void; scrollToR... Imperative Grid API.\n The useGridRef and useGridCallbackRef hooks are exported for convenience use in TypeScript projects.\n onCellsRendered?: (visibleCells: { columnStartIndex: number; columnStopIndex: number; rowStartIndex: number; rowStopIndex: number; }, allCells: { columnStartIndex: number; columnStopIndex: number; rowStartIndex: number; rowStopIndex: number; }) => void Callback notified when the range of rendered cells changes.\n onResize?: (size: { height: number; width: number; }, prevSize: { height: number; width: number; }) => void Callback notified when the Grid's outermost HTMLElement resizes.\nThis may be used to (re)scroll a cell into view.\n overscanCount?: number = 3 How many additional rows/columns to render outside of the visible area.\nThis can reduce visual flickering near the edges of a grid when scrolling.\n style?: CSSProperties Optional CSS properties.\nThe grid of cells will fill the height and width defined by this style.\n tagName?: keyof IntrinsicElements = \"div\" as TagName Can be used to override the root HTML element rendered by the List component.\nThe default value is \"div\", meaning that List renders an HTMLDivElement as its root.\n In most use cases the default ARIA roles are sufficient and this prop is not needed.\n ",
+ "text": " Renders data with many rows and columns.\n Unlike List rows, Grid cell sizes must be known ahead of time.\nEither static sizes or something that can be derived (from the data in CellProps) without rendering.\n Required props cellComponent: (props: { ariaAttributes: { \"aria-colindex\": number; role: \"gridcell\"; }; columnIndex: number; rowIndex: number; style: CSSProperties; } & CellProps) => ReactNode | null React component responsible for rendering a cell.\n This component will receive an index and style prop by default.\nAdditionally it will receive prop values passed to cellProps.\n The prop types for this component are exported as CellComponentProps \n cellProps: CellProps Additional props to be passed to the cell-rendering component.\nGrid will automatically re-render cells when values in this object change.\n This object must not contain ariaAttributes, columnIndex, rowIndex, or style props.\n columnCount: number Number of columns to be rendered in the grid.\n columnWidth: string | number | ((index: number, cellProps: CellProps) => number) Column width; the following formats are supported:\n\nnumber of pixels (number)\npercentage of the grid's current width (string)\nfunction that returns the column width (in pixels) given an index and cellProps \n\n rowCount: number Number of rows to be rendered in the grid.\n rowHeight: string | number | ((index: number, cellProps: CellProps) => number) Row height; the following formats are supported:\n\nnumber of pixels (number)\npercentage of the grid's current height (string)\nfunction that returns the row height (in pixels) given an index and cellProps \n\n Optional props children?: ReactNode Additional content to be rendered within the grid (above cells).\nThis property can be used to render things like overlays or tooltips.\n className?: string CSS class name.\n columnKey?: (args: { columnIndex: number; data: CellProps; rowIndex: number; }) => Key Grids use the column index as a key by default.\nThis prop can be used along with the rowKey prop to provide a custom key value.\n Custom keys can ensure better UX for sortable or filterable grids,\nparticularly if your cell components are stateful.\nRefer to the React documentation for more info.\n This prop cannot be auto-memoized because it is called during render.\nIt is important to always useCallback for this prop; do not use an inline function.\n defaultHeight?: number = 0 Default height of grid for initial render.\nThis value is important for server rendering.\n defaultWidth?: number = 0 Default width of grid for initial render.\nThis value is important for server rendering.\n dir?: string Indicates the directionality of grid cells.\n See HTML dir global attribute for more information.\n gridRef?: Ref<{ readonly element: HTMLDivElement | null; scrollToCell(config: { behavior?: \"auto\" | \"instant\" | \"smooth\"; columnAlign?: \"auto\" | \"center\" | \"end\" | \"smart\" | \"start\"; columnIndex: number; rowAlign?: \"auto\" | ... 3 more ... | \"start\"; rowIndex: number; }): void; scrollToColumn(config: { ...; }): void; scrollToR... Imperative Grid API.\n The useGridRef and useGridCallbackRef hooks are exported for convenience use in TypeScript projects.\n onCellsRendered?: (visibleCells: { columnStartIndex: number; columnStopIndex: number; rowStartIndex: number; rowStopIndex: number; }, allCells: { columnStartIndex: number; columnStopIndex: number; rowStartIndex: number; rowStopIndex: number; }) => void Callback notified when the range of rendered cells changes.\n onResize?: (size: { height: number; width: number; }, prevSize: { height: number; width: number; }) => void Callback notified when the Grid's outermost HTMLElement resizes.\nThis may be used to (re)scroll a cell into view.\n overscanCount?: number = 3 How many additional rows/columns to render outside of the visible area.\nThis can reduce visual flickering near the edges of a grid when scrolling.\n rowKey?: (args: { data: CellProps; rowIndex: number; }) => Key Grids use the row index as a key by default.\nThis prop can be used along with the columnKey prop to provide a custom key value.\n Custom keys can ensure better UX for sortable or filterable grids,\nparticularly if your cell components are stateful.\nRefer to the React documentation for more info.\n This prop cannot be auto-memoized because it is called during render.\nIt is important to always useCallback for this prop; do not use an inline function.\n style?: CSSProperties Optional CSS properties.\nThe grid of cells will fill the height and width defined by this style.\n tagName?: keyof IntrinsicElements = \"div\" as TagName Can be used to override the root HTML element rendered by the List component.\nThe default value is \"div\", meaning that List renders an HTMLDivElement as its root.\n In most use cases the default ARIA roles are sufficient and this prop is not needed.\n ",
"title": "Grid component props"
},
{