2625 lines
96 KiB
JavaScript
2625 lines
96 KiB
JavaScript
"use strict";
|
|
|
|
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
|
|
|
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
|
|
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
|
|
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
|
|
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
|
|
|
|
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
|
|
|
|
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
|
|
|
|
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
|
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
|
|
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
|
|
var React = _interopRequireWildcard(require("react"));
|
|
|
|
var _reactDom = require("react-dom");
|
|
|
|
var _testUtils = require("react-dom/test-utils");
|
|
|
|
var _reactTestRenderer = _interopRequireDefault(require("react-test-renderer"));
|
|
|
|
var _TestUtils = require("../TestUtils");
|
|
|
|
var _Grid = _interopRequireWildcard(require("./Grid"));
|
|
|
|
var _defaultCellRangeRenderer = _interopRequireDefault(require("./defaultCellRangeRenderer"));
|
|
|
|
var _CellMeasurer = require("../CellMeasurer");
|
|
|
|
var _defaultOverscanIndicesGetter = require("./defaultOverscanIndicesGetter");
|
|
|
|
var _maxElementSize = require("./utils/maxElementSize.js");
|
|
|
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
|
|
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
|
|
var DEFAULT_COLUMN_WIDTH = 50;
|
|
var DEFAULT_HEIGHT = 100;
|
|
var DEFAULT_ROW_HEIGHT = 20;
|
|
var DEFAULT_WIDTH = 200;
|
|
var NUM_ROWS = 100;
|
|
var NUM_COLUMNS = 50;
|
|
|
|
function getScrollbarSize0() {
|
|
return 0;
|
|
}
|
|
|
|
function getScrollbarSize20() {
|
|
return 20;
|
|
}
|
|
|
|
describe('Grid', function () {
|
|
function defaultCellRenderer(_ref) {
|
|
var columnIndex = _ref.columnIndex,
|
|
key = _ref.key,
|
|
rowIndex = _ref.rowIndex,
|
|
style = _ref.style;
|
|
return React.createElement("div", {
|
|
className: "gridItem",
|
|
key: key,
|
|
style: style
|
|
}, "row:".concat(rowIndex, ", column:").concat(columnIndex));
|
|
}
|
|
|
|
function simulateScroll(_ref2) {
|
|
var grid = _ref2.grid,
|
|
_ref2$scrollLeft = _ref2.scrollLeft,
|
|
scrollLeft = _ref2$scrollLeft === void 0 ? 0 : _ref2$scrollLeft,
|
|
_ref2$scrollTop = _ref2.scrollTop,
|
|
scrollTop = _ref2$scrollTop === void 0 ? 0 : _ref2$scrollTop;
|
|
var target = {
|
|
scrollLeft: scrollLeft,
|
|
scrollTop: scrollTop
|
|
};
|
|
grid._scrollingContainer = target; // HACK to work around _onScroll target check
|
|
|
|
_testUtils.Simulate.scroll((0, _reactDom.findDOMNode)(grid), {
|
|
target: target
|
|
});
|
|
}
|
|
|
|
function getMarkup() {
|
|
var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
return React.createElement(_Grid["default"], (0, _extends2["default"])({
|
|
cellRenderer: defaultCellRenderer,
|
|
columnCount: NUM_COLUMNS,
|
|
columnWidth: DEFAULT_COLUMN_WIDTH,
|
|
getScrollbarSize: getScrollbarSize0,
|
|
height: DEFAULT_HEIGHT,
|
|
overscanColumnCount: 0,
|
|
overscanRowCount: 0,
|
|
autoHeight: false,
|
|
rowHeight: DEFAULT_ROW_HEIGHT,
|
|
rowCount: NUM_ROWS,
|
|
width: DEFAULT_WIDTH
|
|
}, props));
|
|
}
|
|
|
|
describe('number of rendered children', function () {
|
|
it('should render enough children to fill the available area', function () {
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup()));
|
|
expect(rendered.querySelectorAll('.gridItem').length).toEqual(20); // 5 rows x 4 columns
|
|
});
|
|
it('should not render more rows than available if the area is not filled', function () {
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
rowCount: 2
|
|
})));
|
|
expect(rendered.querySelectorAll('.gridItem').length).toEqual(8); // 2 rows x 4 columns
|
|
});
|
|
it('should not render more columns than available if the area is not filled', function () {
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
columnCount: 2
|
|
})));
|
|
expect(rendered.querySelectorAll('.gridItem').length).toEqual(10); // 5 rows x 2 columns
|
|
}); // Small performance tweak added in 5.5.6
|
|
|
|
it('should not render/parent cells that are null or false', function () {
|
|
function cellRenderer(_ref3) {
|
|
var columnIndex = _ref3.columnIndex,
|
|
key = _ref3.key,
|
|
rowIndex = _ref3.rowIndex,
|
|
style = _ref3.style;
|
|
|
|
if (columnIndex === 0) {
|
|
return null;
|
|
} else if (rowIndex === 0) {
|
|
return false;
|
|
} else {
|
|
return React.createElement("div", {
|
|
className: "cell",
|
|
key: key,
|
|
style: style
|
|
}, "row:".concat(rowIndex, ", column:").concat(columnIndex));
|
|
}
|
|
}
|
|
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
columnCount: 3,
|
|
overscanColumnCount: 0,
|
|
overscanRowCount: 0,
|
|
rowCount: 3,
|
|
cellRenderer: cellRenderer
|
|
})));
|
|
expect(rendered.querySelectorAll('.cell').length).toEqual(4); // [1,1], [1,2], [2,1], and [2,2]
|
|
|
|
expect(rendered.textContent).not.toContain('column:0');
|
|
expect(rendered.textContent).not.toContain('row:0');
|
|
});
|
|
it('should scroll to the last existing point when rows are removed', function () {
|
|
var grid = (0, _TestUtils.render)(getMarkup({
|
|
rowCount: 15
|
|
}));
|
|
simulateScroll({
|
|
grid: grid,
|
|
scrollTop: 200
|
|
});
|
|
var updatedGrid = (0, _TestUtils.render)(getMarkup({
|
|
rowCount: 10
|
|
}));
|
|
expect(updatedGrid.state.scrollTop).toEqual(100);
|
|
});
|
|
it('should scroll to the last existing point when columns are removed', function () {
|
|
var grid = (0, _TestUtils.render)(getMarkup({
|
|
columnCount: 12
|
|
}));
|
|
simulateScroll({
|
|
grid: grid,
|
|
scrollLeft: 400
|
|
});
|
|
var updatedGrid = (0, _TestUtils.render)(getMarkup({
|
|
columnCount: 8
|
|
}));
|
|
expect(updatedGrid.state.scrollLeft).toEqual(200);
|
|
});
|
|
it('should not scroll unseen rows are removed', function () {
|
|
(0, _TestUtils.render)(getMarkup({
|
|
rowCount: 15
|
|
}));
|
|
var updatedGrid = (0, _TestUtils.render)(getMarkup({
|
|
rowCount: 10
|
|
}));
|
|
expect(updatedGrid.state.scrollTop).toEqual(0);
|
|
});
|
|
it('should not scroll when unseen columns are removed', function () {
|
|
(0, _TestUtils.render)(getMarkup({
|
|
columnCount: 12
|
|
}));
|
|
var updatedGrid = (0, _TestUtils.render)(getMarkup({
|
|
columnCount: 8
|
|
}));
|
|
expect(updatedGrid.state.scrollLeft).toEqual(0);
|
|
});
|
|
});
|
|
describe('shows and hides scrollbars based on rendered content', function () {
|
|
it('should set overflowX:hidden if columns fit within the available width and y-axis has no scrollbar', function () {
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
columnCount: 4,
|
|
getScrollbarSize: getScrollbarSize20,
|
|
rowCount: 5
|
|
})));
|
|
expect(rendered.style.overflowX).toEqual('hidden');
|
|
});
|
|
it('should set overflowX:hidden if columns and y-axis scrollbar fit within the available width', function () {
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
columnCount: 4,
|
|
getScrollbarSize: getScrollbarSize20,
|
|
width: 200 + getScrollbarSize20()
|
|
})));
|
|
expect(rendered.style.overflowX).toEqual('hidden');
|
|
});
|
|
it('should leave overflowX:auto if columns require more than the available width', function () {
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
columnCount: 4,
|
|
getScrollbarSize: getScrollbarSize20,
|
|
width: 200 - 1,
|
|
rowCount: 5
|
|
})));
|
|
expect(rendered.style.overflowX).not.toEqual('hidden');
|
|
});
|
|
it('should leave overflowX:auto if columns and y-axis scrollbar require more than the available width', function () {
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
columnCount: 4,
|
|
getScrollbarSize: getScrollbarSize20,
|
|
width: 200 + getScrollbarSize20() - 1
|
|
})));
|
|
expect(rendered.style.overflowX).not.toEqual('hidden');
|
|
});
|
|
it('should set overflowY:hidden if rows fit within the available width and xaxis has no scrollbar', function () {
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
getScrollbarSize: getScrollbarSize20,
|
|
rowCount: 5,
|
|
columnCount: 4
|
|
})));
|
|
expect(rendered.style.overflowY).toEqual('hidden');
|
|
});
|
|
it('should set overflowY:hidden if rows and x-axis scrollbar fit within the available width', function () {
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
getScrollbarSize: getScrollbarSize20,
|
|
rowCount: 5,
|
|
height: 100 + getScrollbarSize20()
|
|
})));
|
|
expect(rendered.style.overflowY).toEqual('hidden');
|
|
});
|
|
it('should leave overflowY:auto if rows require more than the available width', function () {
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
getScrollbarSize: getScrollbarSize20,
|
|
rowCount: 5,
|
|
height: 100 - 1,
|
|
columnCount: 4
|
|
})));
|
|
expect(rendered.style.overflowY).not.toEqual('hidden');
|
|
});
|
|
it('should leave overflowY:auto if rows and x-axis scrollbar require more than the available width', function () {
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
getScrollbarSize: getScrollbarSize20,
|
|
rowCount: 5,
|
|
height: 100 + getScrollbarSize20() - 1
|
|
})));
|
|
expect(rendered.style.overflowY).not.toEqual('hidden');
|
|
});
|
|
it('should accept styles that overwrite calculated ones', function () {
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
columnCount: 1,
|
|
getScrollbarSize: getScrollbarSize20,
|
|
height: 1,
|
|
rowCount: 1,
|
|
style: {
|
|
overflowY: 'visible',
|
|
overflowX: 'visible'
|
|
},
|
|
width: 1
|
|
})));
|
|
expect(rendered.style.overflowY).toEqual('visible');
|
|
expect(rendered.style.overflowX).toEqual('visible');
|
|
});
|
|
});
|
|
/** Tests scrolling via initial props */
|
|
|
|
describe(':scrollToColumn and :scrollToRow', function () {
|
|
it('should scroll to the left', function () {
|
|
var grid = (0, _TestUtils.render)(getMarkup({
|
|
scrollToColumn: 0
|
|
}));
|
|
expect(grid.state.scrollLeft).toEqual(0);
|
|
});
|
|
it('should scroll over to the middle', function () {
|
|
var grid = (0, _TestUtils.render)(getMarkup({
|
|
scrollToColumn: 24
|
|
})); // 50 columns * 50 item width = 2,500 total item width
|
|
// 4 columns can be visible at a time and :scrollLeft is initially 0,
|
|
// So the minimum amount of scrolling leaves the 25th item at the right (just scrolled into view).
|
|
|
|
expect(grid.state.scrollLeft).toEqual(1050);
|
|
});
|
|
it('should scroll to the far right', function () {
|
|
var grid = (0, _TestUtils.render)(getMarkup({
|
|
scrollToColumn: 49
|
|
})); // 50 columns * 50 item width = 2,500 total item width
|
|
// Target offset for the last item then is 2,500 - 200
|
|
|
|
expect(grid.state.scrollLeft).toEqual(2300);
|
|
});
|
|
it('should scroll to the top', function () {
|
|
var grid = (0, _TestUtils.render)(getMarkup({
|
|
scrollToRow: 0
|
|
}));
|
|
expect(grid.state.scrollTop).toEqual(0);
|
|
});
|
|
it('should scroll down to the middle', function () {
|
|
var grid = (0, _TestUtils.render)(getMarkup({
|
|
scrollToRow: 49
|
|
})); // 100 rows * 20 item height = 2,000 total item height
|
|
// 5 rows can be visible at a time and :scrollTop is initially 0,
|
|
// So the minimum amount of scrolling leaves the 50th item at the bottom (just scrolled into view).
|
|
|
|
expect(grid.state.scrollTop).toEqual(900);
|
|
});
|
|
it('should scroll to the bottom', function () {
|
|
var grid = (0, _TestUtils.render)(getMarkup({
|
|
scrollToRow: 99
|
|
})); // 100 rows * 20 item height = 2,000 total item height
|
|
// Target offset for the last item then is 2,000 - 100
|
|
|
|
expect(grid.state.scrollTop).toEqual(1900);
|
|
});
|
|
it('should scroll to a row and column just added', function () {
|
|
var grid = (0, _TestUtils.render)(getMarkup());
|
|
expect(grid.state.scrollLeft).toEqual(0);
|
|
expect(grid.state.scrollTop).toEqual(0);
|
|
grid = (0, _TestUtils.render)(getMarkup({
|
|
columnCount: NUM_COLUMNS + 1,
|
|
rowCount: NUM_ROWS + 1,
|
|
scrollToColumn: NUM_COLUMNS,
|
|
scrollToRow: NUM_ROWS
|
|
}));
|
|
expect(grid.state.scrollLeft).toEqual(2350);
|
|
expect(grid.state.scrollTop).toEqual(1920);
|
|
});
|
|
it('should scroll back to a newly-added cell without a change in prop', function () {
|
|
var grid = (0, _TestUtils.render)(getMarkup({
|
|
columnCount: NUM_COLUMNS,
|
|
rowCount: NUM_ROWS,
|
|
scrollToColumn: NUM_COLUMNS,
|
|
scrollToRow: NUM_ROWS
|
|
}));
|
|
grid = (0, _TestUtils.render)(getMarkup({
|
|
columnCount: NUM_COLUMNS + 1,
|
|
rowCount: NUM_ROWS + 1,
|
|
scrollToColumn: NUM_COLUMNS,
|
|
scrollToRow: NUM_ROWS
|
|
}));
|
|
expect(grid.state.scrollLeft).toEqual(2350);
|
|
expect(grid.state.scrollTop).toEqual(1920);
|
|
});
|
|
it('should scroll to the correct position for :scrollToAlignment "start"', function () {
|
|
var grid = (0, _TestUtils.render)(getMarkup({
|
|
scrollToAlignment: 'start',
|
|
scrollToColumn: 24,
|
|
scrollToRow: 49
|
|
})); // 50 columns * 50 item width = 2,500 total item width
|
|
// 100 rows * 20 item height = 2,000 total item height
|
|
// 4 columns and 5 rows can be visible at a time.
|
|
// The minimum amount of scrolling leaves the specified cell in the bottom/right corner (just scrolled into view).
|
|
// Since alignment is set to "start" we should scroll past this point until the cell is aligned top/left.
|
|
|
|
expect(grid.state.scrollLeft).toEqual(1200);
|
|
expect(grid.state.scrollTop).toEqual(980);
|
|
});
|
|
it('should scroll to the correct position for :scrollToAlignment "end"', function () {
|
|
(0, _TestUtils.render)(getMarkup({
|
|
scrollToColumn: 99,
|
|
scrollToRow: 99
|
|
}));
|
|
var grid = (0, _TestUtils.render)(getMarkup({
|
|
scrollToAlignment: 'end',
|
|
scrollToColumn: 24,
|
|
scrollToRow: 49
|
|
})); // 50 columns * 50 item width = 2,500 total item width
|
|
// 100 rows * 20 item height = 2,000 total item height
|
|
// We first scroll past the specified cell and then back.
|
|
// The minimum amount of scrolling then should leave the specified cell in the top/left corner (just scrolled into view).
|
|
// Since alignment is set to "end" we should scroll past this point until the cell is aligned bottom/right.
|
|
|
|
expect(grid.state.scrollLeft).toEqual(1050);
|
|
expect(grid.state.scrollTop).toEqual(900);
|
|
});
|
|
it('should scroll to the correct position for :scrollToAlignment "center"', function () {
|
|
(0, _TestUtils.render)(getMarkup({
|
|
scrollToColumn: 99,
|
|
scrollToRow: 99
|
|
}));
|
|
var grid = (0, _TestUtils.render)(getMarkup({
|
|
scrollToAlignment: 'center',
|
|
scrollToColumn: 24,
|
|
scrollToRow: 49
|
|
})); // 50 columns * 50 item width = 2,500 total item width
|
|
// Viewport width is 200
|
|
// Column 24 starts at 1,200, center point at 1,225, so...
|
|
|
|
expect(grid.state.scrollLeft).toEqual(1125); // 100 rows * 20 item height = 2,000 total item height
|
|
// Viewport height is 100
|
|
// Row 49 starts at 980, center point at 990, so...
|
|
|
|
expect(grid.state.scrollTop).toEqual(940);
|
|
}); // Tests issue #691
|
|
|
|
it('should set the correct :scrollLeft after height increases from 0', function () {
|
|
_TestUtils.render.unmount();
|
|
|
|
expect((0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
height: 0,
|
|
scrollToColumn: 24
|
|
}))).scrollLeft || 0).toEqual(0);
|
|
expect((0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
height: 100,
|
|
scrollToColumn: 24
|
|
}))).scrollLeft).toEqual(1050);
|
|
}); // Tests issue #691
|
|
|
|
it('should set the correct :scrollTop after width increases from 0', function () {
|
|
_TestUtils.render.unmount();
|
|
|
|
expect((0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
scrollToRow: 49,
|
|
width: 0
|
|
}))).scrollTop || 0).toEqual(0);
|
|
expect((0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
scrollToRow: 49,
|
|
width: 100
|
|
}))).scrollTop).toEqual(900);
|
|
}); // Tests issue #218
|
|
|
|
it('should set the correct :scrollTop after row and column counts increase from 0', function () {
|
|
var expectedScrollTop = 100 * DEFAULT_ROW_HEIGHT - DEFAULT_HEIGHT + DEFAULT_ROW_HEIGHT;
|
|
(0, _TestUtils.render)(getMarkup({
|
|
columnCount: 0,
|
|
rowCount: 150,
|
|
scrollToRow: 100
|
|
}));
|
|
expect((0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
columnCount: 150,
|
|
rowCount: 150,
|
|
scrollToRow: 100
|
|
}))).scrollTop).toEqual(expectedScrollTop);
|
|
});
|
|
it('should support scrollToCell() public method', function () {
|
|
var grid = (0, _TestUtils.render)(getMarkup());
|
|
expect(grid.state.scrollLeft).toEqual(0);
|
|
expect(grid.state.scrollTop).toEqual(0);
|
|
grid.scrollToCell({
|
|
columnIndex: 24,
|
|
rowIndex: 49
|
|
}); // 50 columns * 50 item width = 2,500 total item width
|
|
// 4 columns can be visible at a time and :scrollLeft is initially 0,
|
|
// So the minimum amount of scrolling leaves the 25th item at the right (just scrolled into view).
|
|
|
|
expect(grid.state.scrollLeft).toEqual(1050); // 100 rows * 20 item height = 2,000 total item height
|
|
// 5 rows can be visible at a time and :scrollTop is initially 0,
|
|
// So the minimum amount of scrolling leaves the 50th item at the bottom (just scrolled into view).
|
|
|
|
expect(grid.state.scrollTop).toEqual(900); // Change column without affecting row
|
|
|
|
grid.scrollToCell({
|
|
columnIndex: 49
|
|
});
|
|
expect(grid.state.scrollLeft).toEqual(2300);
|
|
expect(grid.state.scrollTop).toEqual(900); // Change row without affecting column
|
|
|
|
grid.scrollToCell({
|
|
rowIndex: 99
|
|
});
|
|
expect(grid.state.scrollLeft).toEqual(2300);
|
|
expect(grid.state.scrollTop).toEqual(1900);
|
|
});
|
|
it('should support scrollToPosition() public method', function () {
|
|
var grid = (0, _TestUtils.render)(getMarkup());
|
|
expect(grid.state.scrollLeft).toEqual(0);
|
|
expect(grid.state.scrollTop).toEqual(0);
|
|
grid.scrollToPosition({
|
|
scrollLeft: 50,
|
|
scrollTop: 100
|
|
});
|
|
expect(grid.state.scrollLeft).toEqual(50);
|
|
expect(grid.state.scrollTop).toEqual(100); // Change column without affecting row
|
|
|
|
grid.scrollToPosition({
|
|
scrollLeft: 25
|
|
});
|
|
expect(grid.state.scrollLeft).toEqual(25);
|
|
expect(grid.state.scrollTop).toEqual(100); // Change row without affecting column
|
|
|
|
grid.scrollToPosition({
|
|
scrollTop: 50
|
|
});
|
|
expect(grid.state.scrollLeft).toEqual(25);
|
|
expect(grid.state.scrollTop).toEqual(50);
|
|
});
|
|
it('should support handleScrollEvent() public method', function () {
|
|
var grid = (0, _TestUtils.render)(getMarkup());
|
|
expect(grid.state.scrollLeft).toEqual(0);
|
|
expect(grid.state.scrollTop).toEqual(0);
|
|
grid.handleScrollEvent({
|
|
scrollLeft: 50,
|
|
scrollTop: 100
|
|
});
|
|
expect(grid.state.isScrolling).toEqual(true);
|
|
expect(grid.state.scrollLeft).toEqual(50);
|
|
expect(grid.state.scrollTop).toEqual(100);
|
|
});
|
|
it('should support getOffsetForCell() public method', function () {
|
|
var grid = (0, _TestUtils.render)(getMarkup());
|
|
|
|
var _grid$getOffsetForCel = grid.getOffsetForCell({
|
|
columnIndex: 24,
|
|
rowIndex: 49
|
|
}),
|
|
scrollLeft = _grid$getOffsetForCel.scrollLeft,
|
|
scrollTop = _grid$getOffsetForCel.scrollTop; // 50 columns * 50 item width = 2,500 total item width
|
|
// 4 columns can be visible at a time and :scrollLeft is initially 0,
|
|
// So the minimum amount of scrolling leaves the 25th item at the right (just scrolled into view).
|
|
|
|
|
|
expect(scrollLeft).toEqual(1050); // 100 rows * 20 item height = 2,000 total item height
|
|
// 5 rows can be visible at a time and :scrollTop is initially 0,
|
|
// So the minimum amount of scrolling leaves the 50th item at the bottom (just scrolled into view).
|
|
|
|
expect(scrollTop).toEqual(900);
|
|
});
|
|
it('should support getTotalRowsHeight() public method', function () {
|
|
var grid = (0, _TestUtils.render)(getMarkup());
|
|
grid.recomputeGridSize();
|
|
var totalHeight = grid.getTotalRowsHeight(); // 100 rows * 20 item height = 2,000 total item height
|
|
|
|
expect(totalHeight).toEqual(2000);
|
|
});
|
|
it('should support getTotalColumnsWidth() public method', function () {
|
|
var grid = (0, _TestUtils.render)(getMarkup());
|
|
grid.recomputeGridSize();
|
|
var totalWidth = grid.getTotalColumnsWidth(); // 50 columns * 50 item width = 2,500 total item width
|
|
|
|
expect(totalWidth).toEqual(2500);
|
|
}); // See issue #565
|
|
|
|
it('should update scroll position to account for changed cell sizes within a function prop wrapper', function () {
|
|
var _rowHeight = 20;
|
|
var props = {
|
|
height: 100,
|
|
rowCount: 100,
|
|
rowHeight: function rowHeight(_ref4) {
|
|
var index = _ref4.index;
|
|
return index === 99 ? _rowHeight : 20;
|
|
},
|
|
scrollToRow: 99
|
|
};
|
|
var grid = (0, _TestUtils.render)(getMarkup(props));
|
|
var node = (0, _reactDom.findDOMNode)(grid);
|
|
expect(node.scrollTop).toBe(1900);
|
|
_rowHeight = 40;
|
|
grid.recomputeGridSize({
|
|
rowIndex: 99
|
|
});
|
|
expect(node.scrollTop).toBe(1920);
|
|
});
|
|
it('should not restore scrollLeft when scrolling left and recomputeGridSize with columnIndex smaller than scrollToColumn', function () {
|
|
var props = {
|
|
columnWidth: 50,
|
|
columnCount: 100,
|
|
height: 100,
|
|
rowCount: 100,
|
|
rowHeight: 20,
|
|
scrollToColumn: 50,
|
|
scrollToRow: 50,
|
|
width: 100
|
|
};
|
|
var grid = (0, _TestUtils.render)(getMarkup(props));
|
|
expect(grid.state.scrollLeft).toEqual(2450);
|
|
simulateScroll({
|
|
grid: grid,
|
|
scrollLeft: 2250
|
|
});
|
|
expect(grid.state.scrollLeft).toEqual(2250);
|
|
expect(grid.state.scrollDirectionHorizontal).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD);
|
|
grid.recomputeGridSize({
|
|
columnIndex: 30
|
|
});
|
|
expect(grid.state.scrollLeft).toEqual(2250);
|
|
});
|
|
it('should not restore scrollTop when scrolling up and recomputeGridSize with rowIndex smaller than scrollToRow', function () {
|
|
var props = {
|
|
columnWidth: 50,
|
|
columnCount: 100,
|
|
height: 100,
|
|
rowCount: 100,
|
|
rowHeight: 20,
|
|
scrollToColumn: 50,
|
|
scrollToRow: 50,
|
|
width: 100
|
|
};
|
|
var grid = (0, _TestUtils.render)(getMarkup(props));
|
|
expect(grid.state.scrollTop).toEqual(920);
|
|
simulateScroll({
|
|
grid: grid,
|
|
scrollTop: 720
|
|
});
|
|
expect(grid.state.scrollTop).toEqual(720);
|
|
expect(grid.state.scrollDirectionVertical).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD);
|
|
grid.recomputeGridSize({
|
|
rowIndex: 20
|
|
});
|
|
expect(grid.state.scrollTop).toEqual(720);
|
|
});
|
|
it('should restore scroll offset for column when row count increases from 0 (and vice versa)', function () {
|
|
var props = {
|
|
columnWidth: 50,
|
|
columnCount: 100,
|
|
height: 100,
|
|
rowCount: 100,
|
|
rowHeight: 20,
|
|
scrollToColumn: 50,
|
|
scrollToRow: 50,
|
|
width: 100
|
|
};
|
|
var grid = (0, _TestUtils.render)(getMarkup(props));
|
|
expect(grid.state.scrollLeft).toEqual(2450);
|
|
expect(grid.state.scrollTop).toEqual(920);
|
|
(0, _TestUtils.render)(getMarkup(_objectSpread({}, props, {
|
|
columnCount: 0
|
|
})));
|
|
expect(grid.state.scrollLeft).toEqual(0);
|
|
expect(grid.state.scrollTop).toEqual(0);
|
|
(0, _TestUtils.render)(getMarkup(props));
|
|
expect(grid.state.scrollLeft).toEqual(2450);
|
|
expect(grid.state.scrollTop).toEqual(920);
|
|
(0, _TestUtils.render)(getMarkup(_objectSpread({}, props, {
|
|
rowCount: 0
|
|
})));
|
|
expect(grid.state.scrollLeft).toEqual(0);
|
|
expect(grid.state.scrollTop).toEqual(0);
|
|
(0, _TestUtils.render)(getMarkup(props));
|
|
expect(grid.state.scrollLeft).toEqual(2450);
|
|
expect(grid.state.scrollTop).toEqual(920);
|
|
});
|
|
it('should take scrollbar size into account when aligning cells', function () {
|
|
var grid = (0, _TestUtils.render)(getMarkup({
|
|
columnWidth: 50,
|
|
columnCount: 100,
|
|
getScrollbarSize: getScrollbarSize20,
|
|
height: 100,
|
|
rowCount: 100,
|
|
rowHeight: 20,
|
|
scrollToColumn: 50,
|
|
scrollToRow: 50,
|
|
width: 100
|
|
}));
|
|
expect(grid.state.scrollLeft).toEqual(2450 + getScrollbarSize20());
|
|
expect(grid.state.scrollTop).toEqual(920 + getScrollbarSize20());
|
|
});
|
|
});
|
|
describe('property updates', function () {
|
|
it('should update :scrollToColumn position when :columnWidth changes', function () {
|
|
var grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
scrollToColumn: 25
|
|
})));
|
|
expect(grid.textContent).toContain('column:25'); // Making columns taller pushes name off/beyond the scrolled area
|
|
|
|
grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
scrollToColumn: 25,
|
|
columnWidth: 20
|
|
})));
|
|
expect(grid.textContent).toContain('column:25');
|
|
});
|
|
it('should update :scrollToRow position when :rowHeight changes', function () {
|
|
var grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
scrollToRow: 50
|
|
})));
|
|
expect(grid.textContent).toContain('row:50'); // Making rows taller pushes name off/beyond the scrolled area
|
|
|
|
grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
scrollToRow: 50,
|
|
rowHeight: 20
|
|
})));
|
|
expect(grid.textContent).toContain('row:50');
|
|
});
|
|
it('should update :scrollToColumn position when :width changes', function () {
|
|
var grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
scrollToColumn: 25
|
|
})));
|
|
expect(grid.textContent).toContain('column:25'); // Making the grid narrower leaves only room for 1 item
|
|
|
|
grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
scrollToColumn: 25,
|
|
width: 50
|
|
})));
|
|
expect(grid.textContent).toContain('column:25');
|
|
});
|
|
it('should update :scrollToRow position when :height changes', function () {
|
|
var grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
scrollToRow: 50
|
|
})));
|
|
expect(grid.textContent).toContain('row:50'); // Making the grid shorter leaves only room for 1 item
|
|
|
|
grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
scrollToRow: 50,
|
|
height: 20
|
|
})));
|
|
expect(grid.textContent).toContain('row:50');
|
|
});
|
|
it('should update :scrollToColumn position when :scrollToColumn changes', function () {
|
|
var grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup()));
|
|
expect(grid.textContent).not.toContain('column:25');
|
|
grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
scrollToColumn: 25
|
|
})));
|
|
expect(grid.textContent).toContain('column:25');
|
|
});
|
|
it('should update :scrollToRow position when :scrollToRow changes', function () {
|
|
var grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup()));
|
|
expect(grid.textContent).not.toContain('row:50');
|
|
grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
scrollToRow: 50
|
|
})));
|
|
expect(grid.textContent).toContain('row:50');
|
|
});
|
|
it('should update scroll position if size shrinks smaller than the current scroll', function () {
|
|
var grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
scrollToColumn: 250
|
|
})));
|
|
grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup()));
|
|
grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
scrollToColumn: 250,
|
|
columnCount: 10
|
|
})));
|
|
expect(grid.textContent).toContain('column:9');
|
|
});
|
|
it('should update scroll position if size shrinks smaller than the current scroll', function () {
|
|
var grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
scrollToRow: 500
|
|
})));
|
|
grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup()));
|
|
grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
scrollToRow: 500,
|
|
rowCount: 10
|
|
})));
|
|
expect(grid.textContent).toContain('row:9');
|
|
});
|
|
});
|
|
describe('noContentRenderer', function () {
|
|
it('should call :noContentRenderer if :columnCount is 0', function () {
|
|
var list = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
noContentRenderer: function noContentRenderer() {
|
|
return React.createElement("div", null, "No data");
|
|
},
|
|
columnCount: 0
|
|
})));
|
|
expect(list.textContent).toEqual('No data');
|
|
});
|
|
it('should call :noContentRenderer if :rowCount is 0', function () {
|
|
var list = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
noContentRenderer: function noContentRenderer() {
|
|
return React.createElement("div", null, "No data");
|
|
},
|
|
rowCount: 0
|
|
})));
|
|
expect(list.textContent).toEqual('No data');
|
|
}); // Sanity check for bvaughn/react-virtualized/pull/348
|
|
|
|
it('should render an empty body if :rowCount or :columnCount changes to 0', function () {
|
|
function noContentRenderer() {
|
|
return React.createElement("div", null, "No data");
|
|
}
|
|
|
|
var list = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
noContentRenderer: noContentRenderer
|
|
})));
|
|
expect(list.textContent).not.toEqual('No data');
|
|
list = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
noContentRenderer: noContentRenderer,
|
|
rowCount: 0
|
|
})));
|
|
expect(list.textContent).toEqual('No data');
|
|
list = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
noContentRenderer: noContentRenderer
|
|
})));
|
|
expect(list.textContent).not.toEqual('No data');
|
|
list = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
columnCount: 0,
|
|
noContentRenderer: noContentRenderer
|
|
})));
|
|
expect(list.textContent).toEqual('No data');
|
|
});
|
|
it('should render an empty body if :columnCount is 0 and there is no :noContentRenderer', function () {
|
|
var list = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
columnCount: 0
|
|
})));
|
|
expect(list.textContent).toEqual('');
|
|
});
|
|
it('should render an empty body if :rowCount is 0 and there is no :noContentRenderer', function () {
|
|
var list = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
rowCount: 0
|
|
})));
|
|
expect(list.textContent).toEqual('');
|
|
});
|
|
it('should render an empty body there is a :noContentRenderer but :height or :width are 0', function () {
|
|
var list = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
height: 0,
|
|
noContentRenderer: function noContentRenderer() {
|
|
return React.createElement("div", null, "No data");
|
|
}
|
|
})));
|
|
expect(list.textContent).toEqual('');
|
|
list = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
noContentRenderer: function noContentRenderer() {
|
|
return React.createElement("div", null, "No data");
|
|
},
|
|
width: 0
|
|
})));
|
|
expect(list.textContent).toEqual('');
|
|
});
|
|
});
|
|
describe('onSectionRendered', function () {
|
|
it('should call :onSectionRendered if at least one cell is rendered', function () {
|
|
var columnStartIndex, columnStopIndex, rowStartIndex, rowStopIndex;
|
|
(0, _TestUtils.render)(getMarkup({
|
|
onSectionRendered: function onSectionRendered(params) {
|
|
var _params;
|
|
|
|
return _params = params, columnStartIndex = _params.columnStartIndex, columnStopIndex = _params.columnStopIndex, rowStartIndex = _params.rowStartIndex, rowStopIndex = _params.rowStopIndex, _params;
|
|
}
|
|
}));
|
|
expect(columnStartIndex).toEqual(0);
|
|
expect(columnStopIndex).toEqual(3);
|
|
expect(rowStartIndex).toEqual(0);
|
|
expect(rowStopIndex).toEqual(4);
|
|
});
|
|
it('should not call :onSectionRendered unless the column or row start or stop indices have changed', function () {
|
|
var numCalls = 0;
|
|
var columnStartIndex, columnStopIndex, rowStartIndex, rowStopIndex;
|
|
|
|
var onSectionRendered = function onSectionRendered(params) {
|
|
columnStartIndex = params.columnStartIndex;
|
|
columnStopIndex = params.columnStopIndex;
|
|
rowStartIndex = params.rowStartIndex;
|
|
rowStopIndex = params.rowStopIndex;
|
|
numCalls++;
|
|
};
|
|
|
|
(0, _TestUtils.render)(getMarkup({
|
|
onSectionRendered: onSectionRendered
|
|
}));
|
|
expect(numCalls).toEqual(1);
|
|
expect(columnStartIndex).toEqual(0);
|
|
expect(columnStopIndex).toEqual(3);
|
|
expect(rowStartIndex).toEqual(0);
|
|
expect(rowStopIndex).toEqual(4);
|
|
(0, _TestUtils.render)(getMarkup({
|
|
onSectionRendered: onSectionRendered
|
|
}));
|
|
expect(numCalls).toEqual(1);
|
|
expect(columnStartIndex).toEqual(0);
|
|
expect(columnStopIndex).toEqual(3);
|
|
expect(rowStartIndex).toEqual(0);
|
|
expect(rowStopIndex).toEqual(4);
|
|
});
|
|
it('should call :onSectionRendered if the row or column start or stop indices have changed', function () {
|
|
var numCalls = 0;
|
|
var columnStartIndex, columnStopIndex, rowStartIndex, rowStopIndex;
|
|
|
|
var onSectionRendered = function onSectionRendered(params) {
|
|
columnStartIndex = params.columnStartIndex;
|
|
columnStopIndex = params.columnStopIndex;
|
|
rowStartIndex = params.rowStartIndex;
|
|
rowStopIndex = params.rowStopIndex;
|
|
numCalls++;
|
|
};
|
|
|
|
(0, _TestUtils.render)(getMarkup({
|
|
onSectionRendered: onSectionRendered
|
|
}));
|
|
expect(columnStartIndex).toEqual(0);
|
|
expect(columnStopIndex).toEqual(3);
|
|
expect(rowStartIndex).toEqual(0);
|
|
expect(rowStopIndex).toEqual(4);
|
|
(0, _TestUtils.render)(getMarkup({
|
|
height: 50,
|
|
onSectionRendered: onSectionRendered
|
|
}));
|
|
expect(numCalls).toEqual(2);
|
|
expect(columnStartIndex).toEqual(0);
|
|
expect(columnStopIndex).toEqual(3);
|
|
expect(rowStartIndex).toEqual(0);
|
|
expect(rowStopIndex).toEqual(2);
|
|
(0, _TestUtils.render)(getMarkup({
|
|
height: 50,
|
|
onSectionRendered: onSectionRendered,
|
|
width: 100
|
|
}));
|
|
expect(numCalls).toEqual(3);
|
|
expect(columnStartIndex).toEqual(0);
|
|
expect(columnStopIndex).toEqual(1);
|
|
expect(rowStartIndex).toEqual(0);
|
|
expect(rowStopIndex).toEqual(2);
|
|
});
|
|
it('should not call :onSectionRendered if no cells are rendered', function () {
|
|
var numCalls = 0;
|
|
(0, _TestUtils.render)(getMarkup({
|
|
height: 0,
|
|
onSectionRendered: function onSectionRendered() {
|
|
return numCalls++;
|
|
}
|
|
}));
|
|
expect(numCalls).toEqual(0);
|
|
});
|
|
});
|
|
describe(':scrollLeft and :scrollTop properties', function () {
|
|
it('should render correctly when an initial :scrollLeft and :scrollTop properties are specified', function () {
|
|
var columnStartIndex, columnStopIndex, rowStartIndex, rowStopIndex;
|
|
(0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
onSectionRendered: function onSectionRendered(params) {
|
|
var _params2;
|
|
|
|
return _params2 = params, columnStartIndex = _params2.columnStartIndex, columnStopIndex = _params2.columnStopIndex, rowStartIndex = _params2.rowStartIndex, rowStopIndex = _params2.rowStopIndex, _params2;
|
|
},
|
|
scrollLeft: 250,
|
|
scrollTop: 100
|
|
})));
|
|
expect(rowStartIndex).toEqual(5);
|
|
expect(rowStopIndex).toEqual(9);
|
|
expect(columnStartIndex).toEqual(5);
|
|
expect(columnStopIndex).toEqual(8);
|
|
});
|
|
it('should render correctly when :scrollLeft and :scrollTop properties are updated', function () {
|
|
var columnStartIndex, columnStopIndex, rowStartIndex, rowStopIndex;
|
|
(0, _TestUtils.render)(getMarkup({
|
|
onSectionRendered: function onSectionRendered(params) {
|
|
var _params3;
|
|
|
|
return _params3 = params, columnStartIndex = _params3.columnStartIndex, columnStopIndex = _params3.columnStopIndex, rowStartIndex = _params3.rowStartIndex, rowStopIndex = _params3.rowStopIndex, _params3;
|
|
}
|
|
}));
|
|
expect(rowStartIndex).toEqual(0);
|
|
expect(rowStopIndex).toEqual(4);
|
|
expect(columnStartIndex).toEqual(0);
|
|
expect(columnStopIndex).toEqual(3);
|
|
(0, _TestUtils.render)(getMarkup({
|
|
onSectionRendered: function onSectionRendered(params) {
|
|
var _params4;
|
|
|
|
return _params4 = params, columnStartIndex = _params4.columnStartIndex, columnStopIndex = _params4.columnStopIndex, rowStartIndex = _params4.rowStartIndex, rowStopIndex = _params4.rowStopIndex, _params4;
|
|
},
|
|
scrollLeft: 250,
|
|
scrollTop: 100
|
|
}));
|
|
expect(rowStartIndex).toEqual(5);
|
|
expect(rowStopIndex).toEqual(9);
|
|
expect(columnStartIndex).toEqual(5);
|
|
expect(columnStopIndex).toEqual(8);
|
|
});
|
|
});
|
|
describe('styles, classNames, and ids', function () {
|
|
it('should use the expected global CSS classNames', function () {
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup()));
|
|
expect(rendered.className).toEqual('ReactVirtualized__Grid');
|
|
});
|
|
it('should use a custom :className if specified', function () {
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
className: 'foo'
|
|
})));
|
|
expect(rendered.className).toContain('foo');
|
|
});
|
|
it('should use a custom :id if specified', function () {
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
id: 'bar'
|
|
})));
|
|
expect(rendered.getAttribute('id')).toEqual('bar');
|
|
});
|
|
it('should use a custom :style if specified', function () {
|
|
var style = {
|
|
backgroundColor: 'red'
|
|
};
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
style: style
|
|
})));
|
|
expect(rendered.style.backgroundColor).toEqual('red');
|
|
});
|
|
it('should use a custom :containerStyle if specified', function () {
|
|
var containerStyle = {
|
|
backgroundColor: 'red'
|
|
};
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
containerStyle: containerStyle
|
|
})));
|
|
expect(rendered.querySelector('.ReactVirtualized__Grid__innerScrollContainer').style.backgroundColor).toEqual('red');
|
|
});
|
|
});
|
|
describe('onScroll', function () {
|
|
it('should trigger callback when component is mounted', function () {
|
|
var onScrollCalls = [];
|
|
(0, _TestUtils.render)(getMarkup({
|
|
onScroll: function onScroll(params) {
|
|
return onScrollCalls.push(params);
|
|
},
|
|
scrollLeft: 50,
|
|
scrollTop: 100
|
|
}));
|
|
expect(onScrollCalls).toEqual([{
|
|
clientHeight: 100,
|
|
clientWidth: 200,
|
|
scrollHeight: 2000,
|
|
scrollLeft: 50,
|
|
scrollTop: 100,
|
|
scrollWidth: 2500
|
|
}]);
|
|
});
|
|
it('should trigger callback when component scrolls horizontally', function () {
|
|
var onScrollCalls = [];
|
|
var grid = (0, _TestUtils.render)(getMarkup({
|
|
onScroll: function onScroll(params) {
|
|
return onScrollCalls.push(params);
|
|
}
|
|
}));
|
|
simulateScroll({
|
|
grid: grid,
|
|
scrollLeft: 100,
|
|
scrollTop: 0
|
|
});
|
|
expect(onScrollCalls.length).toEqual(2);
|
|
expect(onScrollCalls[1]).toEqual({
|
|
clientHeight: 100,
|
|
clientWidth: 200,
|
|
scrollHeight: 2000,
|
|
scrollLeft: 100,
|
|
scrollTop: 0,
|
|
scrollWidth: 2500
|
|
});
|
|
});
|
|
it('should trigger callback when component scrolls vertically', function () {
|
|
var onScrollCalls = [];
|
|
var grid = (0, _TestUtils.render)(getMarkup({
|
|
onScroll: function onScroll(params) {
|
|
return onScrollCalls.push(params);
|
|
}
|
|
}));
|
|
simulateScroll({
|
|
grid: grid,
|
|
scrollLeft: 0,
|
|
scrollTop: 100
|
|
});
|
|
expect(onScrollCalls.length).toEqual(2);
|
|
expect(onScrollCalls[1]).toEqual({
|
|
clientHeight: 100,
|
|
clientWidth: 200,
|
|
scrollHeight: 2000,
|
|
scrollLeft: 0,
|
|
scrollTop: 100,
|
|
scrollWidth: 2500
|
|
});
|
|
});
|
|
it('should trigger callback with scrollLeft of 0 when total columns width is less than width', function () {
|
|
var onScrollCalls = [];
|
|
var grid = (0, _TestUtils.render)(getMarkup({
|
|
columnCount: 1,
|
|
columnWidth: 50,
|
|
onScroll: function onScroll(params) {
|
|
return onScrollCalls.push(params);
|
|
},
|
|
scrollLeft: 0,
|
|
scrollTop: 10,
|
|
width: 200
|
|
}));
|
|
simulateScroll({
|
|
grid: grid,
|
|
scrollLeft: 0,
|
|
scrollTop: 0
|
|
});
|
|
expect(onScrollCalls.length).toEqual(2);
|
|
expect(onScrollCalls[1]).toEqual({
|
|
clientHeight: 100,
|
|
clientWidth: 200,
|
|
scrollHeight: 2000,
|
|
scrollLeft: 0,
|
|
scrollTop: 0,
|
|
scrollWidth: 50
|
|
});
|
|
});
|
|
it('should trigger callback with scrollTop of 0 when total rows height is less than height', function () {
|
|
var onScrollCalls = [];
|
|
var grid = (0, _TestUtils.render)(getMarkup({
|
|
rowCount: 1,
|
|
rowHeight: 50,
|
|
onScroll: function onScroll(params) {
|
|
return onScrollCalls.push(params);
|
|
},
|
|
scrollLeft: 0,
|
|
scrollTop: 10,
|
|
height: 200
|
|
}));
|
|
simulateScroll({
|
|
grid: grid,
|
|
scrollLeft: 0,
|
|
scrollTop: 0
|
|
});
|
|
expect(onScrollCalls.length).toEqual(2);
|
|
expect(onScrollCalls[1]).toEqual({
|
|
clientHeight: 200,
|
|
clientWidth: 200,
|
|
scrollHeight: 50,
|
|
scrollLeft: 0,
|
|
scrollTop: 0,
|
|
scrollWidth: 2500
|
|
});
|
|
}); // Support use-cases like WindowScroller; enable them to stay in sync with scroll-to-cell changes.
|
|
|
|
it('should trigger when :scrollToColumn or :scrollToRow are changed via props', function () {
|
|
var onScrollCalls = [];
|
|
(0, _TestUtils.render)(getMarkup());
|
|
(0, _TestUtils.render)(getMarkup({
|
|
onScroll: function onScroll(params) {
|
|
return onScrollCalls.push(params);
|
|
},
|
|
scrollToColumn: 24,
|
|
scrollToRow: 49
|
|
}));
|
|
expect(onScrollCalls).toEqual([{
|
|
clientHeight: 100,
|
|
clientWidth: 200,
|
|
scrollHeight: 2000,
|
|
scrollLeft: 1050,
|
|
scrollTop: 900,
|
|
scrollWidth: 2500
|
|
}]);
|
|
});
|
|
});
|
|
describe('overscanColumnCount & overscanRowCount', function () {
|
|
function createHelper() {
|
|
var _columnOverscanStartIndex, _columnOverscanStopIndex, _columnStartIndex, _columnStopIndex, _rowOverscanStartIndex, _rowOverscanStopIndex, _rowStartIndex, _rowStopIndex;
|
|
|
|
function onSectionRendered(params) {
|
|
_columnOverscanStartIndex = params.columnOverscanStartIndex;
|
|
_columnOverscanStopIndex = params.columnOverscanStopIndex;
|
|
_columnStartIndex = params.columnStartIndex;
|
|
_columnStopIndex = params.columnStopIndex;
|
|
_rowOverscanStartIndex = params.rowOverscanStartIndex;
|
|
_rowOverscanStopIndex = params.rowOverscanStopIndex;
|
|
_rowStartIndex = params.rowStartIndex;
|
|
_rowStopIndex = params.rowStopIndex;
|
|
}
|
|
|
|
return {
|
|
columnOverscanStartIndex: function columnOverscanStartIndex() {
|
|
return _columnOverscanStartIndex;
|
|
},
|
|
columnOverscanStopIndex: function columnOverscanStopIndex() {
|
|
return _columnOverscanStopIndex;
|
|
},
|
|
columnStartIndex: function columnStartIndex() {
|
|
return _columnStartIndex;
|
|
},
|
|
columnStopIndex: function columnStopIndex() {
|
|
return _columnStopIndex;
|
|
},
|
|
onSectionRendered: onSectionRendered,
|
|
rowOverscanStartIndex: function rowOverscanStartIndex() {
|
|
return _rowOverscanStartIndex;
|
|
},
|
|
rowOverscanStopIndex: function rowOverscanStopIndex() {
|
|
return _rowOverscanStopIndex;
|
|
},
|
|
rowStartIndex: function rowStartIndex() {
|
|
return _rowStartIndex;
|
|
},
|
|
rowStopIndex: function rowStopIndex() {
|
|
return _rowStopIndex;
|
|
}
|
|
};
|
|
}
|
|
|
|
it('should not overscan if disabled', function () {
|
|
var helper = createHelper();
|
|
(0, _TestUtils.render)(getMarkup({
|
|
onSectionRendered: helper.onSectionRendered
|
|
}));
|
|
expect(helper.columnOverscanStartIndex()).toEqual(helper.columnStartIndex());
|
|
expect(helper.columnOverscanStopIndex()).toEqual(helper.columnStopIndex());
|
|
expect(helper.rowOverscanStartIndex()).toEqual(helper.rowStartIndex());
|
|
expect(helper.rowOverscanStopIndex()).toEqual(helper.rowStopIndex());
|
|
});
|
|
it('should overscan the specified amount', function () {
|
|
var helper = createHelper();
|
|
(0, _TestUtils.render)(getMarkup({
|
|
onSectionRendered: helper.onSectionRendered,
|
|
overscanColumnCount: 2,
|
|
overscanRowCount: 5,
|
|
scrollToColumn: 25,
|
|
scrollToRow: 50
|
|
}));
|
|
expect(helper.columnOverscanStartIndex()).toEqual(22);
|
|
expect(helper.columnOverscanStopIndex()).toEqual(27);
|
|
expect(helper.columnStartIndex()).toEqual(22);
|
|
expect(helper.columnStopIndex()).toEqual(25);
|
|
expect(helper.rowOverscanStartIndex()).toEqual(46);
|
|
expect(helper.rowOverscanStopIndex()).toEqual(55);
|
|
expect(helper.rowStartIndex()).toEqual(46);
|
|
expect(helper.rowStopIndex()).toEqual(50);
|
|
});
|
|
it('should not overscan beyond the bounds of the grid', function () {
|
|
var helper = createHelper();
|
|
(0, _TestUtils.render)(getMarkup({
|
|
onSectionRendered: helper.onSectionRendered,
|
|
columnCount: 6,
|
|
overscanColumnCount: 10,
|
|
overscanRowCount: 10,
|
|
rowCount: 5
|
|
}));
|
|
expect(helper.columnOverscanStartIndex()).toEqual(0);
|
|
expect(helper.columnOverscanStopIndex()).toEqual(5);
|
|
expect(helper.columnStartIndex()).toEqual(0);
|
|
expect(helper.columnStopIndex()).toEqual(3);
|
|
expect(helper.rowOverscanStartIndex()).toEqual(0);
|
|
expect(helper.rowOverscanStopIndex()).toEqual(4);
|
|
expect(helper.rowStartIndex()).toEqual(0);
|
|
expect(helper.rowStopIndex()).toEqual(4);
|
|
});
|
|
it('should set the correct scroll direction', function () {
|
|
// Do not pass in the initial state as props, otherwise the internal state is forbidden from updating itself
|
|
var grid = (0, _TestUtils.render)(getMarkup()); // Simulate a scroll to set the initial internal state
|
|
|
|
simulateScroll({
|
|
grid: grid,
|
|
scrollLeft: 50,
|
|
scrollTop: 50
|
|
});
|
|
expect(grid.state.scrollDirectionHorizontal).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD);
|
|
expect(grid.state.scrollDirectionVertical).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD);
|
|
simulateScroll({
|
|
grid: grid,
|
|
scrollLeft: 0,
|
|
scrollTop: 0
|
|
});
|
|
expect(grid.state.scrollDirectionHorizontal).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD);
|
|
expect(grid.state.scrollDirectionVertical).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD);
|
|
simulateScroll({
|
|
grid: grid,
|
|
scrollLeft: 100,
|
|
scrollTop: 100
|
|
});
|
|
expect(grid.state.scrollDirectionHorizontal).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD);
|
|
expect(grid.state.scrollDirectionVertical).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD);
|
|
});
|
|
it('should set the correct scroll direction when scroll position is updated from props', function () {
|
|
var grid = (0, _TestUtils.render)(getMarkup({
|
|
scrollLeft: 50,
|
|
scrollTop: 50
|
|
}));
|
|
expect(grid.state.scrollDirectionHorizontal).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD);
|
|
expect(grid.state.scrollDirectionVertical).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD);
|
|
grid = (0, _TestUtils.render)(getMarkup({
|
|
scrollLeft: 0,
|
|
scrollTop: 0
|
|
}));
|
|
expect(grid.state.scrollDirectionHorizontal).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD);
|
|
expect(grid.state.scrollDirectionVertical).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD);
|
|
grid = (0, _TestUtils.render)(getMarkup({
|
|
scrollLeft: 100,
|
|
scrollTop: 100
|
|
}));
|
|
expect(grid.state.scrollDirectionHorizontal).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD);
|
|
expect(grid.state.scrollDirectionVertical).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD);
|
|
});
|
|
it('should not reset scroll direction for one axis when scrolled in another', function () {
|
|
// Do not pass in the initial state as props, otherwise the internal state is forbidden from updating itself
|
|
var grid = (0, _TestUtils.render)(getMarkup()); // Simulate a scroll to set the initial internal state
|
|
|
|
simulateScroll({
|
|
grid: grid,
|
|
scrollLeft: 0,
|
|
scrollTop: 5
|
|
});
|
|
expect(grid.state.scrollDirectionHorizontal).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD);
|
|
expect(grid.state.scrollDirectionVertical).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD);
|
|
simulateScroll({
|
|
grid: grid,
|
|
scrollLeft: 5,
|
|
scrollTop: 5
|
|
});
|
|
expect(grid.state.scrollDirectionHorizontal).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD);
|
|
expect(grid.state.scrollDirectionVertical).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD);
|
|
simulateScroll({
|
|
grid: grid,
|
|
scrollLeft: 5,
|
|
scrollTop: 0
|
|
});
|
|
expect(grid.state.scrollDirectionHorizontal).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD);
|
|
expect(grid.state.scrollDirectionVertical).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD);
|
|
simulateScroll({
|
|
grid: grid,
|
|
scrollLeft: 0,
|
|
scrollTop: 0
|
|
});
|
|
expect(grid.state.scrollDirectionHorizontal).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD);
|
|
expect(grid.state.scrollDirectionVertical).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD);
|
|
});
|
|
it('should overscan in the direction being scrolled', function _callee(done) {
|
|
var helper, onSectionRenderedResolve, onSectionRendered, grid, onSectionRenderedPromise;
|
|
return _regenerator["default"].async(function _callee$(_context) {
|
|
while (1) {
|
|
switch (_context.prev = _context.next) {
|
|
case 0:
|
|
onSectionRendered = function _ref5(params) {
|
|
helper.onSectionRendered(params);
|
|
|
|
if (onSectionRenderedResolve) {
|
|
onSectionRenderedResolve();
|
|
}
|
|
};
|
|
|
|
helper = createHelper();
|
|
grid = (0, _TestUtils.render)(getMarkup({
|
|
onSectionRendered: onSectionRendered,
|
|
overscanColumnCount: 2,
|
|
overscanRowCount: 5
|
|
})); // Wait until the onSectionRendered handler / debouncer has processed
|
|
|
|
onSectionRenderedPromise = new Promise(function (resolve) {
|
|
onSectionRenderedResolve = resolve;
|
|
});
|
|
simulateScroll({
|
|
grid: grid,
|
|
scrollLeft: 200,
|
|
scrollTop: 200
|
|
});
|
|
_context.next = 7;
|
|
return _regenerator["default"].awrap(onSectionRenderedPromise);
|
|
|
|
case 7:
|
|
// It should overscan in the direction being scrolled while scroll is in progress
|
|
expect(helper.columnOverscanStartIndex()).toEqual(4);
|
|
expect(helper.columnOverscanStopIndex()).toEqual(9);
|
|
expect(helper.columnStartIndex()).toEqual(4);
|
|
expect(helper.columnStopIndex()).toEqual(7);
|
|
expect(helper.rowOverscanStartIndex()).toEqual(10);
|
|
expect(helper.rowOverscanStopIndex()).toEqual(19);
|
|
expect(helper.rowStartIndex()).toEqual(10);
|
|
expect(helper.rowStopIndex()).toEqual(14); // Wait until the onSectionRendered handler / debouncer has processed
|
|
|
|
onSectionRenderedPromise = new Promise(function (resolve) {
|
|
onSectionRenderedResolve = resolve;
|
|
});
|
|
simulateScroll({
|
|
grid: grid,
|
|
scrollLeft: 100,
|
|
scrollTop: 100
|
|
});
|
|
_context.next = 19;
|
|
return _regenerator["default"].awrap(onSectionRenderedPromise);
|
|
|
|
case 19:
|
|
// It reset overscan once scrolling has finished
|
|
expect(helper.columnOverscanStartIndex()).toEqual(0);
|
|
expect(helper.columnOverscanStopIndex()).toEqual(5);
|
|
expect(helper.columnStartIndex()).toEqual(2);
|
|
expect(helper.columnStopIndex()).toEqual(5);
|
|
expect(helper.rowOverscanStartIndex()).toEqual(0);
|
|
expect(helper.rowOverscanStopIndex()).toEqual(9);
|
|
expect(helper.rowStartIndex()).toEqual(5);
|
|
expect(helper.rowStopIndex()).toEqual(9);
|
|
done();
|
|
|
|
case 28:
|
|
case "end":
|
|
return _context.stop();
|
|
}
|
|
}
|
|
});
|
|
});
|
|
});
|
|
describe('cellRangeRenderer', function () {
|
|
it('should use a custom :cellRangeRenderer if specified', function () {
|
|
var cellRangeRendererCalled = 0;
|
|
var cellRangeRendererParams;
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
cellRangeRenderer: function cellRangeRenderer(params) {
|
|
cellRangeRendererParams = params;
|
|
cellRangeRendererCalled++;
|
|
return [React.createElement("div", {
|
|
key: "0"
|
|
}, "Fake content")];
|
|
}
|
|
})));
|
|
expect(cellRangeRendererCalled).toEqual(1);
|
|
expect(cellRangeRendererParams.columnStartIndex).toEqual(0);
|
|
expect(cellRangeRendererParams.columnStopIndex).toEqual(3);
|
|
expect(cellRangeRendererParams.rowStartIndex).toEqual(0);
|
|
expect(cellRangeRendererParams.rowStopIndex).toEqual(4);
|
|
expect(rendered.textContent).toContain('Fake content');
|
|
});
|
|
});
|
|
describe('estimated row and column sizes', function () {
|
|
it('should not estimate sizes if actual sizes are numbers', function () {
|
|
var grid = (0, _TestUtils.render)(getMarkup({
|
|
columnWidth: 100,
|
|
estimatedColumnSize: 150,
|
|
estimatedRowSize: 15,
|
|
rowHeight: 20
|
|
}));
|
|
expect(_Grid["default"]._getEstimatedColumnSize(grid.props)).toEqual(100);
|
|
expect(_Grid["default"]._getEstimatedRowSize(grid.props)).toEqual(20);
|
|
});
|
|
it('should estimate row and column sizes if actual sizes are functions', function () {
|
|
var grid = (0, _TestUtils.render)(getMarkup({
|
|
columnWidth: function columnWidth() {
|
|
return 100;
|
|
},
|
|
estimatedColumnSize: 150,
|
|
estimatedRowSize: 15,
|
|
rowHeight: function rowHeight() {
|
|
return 20;
|
|
}
|
|
}));
|
|
expect(_Grid["default"]._getEstimatedColumnSize(grid.props)).toEqual(150);
|
|
expect(_Grid["default"]._getEstimatedRowSize(grid.props)).toEqual(15);
|
|
});
|
|
});
|
|
it('should pass the cellRenderer an :isScrolling flag when scrolling is in progress', function _callee2(done) {
|
|
var cellRendererCalls, cellRenderer, grid;
|
|
return _regenerator["default"].async(function _callee2$(_context2) {
|
|
while (1) {
|
|
switch (_context2.prev = _context2.next) {
|
|
case 0:
|
|
cellRenderer = function _ref7(_ref6) {
|
|
var columnIndex = _ref6.columnIndex,
|
|
isScrolling = _ref6.isScrolling,
|
|
key = _ref6.key,
|
|
rowIndex = _ref6.rowIndex,
|
|
style = _ref6.style;
|
|
cellRendererCalls.push(isScrolling);
|
|
return defaultCellRenderer({
|
|
columnIndex: columnIndex,
|
|
key: key,
|
|
rowIndex: rowIndex,
|
|
style: style
|
|
});
|
|
};
|
|
|
|
cellRendererCalls = [];
|
|
grid = (0, _TestUtils.render)(getMarkup({
|
|
cellRenderer: cellRenderer
|
|
}));
|
|
expect(cellRendererCalls[0]).toEqual(false);
|
|
cellRendererCalls.splice(0); // Give React time to process the queued setState()
|
|
|
|
_context2.next = 7;
|
|
return _regenerator["default"].awrap(new Promise(function (resolve) {
|
|
return setTimeout(resolve, 1);
|
|
}));
|
|
|
|
case 7:
|
|
simulateScroll({
|
|
grid: grid,
|
|
scrollTop: 100
|
|
});
|
|
expect(cellRendererCalls[0]).toEqual(true);
|
|
done();
|
|
|
|
case 10:
|
|
case "end":
|
|
return _context2.stop();
|
|
}
|
|
}
|
|
});
|
|
});
|
|
it('should pass the cellRenderer an :isScrolling flag based on props override', function () {
|
|
var cellRenderer = jest.fn();
|
|
cellRenderer.mockImplementation(function (_ref8) {
|
|
var key = _ref8.key,
|
|
style = _ref8.style;
|
|
return React.createElement("div", {
|
|
key: key,
|
|
style: style
|
|
});
|
|
});
|
|
(0, _TestUtils.render)(getMarkup({
|
|
cellRenderer: cellRenderer,
|
|
isScrolling: true
|
|
}));
|
|
expect(cellRenderer).toHaveBeenCalled();
|
|
expect(cellRenderer.mock.calls[0][0].isScrolling).toBe(true);
|
|
cellRenderer.mockReset();
|
|
(0, _TestUtils.render)(getMarkup({
|
|
cellRenderer: cellRenderer,
|
|
isScrolling: false,
|
|
width: DEFAULT_WIDTH + 1
|
|
}));
|
|
expect(cellRenderer).toHaveBeenCalled();
|
|
expect(cellRenderer.mock.calls[0][0].isScrolling).toBe(false);
|
|
});
|
|
it('should pass the cellRenderer an :isVisible flag', function () {
|
|
var cellRendererCalls = [];
|
|
|
|
function cellRenderer(props) {
|
|
cellRendererCalls.push(props);
|
|
return defaultCellRenderer(props);
|
|
}
|
|
|
|
(0, _TestUtils.render)(getMarkup({
|
|
cellRenderer: cellRenderer,
|
|
height: DEFAULT_ROW_HEIGHT,
|
|
overscanColumnCount: 1,
|
|
overscanRowCount: 1,
|
|
width: DEFAULT_COLUMN_WIDTH
|
|
}));
|
|
cellRendererCalls.forEach(function (props) {
|
|
expect(props.isVisible).toEqual(props.columnIndex === 0 && props.rowIndex === 0); // Only the first cell is visible
|
|
});
|
|
});
|
|
describe('cell caching', function () {
|
|
it('should not cache cells if the Grid is not scrolling', function () {
|
|
var cellRendererCalls = [];
|
|
|
|
function cellRenderer(_ref9) {
|
|
var columnIndex = _ref9.columnIndex,
|
|
key = _ref9.key,
|
|
rowIndex = _ref9.rowIndex,
|
|
style = _ref9.style;
|
|
cellRendererCalls.push({
|
|
columnIndex: columnIndex,
|
|
rowIndex: rowIndex
|
|
});
|
|
return defaultCellRenderer({
|
|
columnIndex: columnIndex,
|
|
key: key,
|
|
rowIndex: rowIndex,
|
|
style: style
|
|
});
|
|
}
|
|
|
|
var props = {
|
|
cellRenderer: cellRenderer,
|
|
columnWidth: 100,
|
|
height: 40,
|
|
rowHeight: 20,
|
|
scrollToRow: 0,
|
|
width: 100
|
|
};
|
|
(0, _TestUtils.render)(getMarkup(_objectSpread({}, props, {
|
|
scrollToRow: 0
|
|
})));
|
|
expect(cellRendererCalls).toEqual([{
|
|
columnIndex: 0,
|
|
rowIndex: 0
|
|
}, {
|
|
columnIndex: 0,
|
|
rowIndex: 1
|
|
}]);
|
|
cellRendererCalls.splice(0);
|
|
(0, _TestUtils.render)(getMarkup(_objectSpread({}, props, {
|
|
scrollToRow: 1
|
|
})));
|
|
expect(cellRendererCalls).toEqual([{
|
|
columnIndex: 0,
|
|
rowIndex: 0
|
|
}, {
|
|
columnIndex: 0,
|
|
rowIndex: 1
|
|
}]);
|
|
});
|
|
it('should not cache cells if the offsets are not adjusted', function () {
|
|
var cellRendererCalls = [];
|
|
|
|
function cellRenderer(_ref10) {
|
|
var columnIndex = _ref10.columnIndex,
|
|
key = _ref10.key,
|
|
rowIndex = _ref10.rowIndex,
|
|
style = _ref10.style;
|
|
cellRendererCalls.push({
|
|
columnIndex: columnIndex,
|
|
rowIndex: rowIndex
|
|
});
|
|
return defaultCellRenderer({
|
|
columnIndex: columnIndex,
|
|
key: key,
|
|
rowIndex: rowIndex,
|
|
style: style
|
|
});
|
|
}
|
|
|
|
var props = {
|
|
cellRenderer: cellRenderer,
|
|
columnWidth: 100,
|
|
height: 40,
|
|
rowHeight: 20,
|
|
rowCount: 100000,
|
|
scrollToRow: 0,
|
|
width: 100
|
|
};
|
|
(0, _TestUtils.render)(getMarkup(_objectSpread({}, props, {
|
|
scrollToRow: 0
|
|
})));
|
|
expect(cellRendererCalls).toEqual([{
|
|
columnIndex: 0,
|
|
rowIndex: 0
|
|
}, {
|
|
columnIndex: 0,
|
|
rowIndex: 1
|
|
}]);
|
|
cellRendererCalls.splice(0);
|
|
(0, _TestUtils.render)(getMarkup(_objectSpread({}, props, {
|
|
scrollToRow: 1
|
|
})));
|
|
expect(cellRendererCalls).toEqual([{
|
|
columnIndex: 0,
|
|
rowIndex: 0
|
|
}, {
|
|
columnIndex: 0,
|
|
rowIndex: 1
|
|
}]);
|
|
});
|
|
it('should cache a cell once it has been rendered while scrolling', function () {
|
|
var cellRendererCalls = [];
|
|
|
|
function cellRenderer(_ref11) {
|
|
var columnIndex = _ref11.columnIndex,
|
|
key = _ref11.key,
|
|
rowIndex = _ref11.rowIndex,
|
|
style = _ref11.style;
|
|
cellRendererCalls.push({
|
|
columnIndex: columnIndex,
|
|
rowIndex: rowIndex
|
|
});
|
|
return defaultCellRenderer({
|
|
columnIndex: columnIndex,
|
|
key: key,
|
|
rowIndex: rowIndex,
|
|
style: style
|
|
});
|
|
}
|
|
|
|
var props = {
|
|
cellRenderer: cellRenderer,
|
|
columnWidth: 100,
|
|
height: 40,
|
|
rowHeight: 20,
|
|
width: 100
|
|
};
|
|
var grid = (0, _TestUtils.render)(getMarkup(_objectSpread({}, props, {
|
|
scrollToRow: 0
|
|
})));
|
|
expect(cellRendererCalls).toEqual([{
|
|
columnIndex: 0,
|
|
rowIndex: 0
|
|
}, {
|
|
columnIndex: 0,
|
|
rowIndex: 1
|
|
}]);
|
|
simulateScroll({
|
|
grid: grid,
|
|
scrollTop: 1
|
|
});
|
|
cellRendererCalls.splice(0); // Rows 0-2 have already rendered but row 3 is not yet visible
|
|
// This means that only row 3 should be newly-created
|
|
// The others should come from the cache
|
|
|
|
(0, _TestUtils.render)(getMarkup(_objectSpread({}, props, {
|
|
scrollToRow: 3
|
|
})));
|
|
expect(cellRendererCalls).toEqual([{
|
|
columnIndex: 0,
|
|
rowIndex: 3
|
|
}]);
|
|
});
|
|
it('should clear cache once :isScrolling is false', function _callee3(done) {
|
|
var cellRendererCalls, cellRenderer, props, grid;
|
|
return _regenerator["default"].async(function _callee3$(_context3) {
|
|
while (1) {
|
|
switch (_context3.prev = _context3.next) {
|
|
case 0:
|
|
cellRenderer = function _ref13(_ref12) {
|
|
var columnIndex = _ref12.columnIndex,
|
|
key = _ref12.key,
|
|
rowIndex = _ref12.rowIndex,
|
|
style = _ref12.style;
|
|
cellRendererCalls.push({
|
|
columnIndex: columnIndex,
|
|
rowIndex: rowIndex
|
|
});
|
|
return defaultCellRenderer({
|
|
columnIndex: columnIndex,
|
|
key: key,
|
|
rowIndex: rowIndex,
|
|
style: style
|
|
});
|
|
};
|
|
|
|
cellRendererCalls = [];
|
|
props = {
|
|
cellRenderer: cellRenderer,
|
|
columnWidth: 100,
|
|
height: 40,
|
|
rowHeight: 20,
|
|
scrollToRow: 0,
|
|
width: 100
|
|
};
|
|
grid = (0, _TestUtils.render)(getMarkup(props));
|
|
expect(cellRendererCalls).toEqual([{
|
|
columnIndex: 0,
|
|
rowIndex: 0
|
|
}, {
|
|
columnIndex: 0,
|
|
rowIndex: 1
|
|
}]);
|
|
simulateScroll({
|
|
grid: grid,
|
|
scrollTop: 1
|
|
}); // Allow scrolling timeout to complete so that cell cache is reset
|
|
|
|
_context3.next = 8;
|
|
return _regenerator["default"].awrap(new Promise(function (resolve) {
|
|
return setTimeout(resolve, _Grid.DEFAULT_SCROLLING_RESET_TIME_INTERVAL * 2);
|
|
}));
|
|
|
|
case 8:
|
|
cellRendererCalls.splice(0);
|
|
(0, _TestUtils.render)(getMarkup(_objectSpread({}, props, {
|
|
scrollToRow: 1
|
|
})));
|
|
expect(cellRendererCalls.length).not.toEqual(0);
|
|
done();
|
|
|
|
case 12:
|
|
case "end":
|
|
return _context3.stop();
|
|
}
|
|
}
|
|
});
|
|
});
|
|
it('should clear cache once :isScrolling via props is false', function _callee4() {
|
|
var cellRenderer, props, scrollingStyle;
|
|
return _regenerator["default"].async(function _callee4$(_context4) {
|
|
while (1) {
|
|
switch (_context4.prev = _context4.next) {
|
|
case 0:
|
|
cellRenderer = jest.fn();
|
|
cellRenderer.mockImplementation(function (params) {
|
|
return React.createElement("div", {
|
|
key: params.key,
|
|
style: params.style
|
|
});
|
|
});
|
|
props = {
|
|
autoHeight: true,
|
|
cellRenderer: cellRenderer,
|
|
columnCount: 1,
|
|
isScrolling: true,
|
|
rowCount: 1
|
|
};
|
|
(0, _TestUtils.render)(getMarkup(props));
|
|
(0, _TestUtils.render)(getMarkup(props));
|
|
expect(cellRenderer).toHaveBeenCalledTimes(1); // Due to cell cache
|
|
|
|
scrollingStyle = cellRenderer.mock.calls[0][0].style;
|
|
cellRenderer.mockReset();
|
|
(0, _TestUtils.render)(getMarkup(_objectSpread({}, props, {
|
|
isScrolling: false
|
|
})));
|
|
expect(cellRenderer.mock.calls[0][0].style).toBe(scrollingStyle);
|
|
expect(cellRenderer).toHaveBeenCalledTimes(1); // Reset cache
|
|
|
|
cellRenderer.mockReset();
|
|
(0, _TestUtils.render)(getMarkup(_objectSpread({}, props, {
|
|
isScrolling: true
|
|
})));
|
|
expect(cellRenderer.mock.calls[0][0].style).not.toBe(scrollingStyle);
|
|
expect(cellRenderer).toHaveBeenCalledTimes(1); // Only cached when scrolling
|
|
|
|
case 15:
|
|
case "end":
|
|
return _context4.stop();
|
|
}
|
|
}
|
|
});
|
|
});
|
|
it('should clear cache if :recomputeGridSize is called', function () {
|
|
var cellRendererCalls = [];
|
|
|
|
function cellRenderer(_ref14) {
|
|
var columnIndex = _ref14.columnIndex,
|
|
key = _ref14.key,
|
|
rowIndex = _ref14.rowIndex,
|
|
style = _ref14.style;
|
|
cellRendererCalls.push({
|
|
columnIndex: columnIndex,
|
|
rowIndex: rowIndex
|
|
});
|
|
return defaultCellRenderer({
|
|
columnIndex: columnIndex,
|
|
key: key,
|
|
rowIndex: rowIndex,
|
|
style: style
|
|
});
|
|
}
|
|
|
|
var props = {
|
|
cellRenderer: cellRenderer,
|
|
columnWidth: 100,
|
|
height: 40,
|
|
rowHeight: 20,
|
|
scrollTop: 0,
|
|
width: 100
|
|
};
|
|
var grid = (0, _TestUtils.render)(getMarkup(props));
|
|
expect(cellRendererCalls).toEqual([{
|
|
columnIndex: 0,
|
|
rowIndex: 0
|
|
}, {
|
|
columnIndex: 0,
|
|
rowIndex: 1
|
|
}]);
|
|
simulateScroll({
|
|
grid: grid,
|
|
scrollTop: 1
|
|
});
|
|
cellRendererCalls.splice(0);
|
|
grid.recomputeGridSize();
|
|
expect(cellRendererCalls.length).not.toEqual(0);
|
|
});
|
|
it('should not clear cache if :isScrollingOptOut is true', function () {
|
|
var cellRendererCalls = [];
|
|
|
|
function cellRenderer(_ref15) {
|
|
var columnIndex = _ref15.columnIndex,
|
|
key = _ref15.key,
|
|
rowIndex = _ref15.rowIndex,
|
|
style = _ref15.style;
|
|
cellRendererCalls.push({
|
|
columnIndex: columnIndex,
|
|
rowIndex: rowIndex
|
|
});
|
|
return defaultCellRenderer({
|
|
columnIndex: columnIndex,
|
|
key: key,
|
|
rowIndex: rowIndex,
|
|
style: style
|
|
});
|
|
}
|
|
|
|
var props = {
|
|
cellRenderer: cellRenderer,
|
|
columnWidth: 100,
|
|
height: 40,
|
|
rowHeight: 20,
|
|
scrollTop: 0,
|
|
width: 100,
|
|
isScrollingOptOut: true
|
|
};
|
|
(0, _TestUtils.render)(getMarkup(props));
|
|
(0, _TestUtils.render)(getMarkup(props));
|
|
expect(cellRendererCalls).toEqual([{
|
|
columnIndex: 0,
|
|
rowIndex: 0
|
|
}, {
|
|
columnIndex: 0,
|
|
rowIndex: 1
|
|
}]);
|
|
cellRendererCalls.splice(0);
|
|
(0, _TestUtils.render)(getMarkup(_objectSpread({}, props, {
|
|
isScrolling: false
|
|
}))); // Visible cells are cached
|
|
|
|
expect(cellRendererCalls.length).toEqual(0);
|
|
(0, _TestUtils.render)(getMarkup(_objectSpread({}, props, {
|
|
isScrolling: true
|
|
}))); // Only cleared non-visible cells
|
|
|
|
expect(cellRendererCalls.length).toEqual(0);
|
|
});
|
|
it('should not trigger render by _debounceScrollEndedCallback if process slow table', function _callee5() {
|
|
var scrollingResetTimeInterval, cellRangeRendererCalls, cellRangeRenderer, props, grid, i;
|
|
return _regenerator["default"].async(function _callee5$(_context5) {
|
|
while (1) {
|
|
switch (_context5.prev = _context5.next) {
|
|
case 0:
|
|
cellRangeRenderer = function _ref16(props) {
|
|
var startTime = Date.now();
|
|
|
|
while (Date.now() - startTime <= scrollingResetTimeInterval) {
|
|
;
|
|
} // imitate very slow render
|
|
|
|
|
|
cellRangeRendererCalls++;
|
|
return (0, _defaultCellRangeRenderer["default"])(props);
|
|
};
|
|
|
|
scrollingResetTimeInterval = 50;
|
|
cellRangeRendererCalls = 0;
|
|
props = {
|
|
scrollingResetTimeInterval: scrollingResetTimeInterval,
|
|
cellRangeRenderer: cellRangeRenderer
|
|
};
|
|
grid = (0, _TestUtils.render)(getMarkup(props));
|
|
(0, _TestUtils.render)(getMarkup(props));
|
|
expect(cellRangeRendererCalls).toEqual(1);
|
|
i = 1;
|
|
|
|
case 8:
|
|
if (!(i <= 5)) {
|
|
_context5.next = 17;
|
|
break;
|
|
}
|
|
|
|
cellRangeRendererCalls = 0;
|
|
simulateScroll({
|
|
grid: grid,
|
|
scrollTop: i
|
|
}); // small wait for maybe early _debounceScrollEndedCallback
|
|
|
|
_context5.next = 13;
|
|
return _regenerator["default"].awrap(new Promise(function (resolve) {
|
|
return setTimeout(resolve, scrollingResetTimeInterval / 2);
|
|
}));
|
|
|
|
case 13:
|
|
expect(cellRangeRendererCalls).toEqual(1);
|
|
|
|
case 14:
|
|
i++;
|
|
_context5.next = 8;
|
|
break;
|
|
|
|
case 17:
|
|
cellRangeRendererCalls = 0; // wait for real _debounceScrollEndedCallback
|
|
|
|
_context5.next = 20;
|
|
return _regenerator["default"].awrap(new Promise(function (resolve) {
|
|
return setTimeout(resolve, scrollingResetTimeInterval * 1.5);
|
|
}));
|
|
|
|
case 20:
|
|
expect(cellRangeRendererCalls).toEqual(1);
|
|
|
|
case 21:
|
|
case "end":
|
|
return _context5.stop();
|
|
}
|
|
}
|
|
});
|
|
});
|
|
it('should support a custom :scrollingResetTimeInterval prop', function _callee6(done) {
|
|
var cellRendererCalls, scrollingResetTimeInterval, cellRenderer, props, grid;
|
|
return _regenerator["default"].async(function _callee6$(_context6) {
|
|
while (1) {
|
|
switch (_context6.prev = _context6.next) {
|
|
case 0:
|
|
cellRenderer = function _ref18(_ref17) {
|
|
var columnIndex = _ref17.columnIndex,
|
|
key = _ref17.key,
|
|
rowIndex = _ref17.rowIndex,
|
|
style = _ref17.style;
|
|
cellRendererCalls.push({
|
|
columnIndex: columnIndex,
|
|
rowIndex: rowIndex
|
|
});
|
|
return defaultCellRenderer({
|
|
columnIndex: columnIndex,
|
|
key: key,
|
|
rowIndex: rowIndex,
|
|
style: style
|
|
});
|
|
};
|
|
|
|
cellRendererCalls = [];
|
|
scrollingResetTimeInterval = _Grid.DEFAULT_SCROLLING_RESET_TIME_INTERVAL * 2;
|
|
props = {
|
|
cellRenderer: cellRenderer,
|
|
scrollingResetTimeInterval: scrollingResetTimeInterval
|
|
};
|
|
grid = (0, _TestUtils.render)(getMarkup(props));
|
|
expect(cellRendererCalls.length > 0).toEqual(true);
|
|
simulateScroll({
|
|
grid: grid,
|
|
scrollTop: 1
|
|
});
|
|
_context6.next = 9;
|
|
return _regenerator["default"].awrap(new Promise(function (resolve) {
|
|
return setTimeout(resolve, _Grid.DEFAULT_SCROLLING_RESET_TIME_INTERVAL);
|
|
}));
|
|
|
|
case 9:
|
|
cellRendererCalls.splice(0);
|
|
(0, _TestUtils.render)(getMarkup(_objectSpread({}, props, {
|
|
className: 'foo'
|
|
})));
|
|
expect(cellRendererCalls.length).toEqual(0);
|
|
_context6.next = 14;
|
|
return _regenerator["default"].awrap(new Promise(function (resolve) {
|
|
return setTimeout(resolve, _Grid.DEFAULT_SCROLLING_RESET_TIME_INTERVAL * 2);
|
|
}));
|
|
|
|
case 14:
|
|
cellRendererCalls.splice(0);
|
|
(0, _TestUtils.render)(getMarkup(_objectSpread({}, props, {
|
|
className: 'bar'
|
|
})));
|
|
expect(cellRendererCalls.length).not.toEqual(0);
|
|
done();
|
|
|
|
case 18:
|
|
case "end":
|
|
return _context6.stop();
|
|
}
|
|
}
|
|
});
|
|
});
|
|
});
|
|
describe('measureAllCells', function () {
|
|
it('should measure any unmeasured columns and rows', function () {
|
|
var grid = (0, _TestUtils.render)(getMarkup({
|
|
columnCount: 10,
|
|
columnWidth: function columnWidth() {
|
|
return 100;
|
|
},
|
|
estimatedColumnSize: 150,
|
|
estimatedRowSize: 15,
|
|
height: 0,
|
|
rowCount: 10,
|
|
rowHeight: function rowHeight() {
|
|
return 20;
|
|
},
|
|
width: 0
|
|
}));
|
|
expect(grid.state.instanceProps.columnSizeAndPositionManager.getTotalSize()).toEqual(1500);
|
|
expect(grid.state.instanceProps.rowSizeAndPositionManager.getTotalSize()).toEqual(150);
|
|
grid.measureAllCells();
|
|
expect(grid.state.instanceProps.columnSizeAndPositionManager.getTotalSize()).toEqual(1000);
|
|
expect(grid.state.instanceProps.rowSizeAndPositionManager.getTotalSize()).toEqual(200);
|
|
});
|
|
});
|
|
describe('recomputeGridSize', function () {
|
|
it('should recompute cell sizes and other values when called', function () {
|
|
var columnIndices = [];
|
|
var rowIndices = [];
|
|
|
|
function columnWidth(_ref19) {
|
|
var index = _ref19.index;
|
|
columnIndices.push(index);
|
|
return 10;
|
|
}
|
|
|
|
function rowHeight(_ref20) {
|
|
var index = _ref20.index;
|
|
rowIndices.push(index);
|
|
return 10;
|
|
}
|
|
|
|
var props = {
|
|
columnCount: 50,
|
|
columnWidth: columnWidth,
|
|
height: 50,
|
|
rowHeight: rowHeight,
|
|
rowCount: 50,
|
|
width: 100
|
|
};
|
|
var component = (0, _TestUtils.render)(getMarkup(props));
|
|
columnIndices.splice(0);
|
|
rowIndices.splice(0);
|
|
component.recomputeGridSize(); // Only the rows required to fill the current viewport will be rendered
|
|
|
|
expect(columnIndices[0]).toEqual(0);
|
|
expect(columnIndices[columnIndices.length - 1]).toEqual(9);
|
|
expect(rowIndices[0]).toEqual(0);
|
|
expect(rowIndices[rowIndices.length - 1]).toEqual(4);
|
|
columnIndices.splice(0);
|
|
rowIndices.splice(0);
|
|
component.recomputeGridSize({
|
|
columnIndex: 4,
|
|
rowIndex: 2
|
|
}); // Only the rows required to fill the current viewport will be rendered
|
|
|
|
expect(columnIndices[0]).toEqual(4);
|
|
expect(columnIndices[columnIndices.length - 1]).toEqual(9);
|
|
expect(rowIndices[0]).toEqual(2);
|
|
expect(rowIndices[rowIndices.length - 1]).toEqual(4);
|
|
});
|
|
});
|
|
describe('autoContainerWidth', function () {
|
|
it('should set the innerScrollContainer width to auto to better support single-column HOCs', function () {
|
|
var props = {
|
|
autoContainerWidth: true
|
|
};
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup(props)));
|
|
expect(rendered.querySelector('.ReactVirtualized__Grid__innerScrollContainer').style.width).toEqual('auto');
|
|
});
|
|
it('should set the innerScrollContainer width to :totalColumnsWidth unless :autoContainerWidth', function () {
|
|
var props = {
|
|
autoContainerWidth: false
|
|
};
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup(props)));
|
|
expect(rendered.querySelector('.ReactVirtualized__Grid__innerScrollContainer').style.width).toEqual('2500px'); // 50 columns x 50px
|
|
});
|
|
});
|
|
describe('autoHeight', function () {
|
|
it('should set the container height to auto to adjust to innerScrollContainer height', function () {
|
|
var props = {
|
|
autoHeight: true
|
|
};
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup(props)));
|
|
expect(rendered.style.height).toEqual('auto');
|
|
});
|
|
it('should have container height still affecting number of rows rendered', function () {
|
|
var props = {
|
|
height: 500,
|
|
autoHeight: true
|
|
};
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup(props)));
|
|
expect(rendered.querySelectorAll('.gridItem').length).toEqual(100); // 25 rows x 4 columns
|
|
});
|
|
it('should have innerScrollContainer height to be equal number of rows * rowHeight', function () {
|
|
var props = {
|
|
autoHeight: true
|
|
};
|
|
var grid = (0, _TestUtils.render)(getMarkup(props));
|
|
var rendered = (0, _reactDom.findDOMNode)(grid);
|
|
expect(rendered.querySelector('.ReactVirtualized__Grid__innerScrollContainer').style.height).toEqual('2000px'); // 100 rows * 20px rowHeight
|
|
|
|
expect(grid.state.instanceProps.rowSizeAndPositionManager.getTotalSize()).toEqual(2000);
|
|
});
|
|
});
|
|
describe('autoWidth', function () {
|
|
it('should set the container width to auto to adjust to innerScrollContainer width', function () {
|
|
var props = {
|
|
autoWidth: true
|
|
};
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup(props)));
|
|
expect(rendered.style.width).toEqual('auto');
|
|
});
|
|
it('should have container width still affecting number of columns rendered', function () {
|
|
var props = {
|
|
width: 500,
|
|
autoWidth: true
|
|
};
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup(props)));
|
|
expect(rendered.querySelectorAll('.gridItem').length).toEqual(50); // 5 rows x 10 columns
|
|
});
|
|
it('should have innerScrollContainer width to be equal number of columns * columnWidth', function () {
|
|
var props = {
|
|
autoWidth: true
|
|
};
|
|
var grid = (0, _TestUtils.render)(getMarkup(props));
|
|
var rendered = (0, _reactDom.findDOMNode)(grid);
|
|
expect(rendered.querySelector('.ReactVirtualized__Grid__innerScrollContainer').style.width).toEqual('2500px'); // 50 columns * 50px columnWidth
|
|
|
|
expect(grid.state.instanceProps.columnSizeAndPositionManager.getTotalSize()).toEqual(2500);
|
|
});
|
|
});
|
|
describe('tabIndex', function () {
|
|
it('should be focusable by default', function () {
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup()));
|
|
expect(rendered.tabIndex).toEqual(0);
|
|
});
|
|
it('should allow tabIndex to be overridden', function () {
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
tabIndex: -1
|
|
})));
|
|
expect(rendered.tabIndex).toEqual(-1);
|
|
});
|
|
});
|
|
describe('role', function () {
|
|
it('should have grid role by default', function () {
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup()));
|
|
expect(rendered.getAttribute('role')).toEqual('grid');
|
|
});
|
|
it('should allow role to be overridden', function () {
|
|
var role = null;
|
|
var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({
|
|
role: role
|
|
})));
|
|
expect(rendered.getAttribute('role')).toEqual(role);
|
|
});
|
|
});
|
|
describe('pure', function () {
|
|
it('should not re-render unless props have changed', function () {
|
|
var cellRendererCalled = false;
|
|
|
|
function cellRenderer(_ref21) {
|
|
var key = _ref21.key,
|
|
style = _ref21.style;
|
|
cellRendererCalled = true;
|
|
return React.createElement("div", {
|
|
key: key,
|
|
style: style
|
|
});
|
|
}
|
|
|
|
var markup = getMarkup({
|
|
cellRenderer: cellRenderer
|
|
});
|
|
(0, _TestUtils.render)(markup);
|
|
expect(cellRendererCalled).toEqual(true);
|
|
cellRendererCalled = false;
|
|
(0, _TestUtils.render)(markup);
|
|
expect(cellRendererCalled).toEqual(false);
|
|
});
|
|
it('should not re-render grid components if they extend PureComponent', function () {
|
|
var componentUpdates = 0;
|
|
|
|
var GridComponent =
|
|
/*#__PURE__*/
|
|
function (_React$PureComponent) {
|
|
(0, _inherits2["default"])(GridComponent, _React$PureComponent);
|
|
|
|
function GridComponent() {
|
|
(0, _classCallCheck2["default"])(this, GridComponent);
|
|
return (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(GridComponent).apply(this, arguments));
|
|
}
|
|
|
|
(0, _createClass2["default"])(GridComponent, [{
|
|
key: "componentDidUpdate",
|
|
value: function componentDidUpdate() {
|
|
componentUpdates++;
|
|
}
|
|
}, {
|
|
key: "render",
|
|
value: function render() {
|
|
var _this$props = this.props,
|
|
columnIndex = _this$props.columnIndex,
|
|
rowIndex = _this$props.rowIndex,
|
|
style = _this$props.style;
|
|
return React.createElement("div", {
|
|
className: "gridItem",
|
|
style: style
|
|
}, "row:".concat(rowIndex, ", column:").concat(columnIndex));
|
|
}
|
|
}]);
|
|
return GridComponent;
|
|
}(React.PureComponent);
|
|
|
|
function cellRenderer(_ref22) {
|
|
var columnIndex = _ref22.columnIndex,
|
|
key = _ref22.key,
|
|
rowIndex = _ref22.rowIndex,
|
|
style = _ref22.style;
|
|
return React.createElement(GridComponent, {
|
|
key: key,
|
|
columnIndex: columnIndex,
|
|
rowIndex: rowIndex,
|
|
style: style
|
|
});
|
|
}
|
|
|
|
var props = {
|
|
cellRenderer: cellRenderer,
|
|
columnWidth: 100,
|
|
height: 40,
|
|
rowHeight: 20,
|
|
scrollTop: 0,
|
|
width: 100
|
|
};
|
|
var grid = (0, _TestUtils.render)(getMarkup(props));
|
|
simulateScroll({
|
|
grid: grid,
|
|
scrollToIndex: 1
|
|
});
|
|
expect(componentUpdates).toEqual(0);
|
|
});
|
|
it('should clear all but the visible rows from the style cache once :isScrolling is false', function _callee7(done) {
|
|
var props, grid;
|
|
return _regenerator["default"].async(function _callee7$(_context7) {
|
|
while (1) {
|
|
switch (_context7.prev = _context7.next) {
|
|
case 0:
|
|
props = {
|
|
columnWidth: 50,
|
|
height: 100,
|
|
overscanColumnCount: 0,
|
|
overscanRowCount: 0,
|
|
rowHeight: 50,
|
|
width: 100
|
|
};
|
|
grid = (0, _TestUtils.render)(getMarkup(props));
|
|
expect(Object.keys(grid._styleCache).length).toBe(4);
|
|
simulateScroll({
|
|
grid: grid,
|
|
scrollTop: 50
|
|
});
|
|
expect(Object.keys(grid._styleCache).length).toBe(6); // Allow scrolling timeout to complete so that cell cache is reset
|
|
|
|
_context7.next = 7;
|
|
return _regenerator["default"].awrap(new Promise(function (resolve) {
|
|
return setTimeout(resolve, _Grid.DEFAULT_SCROLLING_RESET_TIME_INTERVAL * 2);
|
|
}));
|
|
|
|
case 7:
|
|
expect(Object.keys(grid._styleCache).length).toBe(4);
|
|
done();
|
|
|
|
case 9:
|
|
case "end":
|
|
return _context7.stop();
|
|
}
|
|
}
|
|
});
|
|
});
|
|
it('should clear style cache if :recomputeGridSize is called', function () {
|
|
var props = {
|
|
columnWidth: 50,
|
|
height: 100,
|
|
overscanColumnCount: 0,
|
|
overscanRowCount: 0,
|
|
rowHeight: 50,
|
|
width: 100
|
|
};
|
|
var grid = (0, _TestUtils.render)(getMarkup(props));
|
|
expect(Object.keys(grid._styleCache).length).toBe(4);
|
|
(0, _TestUtils.render)(getMarkup(_objectSpread({}, props, {
|
|
scrollTop: 50
|
|
})));
|
|
expect(Object.keys(grid._styleCache).length).toBe(6);
|
|
grid.recomputeGridSize();
|
|
expect(Object.keys(grid._styleCache).length).toBe(4);
|
|
});
|
|
it('should clear style cache if cell sizes change', function () {
|
|
var cellRendererCalls = [];
|
|
|
|
function cellRenderer(params) {
|
|
cellRendererCalls.push(params);
|
|
return React.createElement("div", {
|
|
key: params.key,
|
|
style: params.style
|
|
});
|
|
}
|
|
|
|
var props = {
|
|
cellRenderer: cellRenderer,
|
|
columnWidth: 100,
|
|
height: 100,
|
|
overscanColumnCount: 0,
|
|
overscanRowCount: 0,
|
|
rowHeight: 100,
|
|
width: 100
|
|
};
|
|
(0, _TestUtils.render)(getMarkup(props));
|
|
expect(cellRendererCalls.length).toEqual(1);
|
|
expect(cellRendererCalls[0].style.width).toEqual(100);
|
|
(0, _TestUtils.render)(getMarkup(_objectSpread({}, props, {
|
|
columnWidth: 50,
|
|
width: 50
|
|
})));
|
|
expect(cellRendererCalls.length).toEqual(2);
|
|
expect(cellRendererCalls[1].style.width).toEqual(50);
|
|
});
|
|
});
|
|
it('should not pull from the style cache while scrolling if there is an offset adjustment', function () {
|
|
var cellRendererCalls = [];
|
|
|
|
function cellRenderer(params) {
|
|
cellRendererCalls.push(params);
|
|
return React.createElement("div", {
|
|
key: params.key,
|
|
style: params.style
|
|
});
|
|
}
|
|
|
|
var grid = (0, _TestUtils.render)(getMarkup({
|
|
cellRenderer: cellRenderer,
|
|
width: 100,
|
|
height: 100,
|
|
rowHeight: 100,
|
|
columnWidth: 100,
|
|
rowCount: (0, _maxElementSize.getMaxElementSize)() * 2 / 100,
|
|
// lots of offset
|
|
scrollTop: 2000
|
|
}));
|
|
simulateScroll({
|
|
grid: grid,
|
|
scrollTop: 2100
|
|
}); // cellRendererCalls[0] is the element at rowIndex 0
|
|
// only two calls. Since the scrollTop is updated in getDerivedStateFromProps
|
|
|
|
var firstProps = cellRendererCalls[0];
|
|
var secondProps = cellRendererCalls[1];
|
|
expect(cellRendererCalls.length).toEqual(2);
|
|
expect(firstProps.style).not.toBe(secondProps.style);
|
|
});
|
|
it('should only cache styles when a :deferredMeasurementCache is provided if the cell has already been measured', function () {
|
|
var cache = new _CellMeasurer.CellMeasurerCache({
|
|
fixedWidth: true
|
|
});
|
|
cache.set(0, 0, 100, 100);
|
|
cache.set(1, 1, 100, 100);
|
|
var grid = (0, _TestUtils.render)(getMarkup({
|
|
columnCount: 2,
|
|
deferredMeasurementCache: cache,
|
|
rowCount: 2
|
|
}));
|
|
var keys = Object.keys(grid._styleCache);
|
|
expect(keys).toEqual(['0-0', '1-1']);
|
|
});
|
|
describe('DEV warnings', function () {
|
|
it('should warn about cells that forget to include the :style property', function () {
|
|
spyOn(console, 'warn');
|
|
|
|
function cellRenderer(params) {
|
|
return React.createElement("div", {
|
|
key: params.key
|
|
});
|
|
}
|
|
|
|
(0, _TestUtils.render)(getMarkup({
|
|
cellRenderer: cellRenderer
|
|
}));
|
|
expect(console.warn).toHaveBeenCalledWith('Rendered cell should include style property for positioning.');
|
|
expect(console.warn).toHaveBeenCalledTimes(1);
|
|
});
|
|
it('should warn about CellMeasurer measured cells that forget to include the :style property', function () {
|
|
spyOn(console, 'warn');
|
|
var cache = new _CellMeasurer.CellMeasurerCache({
|
|
fixedWidth: true
|
|
});
|
|
var cellRenderer = jest.fn();
|
|
cellRenderer.mockImplementation(function (params) {
|
|
return React.createElement(_CellMeasurer.CellMeasurer, {
|
|
cache: cache,
|
|
columnIndex: params.columnIndex,
|
|
key: params.key,
|
|
parent: params.parent,
|
|
rowIndex: params.rowIndex,
|
|
style: params.style
|
|
}, React.createElement("div", null));
|
|
});
|
|
(0, _TestUtils.render)(getMarkup({
|
|
cellRenderer: cellRenderer,
|
|
columnCount: 1,
|
|
deferredMeasurementCache: cache,
|
|
rowCount: 1
|
|
}));
|
|
expect(console.warn).toHaveBeenCalledWith('Rendered cell should include style property for positioning.');
|
|
expect(console.warn).toHaveBeenCalledTimes(1);
|
|
});
|
|
});
|
|
describe('deferredMeasurementCache', function () {
|
|
it('invalidateCellSizeAfterRender should invalidate cache and refresh displayed cells after mount', function () {
|
|
var cache = new _CellMeasurer.CellMeasurerCache({
|
|
fixedWidth: true
|
|
});
|
|
var invalidateCellSizeAfterRender = true;
|
|
var cellRenderer = jest.fn();
|
|
cellRenderer.mockImplementation(function (params) {
|
|
// Don't get stuck in a loop
|
|
if (invalidateCellSizeAfterRender) {
|
|
invalidateCellSizeAfterRender = false;
|
|
params.parent.invalidateCellSizeAfterRender({
|
|
columnIndex: 1,
|
|
rowIndex: 0
|
|
});
|
|
}
|
|
|
|
return React.createElement("div", {
|
|
key: params.key,
|
|
style: params.style
|
|
});
|
|
});
|
|
var props = {
|
|
cellRenderer: cellRenderer,
|
|
columnCount: 2,
|
|
deferredMeasurementCache: cache,
|
|
rowCount: 2
|
|
};
|
|
(0, _TestUtils.render)(getMarkup(props)); // 4 times for initial render + 4 once cellCache was cleared
|
|
|
|
expect(cellRenderer).toHaveBeenCalledTimes(8);
|
|
});
|
|
it('should invalidate cache and refresh displayed cells after update', function () {
|
|
var cache = new _CellMeasurer.CellMeasurerCache({
|
|
fixedWidth: true
|
|
});
|
|
var cellRenderer = jest.fn();
|
|
cellRenderer.mockImplementation(function (params) {
|
|
return React.createElement("div", {
|
|
key: params.key,
|
|
style: params.style
|
|
});
|
|
});
|
|
var props = {
|
|
cellRenderer: cellRenderer,
|
|
columnCount: 2,
|
|
deferredMeasurementCache: cache,
|
|
rowCount: 2
|
|
};
|
|
var grid = (0, _TestUtils.render)(getMarkup(props));
|
|
expect(cellRenderer).toHaveBeenCalledTimes(4);
|
|
var invalidateCellSizeAfterRender = false;
|
|
cellRenderer.mockReset();
|
|
cellRenderer.mockImplementation(function (params) {
|
|
// Don't get stuck in a loop
|
|
if (invalidateCellSizeAfterRender) {
|
|
invalidateCellSizeAfterRender = false;
|
|
params.parent.invalidateCellSizeAfterRender({
|
|
columnIndex: 1,
|
|
rowIndex: 0
|
|
});
|
|
}
|
|
|
|
return React.createElement("div", {
|
|
key: params.key,
|
|
style: params.style
|
|
});
|
|
});
|
|
invalidateCellSizeAfterRender = true;
|
|
grid.recomputeGridSize(); // 4 times for initial render + 4 once cellCache was cleared
|
|
|
|
expect(cellRenderer).toHaveBeenCalledTimes(8);
|
|
});
|
|
it('should not cache cells until they have been measured by CellMeasurer', function () {
|
|
var cache = new _CellMeasurer.CellMeasurerCache({
|
|
fixedWidth: true
|
|
}); // Fake measure cell 0,0 but not cell 0,1
|
|
|
|
cache.set(0, 0, 100, 30);
|
|
var cellRenderer = jest.fn();
|
|
cellRenderer.mockImplementation(function (params) {
|
|
return React.createElement("div", {
|
|
key: params.key,
|
|
style: params.style
|
|
});
|
|
});
|
|
var props = {
|
|
cellRenderer: cellRenderer,
|
|
columnCount: 2,
|
|
deferredMeasurementCache: cache,
|
|
rowCount: 1
|
|
}; // Trigger 2 renders
|
|
// The second render should re-use the style for cell 0,0
|
|
// But should not re-use the style for cell 0,1 since it was not measured
|
|
|
|
var grid = (0, _TestUtils.render)(getMarkup(props));
|
|
grid.forceUpdate(); // 0,0 - 0,1 - 0,0 - 0,1
|
|
|
|
expect(cellRenderer).toHaveBeenCalledTimes(4);
|
|
var style00A = cellRenderer.mock.calls[0][0].style;
|
|
var style01A = cellRenderer.mock.calls[1][0].style;
|
|
var style00B = cellRenderer.mock.calls[2][0].style;
|
|
var style01B = cellRenderer.mock.calls[3][0].style;
|
|
expect(style00A).toBe(style00B);
|
|
expect(style01A).not.toBe(style01B);
|
|
});
|
|
});
|
|
describe('onScrollbarPresenceChange', function () {
|
|
it('should not trigger on-mount if scrollbars are hidden', function () {
|
|
var onScrollbarPresenceChange = jest.fn();
|
|
(0, _TestUtils.render)(getMarkup({
|
|
columnCount: 1,
|
|
getScrollbarSize: getScrollbarSize20,
|
|
onScrollbarPresenceChange: onScrollbarPresenceChange,
|
|
rowCount: 1
|
|
}));
|
|
expect(onScrollbarPresenceChange).not.toHaveBeenCalled();
|
|
});
|
|
it('should trigger on-mount if scrollbars are visible', function () {
|
|
var onScrollbarPresenceChange = jest.fn();
|
|
(0, _TestUtils.render)(getMarkup({
|
|
columnCount: 100,
|
|
getScrollbarSize: getScrollbarSize20,
|
|
onScrollbarPresenceChange: onScrollbarPresenceChange,
|
|
rowCount: 100
|
|
}));
|
|
expect(onScrollbarPresenceChange).toHaveBeenCalled();
|
|
var args = onScrollbarPresenceChange.mock.calls[0][0];
|
|
expect(args.horizontal).toBe(true);
|
|
expect(args.size).toBe(getScrollbarSize20());
|
|
expect(args.vertical).toBe(true);
|
|
});
|
|
it('should trigger on-update if scrollbar visibility has changed', function () {
|
|
var onScrollbarPresenceChange = jest.fn();
|
|
(0, _TestUtils.render)(getMarkup({
|
|
columnCount: 1,
|
|
getScrollbarSize: getScrollbarSize20,
|
|
onScrollbarPresenceChange: onScrollbarPresenceChange,
|
|
rowCount: 1
|
|
}));
|
|
expect(onScrollbarPresenceChange).not.toHaveBeenCalled();
|
|
(0, _TestUtils.render)(getMarkup({
|
|
columnCount: 100,
|
|
getScrollbarSize: getScrollbarSize20,
|
|
onScrollbarPresenceChange: onScrollbarPresenceChange,
|
|
rowCount: 100
|
|
}));
|
|
expect(onScrollbarPresenceChange).toHaveBeenCalled();
|
|
var args = onScrollbarPresenceChange.mock.calls[0][0];
|
|
expect(args.horizontal).toBe(true);
|
|
expect(args.size).toBe(getScrollbarSize20());
|
|
expect(args.vertical).toBe(true);
|
|
});
|
|
it('should not trigger on-update if scrollbar visibility does not change', function () {
|
|
var onScrollbarPresenceChange = jest.fn();
|
|
(0, _TestUtils.render)(getMarkup({
|
|
columnCount: 1,
|
|
getScrollbarSize: getScrollbarSize20,
|
|
onScrollbarPresenceChange: onScrollbarPresenceChange,
|
|
rowCount: 1
|
|
}));
|
|
expect(onScrollbarPresenceChange).not.toHaveBeenCalled();
|
|
(0, _TestUtils.render)(getMarkup({
|
|
columnCount: 2,
|
|
getScrollbarSize: getScrollbarSize20,
|
|
onScrollbarPresenceChange: onScrollbarPresenceChange,
|
|
rowCount: 2
|
|
}));
|
|
expect(onScrollbarPresenceChange).not.toHaveBeenCalled();
|
|
});
|
|
});
|
|
it('should not complain when using react-test-renderer', function () {
|
|
var instance = _reactTestRenderer["default"].create(getMarkup()).getInstance();
|
|
|
|
expect(instance).toBeTruthy();
|
|
});
|
|
}); |