UNPKG

@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
/** * @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 };