UNPKG

react-window

Version:

<img src="https://react-window.vercel.app/og.svg" alt="react-window logo" width="400" height="210" />

315 lines (278 loc) 19 kB
<img src="https://react-window.vercel.app/og.svg" alt="react-window logo" width="400" height="210" /> `react-window` is a component library that helps render large lists of data quickly and without the performance problems that often go along with rendering a lot of data. It's used in a lot of places, from React DevTools to the Replay browser. ## Support If you like this project there are several ways to support it: - [Become a GitHub sponsor](https://github.com/sponsors/bvaughn/) - [Become an Open Collective sponsor](https://opencollective.com/react-window#sponsor) - or [buy me a coffee](http://givebrian.coffee/) The following wonderful companies and individuals have sponsored react-window: <a href="https://opencollective.com/react-window/sponsor/0/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/0/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/1/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/1/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/2/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/2/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/3/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/3/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/4/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/4/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/5/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/5/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/6/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/6/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/7/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/7/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/8/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/8/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/9/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/9/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/10/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/10/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/11/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/11/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/12/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/12/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/13/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/13/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/14/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/14/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/15/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/15/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/16/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/16/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/17/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/17/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/18/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/18/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/19/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/19/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/20/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/20/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/21/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/21/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/22/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/22/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/23/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/23/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/24/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/24/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/25/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/25/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/26/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/26/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/27/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/27/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/28/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/28/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/29/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/29/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/0/website" target="_blank"><img src="https://opencollective.com/react-window/backer/0/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/1/website" target="_blank"><img src="https://opencollective.com/react-window/backer/1/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/2/website" target="_blank"><img src="https://opencollective.com/react-window/backer/2/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/3/website" target="_blank"><img src="https://opencollective.com/react-window/backer/3/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/4/website" target="_blank"><img src="https://opencollective.com/react-window/backer/4/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/5/website" target="_blank"><img src="https://opencollective.com/react-window/backer/5/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/6/website" target="_blank"><img src="https://opencollective.com/react-window/backer/6/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/7/website" target="_blank"><img src="https://opencollective.com/react-window/backer/7/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/8/website" target="_blank"><img src="https://opencollective.com/react-window/backer/8/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/9/website" target="_blank"><img src="https://opencollective.com/react-window/backer/9/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/10/website" target="_blank"><img src="https://opencollective.com/react-window/backer/10/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/11/website" target="_blank"><img src="https://opencollective.com/react-window/backer/11/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/12/website" target="_blank"><img src="https://opencollective.com/react-window/backer/12/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/13/website" target="_blank"><img src="https://opencollective.com/react-window/backer/13/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/14/website" target="_blank"><img src="https://opencollective.com/react-window/backer/14/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/15/website" target="_blank"><img src="https://opencollective.com/react-window/backer/15/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/16/website" target="_blank"><img src="https://opencollective.com/react-window/backer/16/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/17/website" target="_blank"><img src="https://opencollective.com/react-window/backer/17/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/18/website" target="_blank"><img src="https://opencollective.com/react-window/backer/18/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/19/website" target="_blank"><img src="https://opencollective.com/react-window/backer/19/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/20/website" target="_blank"><img src="https://opencollective.com/react-window/backer/20/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/21/website" target="_blank"><img src="https://opencollective.com/react-window/backer/21/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/22/website" target="_blank"><img src="https://opencollective.com/react-window/backer/22/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/23/website" target="_blank"><img src="https://opencollective.com/react-window/backer/23/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/24/website" target="_blank"><img src="https://opencollective.com/react-window/backer/24/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/25/website" target="_blank"><img src="https://opencollective.com/react-window/backer/25/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/26/website" target="_blank"><img src="https://opencollective.com/react-window/backer/26/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/27/website" target="_blank"><img src="https://opencollective.com/react-window/backer/27/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/28/website" target="_blank"><img src="https://opencollective.com/react-window/backer/28/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/29/website" target="_blank"><img src="https://opencollective.com/react-window/backer/29/avatar.svg"></a> ## Installation Begin by installing the library from NPM: ```sh npm install react-window ``` ## TypeScript types TypeScript definitions are included within the published `dist` folder ## FAQs Frequently asked questions can be found [here](https://react-window.vercel.app/common-questions). ## Documentation Documentation for this project is available at [react-window.vercel.app](https://react-window.vercel.app/); version 1.x documentation can be found at [react-window-v1.vercel.app](https://react-window-v1.vercel.app/). ### List <!-- List:description:begin --> Renders data with many rows. <!-- List:description:end --> #### Required props <!-- List:required-props:begin --> <table> <thead> <tr> <th>Name</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td>rowComponent</td> <td><p>React component responsible for rendering a row.</p> <p>This component will receive an <code>index</code> and <code>style</code> prop by default. Additionally it will receive prop values passed to <code>rowProps</code>.</p> <p>ℹ️ The prop types for this component are exported as <code>RowComponentProps</code></p> </td> </tr> <tr> <td>rowCount</td> <td><p>Number of items to be rendered in the list.</p> </td> </tr> <tr> <td>rowHeight</td> <td><p>Row height; the following formats are supported:</p> <ul> <li>number of pixels (number)</li> <li>percentage of the grid&#39;s current height (string)</li> <li>function that returns the row height (in pixels) given an index and <code>cellProps</code></li> <li>dynamic row height cache returned by the <code>useDynamicRowHeight</code> hook</li> </ul> <p>⚠️ Dynamic row heights are not as efficient as predetermined sizes. It&#39;s recommended to provide your own height values if they can be determined ahead of time.</p> </td> </tr> <tr> <td>rowProps</td> <td><p>Additional props to be passed to the row-rendering component. List will automatically re-render rows when values in this object change.</p> <p>⚠️ This object must not contain <code>ariaAttributes</code>, <code>index</code>, or <code>style</code> props.</p> </td> </tr> </tbody> </table> <!-- List:required-props:end --> #### Optional props <!-- List:optional-props:begin --> <table> <thead> <tr> <th>Name</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td>className</td> <td><p>CSS class name.</p> </td> </tr> <tr> <td>style</td> <td><p>Optional CSS properties. The list of rows will fill the height defined by this style.</p> </td> </tr> <tr> <td>children</td> <td><p>Additional content to be rendered within the list (above cells). This property can be used to render things like overlays or tooltips.</p> </td> </tr> <tr> <td>defaultHeight</td> <td><p>Default height of list for initial render. This value is important for server rendering.</p> </td> </tr> <tr> <td>listRef</td> <td><p>Ref used to interact with this component&#39;s imperative API.</p> <p>This API has imperative methods for scrolling and a getter for the outermost DOM element.</p> <p>ℹ️ The <code>useListRef</code> and <code>useListCallbackRef</code> hooks are exported for convenience use in TypeScript projects.</p> </td> </tr> <tr> <td>onResize</td> <td><p>Callback notified when the List&#39;s outermost HTMLElement resizes. This may be used to (re)scroll a row into view.</p> </td> </tr> <tr> <td>onRowsRendered</td> <td><p>Callback notified when the range of visible rows changes.</p> </td> </tr> <tr> <td>overscanCount</td> <td><p>How many additional rows to render outside of the visible area. This can reduce visual flickering near the edges of a list when scrolling.</p> </td> </tr> <tr> <td>tagName</td> <td><p>Can be used to override the root HTML element rendered by the List component. The default value is &quot;div&quot;, meaning that List renders an HTMLDivElement as its root.</p> <p>⚠️ In most use cases the default ARIA roles are sufficient and this prop is not needed.</p> </td> </tr> </tbody> </table> <!-- List:optional-props:end --> ### Grid <!-- Grid:description:begin --> Renders data with many rows and columns. <!-- Grid:description:end --> #### Required props <!-- Grid:required-props:begin --> <table> <thead> <tr> <th>Name</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td>cellComponent</td> <td><p>React component responsible for rendering a cell.</p> <p>This component will receive an <code>index</code> and <code>style</code> prop by default. Additionally it will receive prop values passed to <code>cellProps</code>.</p> <p>ℹ️ The prop types for this component are exported as <code>CellComponentProps</code></p> </td> </tr> <tr> <td>cellProps</td> <td><p>Additional props to be passed to the cell-rendering component. Grid will automatically re-render cells when values in this object change.</p> <p>⚠️ This object must not contain <code>ariaAttributes</code>, <code>columnIndex</code>, <code>rowIndex</code>, or <code>style</code> props.</p> </td> </tr> <tr> <td>columnCount</td> <td><p>Number of columns to be rendered in the grid.</p> </td> </tr> <tr> <td>columnWidth</td> <td><p>Column width; the following formats are supported:</p> <ul> <li>number of pixels (number)</li> <li>percentage of the grid&#39;s current width (string)</li> <li>function that returns the row width (in pixels) given an index and <code>cellProps</code></li> </ul> </td> </tr> <tr> <td>rowCount</td> <td><p>Number of rows to be rendered in the grid.</p> </td> </tr> <tr> <td>rowHeight</td> <td><p>Row height; the following formats are supported:</p> <ul> <li>number of pixels (number)</li> <li>percentage of the grid&#39;s current height (string)</li> <li>function that returns the row height (in pixels) given an index and <code>cellProps</code></li> </ul> </td> </tr> </tbody> </table> <!-- Grid:required-props:end --> #### Optional props <!-- Grid:optional-props:begin --> <table> <thead> <tr> <th>Name</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td>className</td> <td><p>CSS class name.</p> </td> </tr> <tr> <td>dir</td> <td><p>Indicates the directionality of grid cells.</p> <p>ℹ️ See HTML <code>dir</code> <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/dir">global attribute</a> for more information.</p> </td> </tr> <tr> <td>style</td> <td><p>Optional CSS properties. The grid of cells will fill the height and width defined by this style.</p> </td> </tr> <tr> <td>children</td> <td><p>Additional content to be rendered within the grid (above cells). This property can be used to render things like overlays or tooltips.</p> </td> </tr> <tr> <td>defaultHeight</td> <td><p>Default height of grid for initial render. This value is important for server rendering.</p> </td> </tr> <tr> <td>defaultWidth</td> <td><p>Default width of grid for initial render. This value is important for server rendering.</p> </td> </tr> <tr> <td>gridRef</td> <td><p>Imperative Grid API.</p> <p>ℹ️ The <code>useGridRef</code> and <code>useGridCallbackRef</code> hooks are exported for convenience use in TypeScript projects.</p> </td> </tr> <tr> <td>onCellsRendered</td> <td><p>Callback notified when the range of rendered cells changes.</p> </td> </tr> <tr> <td>onResize</td> <td><p>Callback notified when the Grid&#39;s outermost HTMLElement resizes. This may be used to (re)scroll a cell into view.</p> </td> </tr> <tr> <td>overscanCount</td> <td><p>How many additional rows/columns to render outside of the visible area. This can reduce visual flickering near the edges of a grid when scrolling.</p> </td> </tr> <tr> <td>tagName</td> <td><p>Can be used to override the root HTML element rendered by the List component. The default value is &quot;div&quot;, meaning that List renders an HTMLDivElement as its root.</p> <p>⚠️ In most use cases the default ARIA roles are sufficient and this prop is not needed.</p> </td> </tr> </tbody> </table> <!-- Grid:optional-props:end -->