UNPKG

@bestyled/contrib-flatlist

Version:

Implementation of FlatList for the BeStyled Design System

80 lines (62 loc) 8.17 kB
# bestyled/flatlist A performant, infinite, virtualized list for React. See `react-virtualized`, `react-window` and `react-tiny-virtual-list` for prior art; this package is designed to - Be extremely fast, with fine grained use of React Hooks (16.8+) instead of the less granular PureComponent used by existing solutions - Delegate absolution positioning to the browser with use of FlexBox layout (removes need for `top` / `size` styles on every element, as we simply observe what the browser does and then size the outer container accordingly) - Assumes variable size vertical items by default, with auto-resizing whenever the layout changes; if you want a FixedSizeList or Grid you may want to stick with `react-window` - Avoid dependencies on CellMeasurer and other techniques to pre-determine height of every item and instead build right in using a very simple react hook for ResizeObserver (polyfilled using react-resize-observer) - Support scrolling to Index without calculating the size of all intermediate entries, particularly useful for Scroll-To-End based conversational user interfaces - Removes advanced APIs like sticky index and sticks to the absolute minimum required to run a variable dynamic list Unlike just about all other implemetations of virtualized lists for React, no old-school React Components inside, with just one code file for the Functional Component and one file for the Size and Position state manager. ## Example Usage ```ts import React from 'react' import { render } from 'react-dom' import { FlatList } from '@bestyled/contrib-flatlist' import { AutoSizer } from '@bestyled/contrib-common' // kick off the smoothscroll polyfill (for Safari, etc.) import smoothscroll from 'smoothscroll-polyfill' smoothscroll.polyfill() const listItems = items.map((item, index) => ( <React.Fragment key={index}> <RowHeader date={item.header} /> <RowCard item={item} /> </React.Fragment> )) const renderRow = ({ index }) => { return listItems[index] } render( <AutoSizer flex={1} my={3}> {({ height }) => ( <List estimatedItemSize={100} height={height} itemCount={listItems.length} scrollToIndex={listItems.length - 1} scrollToAlignment="end" renderItem={renderRow} /> )} </AutoSizer> ) ``` ### Prop Types | Property | Type | Required? | Description | | :---------------- | :----------------- | :-------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | height | Number \| String\* | ✓ | Height of List. This property will determine the number of rendered items. | | itemCount | Number || The number of items you want to render | | renderItem | Function | ✓ | Responsible for rendering an item given it's index: `({index: number}): React.PropTypes.node`. The returned element must handle the given item key; any styling is up to you. | | scrollToIndex | Number | | Item index to scroll to (by forcefully scrolling if necessary) x | | scrollToAlignment | String | | Used in combination with `scrollToIndex`, this prop controls the alignment of the scrolled to item. One of: `'start'`, `'center'`, `'end'` or `'auto'`. Use `'start'` to always align items to the top of the container and `'end'` to align them bottom. Use `'center`' to align them in the middle of the container. `'auto'` scrolls the least amount possible to ensure that the specified `scrollToIndex` item is fully visible. | | stickyIndices | Number[] | | An array of indexes (eg. `[0, 10, 25, 30]`) to make certain items in the list sticky (`position: sticky`) | | overscanCount | Number | | Number of extra buffer items to render above/below the visible items. Tweaking this can help reduce scroll flickering on certain browsers/devices. | | estimatedItemSize | Number | | Used to estimate the total size of the list before all of its items have actually been measured. The estimated total height is progressively adjusted as items are rendered. | | onScroll | Function | | Callback invoked whenever the scroll offset changes within the inner scrollable region. It has the following signature: `(scrollTop: number, event: React.UIEvent<HTMLDivElement>)`. | ## Dependencies Three standalone React Hooks are used from `@bestyled/contrib-common`. These could easily be incorporated yourself to eliminate this dependency. One of these has an additional depdency on `ResizeObserver` polyfill - useResizeObserver - simple wrapper around ResizeObserver to be notified whenever an element size has been changed - useForceUpdate - convenience method to force a state change - useInstanceRef - convenience method to lazy initialize an instance reference Peer dependency on `smoothscroll-polyfill` and `react` ## License Apache 2.0