react-virtualized
Advanced tools
Comparing version 10.0.0-alpha.16 to 10.0.0-alpha.17
411
index.cjs.js
@@ -179,2 +179,3 @@ 'use strict'; | ||
_this._itemStyleCache = {}; | ||
_this._resetIsScrollingTimeoutId = null; | ||
@@ -211,10 +212,19 @@ _this.state = { | ||
_this._getCellStyle = function (rowIndex, columnIndex) { | ||
return { | ||
position: 'absolute', | ||
left: getColumnOffset(_this.props, columnIndex, _this._instanceProps), | ||
top: getRowOffset(_this.props, rowIndex, _this._instanceProps), | ||
height: getRowHeight(_this.props, rowIndex, _this._instanceProps), | ||
width: getColumnWidth(_this.props, columnIndex, _this._instanceProps) | ||
}; | ||
_this._getItemStyle = function (rowIndex, columnIndex) { | ||
var key = rowIndex + ':' + columnIndex; | ||
var style = void 0; | ||
if (_this._itemStyleCache.hasOwnProperty(key)) { | ||
style = _this._itemStyleCache[key]; | ||
} else { | ||
_this._itemStyleCache[key] = style = { | ||
position: 'absolute', | ||
left: getColumnOffset(_this.props, columnIndex, _this._instanceProps), | ||
top: getRowOffset(_this.props, rowIndex, _this._instanceProps), | ||
height: getRowHeight(_this.props, rowIndex, _this._instanceProps), | ||
width: getColumnWidth(_this.props, columnIndex, _this._instanceProps) | ||
}; | ||
} | ||
return style; | ||
}; | ||
@@ -273,3 +283,7 @@ | ||
_this.setState({ isScrolling: false }); | ||
_this.setState({ isScrolling: false }, function () { | ||
// Clear style cache after state update has been committed. | ||
// This way we don't break pure sCU for items that don't use isScrolling param. | ||
_this._itemStyleCache = {}; | ||
}); | ||
}; | ||
@@ -365,6 +379,2 @@ | ||
var estimatedTotalHeight = getEstimatedTotalHeight(this.props, this._instanceProps); | ||
var estimatedTotalWidth = getEstimatedTotalWidth(this.props, this._instanceProps); | ||
var _getHorizontalRangeTo = this._getHorizontalRangeToRender(), | ||
@@ -380,13 +390,13 @@ _getHorizontalRangeTo2 = slicedToArray(_getHorizontalRangeTo, 2), | ||
var cells = []; | ||
var items = []; | ||
if (columnCount > 0 && rowCount) { | ||
for (var _rowIndex = rowStartIndex; _rowIndex <= rowStopIndex; _rowIndex++) { | ||
for (var _columnIndex = columnStartIndex; _columnIndex <= columnStopIndex; _columnIndex++) { | ||
cells.push(React__default.createElement(GridItem, { | ||
items.push(React__default.createElement(GridItem, { | ||
columnIndex: _columnIndex, | ||
getCellStyle: this._getCellStyle, | ||
isScrolling: useIsScrolling ? isScrolling : undefined, | ||
key: _rowIndex + ':' + _columnIndex, | ||
renderFunction: this._renderFunction, | ||
rowIndex: _rowIndex | ||
rowIndex: _rowIndex, | ||
style: this._getItemStyle(_rowIndex, _columnIndex) | ||
})); | ||
@@ -397,2 +407,7 @@ } | ||
// Read this value AFTER items have been created, | ||
// So their actual sizes (if variable) are taken into consideration. | ||
var estimatedTotalHeight = getEstimatedTotalHeight(this.props, this._instanceProps); | ||
var estimatedTotalWidth = getEstimatedTotalWidth(this.props, this._instanceProps); | ||
return React__default.createElement( | ||
@@ -423,3 +438,3 @@ 'div', | ||
}, | ||
cells | ||
items | ||
) | ||
@@ -461,3 +476,6 @@ ); | ||
// Lazily create and cache cell styles while scrolling. | ||
// Lazily create and cache item styles while scrolling, | ||
// So that pure component sCU will prevent re-renders. | ||
// We maintain this cache, and pass a style prop rather than index, | ||
// So that List can clear cached styles and force item re-render if necessary. | ||
@@ -478,4 +496,4 @@ }, { | ||
// Overscan by one cell in each direction so that tab/focus works. | ||
// If there isn't at least one extra cell, tab loops back around. | ||
// Overscan by one item in each direction so that tab/focus works. | ||
// If there isn't at least one extra item, tab loops back around. | ||
var overscanBackward = horizontalScrollDirection === 'backward' ? Math.max(1, overscanCount) : 1; | ||
@@ -500,4 +518,4 @@ var overscanForward = horizontalScrollDirection === 'forward' ? Math.max(1, overscanCount) : 1; | ||
// Overscan by one cell in each direction so that tab/focus works. | ||
// If there isn't at least one extra cell, tab loops back around. | ||
// Overscan by one item in each direction so that tab/focus works. | ||
// If there isn't at least one extra item, tab loops back around. | ||
var overscanBackward = verticalScrollDirection === 'backward' ? Math.max(1, overscanCount) : 1; | ||
@@ -512,3 +530,3 @@ var overscanForward = verticalScrollDirection === 'forward' ? Math.max(1, overscanCount) : 1; | ||
// But has hte benefit of not breaking pure sCU checks, | ||
// Allowing List to avoid re-rendering cells until indices change. | ||
// Allowing List to avoid re-rendering items until indices change. | ||
@@ -543,6 +561,6 @@ }], [{ | ||
columnIndex = _props5.columnIndex, | ||
getCellStyle = _props5.getCellStyle, | ||
isScrolling = _props5.isScrolling, | ||
renderFunction = _props5.renderFunction, | ||
rowIndex = _props5.rowIndex; | ||
rowIndex = _props5.rowIndex, | ||
style = _props5.style; | ||
@@ -554,3 +572,3 @@ | ||
rowIndex: rowIndex, | ||
style: getCellStyle(rowIndex, columnIndex) | ||
style: style | ||
}); | ||
@@ -584,12 +602,50 @@ } | ||
var getCellMetadata = function getCellMetadata(cellType, props, index, instanceProps) { | ||
var cellMetadataMap = void 0, | ||
var getEstimatedTotalHeight = function getEstimatedTotalHeight(_ref, _ref2) { | ||
var rowCount = _ref.rowCount; | ||
var rowMetadataMap = _ref2.rowMetadataMap, | ||
estimatedRowHeight = _ref2.estimatedRowHeight, | ||
lastMeasuredRowIndex = _ref2.lastMeasuredRowIndex; | ||
var totalSizeOfMeasuredRows = 0; | ||
if (lastMeasuredRowIndex >= 0) { | ||
var itemMetadata = rowMetadataMap[lastMeasuredRowIndex]; | ||
totalSizeOfMeasuredRows = itemMetadata.offset + itemMetadata.size; | ||
} | ||
var numUnmeasuredItems = rowCount - lastMeasuredRowIndex - 1; | ||
var totalSizeOfUnmeasuredItems = numUnmeasuredItems * estimatedRowHeight; | ||
return totalSizeOfMeasuredRows + totalSizeOfUnmeasuredItems; | ||
}; | ||
var getEstimatedTotalWidth = function getEstimatedTotalWidth(_ref3, _ref4) { | ||
var columnCount = _ref3.columnCount; | ||
var columnMetadataMap = _ref4.columnMetadataMap, | ||
estimatedColumnWidth = _ref4.estimatedColumnWidth, | ||
lastMeasuredColumnIndex = _ref4.lastMeasuredColumnIndex; | ||
var totalSizeOfMeasuredRows = 0; | ||
if (lastMeasuredColumnIndex >= 0) { | ||
var itemMetadata = columnMetadataMap[lastMeasuredColumnIndex]; | ||
totalSizeOfMeasuredRows = itemMetadata.offset + itemMetadata.size; | ||
} | ||
var numUnmeasuredItems = columnCount - lastMeasuredColumnIndex - 1; | ||
var totalSizeOfUnmeasuredItems = numUnmeasuredItems * estimatedColumnWidth; | ||
return totalSizeOfMeasuredRows + totalSizeOfUnmeasuredItems; | ||
}; | ||
var getItemMetadata = function getItemMetadata(itemType, props, index, instanceProps) { | ||
var itemMetadataMap = void 0, | ||
itemSize = void 0, | ||
lastMeasuredIndex = void 0; | ||
if (cellType === 'column') { | ||
cellMetadataMap = instanceProps.columnMetadataMap; | ||
if (itemType === 'column') { | ||
itemMetadataMap = instanceProps.columnMetadataMap; | ||
itemSize = props.columnWidth; | ||
lastMeasuredIndex = instanceProps.lastMeasuredColumnIndex; | ||
} else { | ||
cellMetadataMap = instanceProps.rowMetadataMap; | ||
itemMetadataMap = instanceProps.rowMetadataMap; | ||
itemSize = props.rowHeight; | ||
@@ -602,4 +658,4 @@ lastMeasuredIndex = instanceProps.lastMeasuredRowIndex; | ||
if (lastMeasuredIndex >= 0) { | ||
var cellMetadata = cellMetadataMap[lastMeasuredIndex]; | ||
_offset = cellMetadata.offset + cellMetadata.size; | ||
var itemMetadata = itemMetadataMap[lastMeasuredIndex]; | ||
_offset = itemMetadata.offset + itemMetadata.size; | ||
} | ||
@@ -610,3 +666,3 @@ | ||
cellMetadataMap[i] = { | ||
itemMetadataMap[i] = { | ||
offset: _offset, | ||
@@ -619,3 +675,3 @@ size: _size | ||
if (cellType === 'column') { | ||
if (itemType === 'column') { | ||
instanceProps.lastMeasuredColumnIndex = index; | ||
@@ -627,33 +683,33 @@ } else { | ||
return cellMetadataMap[index]; | ||
return itemMetadataMap[index]; | ||
}; | ||
var findNearestCell = function findNearestCell(cellType, props, instanceProps, offset) { | ||
var cellMetadataMap = void 0, | ||
var findNearestItem = function findNearestItem(itemType, props, instanceProps, offset) { | ||
var itemMetadataMap = void 0, | ||
lastMeasuredIndex = void 0; | ||
if (cellType === 'column') { | ||
cellMetadataMap = instanceProps.columnMetadataMap; | ||
if (itemType === 'column') { | ||
itemMetadataMap = instanceProps.columnMetadataMap; | ||
lastMeasuredIndex = instanceProps.lastMeasuredColumnIndex; | ||
} else { | ||
cellMetadataMap = instanceProps.rowMetadataMap; | ||
itemMetadataMap = instanceProps.rowMetadataMap; | ||
lastMeasuredIndex = instanceProps.lastMeasuredRowIndex; | ||
} | ||
var lastMeasuredCellOffset = lastMeasuredIndex > 0 ? cellMetadataMap[lastMeasuredIndex].offset : 0; | ||
var lastMeasuredItemOffset = lastMeasuredIndex > 0 ? itemMetadataMap[lastMeasuredIndex].offset : 0; | ||
if (lastMeasuredCellOffset >= offset) { | ||
// If we've already measured cells within this range just use a binary search as it's faster. | ||
return findNearestCellBinarySearch(cellType, props, instanceProps, lastMeasuredIndex, 0, offset); | ||
if (lastMeasuredItemOffset >= offset) { | ||
// If we've already measured items within this range just use a binary search as it's faster. | ||
return findNearestItemBinarySearch(itemType, props, instanceProps, lastMeasuredIndex, 0, offset); | ||
} else { | ||
// If we haven't yet measured this high, fallback to an exponential search with an inner binary search. | ||
// The exponential search avoids pre-computing sizes for the full set of cells as a binary search would. | ||
// The exponential search avoids pre-computing sizes for the full set of items as a binary search would. | ||
// The overall complexity for this approach is O(log n). | ||
return findNearestCellExponentialSearch(cellType, props, instanceProps, lastMeasuredIndex, offset); | ||
return findNearestItemExponentialSearch(itemType, props, instanceProps, lastMeasuredIndex, offset); | ||
} | ||
}; | ||
var findNearestCellBinarySearch = function findNearestCellBinarySearch(cellType, props, instanceProps, high, low, offset) { | ||
var findNearestItemBinarySearch = function findNearestItemBinarySearch(itemType, props, instanceProps, high, low, offset) { | ||
while (low <= high) { | ||
var middle = low + Math.floor((high - low) / 2); | ||
var currentOffset = getCellMetadata(cellType, props, middle, instanceProps).offset; | ||
var currentOffset = getItemMetadata(itemType, props, middle, instanceProps).offset; | ||
@@ -676,7 +732,7 @@ if (currentOffset === offset) { | ||
var findNearestCellExponentialSearch = function findNearestCellExponentialSearch(cellType, props, instanceProps, index, offset) { | ||
var itemCount = cellType === 'column' ? props.columnCount : props.rowCount; | ||
var findNearestItemExponentialSearch = function findNearestItemExponentialSearch(itemType, props, instanceProps, index, offset) { | ||
var itemCount = itemType === 'column' ? props.columnCount : props.rowCount; | ||
var interval = 1; | ||
while (index < itemCount && getCellMetadata(cellType, props, index, instanceProps).offset < offset) { | ||
while (index < itemCount && getItemMetadata(itemType, props, index, instanceProps).offset < offset) { | ||
index += interval; | ||
@@ -686,11 +742,16 @@ interval *= 2; | ||
return findNearestCellBinarySearch(cellType, props, instanceProps, Math.min(index, itemCount - 1), Math.floor(index / 2), offset); | ||
return findNearestItemBinarySearch(itemType, props, instanceProps, Math.min(index, itemCount - 1), Math.floor(index / 2), offset); | ||
}; | ||
var getOffsetForIndexAndAlignment = function getOffsetForIndexAndAlignment(cellType, props, index, align, scrollOffset, instanceProps) { | ||
var size = cellType === 'column' ? props.width : props.height; | ||
var cellMetadata = getCellMetadata(cellType, props, index, instanceProps); | ||
var maxOffset = cellMetadata.offset; | ||
var minOffset = cellMetadata.offset - size + cellMetadata.size; | ||
var getOffsetForIndexAndAlignment = function getOffsetForIndexAndAlignment(itemType, props, index, align, scrollOffset, instanceProps) { | ||
var size = itemType === 'column' ? props.width : props.height; | ||
var itemMetadata = getItemMetadata(itemType, props, index, instanceProps); | ||
// Get estimated total size after ItemMetadata is computed, | ||
// To ensure it reflects actual measurements instead of just estimates. | ||
var estimatedTotalSize = itemType === 'column' ? getEstimatedTotalWidth(props, instanceProps) : getEstimatedTotalHeight(props, instanceProps); | ||
var maxOffset = Math.min(estimatedTotalSize - size, itemMetadata.offset); | ||
var minOffset = Math.max(0, itemMetadata.offset - size + itemMetadata.size); | ||
switch (align) { | ||
@@ -717,7 +778,7 @@ case 'start': | ||
getColumnOffset: function getColumnOffset(props, index, instanceProps) { | ||
return getCellMetadata('column', props, index, instanceProps).offset; | ||
return getItemMetadata('column', props, index, instanceProps).offset; | ||
}, | ||
getColumnStartIndexForOffset: function getColumnStartIndexForOffset(props, scrollLeft, instanceProps) { | ||
return findNearestCell('column', props, instanceProps, scrollLeft); | ||
return findNearestItem('column', props, instanceProps, scrollLeft); | ||
}, | ||
@@ -730,6 +791,6 @@ | ||
var cellMetadata = getCellMetadata('column', props, startIndex, instanceProps); | ||
var itemMetadata = getItemMetadata('column', props, startIndex, instanceProps); | ||
var maxOffset = scrollLeft + width; | ||
var offset = cellMetadata.offset + cellMetadata.size; | ||
var offset = itemMetadata.offset + itemMetadata.size; | ||
var stopIndex = startIndex; | ||
@@ -739,3 +800,3 @@ | ||
stopIndex++; | ||
offset += getCellMetadata('column', props, stopIndex, instanceProps).size; | ||
offset += getItemMetadata('column', props, stopIndex, instanceProps).size; | ||
} | ||
@@ -750,40 +811,5 @@ | ||
getEstimatedTotalHeight: function getEstimatedTotalHeight(_ref, _ref2) { | ||
var rowCount = _ref.rowCount; | ||
var rowMetadataMap = _ref2.rowMetadataMap, | ||
estimatedRowHeight = _ref2.estimatedRowHeight, | ||
lastMeasuredRowIndex = _ref2.lastMeasuredRowIndex; | ||
getEstimatedTotalHeight: getEstimatedTotalHeight, | ||
getEstimatedTotalWidth: getEstimatedTotalWidth, | ||
var totalSizeOfMeasuredRows = 0; | ||
if (lastMeasuredRowIndex >= 0) { | ||
var cellMetadata = rowMetadataMap[lastMeasuredRowIndex]; | ||
totalSizeOfMeasuredRows = cellMetadata.offset + cellMetadata.size; | ||
} | ||
var numUnmeasuredCells = rowCount - lastMeasuredRowIndex - 1; | ||
var totalSizeOfUnmeasuredCells = numUnmeasuredCells * estimatedRowHeight; | ||
return totalSizeOfMeasuredRows + totalSizeOfUnmeasuredCells; | ||
}, | ||
getEstimatedTotalWidth: function getEstimatedTotalWidth(_ref3, _ref4) { | ||
var columnCount = _ref3.columnCount; | ||
var columnMetadataMap = _ref4.columnMetadataMap, | ||
estimatedColumnWidth = _ref4.estimatedColumnWidth, | ||
lastMeasuredColumnIndex = _ref4.lastMeasuredColumnIndex; | ||
var totalSizeOfMeasuredRows = 0; | ||
if (lastMeasuredColumnIndex >= 0) { | ||
var cellMetadata = columnMetadataMap[lastMeasuredColumnIndex]; | ||
totalSizeOfMeasuredRows = cellMetadata.offset + cellMetadata.size; | ||
} | ||
var numUnmeasuredCells = columnCount - lastMeasuredColumnIndex - 1; | ||
var totalSizeOfUnmeasuredCells = numUnmeasuredCells * estimatedColumnWidth; | ||
return totalSizeOfMeasuredRows + totalSizeOfUnmeasuredCells; | ||
}, | ||
getOffsetForColumnAndAlignment: function getOffsetForColumnAndAlignment(props, index, align, scrollOffset, instanceProps) { | ||
@@ -798,3 +824,3 @@ return getOffsetForIndexAndAlignment('column', props, index, align, scrollOffset, instanceProps); | ||
getRowOffset: function getRowOffset(props, index, instanceProps) { | ||
return getCellMetadata('row', props, index, instanceProps).offset; | ||
return getItemMetadata('row', props, index, instanceProps).offset; | ||
}, | ||
@@ -807,3 +833,3 @@ | ||
getRowStartIndexForOffset: function getRowStartIndexForOffset(props, scrollTop, instanceProps) { | ||
return findNearestCell('row', props, instanceProps, scrollTop); | ||
return findNearestItem('row', props, instanceProps, scrollTop); | ||
}, | ||
@@ -816,6 +842,6 @@ | ||
var cellMetadata = getCellMetadata('row', props, startIndex, instanceProps); | ||
var itemMetadata = getItemMetadata('row', props, startIndex, instanceProps); | ||
var maxOffset = scrollTop + height; | ||
var offset = cellMetadata.offset + cellMetadata.size; | ||
var offset = itemMetadata.offset + itemMetadata.size; | ||
var stopIndex = startIndex; | ||
@@ -825,3 +851,3 @@ | ||
stopIndex++; | ||
offset += getCellMetadata('row', props, stopIndex, instanceProps).size; | ||
offset += getItemMetadata('row', props, stopIndex, instanceProps).size; | ||
} | ||
@@ -848,9 +874,23 @@ | ||
instance.resetAfterColumnIndex = function (index) { | ||
instanceProps.lastMeasuredColumnIndex = index - 1; | ||
instanceProps.lastMeasuredColumnIndex = Math.min(instanceProps.lastMeasuredColumnIndex, index - 1); | ||
instance._itemStyleCache = {}; | ||
instance.forceUpdate(); | ||
}; | ||
instance.resetAfterRowIndex = function (index) { | ||
instanceProps.lastMeasuredRowIndex = index - 1; | ||
instanceProps.lastMeasuredRowIndex = Math.min(instanceProps.lastMeasuredRowIndex, index - 1); | ||
instance._itemStyleCache = {}; | ||
instance.forceUpdate(); | ||
}; | ||
instance.resetAfterIndices = function (_ref6) { | ||
var columnIndex = _ref6.columnIndex, | ||
rowIndex = _ref6.rowIndex; | ||
instanceProps.lastMeasuredColumnIndex = Math.min(instanceProps.lastMeasuredColumnIndex, columnIndex - 1); | ||
instanceProps.lastMeasuredRowIndex = Math.min(instanceProps.lastMeasuredRowIndex, rowIndex - 1); | ||
instance._itemStyleCache = {}; | ||
instance.forceUpdate(); | ||
}; | ||
return instanceProps; | ||
@@ -860,5 +900,5 @@ }, | ||
validateProps: function validateProps(_ref6) { | ||
var columnWidth = _ref6.columnWidth, | ||
rowHeight = _ref6.rowHeight; | ||
validateProps: function validateProps(_ref7) { | ||
var columnWidth = _ref7.columnWidth, | ||
rowHeight = _ref7.rowHeight; | ||
@@ -880,3 +920,3 @@ if (process.env.NODE_ENV !== 'production') { | ||
var getCellOffset = _ref.getCellOffset, | ||
var getItemOffset = _ref.getItemOffset, | ||
getEstimatedTotalSize = _ref.getEstimatedTotalSize, | ||
@@ -904,3 +944,3 @@ getItemSize = _ref.getItemSize, | ||
return _ret = (_temp = (_this = possibleConstructorReturn(this, (_ref2 = List.__proto__ || Object.getPrototypeOf(List)).call.apply(_ref2, [this].concat(args))), _this), _this._instanceProps = initInstanceProps(_this.props, _this), _this._resetIsScrollingTimeoutId = null, _this.state = { | ||
return _ret = (_temp = (_this = possibleConstructorReturn(this, (_ref2 = List.__proto__ || Object.getPrototypeOf(List)).call.apply(_ref2, [this].concat(args))), _this), _this._instanceProps = initInstanceProps(_this.props, _this), _this._itemStyleCache = {}, _this._resetIsScrollingTimeoutId = null, _this.state = { | ||
isScrolling: false, | ||
@@ -923,12 +963,20 @@ scrollDirection: 'forward', | ||
}); | ||
}), _this._getCellStyle = function (index) { | ||
}), _this._getItemStyle = function (index) { | ||
var direction = _this.props.direction; | ||
return { | ||
position: 'absolute', | ||
left: direction === 'horizontal' ? getCellOffset(_this.props, index, _this._instanceProps) : 0, | ||
top: direction === 'vertical' ? getCellOffset(_this.props, index, _this._instanceProps) : 0, | ||
height: direction === 'vertical' ? getItemSize(_this.props, index, _this._instanceProps) : '100%', | ||
width: direction === 'horizontal' ? getItemSize(_this.props, index, _this._instanceProps) : '100%' | ||
}; | ||
var style = void 0; | ||
if (_this._itemStyleCache.hasOwnProperty(index)) { | ||
style = _this._itemStyleCache[index]; | ||
} else { | ||
_this._itemStyleCache[index] = style = { | ||
position: 'absolute', | ||
left: direction === 'horizontal' ? getItemOffset(_this.props, index, _this._instanceProps) : 0, | ||
top: direction === 'vertical' ? getItemOffset(_this.props, index, _this._instanceProps) : 0, | ||
height: direction === 'vertical' ? getItemSize(_this.props, index, _this._instanceProps) : '100%', | ||
width: direction === 'horizontal' ? getItemSize(_this.props, index, _this._instanceProps) : '100%' | ||
}; | ||
} | ||
return style; | ||
}, _this._onScrollHorizontal = function (event) { | ||
@@ -983,3 +1031,7 @@ var scrollLeft = event.currentTarget.scrollLeft; | ||
_this.setState({ isScrolling: false }); | ||
_this.setState({ isScrolling: false }, function () { | ||
// Clear style cache after state update has been committed. | ||
// This way we don't break pure sCU for items that don't use isScrolling param. | ||
_this._itemStyleCache = {}; | ||
}); | ||
}, _temp), possibleConstructorReturn(_this, _ret); | ||
@@ -1067,4 +1119,2 @@ } | ||
var estimatedTotalSize = getEstimatedTotalSize(this.props, this._instanceProps); | ||
var _getRangeToRender2 = this._getRangeToRender(), | ||
@@ -1075,11 +1125,11 @@ _getRangeToRender3 = slicedToArray(_getRangeToRender2, 2), | ||
var cells = []; | ||
var items = []; | ||
if (itemCount > 0) { | ||
for (var _index = startIndex; _index <= stopIndex; _index++) { | ||
cells.push(React__default.createElement(ListItem, { | ||
getCellStyle: this._getCellStyle, | ||
items.push(React__default.createElement(ListItem, { | ||
key: _index, | ||
index: _index, | ||
isScrolling: useIsScrolling ? isScrolling : undefined, | ||
renderFunction: this._renderFunction | ||
renderFunction: this._renderFunction, | ||
style: this._getItemStyle(_index) | ||
})); | ||
@@ -1089,2 +1139,6 @@ } | ||
// Read this value AFTER items have been created, | ||
// So their actual sizes (if variable) are taken into consideration. | ||
var estimatedTotalSize = getEstimatedTotalSize(this.props, this._instanceProps); | ||
return React__default.createElement( | ||
@@ -1115,3 +1169,3 @@ 'div', | ||
}, | ||
cells | ||
items | ||
) | ||
@@ -1144,3 +1198,6 @@ ); | ||
// Lazily create and cache cell styles while scrolling. | ||
// Lazily create and cache item styles while scrolling, | ||
// So that pure component sCU will prevent re-renders. | ||
// We maintain this cache, and pass a style prop rather than index, | ||
// So that List can clear cached styles and force item re-render if necessary. | ||
@@ -1161,4 +1218,4 @@ }, { | ||
// Overscan by one cell in each direction so that tab/focus works. | ||
// If there isn't at least one extra cell, tab loops back around. | ||
// Overscan by one item in each direction so that tab/focus works. | ||
// If there isn't at least one extra item, tab loops back around. | ||
var overscanBackward = scrollDirection === 'backward' ? Math.max(1, overscanCount) : 1; | ||
@@ -1173,3 +1230,3 @@ var overscanForward = scrollDirection === 'forward' ? Math.max(1, overscanCount) : 1; | ||
// But has hte benefit of not breaking pure sCU checks, | ||
// Allowing List to avoid re-rendering cells until indices change. | ||
// Allowing List to avoid re-rendering items until indices change. | ||
@@ -1204,6 +1261,6 @@ }], [{ | ||
var _props4 = this.props, | ||
getCellStyle = _props4.getCellStyle, | ||
index = _props4.index, | ||
isScrolling = _props4.isScrolling, | ||
renderFunction = _props4.renderFunction; | ||
renderFunction = _props4.renderFunction, | ||
style = _props4.style; | ||
@@ -1214,3 +1271,3 @@ | ||
isScrolling: isScrolling, | ||
style: getCellStyle(index) | ||
style: style | ||
}); | ||
@@ -1253,6 +1310,6 @@ } | ||
var getCellMetadata$1 = function getCellMetadata(props, index, instanceProps) { | ||
var getItemMetadata$1 = function getItemMetadata(props, index, instanceProps) { | ||
var _ref = props, | ||
itemSize = _ref.itemSize; | ||
var cellMetadataMap = instanceProps.cellMetadataMap, | ||
var itemMetadataMap = instanceProps.itemMetadataMap, | ||
lastMeasuredIndex = instanceProps.lastMeasuredIndex; | ||
@@ -1264,4 +1321,4 @@ | ||
if (lastMeasuredIndex >= 0) { | ||
var cellMetadata = cellMetadataMap[lastMeasuredIndex]; | ||
_offset = cellMetadata.offset + cellMetadata.size; | ||
var itemMetadata = itemMetadataMap[lastMeasuredIndex]; | ||
_offset = itemMetadata.offset + itemMetadata.size; | ||
} | ||
@@ -1272,3 +1329,3 @@ | ||
cellMetadataMap[i] = { | ||
itemMetadataMap[i] = { | ||
offset: _offset, | ||
@@ -1284,27 +1341,27 @@ size: _size | ||
return cellMetadataMap[index]; | ||
return itemMetadataMap[index]; | ||
}; | ||
var findNearestCell$1 = function findNearestCell(props, instanceProps, offset) { | ||
var cellMetadataMap = instanceProps.cellMetadataMap, | ||
var findNearestItem$1 = function findNearestItem(props, instanceProps, offset) { | ||
var itemMetadataMap = instanceProps.itemMetadataMap, | ||
lastMeasuredIndex = instanceProps.lastMeasuredIndex; | ||
var lastMeasuredCellOffset = lastMeasuredIndex > 0 ? cellMetadataMap[lastMeasuredIndex].offset : 0; | ||
var lastMeasuredItemOffset = lastMeasuredIndex > 0 ? itemMetadataMap[lastMeasuredIndex].offset : 0; | ||
if (lastMeasuredCellOffset >= offset) { | ||
// If we've already measured cells within this range just use a binary search as it's faster. | ||
return findNearestCellBinarySearch$1(props, instanceProps, lastMeasuredIndex, 0, offset); | ||
if (lastMeasuredItemOffset >= offset) { | ||
// If we've already measured items within this range just use a binary search as it's faster. | ||
return findNearestItemBinarySearch$1(props, instanceProps, lastMeasuredIndex, 0, offset); | ||
} else { | ||
// If we haven't yet measured this high, fallback to an exponential search with an inner binary search. | ||
// The exponential search avoids pre-computing sizes for the full set of cells as a binary search would. | ||
// The exponential search avoids pre-computing sizes for the full set of items as a binary search would. | ||
// The overall complexity for this approach is O(log n). | ||
return findNearestCellExponentialSearch$1(props, instanceProps, lastMeasuredIndex, offset); | ||
return findNearestItemExponentialSearch$1(props, instanceProps, lastMeasuredIndex, offset); | ||
} | ||
}; | ||
var findNearestCellBinarySearch$1 = function findNearestCellBinarySearch(props, instanceProps, high, low, offset) { | ||
var findNearestItemBinarySearch$1 = function findNearestItemBinarySearch(props, instanceProps, high, low, offset) { | ||
while (low <= high) { | ||
var middle = low + Math.floor((high - low) / 2); | ||
var currentOffset = getCellMetadata$1(props, middle, instanceProps).offset; | ||
var currentOffset = getItemMetadata$1(props, middle, instanceProps).offset; | ||
@@ -1327,3 +1384,3 @@ if (currentOffset === offset) { | ||
var findNearestCellExponentialSearch$1 = function findNearestCellExponentialSearch(props, instanceProps, index, offset) { | ||
var findNearestItemExponentialSearch$1 = function findNearestItemExponentialSearch(props, instanceProps, index, offset) { | ||
var itemCount = props.itemCount; | ||
@@ -1333,3 +1390,3 @@ | ||
while (index < itemCount && getCellMetadata$1(props, index, instanceProps).offset < offset) { | ||
while (index < itemCount && getItemMetadata$1(props, index, instanceProps).offset < offset) { | ||
index += interval; | ||
@@ -1339,3 +1396,3 @@ interval *= 2; | ||
return findNearestCellBinarySearch$1(props, instanceProps, Math.min(index, itemCount - 1), Math.floor(index / 2), offset); | ||
return findNearestItemBinarySearch$1(props, instanceProps, Math.min(index, itemCount - 1), Math.floor(index / 2), offset); | ||
}; | ||
@@ -1345,26 +1402,26 @@ | ||
var itemCount = _ref2.itemCount; | ||
var cellMetadataMap = _ref3.cellMetadataMap, | ||
var itemMetadataMap = _ref3.itemMetadataMap, | ||
estimatedItemSize = _ref3.estimatedItemSize, | ||
lastMeasuredIndex = _ref3.lastMeasuredIndex; | ||
var totalSizeOfMeasuredCells = 0; | ||
var totalSizeOfMeasuredItems = 0; | ||
if (lastMeasuredIndex >= 0) { | ||
var cellMetadata = cellMetadataMap[lastMeasuredIndex]; | ||
totalSizeOfMeasuredCells = cellMetadata.offset + cellMetadata.size; | ||
var itemMetadata = itemMetadataMap[lastMeasuredIndex]; | ||
totalSizeOfMeasuredItems = itemMetadata.offset + itemMetadata.size; | ||
} | ||
var numUnmeasuredCells = itemCount - lastMeasuredIndex - 1; | ||
var totalSizeOfUnmeasuredCells = numUnmeasuredCells * estimatedItemSize; | ||
var numUnmeasuredItems = itemCount - lastMeasuredIndex - 1; | ||
var totalSizeOfUnmeasuredItems = numUnmeasuredItems * estimatedItemSize; | ||
return totalSizeOfMeasuredCells + totalSizeOfUnmeasuredCells; | ||
return totalSizeOfMeasuredItems + totalSizeOfUnmeasuredItems; | ||
}; | ||
var VariableSizeList = createListComponent({ | ||
getCellOffset: function getCellOffset(props, index, instanceProps) { | ||
return getCellMetadata$1(props, index, instanceProps).offset; | ||
getItemOffset: function getItemOffset(props, index, instanceProps) { | ||
return getItemMetadata$1(props, index, instanceProps).offset; | ||
}, | ||
getItemSize: function getItemSize(props, index, instanceProps) { | ||
return instanceProps.cellMetadataMap[index].size; | ||
return instanceProps.itemMetadataMap[index].size; | ||
}, | ||
@@ -1381,10 +1438,10 @@ | ||
var size = direction === 'horizontal' ? width : height; | ||
var cellMetadata = getCellMetadata$1(props, index, instanceProps); | ||
var itemMetadata = getItemMetadata$1(props, index, instanceProps); | ||
// Get estimated total size after CellMetadata is computed, | ||
// Get estimated total size after ItemMetadata is computed, | ||
// To ensure it reflects actual measurements instead of just estimates. | ||
var estimatedTotalSize = getEstimatedTotalSize(props, instanceProps); | ||
var maxOffset = Math.min(estimatedTotalSize - size, cellMetadata.offset); | ||
var minOffset = Math.max(0, cellMetadata.offset - size + cellMetadata.size); | ||
var maxOffset = Math.min(estimatedTotalSize - size, itemMetadata.offset); | ||
var minOffset = Math.max(0, itemMetadata.offset - size + itemMetadata.size); | ||
@@ -1411,3 +1468,3 @@ switch (align) { | ||
getStartIndexForOffset: function getStartIndexForOffset(props, offset, instanceProps) { | ||
return findNearestCell$1(props, instanceProps, offset); | ||
return findNearestItem$1(props, instanceProps, offset); | ||
}, | ||
@@ -1423,6 +1480,6 @@ | ||
var size = direction === 'horizontal' ? width : height; | ||
var cellMetadata = getCellMetadata$1(props, startIndex, instanceProps); | ||
var itemMetadata = getItemMetadata$1(props, startIndex, instanceProps); | ||
var maxOffset = scrollOffset + size; | ||
var offset = cellMetadata.offset + cellMetadata.size; | ||
var offset = itemMetadata.offset + itemMetadata.size; | ||
var stopIndex = startIndex; | ||
@@ -1432,3 +1489,3 @@ | ||
stopIndex++; | ||
offset += getCellMetadata$1(props, stopIndex, instanceProps).size; | ||
offset += getItemMetadata$1(props, stopIndex, instanceProps).size; | ||
} | ||
@@ -1445,3 +1502,3 @@ | ||
var instanceProps = { | ||
cellMetadataMap: {}, | ||
itemMetadataMap: {}, | ||
estimatedItemSize: estimatedItemSize || DEFAULT_ESTIMATED_ITEM_SIZE$1, | ||
@@ -1452,3 +1509,5 @@ lastMeasuredIndex: -1 | ||
instance.resetAfterIndex = function (index) { | ||
instanceProps.lastMeasuredIndex = index - 1; | ||
instanceProps.lastMeasuredIndex = Math.min(instanceProps.lastMeasuredIndex, index - 1); | ||
instance._itemStyleCache = {}; | ||
instance.forceUpdate(); | ||
}; | ||
@@ -1610,3 +1669,3 @@ | ||
var FixedSizeList = createListComponent({ | ||
getCellOffset: function getCellOffset(_ref, index) { | ||
getItemOffset: function getItemOffset(_ref, index) { | ||
var itemSize = _ref.itemSize, | ||
@@ -1613,0 +1672,0 @@ size = _ref.size; |
411
index.esm.js
@@ -172,2 +172,3 @@ import React, { PureComponent } from 'react'; | ||
_this._itemStyleCache = {}; | ||
_this._resetIsScrollingTimeoutId = null; | ||
@@ -204,10 +205,19 @@ _this.state = { | ||
_this._getCellStyle = function (rowIndex, columnIndex) { | ||
return { | ||
position: 'absolute', | ||
left: getColumnOffset(_this.props, columnIndex, _this._instanceProps), | ||
top: getRowOffset(_this.props, rowIndex, _this._instanceProps), | ||
height: getRowHeight(_this.props, rowIndex, _this._instanceProps), | ||
width: getColumnWidth(_this.props, columnIndex, _this._instanceProps) | ||
}; | ||
_this._getItemStyle = function (rowIndex, columnIndex) { | ||
var key = rowIndex + ':' + columnIndex; | ||
var style = void 0; | ||
if (_this._itemStyleCache.hasOwnProperty(key)) { | ||
style = _this._itemStyleCache[key]; | ||
} else { | ||
_this._itemStyleCache[key] = style = { | ||
position: 'absolute', | ||
left: getColumnOffset(_this.props, columnIndex, _this._instanceProps), | ||
top: getRowOffset(_this.props, rowIndex, _this._instanceProps), | ||
height: getRowHeight(_this.props, rowIndex, _this._instanceProps), | ||
width: getColumnWidth(_this.props, columnIndex, _this._instanceProps) | ||
}; | ||
} | ||
return style; | ||
}; | ||
@@ -266,3 +276,7 @@ | ||
_this.setState({ isScrolling: false }); | ||
_this.setState({ isScrolling: false }, function () { | ||
// Clear style cache after state update has been committed. | ||
// This way we don't break pure sCU for items that don't use isScrolling param. | ||
_this._itemStyleCache = {}; | ||
}); | ||
}; | ||
@@ -358,6 +372,2 @@ | ||
var estimatedTotalHeight = getEstimatedTotalHeight(this.props, this._instanceProps); | ||
var estimatedTotalWidth = getEstimatedTotalWidth(this.props, this._instanceProps); | ||
var _getHorizontalRangeTo = this._getHorizontalRangeToRender(), | ||
@@ -373,13 +383,13 @@ _getHorizontalRangeTo2 = slicedToArray(_getHorizontalRangeTo, 2), | ||
var cells = []; | ||
var items = []; | ||
if (columnCount > 0 && rowCount) { | ||
for (var _rowIndex = rowStartIndex; _rowIndex <= rowStopIndex; _rowIndex++) { | ||
for (var _columnIndex = columnStartIndex; _columnIndex <= columnStopIndex; _columnIndex++) { | ||
cells.push(React.createElement(GridItem, { | ||
items.push(React.createElement(GridItem, { | ||
columnIndex: _columnIndex, | ||
getCellStyle: this._getCellStyle, | ||
isScrolling: useIsScrolling ? isScrolling : undefined, | ||
key: _rowIndex + ':' + _columnIndex, | ||
renderFunction: this._renderFunction, | ||
rowIndex: _rowIndex | ||
rowIndex: _rowIndex, | ||
style: this._getItemStyle(_rowIndex, _columnIndex) | ||
})); | ||
@@ -390,2 +400,7 @@ } | ||
// Read this value AFTER items have been created, | ||
// So their actual sizes (if variable) are taken into consideration. | ||
var estimatedTotalHeight = getEstimatedTotalHeight(this.props, this._instanceProps); | ||
var estimatedTotalWidth = getEstimatedTotalWidth(this.props, this._instanceProps); | ||
return React.createElement( | ||
@@ -416,3 +431,3 @@ 'div', | ||
}, | ||
cells | ||
items | ||
) | ||
@@ -454,3 +469,6 @@ ); | ||
// Lazily create and cache cell styles while scrolling. | ||
// Lazily create and cache item styles while scrolling, | ||
// So that pure component sCU will prevent re-renders. | ||
// We maintain this cache, and pass a style prop rather than index, | ||
// So that List can clear cached styles and force item re-render if necessary. | ||
@@ -471,4 +489,4 @@ }, { | ||
// Overscan by one cell in each direction so that tab/focus works. | ||
// If there isn't at least one extra cell, tab loops back around. | ||
// Overscan by one item in each direction so that tab/focus works. | ||
// If there isn't at least one extra item, tab loops back around. | ||
var overscanBackward = horizontalScrollDirection === 'backward' ? Math.max(1, overscanCount) : 1; | ||
@@ -493,4 +511,4 @@ var overscanForward = horizontalScrollDirection === 'forward' ? Math.max(1, overscanCount) : 1; | ||
// Overscan by one cell in each direction so that tab/focus works. | ||
// If there isn't at least one extra cell, tab loops back around. | ||
// Overscan by one item in each direction so that tab/focus works. | ||
// If there isn't at least one extra item, tab loops back around. | ||
var overscanBackward = verticalScrollDirection === 'backward' ? Math.max(1, overscanCount) : 1; | ||
@@ -505,3 +523,3 @@ var overscanForward = verticalScrollDirection === 'forward' ? Math.max(1, overscanCount) : 1; | ||
// But has hte benefit of not breaking pure sCU checks, | ||
// Allowing List to avoid re-rendering cells until indices change. | ||
// Allowing List to avoid re-rendering items until indices change. | ||
@@ -536,6 +554,6 @@ }], [{ | ||
columnIndex = _props5.columnIndex, | ||
getCellStyle = _props5.getCellStyle, | ||
isScrolling = _props5.isScrolling, | ||
renderFunction = _props5.renderFunction, | ||
rowIndex = _props5.rowIndex; | ||
rowIndex = _props5.rowIndex, | ||
style = _props5.style; | ||
@@ -547,3 +565,3 @@ | ||
rowIndex: rowIndex, | ||
style: getCellStyle(rowIndex, columnIndex) | ||
style: style | ||
}); | ||
@@ -577,12 +595,50 @@ } | ||
var getCellMetadata = function getCellMetadata(cellType, props, index, instanceProps) { | ||
var cellMetadataMap = void 0, | ||
var getEstimatedTotalHeight = function getEstimatedTotalHeight(_ref, _ref2) { | ||
var rowCount = _ref.rowCount; | ||
var rowMetadataMap = _ref2.rowMetadataMap, | ||
estimatedRowHeight = _ref2.estimatedRowHeight, | ||
lastMeasuredRowIndex = _ref2.lastMeasuredRowIndex; | ||
var totalSizeOfMeasuredRows = 0; | ||
if (lastMeasuredRowIndex >= 0) { | ||
var itemMetadata = rowMetadataMap[lastMeasuredRowIndex]; | ||
totalSizeOfMeasuredRows = itemMetadata.offset + itemMetadata.size; | ||
} | ||
var numUnmeasuredItems = rowCount - lastMeasuredRowIndex - 1; | ||
var totalSizeOfUnmeasuredItems = numUnmeasuredItems * estimatedRowHeight; | ||
return totalSizeOfMeasuredRows + totalSizeOfUnmeasuredItems; | ||
}; | ||
var getEstimatedTotalWidth = function getEstimatedTotalWidth(_ref3, _ref4) { | ||
var columnCount = _ref3.columnCount; | ||
var columnMetadataMap = _ref4.columnMetadataMap, | ||
estimatedColumnWidth = _ref4.estimatedColumnWidth, | ||
lastMeasuredColumnIndex = _ref4.lastMeasuredColumnIndex; | ||
var totalSizeOfMeasuredRows = 0; | ||
if (lastMeasuredColumnIndex >= 0) { | ||
var itemMetadata = columnMetadataMap[lastMeasuredColumnIndex]; | ||
totalSizeOfMeasuredRows = itemMetadata.offset + itemMetadata.size; | ||
} | ||
var numUnmeasuredItems = columnCount - lastMeasuredColumnIndex - 1; | ||
var totalSizeOfUnmeasuredItems = numUnmeasuredItems * estimatedColumnWidth; | ||
return totalSizeOfMeasuredRows + totalSizeOfUnmeasuredItems; | ||
}; | ||
var getItemMetadata = function getItemMetadata(itemType, props, index, instanceProps) { | ||
var itemMetadataMap = void 0, | ||
itemSize = void 0, | ||
lastMeasuredIndex = void 0; | ||
if (cellType === 'column') { | ||
cellMetadataMap = instanceProps.columnMetadataMap; | ||
if (itemType === 'column') { | ||
itemMetadataMap = instanceProps.columnMetadataMap; | ||
itemSize = props.columnWidth; | ||
lastMeasuredIndex = instanceProps.lastMeasuredColumnIndex; | ||
} else { | ||
cellMetadataMap = instanceProps.rowMetadataMap; | ||
itemMetadataMap = instanceProps.rowMetadataMap; | ||
itemSize = props.rowHeight; | ||
@@ -595,4 +651,4 @@ lastMeasuredIndex = instanceProps.lastMeasuredRowIndex; | ||
if (lastMeasuredIndex >= 0) { | ||
var cellMetadata = cellMetadataMap[lastMeasuredIndex]; | ||
_offset = cellMetadata.offset + cellMetadata.size; | ||
var itemMetadata = itemMetadataMap[lastMeasuredIndex]; | ||
_offset = itemMetadata.offset + itemMetadata.size; | ||
} | ||
@@ -603,3 +659,3 @@ | ||
cellMetadataMap[i] = { | ||
itemMetadataMap[i] = { | ||
offset: _offset, | ||
@@ -612,3 +668,3 @@ size: _size | ||
if (cellType === 'column') { | ||
if (itemType === 'column') { | ||
instanceProps.lastMeasuredColumnIndex = index; | ||
@@ -620,33 +676,33 @@ } else { | ||
return cellMetadataMap[index]; | ||
return itemMetadataMap[index]; | ||
}; | ||
var findNearestCell = function findNearestCell(cellType, props, instanceProps, offset) { | ||
var cellMetadataMap = void 0, | ||
var findNearestItem = function findNearestItem(itemType, props, instanceProps, offset) { | ||
var itemMetadataMap = void 0, | ||
lastMeasuredIndex = void 0; | ||
if (cellType === 'column') { | ||
cellMetadataMap = instanceProps.columnMetadataMap; | ||
if (itemType === 'column') { | ||
itemMetadataMap = instanceProps.columnMetadataMap; | ||
lastMeasuredIndex = instanceProps.lastMeasuredColumnIndex; | ||
} else { | ||
cellMetadataMap = instanceProps.rowMetadataMap; | ||
itemMetadataMap = instanceProps.rowMetadataMap; | ||
lastMeasuredIndex = instanceProps.lastMeasuredRowIndex; | ||
} | ||
var lastMeasuredCellOffset = lastMeasuredIndex > 0 ? cellMetadataMap[lastMeasuredIndex].offset : 0; | ||
var lastMeasuredItemOffset = lastMeasuredIndex > 0 ? itemMetadataMap[lastMeasuredIndex].offset : 0; | ||
if (lastMeasuredCellOffset >= offset) { | ||
// If we've already measured cells within this range just use a binary search as it's faster. | ||
return findNearestCellBinarySearch(cellType, props, instanceProps, lastMeasuredIndex, 0, offset); | ||
if (lastMeasuredItemOffset >= offset) { | ||
// If we've already measured items within this range just use a binary search as it's faster. | ||
return findNearestItemBinarySearch(itemType, props, instanceProps, lastMeasuredIndex, 0, offset); | ||
} else { | ||
// If we haven't yet measured this high, fallback to an exponential search with an inner binary search. | ||
// The exponential search avoids pre-computing sizes for the full set of cells as a binary search would. | ||
// The exponential search avoids pre-computing sizes for the full set of items as a binary search would. | ||
// The overall complexity for this approach is O(log n). | ||
return findNearestCellExponentialSearch(cellType, props, instanceProps, lastMeasuredIndex, offset); | ||
return findNearestItemExponentialSearch(itemType, props, instanceProps, lastMeasuredIndex, offset); | ||
} | ||
}; | ||
var findNearestCellBinarySearch = function findNearestCellBinarySearch(cellType, props, instanceProps, high, low, offset) { | ||
var findNearestItemBinarySearch = function findNearestItemBinarySearch(itemType, props, instanceProps, high, low, offset) { | ||
while (low <= high) { | ||
var middle = low + Math.floor((high - low) / 2); | ||
var currentOffset = getCellMetadata(cellType, props, middle, instanceProps).offset; | ||
var currentOffset = getItemMetadata(itemType, props, middle, instanceProps).offset; | ||
@@ -669,7 +725,7 @@ if (currentOffset === offset) { | ||
var findNearestCellExponentialSearch = function findNearestCellExponentialSearch(cellType, props, instanceProps, index, offset) { | ||
var itemCount = cellType === 'column' ? props.columnCount : props.rowCount; | ||
var findNearestItemExponentialSearch = function findNearestItemExponentialSearch(itemType, props, instanceProps, index, offset) { | ||
var itemCount = itemType === 'column' ? props.columnCount : props.rowCount; | ||
var interval = 1; | ||
while (index < itemCount && getCellMetadata(cellType, props, index, instanceProps).offset < offset) { | ||
while (index < itemCount && getItemMetadata(itemType, props, index, instanceProps).offset < offset) { | ||
index += interval; | ||
@@ -679,11 +735,16 @@ interval *= 2; | ||
return findNearestCellBinarySearch(cellType, props, instanceProps, Math.min(index, itemCount - 1), Math.floor(index / 2), offset); | ||
return findNearestItemBinarySearch(itemType, props, instanceProps, Math.min(index, itemCount - 1), Math.floor(index / 2), offset); | ||
}; | ||
var getOffsetForIndexAndAlignment = function getOffsetForIndexAndAlignment(cellType, props, index, align, scrollOffset, instanceProps) { | ||
var size = cellType === 'column' ? props.width : props.height; | ||
var cellMetadata = getCellMetadata(cellType, props, index, instanceProps); | ||
var maxOffset = cellMetadata.offset; | ||
var minOffset = cellMetadata.offset - size + cellMetadata.size; | ||
var getOffsetForIndexAndAlignment = function getOffsetForIndexAndAlignment(itemType, props, index, align, scrollOffset, instanceProps) { | ||
var size = itemType === 'column' ? props.width : props.height; | ||
var itemMetadata = getItemMetadata(itemType, props, index, instanceProps); | ||
// Get estimated total size after ItemMetadata is computed, | ||
// To ensure it reflects actual measurements instead of just estimates. | ||
var estimatedTotalSize = itemType === 'column' ? getEstimatedTotalWidth(props, instanceProps) : getEstimatedTotalHeight(props, instanceProps); | ||
var maxOffset = Math.min(estimatedTotalSize - size, itemMetadata.offset); | ||
var minOffset = Math.max(0, itemMetadata.offset - size + itemMetadata.size); | ||
switch (align) { | ||
@@ -710,7 +771,7 @@ case 'start': | ||
getColumnOffset: function getColumnOffset(props, index, instanceProps) { | ||
return getCellMetadata('column', props, index, instanceProps).offset; | ||
return getItemMetadata('column', props, index, instanceProps).offset; | ||
}, | ||
getColumnStartIndexForOffset: function getColumnStartIndexForOffset(props, scrollLeft, instanceProps) { | ||
return findNearestCell('column', props, instanceProps, scrollLeft); | ||
return findNearestItem('column', props, instanceProps, scrollLeft); | ||
}, | ||
@@ -723,6 +784,6 @@ | ||
var cellMetadata = getCellMetadata('column', props, startIndex, instanceProps); | ||
var itemMetadata = getItemMetadata('column', props, startIndex, instanceProps); | ||
var maxOffset = scrollLeft + width; | ||
var offset = cellMetadata.offset + cellMetadata.size; | ||
var offset = itemMetadata.offset + itemMetadata.size; | ||
var stopIndex = startIndex; | ||
@@ -732,3 +793,3 @@ | ||
stopIndex++; | ||
offset += getCellMetadata('column', props, stopIndex, instanceProps).size; | ||
offset += getItemMetadata('column', props, stopIndex, instanceProps).size; | ||
} | ||
@@ -743,40 +804,5 @@ | ||
getEstimatedTotalHeight: function getEstimatedTotalHeight(_ref, _ref2) { | ||
var rowCount = _ref.rowCount; | ||
var rowMetadataMap = _ref2.rowMetadataMap, | ||
estimatedRowHeight = _ref2.estimatedRowHeight, | ||
lastMeasuredRowIndex = _ref2.lastMeasuredRowIndex; | ||
getEstimatedTotalHeight: getEstimatedTotalHeight, | ||
getEstimatedTotalWidth: getEstimatedTotalWidth, | ||
var totalSizeOfMeasuredRows = 0; | ||
if (lastMeasuredRowIndex >= 0) { | ||
var cellMetadata = rowMetadataMap[lastMeasuredRowIndex]; | ||
totalSizeOfMeasuredRows = cellMetadata.offset + cellMetadata.size; | ||
} | ||
var numUnmeasuredCells = rowCount - lastMeasuredRowIndex - 1; | ||
var totalSizeOfUnmeasuredCells = numUnmeasuredCells * estimatedRowHeight; | ||
return totalSizeOfMeasuredRows + totalSizeOfUnmeasuredCells; | ||
}, | ||
getEstimatedTotalWidth: function getEstimatedTotalWidth(_ref3, _ref4) { | ||
var columnCount = _ref3.columnCount; | ||
var columnMetadataMap = _ref4.columnMetadataMap, | ||
estimatedColumnWidth = _ref4.estimatedColumnWidth, | ||
lastMeasuredColumnIndex = _ref4.lastMeasuredColumnIndex; | ||
var totalSizeOfMeasuredRows = 0; | ||
if (lastMeasuredColumnIndex >= 0) { | ||
var cellMetadata = columnMetadataMap[lastMeasuredColumnIndex]; | ||
totalSizeOfMeasuredRows = cellMetadata.offset + cellMetadata.size; | ||
} | ||
var numUnmeasuredCells = columnCount - lastMeasuredColumnIndex - 1; | ||
var totalSizeOfUnmeasuredCells = numUnmeasuredCells * estimatedColumnWidth; | ||
return totalSizeOfMeasuredRows + totalSizeOfUnmeasuredCells; | ||
}, | ||
getOffsetForColumnAndAlignment: function getOffsetForColumnAndAlignment(props, index, align, scrollOffset, instanceProps) { | ||
@@ -791,3 +817,3 @@ return getOffsetForIndexAndAlignment('column', props, index, align, scrollOffset, instanceProps); | ||
getRowOffset: function getRowOffset(props, index, instanceProps) { | ||
return getCellMetadata('row', props, index, instanceProps).offset; | ||
return getItemMetadata('row', props, index, instanceProps).offset; | ||
}, | ||
@@ -800,3 +826,3 @@ | ||
getRowStartIndexForOffset: function getRowStartIndexForOffset(props, scrollTop, instanceProps) { | ||
return findNearestCell('row', props, instanceProps, scrollTop); | ||
return findNearestItem('row', props, instanceProps, scrollTop); | ||
}, | ||
@@ -809,6 +835,6 @@ | ||
var cellMetadata = getCellMetadata('row', props, startIndex, instanceProps); | ||
var itemMetadata = getItemMetadata('row', props, startIndex, instanceProps); | ||
var maxOffset = scrollTop + height; | ||
var offset = cellMetadata.offset + cellMetadata.size; | ||
var offset = itemMetadata.offset + itemMetadata.size; | ||
var stopIndex = startIndex; | ||
@@ -818,3 +844,3 @@ | ||
stopIndex++; | ||
offset += getCellMetadata('row', props, stopIndex, instanceProps).size; | ||
offset += getItemMetadata('row', props, stopIndex, instanceProps).size; | ||
} | ||
@@ -841,9 +867,23 @@ | ||
instance.resetAfterColumnIndex = function (index) { | ||
instanceProps.lastMeasuredColumnIndex = index - 1; | ||
instanceProps.lastMeasuredColumnIndex = Math.min(instanceProps.lastMeasuredColumnIndex, index - 1); | ||
instance._itemStyleCache = {}; | ||
instance.forceUpdate(); | ||
}; | ||
instance.resetAfterRowIndex = function (index) { | ||
instanceProps.lastMeasuredRowIndex = index - 1; | ||
instanceProps.lastMeasuredRowIndex = Math.min(instanceProps.lastMeasuredRowIndex, index - 1); | ||
instance._itemStyleCache = {}; | ||
instance.forceUpdate(); | ||
}; | ||
instance.resetAfterIndices = function (_ref6) { | ||
var columnIndex = _ref6.columnIndex, | ||
rowIndex = _ref6.rowIndex; | ||
instanceProps.lastMeasuredColumnIndex = Math.min(instanceProps.lastMeasuredColumnIndex, columnIndex - 1); | ||
instanceProps.lastMeasuredRowIndex = Math.min(instanceProps.lastMeasuredRowIndex, rowIndex - 1); | ||
instance._itemStyleCache = {}; | ||
instance.forceUpdate(); | ||
}; | ||
return instanceProps; | ||
@@ -853,5 +893,5 @@ }, | ||
validateProps: function validateProps(_ref6) { | ||
var columnWidth = _ref6.columnWidth, | ||
rowHeight = _ref6.rowHeight; | ||
validateProps: function validateProps(_ref7) { | ||
var columnWidth = _ref7.columnWidth, | ||
rowHeight = _ref7.rowHeight; | ||
@@ -873,3 +913,3 @@ if (process.env.NODE_ENV !== 'production') { | ||
var getCellOffset = _ref.getCellOffset, | ||
var getItemOffset = _ref.getItemOffset, | ||
getEstimatedTotalSize = _ref.getEstimatedTotalSize, | ||
@@ -897,3 +937,3 @@ getItemSize = _ref.getItemSize, | ||
return _ret = (_temp = (_this = possibleConstructorReturn(this, (_ref2 = List.__proto__ || Object.getPrototypeOf(List)).call.apply(_ref2, [this].concat(args))), _this), _this._instanceProps = initInstanceProps(_this.props, _this), _this._resetIsScrollingTimeoutId = null, _this.state = { | ||
return _ret = (_temp = (_this = possibleConstructorReturn(this, (_ref2 = List.__proto__ || Object.getPrototypeOf(List)).call.apply(_ref2, [this].concat(args))), _this), _this._instanceProps = initInstanceProps(_this.props, _this), _this._itemStyleCache = {}, _this._resetIsScrollingTimeoutId = null, _this.state = { | ||
isScrolling: false, | ||
@@ -916,12 +956,20 @@ scrollDirection: 'forward', | ||
}); | ||
}), _this._getCellStyle = function (index) { | ||
}), _this._getItemStyle = function (index) { | ||
var direction = _this.props.direction; | ||
return { | ||
position: 'absolute', | ||
left: direction === 'horizontal' ? getCellOffset(_this.props, index, _this._instanceProps) : 0, | ||
top: direction === 'vertical' ? getCellOffset(_this.props, index, _this._instanceProps) : 0, | ||
height: direction === 'vertical' ? getItemSize(_this.props, index, _this._instanceProps) : '100%', | ||
width: direction === 'horizontal' ? getItemSize(_this.props, index, _this._instanceProps) : '100%' | ||
}; | ||
var style = void 0; | ||
if (_this._itemStyleCache.hasOwnProperty(index)) { | ||
style = _this._itemStyleCache[index]; | ||
} else { | ||
_this._itemStyleCache[index] = style = { | ||
position: 'absolute', | ||
left: direction === 'horizontal' ? getItemOffset(_this.props, index, _this._instanceProps) : 0, | ||
top: direction === 'vertical' ? getItemOffset(_this.props, index, _this._instanceProps) : 0, | ||
height: direction === 'vertical' ? getItemSize(_this.props, index, _this._instanceProps) : '100%', | ||
width: direction === 'horizontal' ? getItemSize(_this.props, index, _this._instanceProps) : '100%' | ||
}; | ||
} | ||
return style; | ||
}, _this._onScrollHorizontal = function (event) { | ||
@@ -976,3 +1024,7 @@ var scrollLeft = event.currentTarget.scrollLeft; | ||
_this.setState({ isScrolling: false }); | ||
_this.setState({ isScrolling: false }, function () { | ||
// Clear style cache after state update has been committed. | ||
// This way we don't break pure sCU for items that don't use isScrolling param. | ||
_this._itemStyleCache = {}; | ||
}); | ||
}, _temp), possibleConstructorReturn(_this, _ret); | ||
@@ -1060,4 +1112,2 @@ } | ||
var estimatedTotalSize = getEstimatedTotalSize(this.props, this._instanceProps); | ||
var _getRangeToRender2 = this._getRangeToRender(), | ||
@@ -1068,11 +1118,11 @@ _getRangeToRender3 = slicedToArray(_getRangeToRender2, 2), | ||
var cells = []; | ||
var items = []; | ||
if (itemCount > 0) { | ||
for (var _index = startIndex; _index <= stopIndex; _index++) { | ||
cells.push(React.createElement(ListItem, { | ||
getCellStyle: this._getCellStyle, | ||
items.push(React.createElement(ListItem, { | ||
key: _index, | ||
index: _index, | ||
isScrolling: useIsScrolling ? isScrolling : undefined, | ||
renderFunction: this._renderFunction | ||
renderFunction: this._renderFunction, | ||
style: this._getItemStyle(_index) | ||
})); | ||
@@ -1082,2 +1132,6 @@ } | ||
// Read this value AFTER items have been created, | ||
// So their actual sizes (if variable) are taken into consideration. | ||
var estimatedTotalSize = getEstimatedTotalSize(this.props, this._instanceProps); | ||
return React.createElement( | ||
@@ -1108,3 +1162,3 @@ 'div', | ||
}, | ||
cells | ||
items | ||
) | ||
@@ -1137,3 +1191,6 @@ ); | ||
// Lazily create and cache cell styles while scrolling. | ||
// Lazily create and cache item styles while scrolling, | ||
// So that pure component sCU will prevent re-renders. | ||
// We maintain this cache, and pass a style prop rather than index, | ||
// So that List can clear cached styles and force item re-render if necessary. | ||
@@ -1154,4 +1211,4 @@ }, { | ||
// Overscan by one cell in each direction so that tab/focus works. | ||
// If there isn't at least one extra cell, tab loops back around. | ||
// Overscan by one item in each direction so that tab/focus works. | ||
// If there isn't at least one extra item, tab loops back around. | ||
var overscanBackward = scrollDirection === 'backward' ? Math.max(1, overscanCount) : 1; | ||
@@ -1166,3 +1223,3 @@ var overscanForward = scrollDirection === 'forward' ? Math.max(1, overscanCount) : 1; | ||
// But has hte benefit of not breaking pure sCU checks, | ||
// Allowing List to avoid re-rendering cells until indices change. | ||
// Allowing List to avoid re-rendering items until indices change. | ||
@@ -1197,6 +1254,6 @@ }], [{ | ||
var _props4 = this.props, | ||
getCellStyle = _props4.getCellStyle, | ||
index = _props4.index, | ||
isScrolling = _props4.isScrolling, | ||
renderFunction = _props4.renderFunction; | ||
renderFunction = _props4.renderFunction, | ||
style = _props4.style; | ||
@@ -1207,3 +1264,3 @@ | ||
isScrolling: isScrolling, | ||
style: getCellStyle(index) | ||
style: style | ||
}); | ||
@@ -1246,6 +1303,6 @@ } | ||
var getCellMetadata$1 = function getCellMetadata(props, index, instanceProps) { | ||
var getItemMetadata$1 = function getItemMetadata(props, index, instanceProps) { | ||
var _ref = props, | ||
itemSize = _ref.itemSize; | ||
var cellMetadataMap = instanceProps.cellMetadataMap, | ||
var itemMetadataMap = instanceProps.itemMetadataMap, | ||
lastMeasuredIndex = instanceProps.lastMeasuredIndex; | ||
@@ -1257,4 +1314,4 @@ | ||
if (lastMeasuredIndex >= 0) { | ||
var cellMetadata = cellMetadataMap[lastMeasuredIndex]; | ||
_offset = cellMetadata.offset + cellMetadata.size; | ||
var itemMetadata = itemMetadataMap[lastMeasuredIndex]; | ||
_offset = itemMetadata.offset + itemMetadata.size; | ||
} | ||
@@ -1265,3 +1322,3 @@ | ||
cellMetadataMap[i] = { | ||
itemMetadataMap[i] = { | ||
offset: _offset, | ||
@@ -1277,27 +1334,27 @@ size: _size | ||
return cellMetadataMap[index]; | ||
return itemMetadataMap[index]; | ||
}; | ||
var findNearestCell$1 = function findNearestCell(props, instanceProps, offset) { | ||
var cellMetadataMap = instanceProps.cellMetadataMap, | ||
var findNearestItem$1 = function findNearestItem(props, instanceProps, offset) { | ||
var itemMetadataMap = instanceProps.itemMetadataMap, | ||
lastMeasuredIndex = instanceProps.lastMeasuredIndex; | ||
var lastMeasuredCellOffset = lastMeasuredIndex > 0 ? cellMetadataMap[lastMeasuredIndex].offset : 0; | ||
var lastMeasuredItemOffset = lastMeasuredIndex > 0 ? itemMetadataMap[lastMeasuredIndex].offset : 0; | ||
if (lastMeasuredCellOffset >= offset) { | ||
// If we've already measured cells within this range just use a binary search as it's faster. | ||
return findNearestCellBinarySearch$1(props, instanceProps, lastMeasuredIndex, 0, offset); | ||
if (lastMeasuredItemOffset >= offset) { | ||
// If we've already measured items within this range just use a binary search as it's faster. | ||
return findNearestItemBinarySearch$1(props, instanceProps, lastMeasuredIndex, 0, offset); | ||
} else { | ||
// If we haven't yet measured this high, fallback to an exponential search with an inner binary search. | ||
// The exponential search avoids pre-computing sizes for the full set of cells as a binary search would. | ||
// The exponential search avoids pre-computing sizes for the full set of items as a binary search would. | ||
// The overall complexity for this approach is O(log n). | ||
return findNearestCellExponentialSearch$1(props, instanceProps, lastMeasuredIndex, offset); | ||
return findNearestItemExponentialSearch$1(props, instanceProps, lastMeasuredIndex, offset); | ||
} | ||
}; | ||
var findNearestCellBinarySearch$1 = function findNearestCellBinarySearch(props, instanceProps, high, low, offset) { | ||
var findNearestItemBinarySearch$1 = function findNearestItemBinarySearch(props, instanceProps, high, low, offset) { | ||
while (low <= high) { | ||
var middle = low + Math.floor((high - low) / 2); | ||
var currentOffset = getCellMetadata$1(props, middle, instanceProps).offset; | ||
var currentOffset = getItemMetadata$1(props, middle, instanceProps).offset; | ||
@@ -1320,3 +1377,3 @@ if (currentOffset === offset) { | ||
var findNearestCellExponentialSearch$1 = function findNearestCellExponentialSearch(props, instanceProps, index, offset) { | ||
var findNearestItemExponentialSearch$1 = function findNearestItemExponentialSearch(props, instanceProps, index, offset) { | ||
var itemCount = props.itemCount; | ||
@@ -1326,3 +1383,3 @@ | ||
while (index < itemCount && getCellMetadata$1(props, index, instanceProps).offset < offset) { | ||
while (index < itemCount && getItemMetadata$1(props, index, instanceProps).offset < offset) { | ||
index += interval; | ||
@@ -1332,3 +1389,3 @@ interval *= 2; | ||
return findNearestCellBinarySearch$1(props, instanceProps, Math.min(index, itemCount - 1), Math.floor(index / 2), offset); | ||
return findNearestItemBinarySearch$1(props, instanceProps, Math.min(index, itemCount - 1), Math.floor(index / 2), offset); | ||
}; | ||
@@ -1338,26 +1395,26 @@ | ||
var itemCount = _ref2.itemCount; | ||
var cellMetadataMap = _ref3.cellMetadataMap, | ||
var itemMetadataMap = _ref3.itemMetadataMap, | ||
estimatedItemSize = _ref3.estimatedItemSize, | ||
lastMeasuredIndex = _ref3.lastMeasuredIndex; | ||
var totalSizeOfMeasuredCells = 0; | ||
var totalSizeOfMeasuredItems = 0; | ||
if (lastMeasuredIndex >= 0) { | ||
var cellMetadata = cellMetadataMap[lastMeasuredIndex]; | ||
totalSizeOfMeasuredCells = cellMetadata.offset + cellMetadata.size; | ||
var itemMetadata = itemMetadataMap[lastMeasuredIndex]; | ||
totalSizeOfMeasuredItems = itemMetadata.offset + itemMetadata.size; | ||
} | ||
var numUnmeasuredCells = itemCount - lastMeasuredIndex - 1; | ||
var totalSizeOfUnmeasuredCells = numUnmeasuredCells * estimatedItemSize; | ||
var numUnmeasuredItems = itemCount - lastMeasuredIndex - 1; | ||
var totalSizeOfUnmeasuredItems = numUnmeasuredItems * estimatedItemSize; | ||
return totalSizeOfMeasuredCells + totalSizeOfUnmeasuredCells; | ||
return totalSizeOfMeasuredItems + totalSizeOfUnmeasuredItems; | ||
}; | ||
var VariableSizeList = createListComponent({ | ||
getCellOffset: function getCellOffset(props, index, instanceProps) { | ||
return getCellMetadata$1(props, index, instanceProps).offset; | ||
getItemOffset: function getItemOffset(props, index, instanceProps) { | ||
return getItemMetadata$1(props, index, instanceProps).offset; | ||
}, | ||
getItemSize: function getItemSize(props, index, instanceProps) { | ||
return instanceProps.cellMetadataMap[index].size; | ||
return instanceProps.itemMetadataMap[index].size; | ||
}, | ||
@@ -1374,10 +1431,10 @@ | ||
var size = direction === 'horizontal' ? width : height; | ||
var cellMetadata = getCellMetadata$1(props, index, instanceProps); | ||
var itemMetadata = getItemMetadata$1(props, index, instanceProps); | ||
// Get estimated total size after CellMetadata is computed, | ||
// Get estimated total size after ItemMetadata is computed, | ||
// To ensure it reflects actual measurements instead of just estimates. | ||
var estimatedTotalSize = getEstimatedTotalSize(props, instanceProps); | ||
var maxOffset = Math.min(estimatedTotalSize - size, cellMetadata.offset); | ||
var minOffset = Math.max(0, cellMetadata.offset - size + cellMetadata.size); | ||
var maxOffset = Math.min(estimatedTotalSize - size, itemMetadata.offset); | ||
var minOffset = Math.max(0, itemMetadata.offset - size + itemMetadata.size); | ||
@@ -1404,3 +1461,3 @@ switch (align) { | ||
getStartIndexForOffset: function getStartIndexForOffset(props, offset, instanceProps) { | ||
return findNearestCell$1(props, instanceProps, offset); | ||
return findNearestItem$1(props, instanceProps, offset); | ||
}, | ||
@@ -1416,6 +1473,6 @@ | ||
var size = direction === 'horizontal' ? width : height; | ||
var cellMetadata = getCellMetadata$1(props, startIndex, instanceProps); | ||
var itemMetadata = getItemMetadata$1(props, startIndex, instanceProps); | ||
var maxOffset = scrollOffset + size; | ||
var offset = cellMetadata.offset + cellMetadata.size; | ||
var offset = itemMetadata.offset + itemMetadata.size; | ||
var stopIndex = startIndex; | ||
@@ -1425,3 +1482,3 @@ | ||
stopIndex++; | ||
offset += getCellMetadata$1(props, stopIndex, instanceProps).size; | ||
offset += getItemMetadata$1(props, stopIndex, instanceProps).size; | ||
} | ||
@@ -1438,3 +1495,3 @@ | ||
var instanceProps = { | ||
cellMetadataMap: {}, | ||
itemMetadataMap: {}, | ||
estimatedItemSize: estimatedItemSize || DEFAULT_ESTIMATED_ITEM_SIZE$1, | ||
@@ -1445,3 +1502,5 @@ lastMeasuredIndex: -1 | ||
instance.resetAfterIndex = function (index) { | ||
instanceProps.lastMeasuredIndex = index - 1; | ||
instanceProps.lastMeasuredIndex = Math.min(instanceProps.lastMeasuredIndex, index - 1); | ||
instance._itemStyleCache = {}; | ||
instance.forceUpdate(); | ||
}; | ||
@@ -1603,3 +1662,3 @@ | ||
var FixedSizeList = createListComponent({ | ||
getCellOffset: function getCellOffset(_ref, index) { | ||
getItemOffset: function getItemOffset(_ref, index) { | ||
var itemSize = _ref.itemSize, | ||
@@ -1606,0 +1665,0 @@ size = _ref.size; |
{ | ||
"name": "react-virtualized", | ||
"description": "React components for efficiently rendering large, scrollable lists and tabular data", | ||
"version": "10.0.0-alpha.16", | ||
"version": "10.0.0-alpha.17", | ||
"main": "index.cjs.js", | ||
@@ -6,0 +6,0 @@ "module": "index.esm.js", |
127352
2811