Skip to content

Commit dc02bd5

Browse files
authored
fix(react-grid): fix hidden tall rows in VirtualTable (#747)
fixes #745
1 parent 4bf8810 commit dc02bd5

File tree

2 files changed

+47
-10
lines changed

2 files changed

+47
-10
lines changed

packages/dx-react-grid/src/components/table-layout/virtual-table-utils.js

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,29 @@ const ENDING_KEY = 'ending';
1010
export const getVisibleRows = (rows, viewportTop, viewportHeight, getRowHeight) => {
1111
const result = [];
1212

13-
const bottom = viewportTop + viewportHeight;
14-
let position = 0;
13+
const viewportBottom = viewportTop + viewportHeight;
14+
let topPosition = 0;
1515
for (let i = 0; i < rows.length; i += 1) {
1616
const row = rows[i];
17-
const last = result[result.length - 1];
17+
const lastIndex = result.length - 1;
18+
const last = result[lastIndex];
1819

1920
const height = getRowHeight(row);
20-
const nextPosition = position + height;
21+
const bottomPosition = topPosition + height;
2122
if (
22-
(viewportTop <= position && position < bottom
23-
&& viewportTop < nextPosition && nextPosition <= bottom) ||
24-
(viewportTop > position && nextPosition > bottom)
23+
(topPosition >= viewportTop && topPosition < viewportBottom) ||
24+
(bottomPosition > viewportTop && bottomPosition <= viewportBottom) ||
25+
(topPosition < viewportTop && bottomPosition > viewportBottom)
2526
) {
2627
if (last && last.type === STUB_TYPE) {
2728
rows.slice(Math.max(0, i - OVERSCAN), i).forEach((overscanRow) => {
2829
const overscanRowSize = getRowHeight(overscanRow);
2930
last.height -= overscanRowSize;
3031
result.push({ type: OVERSCAN_TYPE, height: overscanRowSize, row: overscanRow });
3132
});
33+
if (last.height === 0) {
34+
result.splice(lastIndex, 1);
35+
}
3236
}
3337
result.push({ type: VISIBLE_TYPE, height, row });
3438
} else if (last && last.type === STUB_TYPE) {
@@ -45,7 +49,7 @@ export const getVisibleRows = (rows, viewportTop, viewportHeight, getRowHeight)
4549
} else {
4650
result.push({ type: STUB_TYPE, key: STARTING_KEY, height });
4751
}
48-
position = nextPosition;
52+
topPosition = bottomPosition;
4953
}
5054

5155
return result;

packages/dx-react-grid/src/components/table-layout/virtual-table-utils.test.js

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,16 @@ describe('VirtualTableLaout utils', () => {
1313
{ key: 3, height: 40 },
1414
{ key: 4, height: 40 },
1515
{ key: 5, height: 40 },
16+
{ key: 6, height: 40 },
1617
];
1718

1819
expect(getVisibleRows(rows, 0, 50, row => row.height))
1920
.toEqual([
2021
{ type: 'visible', height: 40, row: rows[0] },
21-
{ type: 'overscan', height: 40, row: rows[1] },
22+
{ type: 'visible', height: 40, row: rows[1] },
2223
{ type: 'overscan', height: 40, row: rows[2] },
2324
{ type: 'overscan', height: 40, row: rows[3] },
25+
{ type: 'overscan', height: 40, row: rows[4] },
2426
{ type: 'stub', height: 80, key: 'ending' },
2527
]);
2628
});
@@ -33,15 +35,17 @@ describe('VirtualTableLaout utils', () => {
3335
{ key: 3, height: 40 },
3436
{ key: 4, height: 40 },
3537
{ key: 5, height: 40 },
38+
{ key: 6, height: 40 },
3639
];
3740

38-
expect(getVisibleRows(rows, 190, 50, row => row.height))
41+
expect(getVisibleRows(rows, 230, 50, row => row.height))
3942
.toEqual([
4043
{ type: 'stub', height: 80, key: 'starting' },
4144
{ type: 'overscan', height: 40, row: rows[2] },
4245
{ type: 'overscan', height: 40, row: rows[3] },
4346
{ type: 'overscan', height: 40, row: rows[4] },
4447
{ type: 'visible', height: 40, row: rows[5] },
48+
{ type: 'visible', height: 40, row: rows[6] },
4549
]);
4650
});
4751

@@ -71,6 +75,35 @@ describe('VirtualTableLaout utils', () => {
7175
{ type: 'stub', height: 40, key: 'ending' },
7276
]);
7377
});
78+
79+
it('should return visible rows in center with one big row', () => {
80+
const rows = [
81+
{ key: 0, height: 40 },
82+
{ key: 1, height: 400 },
83+
{ key: 2, height: 40 },
84+
];
85+
86+
expect(getVisibleRows(rows, 170, 20, row => row.height))
87+
.toEqual([
88+
{ type: 'overscan', height: 40, row: rows[0] },
89+
{ type: 'visible', height: 400, row: rows[1] },
90+
{ type: 'overscan', height: 40, row: rows[2] },
91+
]);
92+
93+
expect(getVisibleRows(rows, 30, 20, row => row.height))
94+
.toEqual([
95+
{ type: 'visible', height: 40, row: rows[0] },
96+
{ type: 'visible', height: 400, row: rows[1] },
97+
{ type: 'overscan', height: 40, row: rows[2] },
98+
]);
99+
100+
expect(getVisibleRows(rows, 430, 20, row => row.height))
101+
.toEqual([
102+
{ type: 'overscan', height: 40, row: rows[0] },
103+
{ type: 'visible', height: 400, row: rows[1] },
104+
{ type: 'visible', height: 40, row: rows[2] },
105+
]);
106+
});
74107
});
75108

76109
describe('#firstVisibleRowOffset', () => {

0 commit comments

Comments
 (0)