@progress/kendo-react-grid
Version:
KendoReact Grid package
200 lines • 8.11 kB
JavaScript
/**
* @hidden
*/
var VirtualScroll = /** @class */ (function () {
function VirtualScroll(cached) {
this.containerHeight = 0;
this.topCacheCount = 0; // 4;
this.attendedSkip = 0; // -4;
this.propsSkip = 0;
this.total = 0;
this.scrollableVirtual = false;
this.realSkip = 0;
this.pageSize = 0;
this.heightContainer = null;
this.prevScrollPos = 0;
this.tableTranslate = 0;
this.scrollSyncing = false;
if (cached) {
this.topCacheCount = 4;
this.attendedSkip = -this.topCacheCount;
}
this.scrollHandler = this.scrollHandler.bind(this);
}
Object.defineProperty(VirtualScroll.prototype, "rowHeights", {
/**
* @return - The row heights in an array.
*/
get: function () {
var result = [];
var allRows = this.tableBody && this.tableBody.children || [];
var accumulate = 0;
for (var i = 0; i < allRows.length; i++) {
if (allRows[i].className.indexOf('k-grouping-row') > -1) {
accumulate += allRows[i].scrollHeight;
continue;
}
if (allRows[i].className.indexOf('k-detail-row') > -1) {
result[result.length - 1].line += allRows[i].scrollHeight;
}
else {
result.push({
line: allRows[i].scrollHeight,
acc: accumulate
});
accumulate = 0;
}
}
return result;
},
enumerable: true,
configurable: true
});
VirtualScroll.prototype.changePage = function (skip, e) {
this.attendedSkip = skip - this.topCacheCount;
this.PageChange({
skip: Math.max(0, skip - this.topCacheCount),
take: this.pageSize
}, e);
};
VirtualScroll.prototype.translate = function (dY) {
this.tableTranslate = dY;
if (this.table) {
this.table.style.transform = 'translateY(' + dY + 'px)';
}
};
VirtualScroll.prototype.syncScroll = function () {
if (!this.scrollableVirtual || !this.container) {
return;
}
this.syncTimeout = null;
var scrollTop = this.container.scrollTop;
var containerHeight = this.containerHeight; // = this.container.scrollHeight;
var rowHeights = this.rowHeights;
var percentage = (scrollTop - this.tableTranslate) / rowHeights[0].line;
var targetFloorScrollPosition = Math.floor((containerHeight) * (this.propsSkip + percentage) / this.total);
if (this.container.scrollTop !== (this.prevScrollPos = targetFloorScrollPosition)) {
this.scrollSyncing = true;
this.container.scrollTop = (this.prevScrollPos = targetFloorScrollPosition);
}
this.translate(this.tableTranslate + targetFloorScrollPosition - scrollTop);
};
VirtualScroll.prototype.reset = function () {
this.scrollSyncing = true;
if (this.container) {
this.container.scrollTop = 0;
}
this.translate(0);
};
VirtualScroll.prototype.localScrollUp = function (e) {
if (!this.container) {
return;
}
var heights = this.rowHeights;
var scrollTop = this.container.scrollTop;
var targetTranslate = this.tableTranslate;
var rowsCount = 0;
var additionalOnTop = scrollTop - targetTranslate;
if (additionalOnTop > 0) {
return;
}
while ((rowsCount < this.topCacheCount + this.attendedSkip - this.realSkip)
&& this.propsSkip - rowsCount > 0 &&
!(targetTranslate + (heights[heights.length - 1 - rowsCount].line + heights[heights.length - 1 - rowsCount].acc) + additionalOnTop <= scrollTop)) {
targetTranslate -= heights[heights.length - 1 - rowsCount].line +
heights[heights.length - 1 - rowsCount].acc;
rowsCount++;
}
if (rowsCount === 0 && this.topCacheCount === 0 && this.attendedSkip > 0) {
// allows local scrolling up, when top caching is disabled
// for variable heights 'topCacheCount' should be atleast 1 to avoid flickering
targetTranslate = Math.max(targetTranslate - heights[0].line, 0);
rowsCount = 1;
}
if (this.propsSkip - rowsCount <= 0 && targetTranslate > scrollTop) {
this.translate(0);
this.changePage(0, e);
this.container.scrollTop = 0;
return;
}
if (targetTranslate > scrollTop) {
targetTranslate = scrollTop;
// need to handle these cases
// if the item height is not available:
// floor the translate to beginning of the item in absolute value
}
if (targetTranslate !== this.tableTranslate) {
this.translate(targetTranslate);
this.changePage(this.propsSkip - rowsCount, e);
}
};
VirtualScroll.prototype.localScrollDown = function (e) {
if (!this.container) {
return;
}
var heights = this.rowHeights;
var scrollTop = this.container.scrollTop;
var targetTranslate = this.tableTranslate;
var rowsCount = 0;
while (rowsCount < heights.length - this.topCacheCount &&
!(targetTranslate + heights[rowsCount].line + heights[rowsCount].acc > scrollTop)) {
targetTranslate += heights[rowsCount].line + heights[rowsCount].acc;
rowsCount++;
}
if (rowsCount >= heights.length - this.topCacheCount && this.propsSkip + rowsCount >= this.total) {
this.translate(targetTranslate);
this.changePage(this.total - 1, e);
}
else if (targetTranslate !== this.tableTranslate) {
this.translate(targetTranslate);
this.changePage(this.propsSkip + rowsCount, e);
}
};
VirtualScroll.prototype.scrollNonStrict = function (e) {
var floatRowIndex = this.total * this.prevScrollPos / (this.containerHeight);
var rowIndex = Math.floor(floatRowIndex);
if (rowIndex >= this.total) {
rowIndex = this.total - 1;
}
var rowpercentage = Math.min(floatRowIndex - rowIndex, 1);
var microAdjust = 0;
var rowIndexOffset = rowIndex - this.propsSkip;
var heights = this.rowHeights;
if (rowIndexOffset >= 0 && rowIndexOffset <= 1) {
microAdjust = -((heights[0].line + heights[0].acc) * rowpercentage);
}
else if (rowIndexOffset === -1) {
microAdjust = -((heights[heights.length - 1].line + heights[heights.length - 1].acc) * rowpercentage);
}
this.translate(microAdjust + this.containerHeight * floatRowIndex / this.total);
this.changePage(rowIndex, e);
};
VirtualScroll.prototype.scrollHandler = function (e) {
if (!this.scrollableVirtual) {
return;
}
if (this.scrollSyncing || !this.container || !this.table) {
this.scrollSyncing = false;
return;
}
var grid = this;
clearTimeout(this.syncTimeout);
this.syncTimeout = setTimeout(function () { grid.syncScroll(); }, 200);
var scrollTop = this.container.scrollTop;
var prev = this.prevScrollPos;
this.prevScrollPos = scrollTop;
if (scrollTop - prev < 0 && scrollTop > this.tableTranslate - this.table.scrollHeight / 10) {
this.localScrollUp(e);
}
else if (scrollTop - prev > 0 && scrollTop < this.tableTranslate + this.table.scrollHeight * 2 / 3) {
this.localScrollDown(e);
}
else {
this.scrollNonStrict(e);
}
this.prevScrollPos = scrollTop;
};
return VirtualScroll;
}());
export { VirtualScroll };
//# sourceMappingURL=VirtualScroll.js.map