@tanstack/virtual-core
Advanced tools
+44
-21
@@ -423,3 +423,4 @@ "use strict"; | ||
| this.scrollAdjustments = 0; | ||
| this.scrollDirection = isScrolling ? this.getScrollOffset() < offset ? "forward" : "backward" : null; | ||
| const prevOffset = this.getScrollOffset(); | ||
| this.scrollDirection = isScrolling ? prevOffset === offset ? this.scrollDirection : prevOffset < offset ? "forward" : "backward" : null; | ||
| this.scrollOffset = offset; | ||
@@ -722,3 +723,7 @@ this.isScrolling = isScrolling; | ||
| (measurements, outerSize, scrollOffset, lanes) => { | ||
| return this.range = measurements.length > 0 && outerSize > 0 ? calculateRange({ | ||
| if (measurements.length === 0 || outerSize === 0) { | ||
| this.range = null; | ||
| return null; | ||
| } | ||
| this.range = calculateRangeImpl( | ||
| measurements, | ||
@@ -728,7 +733,7 @@ outerSize, | ||
| lanes, | ||
| // Pass the typed array so binary search + forward-walk can | ||
| // read start/end directly from Float64Array, skipping the | ||
| // Proxy traps that materialize a full VirtualItem per probe. | ||
| flat: lanes === 1 && this._flatMeasurements != null ? this._flatMeasurements : null | ||
| }) : null; | ||
| // Pass the typed array so binary search + forward-walk can read | ||
| // start/end directly from Float64Array, skipping the Proxy traps. | ||
| lanes === 1 && this._flatMeasurements != null ? this._flatMeasurements : null | ||
| ); | ||
| return this.range; | ||
| }, | ||
@@ -1193,22 +1198,40 @@ { | ||
| }; | ||
| function calculateRange({ | ||
| measurements, | ||
| outerSize, | ||
| scrollOffset, | ||
| lanes, | ||
| flat | ||
| }) { | ||
| function findNearestBinarySearchFlat(flat, high, value) { | ||
| let low = 0; | ||
| while (low <= high) { | ||
| const middle = (low + high) / 2 | 0; | ||
| const currentValue = flat[middle * 2]; | ||
| if (currentValue < value) { | ||
| low = middle + 1; | ||
| } else if (currentValue > value) { | ||
| high = middle - 1; | ||
| } else { | ||
| return middle; | ||
| } | ||
| } | ||
| return low > 0 ? low - 1 : 0; | ||
| } | ||
| function calculateRangeImpl(measurements, outerSize, scrollOffset, lanes, flat) { | ||
| const lastIndex = measurements.length - 1; | ||
| const getStart = flat ? (index) => flat[index * 2] : (index) => measurements[index].start; | ||
| const getEnd = flat ? (index) => flat[index * 2] + flat[index * 2 + 1] : (index) => measurements[index].end; | ||
| if (measurements.length <= lanes) { | ||
| return { | ||
| startIndex: 0, | ||
| endIndex: lastIndex | ||
| }; | ||
| return { startIndex: 0, endIndex: lastIndex }; | ||
| } | ||
| if (lanes === 1 && flat !== null) { | ||
| const startIndex2 = findNearestBinarySearchFlat( | ||
| flat, | ||
| lastIndex, | ||
| scrollOffset | ||
| ); | ||
| let endIndex2 = startIndex2; | ||
| const limit = scrollOffset + outerSize; | ||
| while (endIndex2 < lastIndex && flat[endIndex2 * 2] + flat[endIndex2 * 2 + 1] < limit) { | ||
| endIndex2++; | ||
| } | ||
| return { startIndex: startIndex2, endIndex: endIndex2 }; | ||
| } | ||
| const getStart = (index) => measurements[index].start; | ||
| let startIndex = findNearestBinarySearch(0, lastIndex, getStart, scrollOffset); | ||
| let endIndex = startIndex; | ||
| if (lanes === 1) { | ||
| while (endIndex < lastIndex && getEnd(endIndex) < scrollOffset + outerSize) { | ||
| while (endIndex < lastIndex && measurements[endIndex].end < scrollOffset + outerSize) { | ||
| endIndex++; | ||
@@ -1215,0 +1238,0 @@ } |
+44
-21
@@ -421,3 +421,4 @@ import { createLazyMeasurementsView } from "./lazy-measurements.js"; | ||
| this.scrollAdjustments = 0; | ||
| this.scrollDirection = isScrolling ? this.getScrollOffset() < offset ? "forward" : "backward" : null; | ||
| const prevOffset = this.getScrollOffset(); | ||
| this.scrollDirection = isScrolling ? prevOffset === offset ? this.scrollDirection : prevOffset < offset ? "forward" : "backward" : null; | ||
| this.scrollOffset = offset; | ||
@@ -720,3 +721,7 @@ this.isScrolling = isScrolling; | ||
| (measurements, outerSize, scrollOffset, lanes) => { | ||
| return this.range = measurements.length > 0 && outerSize > 0 ? calculateRange({ | ||
| if (measurements.length === 0 || outerSize === 0) { | ||
| this.range = null; | ||
| return null; | ||
| } | ||
| this.range = calculateRangeImpl( | ||
| measurements, | ||
@@ -726,7 +731,7 @@ outerSize, | ||
| lanes, | ||
| // Pass the typed array so binary search + forward-walk can | ||
| // read start/end directly from Float64Array, skipping the | ||
| // Proxy traps that materialize a full VirtualItem per probe. | ||
| flat: lanes === 1 && this._flatMeasurements != null ? this._flatMeasurements : null | ||
| }) : null; | ||
| // Pass the typed array so binary search + forward-walk can read | ||
| // start/end directly from Float64Array, skipping the Proxy traps. | ||
| lanes === 1 && this._flatMeasurements != null ? this._flatMeasurements : null | ||
| ); | ||
| return this.range; | ||
| }, | ||
@@ -1191,22 +1196,40 @@ { | ||
| }; | ||
| function calculateRange({ | ||
| measurements, | ||
| outerSize, | ||
| scrollOffset, | ||
| lanes, | ||
| flat | ||
| }) { | ||
| function findNearestBinarySearchFlat(flat, high, value) { | ||
| let low = 0; | ||
| while (low <= high) { | ||
| const middle = (low + high) / 2 | 0; | ||
| const currentValue = flat[middle * 2]; | ||
| if (currentValue < value) { | ||
| low = middle + 1; | ||
| } else if (currentValue > value) { | ||
| high = middle - 1; | ||
| } else { | ||
| return middle; | ||
| } | ||
| } | ||
| return low > 0 ? low - 1 : 0; | ||
| } | ||
| function calculateRangeImpl(measurements, outerSize, scrollOffset, lanes, flat) { | ||
| const lastIndex = measurements.length - 1; | ||
| const getStart = flat ? (index) => flat[index * 2] : (index) => measurements[index].start; | ||
| const getEnd = flat ? (index) => flat[index * 2] + flat[index * 2 + 1] : (index) => measurements[index].end; | ||
| if (measurements.length <= lanes) { | ||
| return { | ||
| startIndex: 0, | ||
| endIndex: lastIndex | ||
| }; | ||
| return { startIndex: 0, endIndex: lastIndex }; | ||
| } | ||
| if (lanes === 1 && flat !== null) { | ||
| const startIndex2 = findNearestBinarySearchFlat( | ||
| flat, | ||
| lastIndex, | ||
| scrollOffset | ||
| ); | ||
| let endIndex2 = startIndex2; | ||
| const limit = scrollOffset + outerSize; | ||
| while (endIndex2 < lastIndex && flat[endIndex2 * 2] + flat[endIndex2 * 2 + 1] < limit) { | ||
| endIndex2++; | ||
| } | ||
| return { startIndex: startIndex2, endIndex: endIndex2 }; | ||
| } | ||
| const getStart = (index) => measurements[index].start; | ||
| let startIndex = findNearestBinarySearch(0, lastIndex, getStart, scrollOffset); | ||
| let endIndex = startIndex; | ||
| if (lanes === 1) { | ||
| while (endIndex < lastIndex && getEnd(endIndex) < scrollOffset + outerSize) { | ||
| while (endIndex < lastIndex && measurements[endIndex].end < scrollOffset + outerSize) { | ||
| endIndex++; | ||
@@ -1213,0 +1236,0 @@ } |
+1
-1
| { | ||
| "name": "@tanstack/virtual-core", | ||
| "version": "3.17.2", | ||
| "version": "3.17.3", | ||
| "description": "Headless UI for virtualizing scrollable elements in TS/JS + Frameworks", | ||
@@ -5,0 +5,0 @@ "author": "Tanner Linsley", |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
389311
1.42%4884
1.58%