Repository navigation
fix(virtual-core): keep the iOS correction when a start-aligned scrollToIndex ends before it lands #1306
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(virtual-core): keep the iOS correction when a start-aligned scrollToIndex ends before it lands #1306
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| '@tanstack/virtual-core': patch | ||
| --- | ||
|
|
||
| fix(virtual-core): keep iOS-deferred size corrections when a gesture interrupts an in-flight `scrollToIndex` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -970,7 +970,7 @@ export class Virtualizer< | |
| // The index scroll reached its target, but an external scroll moved | ||
| // away while we waited for measurements. Our own measurement updates | ||
| // (including clamped writes) still need to reconcile. | ||
| this.scrollState = null | ||
| this.dropScrollState() | ||
| } | ||
| this._intendedScrollOffset = null | ||
|
|
||
|
|
@@ -1210,6 +1210,33 @@ export class Virtualizer< | |
| : undefined | ||
| return offsetInfo ? offsetInfo[0] : state.lastTargetOffset | ||
| } | ||
| // Ends a scroll state before it lands (a gesture, cancelScroll, the safety | ||
| // valve). While an index scroll runs, applyScrollAdjustment leaves resizes | ||
| // to reconcileScroll (#1304), so one that moved the target after the last | ||
| // write would be lost. When the viewport's top sits on a start-aligned | ||
| // target in a single lane with no scrollPaddingStart, the rows above the | ||
| // target are the rows above the viewport, and the target's drift is exactly | ||
| // what resizeItem's default predicate would have compensated. Anywhere else | ||
|
Comment on lines
+1218
to
+1219
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π― Functional Correctness | π‘ Minor | β‘ Quick win Exclude clamped start targets from drift compensation. Near the end of the list, π€ Prompt for AI Agents |
||
| // (mid-travel, padding or an end/center/toEnd target that also moves when a | ||
| // row in view grows, lanes where rows span the fold or the target changes | ||
| // lane, or a custom predicate) the drift says nothing about what is owed. | ||
| private dropScrollState() { | ||
| const state = this.scrollState | ||
| if ( | ||
| state?.index != null && | ||
| state.align === 'start' && | ||
| this.options.lanes === 1 && | ||
| this.options.scrollPaddingStart === 0 && | ||
| this.shouldAdjustScrollPositionOnItemSizeChange === undefined && | ||
| isIOSWebKit() && | ||
| approxEqual(this.getScrollOffset(), state.lastTargetOffset) | ||
| ) { | ||
| this.getMeasurements() | ||
| this._iosDeferredAdjustment += | ||
| this.getScrollStateTarget(state) - state.lastTargetOffset | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| } | ||
| this.scrollState = null | ||
| } | ||
| private reconcileScroll() { | ||
| if (!this.scrollState) return | ||
|
|
||
|
|
@@ -1219,7 +1246,7 @@ export class Virtualizer< | |
| // Safety valve: bail out if reconciliation has been running too long | ||
| const MAX_RECONCILE_MS = 5000 | ||
| if (this.now() - this.scrollState.startedAt > MAX_RECONCILE_MS) { | ||
| this.scrollState = null | ||
| this.dropScrollState() | ||
| return | ||
| } | ||
|
|
||
|
|
@@ -2137,7 +2164,7 @@ export class Virtualizer< | |
| this.targetWindow.cancelAnimationFrame(this.rafId) | ||
| this.rafId = null | ||
| } | ||
| this.scrollState = null | ||
| this.dropScrollState() | ||
| } | ||
|
|
||
| getTotalSize = () => { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.