UNPKG

@progress/kendo-vue-grid

Version:
135 lines (134 loc) 5.98 kB
/** * @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 };