react-virtualized
Version:
React components for efficiently rendering large, scrollable lists and tabular data
139 lines (134 loc) • 6.39 kB
JavaScript
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = defaultCellRangeRenderer;
var _react = _interopRequireDefault(require("react"));
/*:: import type {CellRangeRendererParams} from './types';*/
/**
* Default implementation of cellRangeRenderer used by Grid.
* This renderer supports cell-caching while the user is scrolling.
*/
function defaultCellRangeRenderer(_ref /*:: */) {
var cellCache = _ref /*:: */.cellCache,
cellRenderer = _ref /*:: */.cellRenderer,
columnSizeAndPositionManager = _ref /*:: */.columnSizeAndPositionManager,
columnStartIndex = _ref /*:: */.columnStartIndex,
columnStopIndex = _ref /*:: */.columnStopIndex,
deferredMeasurementCache = _ref /*:: */.deferredMeasurementCache,
horizontalOffsetAdjustment = _ref /*:: */.horizontalOffsetAdjustment,
isScrolling = _ref /*:: */.isScrolling,
isScrollingOptOut = _ref /*:: */.isScrollingOptOut,
parent = _ref /*:: */.parent,
rowSizeAndPositionManager = _ref /*:: */.rowSizeAndPositionManager,
rowStartIndex = _ref /*:: */.rowStartIndex,
rowStopIndex = _ref /*:: */.rowStopIndex,
styleCache = _ref /*:: */.styleCache,
verticalOffsetAdjustment = _ref /*:: */.verticalOffsetAdjustment,
visibleColumnIndices = _ref /*:: */.visibleColumnIndices,
visibleRowIndices = _ref /*:: */.visibleRowIndices;
var renderedCells = [];
// Browsers have native size limits for elements (eg Chrome 33M pixels, IE 1.5M pixes).
// User cannot scroll beyond these size limitations.
// In order to work around this, ScalingCellSizeAndPositionManager compresses offsets.
// We should never cache styles for compressed offsets though as this can lead to bugs.
// See issue #576 for more.
var areOffsetsAdjusted = columnSizeAndPositionManager.areOffsetsAdjusted() || rowSizeAndPositionManager.areOffsetsAdjusted();
var canCacheStyle = !isScrolling && !areOffsetsAdjusted;
for (var rowIndex = rowStartIndex; rowIndex <= rowStopIndex; rowIndex++) {
var rowDatum = rowSizeAndPositionManager.getSizeAndPositionOfCell(rowIndex);
for (var columnIndex = columnStartIndex; columnIndex <= columnStopIndex; columnIndex++) {
var columnDatum = columnSizeAndPositionManager.getSizeAndPositionOfCell(columnIndex);
var isVisible = columnIndex >= visibleColumnIndices.start && columnIndex <= visibleColumnIndices.stop && rowIndex >= visibleRowIndices.start && rowIndex <= visibleRowIndices.stop;
var key = "".concat(rowIndex, "-").concat(columnIndex);
var style = void 0;
// Cache style objects so shallow-compare doesn't re-render unnecessarily.
if (canCacheStyle && styleCache[key]) {
style = styleCache[key];
} else {
// In deferred mode, cells will be initially rendered before we know their size.
// Don't interfere with CellMeasurer's measurements by setting an invalid size.
if (deferredMeasurementCache && !deferredMeasurementCache.has(rowIndex, columnIndex)) {
// Position not-yet-measured cells at top/left 0,0,
// And give them width/height of 'auto' so they can grow larger than the parent Grid if necessary.
// Positioning them further to the right/bottom influences their measured size.
style = {
height: 'auto',
left: 0,
position: 'absolute',
top: 0,
width: 'auto'
};
} else {
style = {
height: rowDatum.size,
left: columnDatum.offset + horizontalOffsetAdjustment,
position: 'absolute',
top: rowDatum.offset + verticalOffsetAdjustment,
width: columnDatum.size
};
styleCache[key] = style;
}
}
var cellRendererParams = {
columnIndex: columnIndex,
isScrolling: isScrolling,
isVisible: isVisible,
key: key,
parent: parent,
rowIndex: rowIndex,
style: style
};
var renderedCell = void 0;
// Avoid re-creating cells while scrolling.
// This can lead to the same cell being created many times and can cause performance issues for "heavy" cells.
// If a scroll is in progress- cache and reuse cells.
// This cache will be thrown away once scrolling completes.
// However if we are scaling scroll positions and sizes, we should also avoid caching.
// This is because the offset changes slightly as scroll position changes and caching leads to stale values.
// For more info refer to issue #395
//
// If isScrollingOptOut is specified, we always cache cells.
// For more info refer to issue #1028
if ((isScrollingOptOut || isScrolling) && !horizontalOffsetAdjustment && !verticalOffsetAdjustment) {
if (!cellCache[key]) {
cellCache[key] = cellRenderer(cellRendererParams);
}
renderedCell = cellCache[key];
// If the user is no longer scrolling, don't cache cells.
// This makes dynamic cell content difficult for users and would also lead to a heavier memory footprint.
} else {
renderedCell = cellRenderer(cellRendererParams);
}
if (renderedCell == null || renderedCell === false) {
continue;
}
if (process.env.NODE_ENV !== 'production') {
warnAboutMissingStyle(parent, renderedCell);
}
if (!renderedCell.props.role) {
renderedCell = /*#__PURE__*/_react["default"].cloneElement(renderedCell, {
role: 'gridcell'
});
}
renderedCells.push(renderedCell);
}
}
return renderedCells;
}
function warnAboutMissingStyle(parent, renderedCell) {
if (process.env.NODE_ENV !== 'production') {
if (renderedCell) {
// If the direct child is a CellMeasurer, then we should check its child
// See issue #611
if (renderedCell.type && renderedCell.type.__internalCellMeasurerFlag) {
renderedCell = renderedCell.props.children;
}
if (renderedCell && renderedCell.props && renderedCell.props.style === undefined && parent.__warnedAboutMissingStyle !== true) {
parent.__warnedAboutMissingStyle = true;
console.warn('Rendered cell should include style property for positioning.');
}
}
}
}
;