Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/dull-kings-stare.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tanstack/virtual-core': patch
---

fix(virtual-core): cancel stale anchor work on explicit scroll
6 changes: 6 additions & 0 deletions packages/virtual-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2429,6 +2429,12 @@ export class Virtualizer<
behavior: ScrollBehavior,
kind: 'absolute' | 'relative',
) {
// A new explicit command supersedes layout-driven work queued before it.
// Clear both before any iOS deferral so a later commit/retry cannot
// overwrite the user's newer scroll intent.
this.pendingScrollAnchor = null
this._clampedAdjustment = null

const tail = this._iosGesture.tail()
if (kind === 'absolute' && tail !== null) {
if (tail === 'fling' && iosMomentumOverridesWrites()) {
Expand Down
32 changes: 16 additions & 16 deletions packages/virtual-core/tests/__snapshots__/scroll-trace.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ exports[`scroll behaviour snapshot > anchorEnd web 1`] = `
"20: 6616fe9d f780f908 13bd300f 30643489 ec2d1b0c ebb40e0f 63ed23da 68a18267 253fe61c 09a1874e",
"30: 5e6688c5 009cbdfe 8c8bdd3e 46527f28 f7133699 9b9b908c e14b74d0 8f93c51a 552b4b5b 660f3603",
"40: 93dd81a7 c9c39478 622e6d21 4d60c709 e721cb06 5b6d2738 868d9e7b f3ef7742 2aa59586 886aae03",
"50: d2429922 8cc11ea8 81d0357b cfd20837 8fcc29b1 3cea4ec5 27af96a0 e46aa4df 3c8d8225 18bcf75b",
"50: d2429922 8cc11ea8 81d0357b cfd20837 8fcc29b1 3cea4ec5 27af96a0 e46aa4df 4bc85495 18bcf75b",
]
`;

Expand Down Expand Up @@ -62,7 +62,7 @@ exports[`scroll behaviour snapshot > base web 1`] = `
"20: 7886a736 ceac4ab2 2c8bfacf 6865f6c2 d47af093 a7b02f04 63ed23da 715e0039 4ddf6da0 a5002541",
"30: 5978f80e 0c5f12e2 79ef7be1 aec3dd30 1b99b475 46df8677 4e88df21 8f93c51a 5b30b633 66d94fc8",
"40: 8249f4ed 2170911f c938e8f5 feacb1d8 826217e9 8a2b7146 f9ead96e d1dc687f 36e554f8 03c3bcc1",
"50: d2429922 07cac42c 78c9d354 cfd20837 b30f44cd 5f27e381 5c11a132 1841edc4 36b0937d 9ddde49c",
"50: d2429922 07cac42c 78c9d354 cfd20837 b30f44cd 5f27e381 5c11a132 1841edc4 d58fa408 9ddde49c",
]
`;

Expand Down Expand Up @@ -128,7 +128,7 @@ exports[`scroll behaviour snapshot > horizontal web 1`] = `
"20: 7886a736 ceac4ab2 2c8bfacf 6865f6c2 d47af093 a7b02f04 63ed23da 715e0039 4ddf6da0 a5002541",
"30: 5978f80e 0c5f12e2 79ef7be1 aec3dd30 1b99b475 46df8677 4e88df21 8f93c51a 5b30b633 66d94fc8",
"40: 8249f4ed 2170911f c938e8f5 feacb1d8 826217e9 8a2b7146 f9ead96e d1dc687f 36e554f8 03c3bcc1",
"50: d2429922 07cac42c 78c9d354 cfd20837 b30f44cd 5f27e381 5c11a132 1841edc4 36b0937d 9ddde49c",
"50: d2429922 07cac42c 78c9d354 cfd20837 b30f44cd 5f27e381 5c11a132 1841edc4 d58fa408 9ddde49c",
]
`;

Expand All @@ -138,8 +138,8 @@ exports[`scroll behaviour snapshot > lanes ios 1`] = `
"10: 514a82cf 25c644f3 7a8d2a09 2abee23f 5872f8d5 c103e623 c4d2fe64 554a1766 21de167e 487aeb4b",
"20: f2245f58 81bd9a1e 79b54054 6e12648a 38539662 4b10cf13 0bddc3e4 11317c75 bbfdc970 d2432a43",
"30: 12468132 20c7aff9 67dcb6d5 03291755 c9ffab63 5f0a007d ec1d6907 f41ff60d f7397d3b 701d9fb6",
"40: d7be12c4 972dd8d5 cd9e5629 bc8f344f 60dc134e 96523d8a d0d37a83 08867236 7da74ce4 bbba1406",
"50: 89573ef3 4d90e248 f737f69e c3acfdb6 39c42ebf 55ca59be e01db9de cedb1bda cc70c64d 00e88da4",
"40: d7be12c4 972dd8d5 cd9e5629 bc8f344f 3d61d1ac 96523d8a d0d37a83 08867236 7da74ce4 bbba1406",
"50: 89573ef3 1fa2a7b0 f737f69e c3acfdb6 39c42ebf 55ca59be e01db9de cedb1bda cc70c64d 00e88da4",
]
`;

Expand All @@ -149,19 +149,19 @@ exports[`scroll behaviour snapshot > lanes ios27 1`] = `
"10: 514a82cf ddf40a6b 7a8d2a09 2abee23f af7ac992 c103e623 00ca2427 29c40818 21de167e 487aeb4b",
"20: f2245f58 2424b184 79b54054 6e12648a 38539662 4b10cf13 feb6fb5c 11317c75 42d7823b d2432a43",
"30: 65523943 20c7aff9 67dcb6d5 473c2a8f 7d23b05f 5f0a007d ec1d6907 e86742e8 f7397d3b 701d9fb6",
"40: d7be12c4 95d3e050 cd9e5629 bc8f344f d553998f 96523d8a d0d37a83 08867236 f50ddbf7 bbba1406",
"50: 89573ef3 4d90e248 53dfd836 9b5a1c5a b5b1ab21 8dd98e7e e01db9de cedb1bda cc70c64d 00e88da4",
"40: d7be12c4 95d3e050 cd9e5629 bc8f344f 6df9343f 96523d8a d0d37a83 08867236 f50ddbf7 bbba1406",
"50: 89573ef3 1fa2a7b0 53dfd836 9b5a1c5a b5b1ab21 8dd98e7e e01db9de cedb1bda cc70c64d 00e88da4",
]
`;

exports[`scroll behaviour snapshot > lanes web 1`] = `
[
"0: 07b019d6 50ba0f48 2528ce0b 56751a0d f27c3816 3ad778af 510a0a14 de5f2a5e 8a8df520 9c4df1f6",
"10: 0e9abc72 9ab1beaa 7a8d2a09 cc167259 bfd342b3 c103e623 cb717084 554a1766 21de167e 487aeb4b",
"10: 0e9abc72 9ab1beaa 7a8d2a09 cc167259 bfd342b3 c103e623 d68fb624 554a1766 21de167e 487aeb4b",
"20: 3fb995ae 81bd9a1e 79b54054 e99e680d f2c453bb 4b10cf13 588f804a bf451280 912642c1 d2432a43",
"30: 5a9c1d81 20c7aff9 9b7acc6c 03291755 c12620e1 5f0a007d ec1d6907 e64d3f41 f7397d3b 2e9ca3d4",
"40: 1bd23826 16a5fa48 410c3108 bc8f344f 149cffe2 49344e33 d0d37a83 d4926881 5860422c bf14dd85",
"50: 89573ef3 4d90e248 05101a4e 9886e68a 39c42ebf 55ca59be e01db9de cedb1bda 9a73528c b6ea452c",
"30: 5a9c1d81 20c7aff9 1fd7b2b0 03291755 c12620e1 5f0a007d ec1d6907 e64d3f41 f7397d3b 2e9ca3d4",
"40: 1bd23826 16a5fa48 410c3108 bc8f344f 9ec26077 8403f63f d0d37a83 d4926881 5860422c bf14dd85",
"50: 89573ef3 1fa2a7b0 05101a4e 9886e68a 39c42ebf 55ca59be e01db9de cedb1bda 632ce26a b6ea452c",
]
`;

Expand Down Expand Up @@ -194,7 +194,7 @@ exports[`scroll behaviour snapshot > margin web 1`] = `
"20: 9e4b77f5 cb7198cf 9af764d5 a3f06d61 167abfaf d0cffbec f4d9b186 d9d12542 13de058c 200d4ab4",
"30: aadc45f7 37ce7a93 d1388d46 f4d2cc30 c28043e6 f2b45513 8801c1ac c8ac484a 94e08cb6 2171ac81",
"40: 62dfcbaf 657f1b43 a3a841e4 22ee5368 d3e0e255 bfb3f87c 20a8933f 0d454d4f 70957626 87f80beb",
"50: 5baeb658 6ee3c4c0 cec3a144 d5b8753e 3371d972 2ad8996d 2f514fed 95424c35 c8a0843e ce539614",
"50: 5baeb658 6ee3c4c0 cec3a144 d5b8753e 3371d972 2ad8996d 2f514fed 95424c35 860fbdef ce539614",
]
`;

Expand Down Expand Up @@ -234,7 +234,7 @@ exports[`scroll behaviour snapshot > padding web 1`] = `
exports[`scroll behaviour snapshot > predicate ios 1`] = `
[
"0: 1503987b da28a13a 54033cbd 75995293 b092f4c8 d731f6c6 96911d82 a3c61d73 0b82d0ed 2b56adca",
"10: 75e68079 2bc31908 888425aa 5683ada3 2b4bbf15 89be8bb7 ebfa70d4 9e4371d0 8134fb03 750041da",
"10: 75e68079 2bc31908 888425aa 5683ada3 2b4bbf15 89be8bb7 4743c770 9e4371d0 8134fb03 750041da",
"20: 9f915474 4ca88661 54fd2515 1bc77d21 0daaca4c b368ca7e 35aedf09 b8e64de7 675f9530 8caf71f9",
"30: 65d2a727 4f062147 b61ba9ff 4c406d77 0c47a6ac 7cbdb0c8 d11197a6 caebb6d3 82cf0b2e 087a5d0c",
"40: 079790e8 ae3a4374 d5dec481 ac3796cc a2874f32 2fba1d55 f5b117d9 384995f7 54142c26 d1dae953",
Expand All @@ -245,7 +245,7 @@ exports[`scroll behaviour snapshot > predicate ios 1`] = `
exports[`scroll behaviour snapshot > predicate ios27 1`] = `
[
"0: 1503987b da28a13a 54033cbd 6c0916d9 b092f4c8 d731f6c6 96911d82 a3c61d73 0b82d0ed a68350d1",
"10: 75e68079 1ff40218 888425aa 671c1e2a 9d2e455d 89be8bb7 de3c22d4 ccdc126b 8134fb03 750041da",
"10: 75e68079 1ff40218 888425aa 671c1e2a 9d2e455d 89be8bb7 a182b468 ccdc126b 8134fb03 750041da",
"20: 9f915474 4b896a03 54fd2515 1bc77d21 407334c6 b368ca7e 0727dcf4 b8e64de7 9effe82d 8caf71f9",
"30: 60b29a8e 4f062147 7ea2c9cf 6fb5a6e2 0ecf3bcb 7cbdb0c8 d11197a6 d6c24b0e 82cf0b2e 087a5d0c",
"40: 079790e8 7e7eb94d d5dec481 ac3796cc a3f65d93 2fba1d55 f5b117d9 384995f7 9c1a89ca d1dae953",
Expand All @@ -256,11 +256,11 @@ exports[`scroll behaviour snapshot > predicate ios27 1`] = `
exports[`scroll behaviour snapshot > predicate web 1`] = `
[
"0: 1ae1fc6f 54daaa9d e2050bb4 704e0476 1a3b7240 b3620452 ea6b67f3 a3c61d73 09968012 d9597113",
"10: c449bc54 0a115668 20a0834c a6fbd596 bec39b4c 89be8bb7 dddeb6fa 9e4371d0 8134fb03 750041da",
"10: c449bc54 0a115668 20a0834c a6fbd596 bec39b4c 89be8bb7 79981adc 9e4371d0 8134fb03 750041da",
"20: a7943819 4ca88661 48a2a876 9c67b567 48734ee1 b368ca7e e989bf83 ce41bea9 675f9530 8caf71f9",
"30: f30525e8 7cab4af4 9250e3e4 4c406d77 7417e967 7cbdb0c8 9eeab09f ea061649 82cf0b2e 65080957",
"40: 81e56faa a8750438 d5dec481 ac3796cc 1d279633 03a1759f 046db9c2 1e074853 a0c847de 842f2579",
"50: 274e92c7 5b749586 ad467091 da0b01ac 9274c4ab e0f3944f f21db6d8 0ab9d71e d02c95f3 0ef2236c",
"50: 274e92c7 3655a421 ad467091 da0b01ac 9274c4ab e0f3944f f21db6d8 0ab9d71e b798f2f5 0ef2236c",
]
`;

Expand Down
28 changes: 28 additions & 0 deletions packages/virtual-core/tests/scroll-commands.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1882,3 +1882,31 @@ test('a write to a scroll element that went away is not adopted by the next one'

expect(v.scrollOffset).toBe(1001)
})

test('an explicit scroll cancels a pending anchor before layout commit', () => {
const { v, el, scroll } = setupHandDrivenScroll({
anchorTo: 'end',
getItemKey: (i) => i,
})

el.scrollTop = 2000
scroll(2000, false)
v.setOptions({ ...v.options, count: 112, getItemKey: (i) => i - 12 })

v.scrollToOffset(100)
v._willUpdate()
expect(el.scrollTop).toBe(100)
})

test('an explicit scroll cancels a pending clamped retry', () => {
const { v, el, scroll } = setupHandDrivenScroll()

el.scrollTop = 4800
scroll(4800, false)
v.resizeItem(0, 100)
v.scrollToOffset(100)

el.scrollHeight = 5050
v._willUpdate()
expect(el.scrollTop).toBe(100)
})
Loading