diff --git a/dist/cjs/index.cjs b/dist/cjs/index.cjs index e470032a9572b3ced764ca02238a8c6be435a9d4..65cd7ba4159d47d4c0cfb1adea69281ee30ba28a 100644 --- a/dist/cjs/index.cjs +++ b/dist/cjs/index.cjs @@ -289,7 +289,7 @@ class Virtualizer { let anchor = null; let followOnAppend = null; let edgeKeysChanged = false; - if (prevOptions !== void 0 && prevOptions.enabled && merged.enabled && merged.anchorTo === "end" && this.scrollElement !== null) { + if (prevOptions !== void 0 && prevOptions.enabled && merged.enabled && this.scrollElement !== null) { const prevCount = prevOptions.count; const nextCount = merged.count; const measurements = this.getMeasurements(); @@ -303,7 +303,7 @@ class Virtualizer { if (item) { anchor = [item.key, this.getScrollOffset() - item.start]; } - const behavior = merged.followOnAppend === true ? "auto" : merged.followOnAppend || null; + const behavior = merged.anchorTo === "end" ? merged.followOnAppend === true ? "auto" : merged.followOnAppend || null : null; if (behavior && nextCount > prevCount && this.isAtEnd(prevOptions.scrollEndThreshold) && (prevCount === 0 || merged.getItemKey(nextCount - 1) !== prevLastKey)) { followOnAppend = behavior; } @@ -725,17 +725,20 @@ class Virtualizer { this.getMeasurements(), this.getSize(), this.getScrollOffset(), - this.options.lanes + this.options.lanes, + this.options.paddingEnd ], - (measurements, outerSize, scrollOffset, lanes) => { + (measurements, outerSize, scrollOffset, lanes, _paddingEnd) => { if (measurements.length === 0 || outerSize === 0) { this.range = null; return null; } + const maxScrollOffset = Math.max(this.options.scrollMargin + this.getTotalSize() - outerSize, 0); + const effectiveScrollOffset = Math.min(Math.max(scrollOffset, 0), maxScrollOffset); this.range = calculateRangeImpl( measurements, outerSize, - scrollOffset, + effectiveScrollOffset, lanes, // Pass the typed array so binary search + forward-walk can read // start/end directly from Float64Array, skipping the Proxy traps. diff --git a/dist/cjs/index.d.cts b/dist/cjs/index.d.cts index cc1001b8a14d06aa73a3a9e8f59870557ee9e7d6..70b202ed436ce1f3283a8465a81faf2e6e2e7983 100644 --- a/dist/cjs/index.d.cts +++ b/dist/cjs/index.d.cts @@ -144,7 +144,7 @@ export declare class Virtualizer prevCount && this.isAtEnd(prevOptions.scrollEndThreshold) && (prevCount === 0 || merged.getItemKey(nextCount - 1) !== prevLastKey)) { followOnAppend = behavior; } @@ -723,17 +723,20 @@ class Virtualizer { this.getMeasurements(), this.getSize(), this.getScrollOffset(), - this.options.lanes + this.options.lanes, + this.options.paddingEnd ], - (measurements, outerSize, scrollOffset, lanes) => { + (measurements, outerSize, scrollOffset, lanes, _paddingEnd) => { if (measurements.length === 0 || outerSize === 0) { this.range = null; return null; } + const maxScrollOffset = Math.max(this.options.scrollMargin + this.getTotalSize() - outerSize, 0); + const effectiveScrollOffset = Math.min(Math.max(scrollOffset, 0), maxScrollOffset); this.range = calculateRangeImpl( measurements, outerSize, - scrollOffset, + effectiveScrollOffset, lanes, // Pass the typed array so binary search + forward-walk can read // start/end directly from Float64Array, skipping the Proxy traps. diff --git a/src/index.ts b/src/index.ts index dc6f1010c4d4758de9c46fb8d69209e582e47171..6988f58f7406ee64789ad9ad44f519ed4cf9a00f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -575,7 +575,6 @@ export class Virtualizer< prevOptions !== undefined && prevOptions.enabled && merged.enabled && - merged.anchorTo === 'end' && this.scrollElement !== null ) { const prevCount = prevOptions.count @@ -611,9 +610,11 @@ export class Virtualizer< } const behavior = - merged.followOnAppend === true - ? 'auto' - : merged.followOnAppend || null + merged.anchorTo === 'end' + ? merged.followOnAppend === true + ? 'auto' + : merged.followOnAppend || null + : null if ( behavior && @@ -1410,16 +1411,25 @@ export class Virtualizer< this.getSize(), this.getScrollOffset(), this.options.lanes, + this.options.paddingEnd, ], - (measurements, outerSize, scrollOffset, lanes) => { + (measurements, outerSize, scrollOffset, lanes, _paddingEnd) => { if (measurements.length === 0 || outerSize === 0) { this.range = null return null } + const maxScrollOffset = Math.max( + this.options.scrollMargin + this.getTotalSize() - outerSize, + 0, + ) + const effectiveScrollOffset = Math.min( + Math.max(scrollOffset, 0), + maxScrollOffset, + ) this.range = calculateRangeImpl( measurements, outerSize, - scrollOffset, + effectiveScrollOffset, lanes, // Pass the typed array so binary search + forward-walk can read // start/end directly from Float64Array, skipping the Proxy traps.