react-windowed-list
Version:
A fast, versatile virtual-render list component for React
136 lines (123 loc) • 5 kB
JavaScript
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
// external dependencies
import PropTypes from 'prop-types';
import React from 'react';
import { createComponent } from 'react-parm';
import { measure } from 'remeasure';
// constants
import { HAS_NEW_LIFECYCLE_METHODS, OUTER_CONTAINER_STYLE, VALID_AXES, VALID_AXIS_VALUES, VALID_TYPES, VALID_TYPE_VALUES } from './constants';
// instance methods
import { getItemSizeAndItemsPerRow, getScrollOffset, getScrollParent, getSizeOfListItem, getSpaceBefore, getStartAndEnd, getVisibleRange, renderItems, scrollAround, scrollTo, setReconcileFrameAfterUpdate, setScroll, setStateIfAppropriate, updateFrame, updateScrollParent, updateSimpleFrame, updateUniformFrame, updateVariableFrame } from './instanceMethods';
// lifecycle methods
import { onConstruct, componentDidMount, getDerivedStateFromProps, componentWillReceiveProps, getSnapshotBeforeUpdate, componentDidUpdate, componentWillUnmount } from './lifecycleMethods';
// utils
import { DefaultItemRenderer, DefaultContainerRenderer, getInnerContainerStyle, getListContainerStyle } from './utils';
export var DEFAULT_PARM_OPTIONS = {
// state
state: {
from: 0,
itemsPerRow: 0,
size: 0
},
// lifecycle methods
onConstruct: onConstruct,
componentDidMount: componentDidMount,
componentDidUpdate: componentDidUpdate,
componentWillUnmount: componentWillUnmount,
// instance values
cache: {},
outerContainer: null,
reconcileFrameAfterUpdate: null,
unstableTimeoutId: null,
updateCounter: 0,
updateCounterTimeoutId: null,
// instance methods
getItemSizeAndItemsPerRow: getItemSizeAndItemsPerRow,
getScrollOffset: getScrollOffset,
getScrollParent: getScrollParent,
getSizeOfListItem: getSizeOfListItem,
getSpaceBefore: getSpaceBefore,
getStartAndEnd: getStartAndEnd,
getVisibleRange: getVisibleRange,
renderItems: renderItems,
scrollAround: scrollAround,
scrollTo: scrollTo,
setReconcileFrameAfterUpdate: setReconcileFrameAfterUpdate,
setScroll: setScroll,
setStateIfAppropriate: setStateIfAppropriate,
updateFrame: updateFrame,
updateScrollParent: updateScrollParent,
updateSimpleFrame: updateSimpleFrame,
updateUniformFrame: updateUniformFrame,
updateVariableFrame: updateVariableFrame
};
export var PARM_OPTIONS = HAS_NEW_LIFECYCLE_METHODS ? _extends({}, DEFAULT_PARM_OPTIONS, {
getSnapshotBeforeUpdate: getSnapshotBeforeUpdate
}) : _extends({}, DEFAULT_PARM_OPTIONS, {
componentWillReceiveProps: componentWillReceiveProps
});
export var WindowedListRenderer = createComponent(function (_ref, _ref2) {
var axis = _ref.axis,
length = _ref.length,
type = _ref.type,
usePosition = _ref.usePosition,
useTranslate3d = _ref.useTranslate3d;
var getSpaceBefore = _ref2.getSpaceBefore,
renderItems = _ref2.renderItems,
_ref2$state = _ref2.state,
from = _ref2$state.from,
itemsPerRow = _ref2$state.itemsPerRow;
return type === VALID_TYPES.SIMPLE ? renderItems() : React.createElement(
'div',
{ style: OUTER_CONTAINER_STYLE },
React.createElement(
'div',
{ style: getInnerContainerStyle(axis, length, itemsPerRow, getSpaceBefore) },
React.createElement(
'div',
{ style: getListContainerStyle(axis, usePosition, useTranslate3d, from, getSpaceBefore) },
renderItems()
)
)
);
}, PARM_OPTIONS);
WindowedListRenderer.displayName = 'WindowedListRenderer';
WindowedListRenderer.propTypes = {
axis: PropTypes.oneOf(VALID_AXIS_VALUES).isRequired,
containerRenderer: PropTypes.func.isRequired,
debounceReconciler: PropTypes.number,
getEstimatedItemSize: PropTypes.func,
getItemSize: PropTypes.func,
getScrollParent: PropTypes.func,
initialIndex: PropTypes.number.isRequired,
isHidden: PropTypes.bool.isRequired,
isLazy: PropTypes.bool.isRequired,
itemRenderer: PropTypes.func.isRequired,
length: PropTypes.number.isRequired,
pageSize: PropTypes.number.isRequired,
threshold: PropTypes.number.isRequired,
type: PropTypes.oneOf(VALID_TYPE_VALUES).isRequired,
usePosition: PropTypes.bool.isRequired,
useStaticSize: PropTypes.bool.isRequired,
useTranslate3d: PropTypes.bool.isRequired
};
WindowedListRenderer.defaultProps = {
axis: VALID_AXES.Y,
containerRenderer: DefaultContainerRenderer,
initialIndex: 0,
isHidden: false,
isLazy: false,
itemRenderer: DefaultItemRenderer,
length: 0,
minSize: 1,
pageSize: 10,
threshold: 100,
type: VALID_TYPES.SIMPLE,
usePosition: false,
useStaticSize: false,
useTranslate3d: false
};
if (HAS_NEW_LIFECYCLE_METHODS) {
WindowedListRenderer.getDerivedStateFromProps = getDerivedStateFromProps;
}
export default measure(['height', 'width'], { namespace: '__windowedListMeasurements' })(WindowedListRenderer);