@progress/kendo-vue-grid
Version:
135 lines (134 loc) • 5.98 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
*-------------------------------------------------------------------------------------------
*/
class u {
constructor(s, t) {
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.fixedScroll = !1, this.askedSkip = void 0, this.tableTransform = "", this.prevScrollPos = 0, this.tableTranslate = 0, this.scrollSyncing = !1, this.topItems = (o, e) => {
if (!this.container || e)
return { topItemsCount: 0, topItemsHeight: 0 };
const i = this.container.clientHeight, n = this.container.querySelectorAll(".k-group-footer").length, l = Math.ceil(i / o[0].line), h = Math.ceil(n / l), a = Math.max(h, Math.ceil((o.length - l) / 2));
let r = 0;
for (let p = 0; p < a; p++)
r += o[p].line + o[p].acc;
const c = h ? n / (1 + h) : 0, g = l + l / 2 + c;
return {
topItemsCount: a,
topItemsHeight: r,
itemsNeededOnScreen: g
};
}, this.horizontalScrollbarHeight = () => this.container ? this.container.offsetHeight - this.container.clientHeight : 0, s && (this.topCacheCount = t, this.attendedSkip = -this.topCacheCount), this.scrollHandler = this.scrollHandler.bind(this);
}
get container() {
return this.containerRef;
}
/**
* @return - The row heights in an array.
*/
get rowHeights() {
const s = [], t = this.tableBodyRef && this.tableBodyRef.children || [];
let o = 0;
for (let e = 0; e < t.length; e++) {
if (t[e].className.indexOf("k-grouping-row") > -1) {
o += t[e].scrollHeight;
continue;
}
t[e].className.indexOf("k-detail-row") > -1 ? s[s.length - 1].line += t[e].scrollHeight : (s.push({
line: t[e].scrollHeight,
acc: o
}), o = 0);
}
return s;
}
changePage(s, t) {
this.attendedSkip = s - this.topCacheCount, this.PageChange(
{
skip: Math.max(0, s - this.topCacheCount),
take: this.pageSize
},
t
);
}
translate(s) {
this.tableTranslate = s, this.scrollableVirtual && this.table && (this.table.style.transform = "translateY(" + s + "px)");
}
reset() {
this.scrollSyncing = !0, !this.fixedScroll && (this.container && (this.container.scrollTop = 0), this.translate(0));
}
localScrollUp(s) {
if (!this.container)
return;
const t = this.rowHeights, o = this.container.scrollTop;
let e = this.tableTranslate, i = 0;
const {
topItemsCount: n,
topItemsHeight: l,
itemsNeededOnScreen: h
} = this.topItems(t, !!this.topCacheCount), a = o - e;
if (!(a > l || t.length <= h)) {
for (; i < this.topCacheCount + this.attendedSkip - this.realSkip + n && this.propsSkip - i > 0 && !(e + (t[t.length - 1 - i].line + t[t.length - 1 - i].acc) + a <= o); )
e -= t[t.length - 1 - i].line + t[t.length - 1 - i].acc, i++;
if (i === 0 && this.topCacheCount === 0 && this.attendedSkip > 0 && (e = Math.max(e - t[0].line, 0), i = 1), this.propsSkip - i <= 0 && e > o) {
this.translate(0), this.changePage(0, s), this.container.scrollTop = 0;
return;
}
if (e > o && (e = o), e !== this.tableTranslate) {
this.translate(Math.max(0, e - l));
const r = Math.max(0, this.propsSkip - i - n);
this.changePage(r, s);
}
}
}
localScrollDown(s) {
if (!this.container)
return;
const t = this.rowHeights, o = this.container.scrollTop;
let e = this.tableTranslate, i = 0;
const {
topItemsCount: n,
topItemsHeight: l,
itemsNeededOnScreen: h
} = this.topItems(t, !!this.topCacheCount);
for (; i < t.length - this.topCacheCount && !(e + t[i].line + t[i].acc > o); )
e += t[i].line + t[i].acc, i++;
n > this.propsSkip + i || t.length <= h || (i >= t.length - this.topCacheCount && this.propsSkip + i >= this.total ? (this.translate(e - l), this.changePage(this.total - 1 - n, s)) : e !== this.tableTranslate && this.propsSkip + i - n !== this.propsSkip && (this.translate(e - l), this.changePage(this.propsSkip + i - n, s)));
}
scrollNonStrict(s) {
const t = this.total * this.prevScrollPos / this.containerHeight;
let o = Math.floor(t);
o >= this.total && (o = this.total - 1);
const e = Math.min(t - o, 1);
let i = 0;
const n = o - this.propsSkip, l = this.rowHeights;
n >= 0 && n <= 1 ? i = -((l[0].line + l[0].acc) * e) : n === -1 && (i = -((l[l.length - 1].line + l[l.length - 1].acc) * e));
const {
topItemsCount: h,
topItemsHeight: a,
itemsNeededOnScreen: r
} = this.topItems(l, !!this.topCacheCount), c = Math.max(
0,
i - a - this.horizontalScrollbarHeight() + this.containerHeight * t / this.total
);
this.prevScrollPos < c && l.length <= r || (this.translate(c), this.changePage(o - h, s));
}
scrollHandler(s) {
if (!this.scrollableVirtual)
return;
if (this.scrollSyncing || !this.container || !this.table) {
this.scrollSyncing = !1;
return;
}
const t = this.container.scrollTop, o = this.prevScrollPos;
if (this.prevScrollPos = t, this.askedSkip !== void 0) {
this.translate(this.containerHeight * this.askedSkip / this.total), this.changePage(this.askedSkip, s), this.prevScrollPos = t, this.askedSkip = void 0;
return;
}
t - o < 0 && t > this.tableTranslate - this.table.scrollHeight / 10 ? this.localScrollUp(s) : t - o > 0 && t < this.tableTranslate + this.table.scrollHeight * 2 / 3 ? this.localScrollDown(s) : this.scrollNonStrict(s), this.prevScrollPos = t;
}
}
export {
u as VirtualScroll
};