UNPKG

react-native-mock-tmp-build

Version:

A fully mocked and test-friendly version of react native

169 lines (155 loc) 5.95 kB
import PropTypes from 'prop-types'; import React from 'react'; import ScrollResponder from '../mixins/ScrollResponder'; import TimerMixin from 'react-timer-mixin'; import ScrollView from './ScrollView'; import ListViewDataSource from '../api/ListViewDataSource'; import createReactClass from 'create-react-class'; const SCROLLVIEW_REF = 'listviewscroll'; const ListView = createReactClass({ propTypes: { ...ScrollView.propTypes, dataSource: PropTypes.instanceOf(ListViewDataSource).isRequired, /** * (sectionID, rowID, adjacentRowHighlighted) => renderable * * If provided, a renderable component to be rendered as the separator * below each row but not the last row if there is a section header below. * Take a sectionID and rowID of the row above and whether its adjacent row * is highlighted. */ renderSeparator: PropTypes.func, /** * (rowData, sectionID, rowID, highlightRow) => renderable * * Takes a data entry from the data source and its ids and should return * a renderable component to be rendered as the row. By default the data * is exactly what was put into the data source, but it's also possible to * provide custom extractors. ListView can be notified when a row is * being highlighted by calling highlightRow function. The separators above and * below will be hidden when a row is highlighted. The highlighted state of * a row can be reset by calling highlightRow(null). */ renderRow: PropTypes.func.isRequired, /** * How many rows to render on initial component mount. Use this to make * it so that the first screen worth of data appears at one time instead of * over the course of multiple frames. */ initialListSize: PropTypes.number, /** * Called when all rows have been rendered and the list has been scrolled * to within onEndReachedThreshold of the bottom. The native scroll * event is provided. */ onEndReached: PropTypes.func, /** * Threshold in pixels for onEndReached. */ onEndReachedThreshold: PropTypes.number, /** * Number of rows to render per event loop. */ pageSize: PropTypes.number, /** * () => renderable * * The header and footer are always rendered (if these props are provided) * on every render pass. If they are expensive to re-render, wrap them * in StaticContainer or other mechanism as appropriate. Footer is always * at the bottom of the list, and header at the top, on every render pass. */ renderFooter: PropTypes.func, renderHeader: PropTypes.func, /** * (sectionData, sectionID) => renderable * * If provided, a sticky header is rendered for this section. The sticky * behavior means that it will scroll with the content at the top of the * section until it reaches the top of the screen, at which point it will * stick to the top until it is pushed off the screen by the next section * header. */ renderSectionHeader: PropTypes.func, /** * (props) => renderable * * A function that returns the scrollable component in which the list rows * are rendered. Defaults to returning a ScrollView with the given props. */ renderScrollComponent: PropTypes.func.isRequired, /** * How early to start rendering rows before they come on screen, in * pixels. */ scrollRenderAheadDistance: PropTypes.number, /** * (visibleRows, changedRows) => void * * Called when the set of visible rows changes. `visibleRows` maps * { sectionID: { rowID: true }} for all the visible rows, and * `changedRows` maps { sectionID: { rowID: true | false }} for the rows * that have changed their visibility, with true indicating visible, and * false indicating the view has moved out of view. */ onChangeVisibleRows: PropTypes.func, /** * A performance optimization for improving scroll perf of * large lists, used in conjunction with overflow: 'hidden' on the row * containers. This is enabled by default. */ removeClippedSubviews: PropTypes.bool, /** * An array of child indices determining which children get docked to the * top of the screen when scrolling. For example, passing * `stickyHeaderIndices={[0]}` will cause the first child to be fixed to the * top of the scroll view. This property is not supported in conjunction * with `horizontal={true}`. * @platform ios */ stickyHeaderIndices: PropTypes.arrayOf(PropTypes.number), }, mixins: [ScrollResponder.Mixin, TimerMixin], statics: { DataSource: ListViewDataSource, }, /** * Exports some data, e.g. for perf investigations or analytics. */ getMetrics() { // eslint-disable-line react/sort-comp // It's fixed, but the linter doesnt want to recognise it... return { contentLength: this.scrollProperties.contentLength, totalRows: this.props.dataSource.getRowCount(), renderedRows: this.state.curRenderedRowsCount, visibleRows: Object.keys(this._visibleRows).length, }; }, scrollTo(destY, destX) { this.getScrollResponder().scrollResponderScrollTo(destX || 0, destY || 0); }, /** * Provides a handle to the underlying scroll responder to support operations * such as scrollTo. */ getScrollResponder() { return this.refs[SCROLLVIEW_REF] && this.refs[SCROLLVIEW_REF].getScrollResponder && this.refs[SCROLLVIEW_REF].getScrollResponder(); }, setNativeProps(props) { this.refs[SCROLLVIEW_REF].setNativeProps(props); }, getDefaultProps() { return { renderScrollComponent: (props) => <ScrollView {...props} /> }; }, getInnerViewNode() { return this.refs[SCROLLVIEW_REF].getInnerViewNode(); }, render() { return null; }, }); module.exports = ListView;