@progress/kendo-react-grid
Version:
React Data Grid (Table) provides 100+ ready-to-use data grid features. KendoReact Grid package
133 lines (132 loc) • 6.14 kB
JavaScript
/**
* @license
*-------------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the package root for more information
*-------------------------------------------------------------------------------------------
*/
import * as c from "react";
class g {
constructor(i) {
this.table = null, this.containerHeight = 0, this.topCacheCount = 0, this.attendedSkip = 0, this.propsSkip = 0, this.total = 0, this.scrollableVirtual = !1, this.realSkip = 0, this.pageSize = 0, this.PageChange = null, this.tableBodyRef = null, this.fixedScroll = !1, this.askedSkip = void 0, this.containerRef = null, this.tableTransform = "", this.prevScrollPos = 0, this.tableTranslate = 0, this.scrollSyncing = !1, this.reactVersion = Number.parseFloat(c.version), this.topItems = (t, l) => {
if (!this.container || l)
return { topItemsCount: 0, topItemsHeight: 0 };
const s = this.container.clientHeight, e = Math.ceil(s / t[0].line), o = Math.ceil((t.length - e) / 2);
let n = 0;
for (let a = 0; a < o; a++)
n += t[a].line + t[a].acc;
return {
topItemsCount: o,
topItemsHeight: n,
itemsNeededOnScreen: e + e / 2
};
}, this.horizontalScrollbarHeight = () => this.container ? this.container.offsetHeight - this.container.clientHeight : 0, i && (this.topCacheCount = 4, this.attendedSkip = -this.topCacheCount), this.scrollHandler = this.scrollHandler.bind(this);
}
get container() {
var i;
return (i = this.containerRef) == null ? void 0 : i.current;
}
/**
* @return - The row heights in an array.
*/
get rowHeights() {
var s, e;
const i = [], t = ((s = this.tableBodyRef) == null ? void 0 : s.current) && ((e = this.tableBodyRef) == null ? void 0 : e.current.children) || [];
let l = 0;
for (let o = 0; o < t.length; o++) {
if (t[o].className.indexOf("k-grouping-row") > -1) {
l += t[o].scrollHeight;
continue;
}
t[o].className.indexOf("k-detail-row") > -1 ? i[i.length - 1].line += t[o].scrollHeight : (i.push({
line: t[o].scrollHeight,
acc: l
}), l = 0);
}
return i;
}
changePage(i, t) {
this.attendedSkip = i - this.topCacheCount, this.PageChange && this.PageChange(
{
skip: Math.max(0, i - this.topCacheCount),
take: this.pageSize
},
t
);
}
translate(i, t) {
this.tableTranslate = i, this.scrollableVirtual && this.table && (this.reactVersion <= 17 || t ? this.table.style.transform = "translateY(" + i + "px)" : this.tableTransform = "translateY(" + i + "px)");
}
reset() {
this.scrollSyncing = !0, !this.fixedScroll && (this.container && (this.container.scrollTop = 0), this.translate(0, !0));
}
localScrollUp(i) {
if (!this.container)
return;
const t = this.rowHeights, l = this.container.scrollTop;
let s = this.tableTranslate, e = 0;
const { topItemsCount: o, topItemsHeight: n, itemsNeededOnScreen: a } = this.topItems(
t,
!!this.topCacheCount
), h = l - s;
if (!(h > n || t.length <= a)) {
for (; e < this.topCacheCount + this.attendedSkip - this.realSkip + o && this.propsSkip - e > 0 && !(s + (t[t.length - 1 - e].line + t[t.length - 1 - e].acc) + h <= l); )
s -= t[t.length - 1 - e].line + t[t.length - 1 - e].acc, e++;
if (e === 0 && this.topCacheCount === 0 && this.attendedSkip > 0 && (s = Math.max(s - t[0].line, 0), e = 1), this.propsSkip - e <= 0 && s > l) {
this.translate(0), this.changePage(0, i), this.container.scrollTop = 0;
return;
}
if (s > l && (s = l), s !== this.tableTranslate) {
this.translate(Math.max(0, s - n));
const r = Math.max(0, this.propsSkip - e - o);
this.changePage(r, i);
}
}
}
localScrollDown(i) {
if (!this.container)
return;
const t = this.rowHeights, l = this.container.scrollTop;
let s = this.tableTranslate, e = 0;
const { topItemsCount: o, topItemsHeight: n, itemsNeededOnScreen: a } = this.topItems(
t,
!!this.topCacheCount
);
for (; e < t.length - this.topCacheCount && !(s + t[e].line + t[e].acc > l); )
s += t[e].line + t[e].acc, e++;
o > this.propsSkip + e || t.length <= a || (e >= t.length - this.topCacheCount && this.propsSkip + e >= this.total ? (this.translate(s - n), this.changePage(this.total - 1 - o, i)) : s !== this.tableTranslate && this.propsSkip + e - o !== this.propsSkip && (this.translate(s - n), this.changePage(this.propsSkip + e - o, i)));
}
scrollNonStrict(i) {
const t = this.total * this.prevScrollPos / this.containerHeight;
let l = Math.floor(t);
l >= this.total && (l = this.total - 1);
const s = Math.min(t - l, 1);
let e = 0;
const o = l - this.propsSkip, n = this.rowHeights;
o >= 0 && o <= 1 ? e = -((n[0].line + n[0].acc) * s) : o === -1 && (e = -((n[n.length - 1].line + n[n.length - 1].acc) * s));
const { topItemsCount: a, topItemsHeight: h } = this.topItems(n, !!this.topCacheCount);
this.translate(
Math.max(
0,
e - h - this.horizontalScrollbarHeight() + this.containerHeight * t / this.total
)
), this.changePage(l - a, i);
}
scrollHandler(i) {
if (!this.scrollableVirtual)
return;
if (this.scrollSyncing || !this.container || !this.table) {
this.scrollSyncing = !1;
return;
}
const t = this.container.scrollTop, l = this.prevScrollPos;
if (this.prevScrollPos = t, this.askedSkip !== void 0) {
this.translate(this.containerHeight * this.askedSkip / this.total), this.changePage(this.askedSkip, i), this.prevScrollPos = t, this.askedSkip = void 0;
return;
}
t - l < 0 && t > this.tableTranslate - this.table.scrollHeight / 10 ? this.localScrollUp(i) : t - l > 0 && t < this.tableTranslate + this.table.scrollHeight * 2 / 3 ? this.localScrollDown(i) : this.scrollNonStrict(i), this.prevScrollPos = t;
}
}
export {
g as VirtualScroll
};