vuetifyjs / vuetify

🐉 Vue Component Framework
https://vuetifyjs.com
MIT License
39.88k stars 6.96k forks source link

[Bug Report][3.7.1] v-virtual-scroll will not scroll to newly created item using scrollToIndex #20482

Open griffinallen opened 1 month ago

griffinallen commented 1 month ago

Environment

Vuetify Version: 3.7.1 Vue Version: 3.5.6 Browsers: Chrome 128.0.0.0 OS: Windows 10

Steps to reproduce

  1. Create the virtual scroll container and initialize it with a bunch of random items
    • the list must extend beyond the height of the container
    • the container must have the height and item-height properties
  2. Create a button for adding an item to the list
  3. Upon clicking the button, add an item to the list and use "scrollToIndex" with the index being the length of the list

Expected Behavior

The list should be scrolled so that the newest added item is now visible.

Actual Behavior

The list scrolls such that the second to last item is visible, but the newly added item is still not visible.

Reproduction Link

https://play.vuetifyjs.com/#...

KaelWD commented 1 month ago

It has a frame debounce, you will have to use requestAnimationFrame instead of nextTick: https://github.com/vuetifyjs/vuetify/blob/7d3557a75497c508e2d7f855b5db54fc52d7ec9e/packages/vuetify/src/composables/virtual.ts#L184-L187

scrollToIndex should be async and wait for render before returning.

setTimeout(50) might work sometimes but will break if you get a frame that takes over 50ms.

griffinallen commented 1 month ago

It has a frame debounce, you will have to use requestAnimationFrame instead of nextTick:

https://github.com/vuetifyjs/vuetify/blob/7d3557a75497c508e2d7f855b5db54fc52d7ec9e/packages/vuetify/src/composables/virtual.ts#L184-L187

scrollToIndex should be async and wait for render before returning.

setTimeout(50) might work sometimes but will break if you get a frame that takes over 50ms.

I have tried your instructions and it solves one part of the issue. When you are at the bottom of the list and add another item, it now displays the next item. However, if you are not add the bottom of the list and add another item, it will still scroll to the second to last item in the list.

Maybe I have misunderstood your instructions. Can you provide a working example?

See my code here: https://play.vuetifyjs.com/#eNptUslu2zAQ/ZUH9RAXpRe5ddoattFcCvTc3OIcWImOiVKUwsVwIOjfMyTlRUkOEsl5b9Y3D21mTTG9a5rJwYtsma2cqBrFndhsNbA6jHnTxGt8FLV2XGphelM0/nMavwoli//rbcbLcvR5m23oXE0jdk09SOM8V2NbmFqpEwAYsSPfHv2bwOwCLyVVZYkRz2tkL+TT3hGSz2bN8Z3P+IzPFxfwXBHVdGoXn0qx414FbovgyyB1KY7oqJuLQ3AxsO5FCWKm8EvMFyH5gBaI5aZtQ6iuW03pMYgydZchxuf13JPp7bxOOhAwFCJYkk6DOPQkR9k4WOF8klFWTW0c2jByBi2O7p6EQ4edqSvc0BLcBEeAMliHgSRYBy+S9wxHPXrzQ84wZ/jK8I1hwXDL8J3hB8NPhnxGH+E5EXJi5ETJiZPfPlK0EI/bF11g53XhZK0R1whtajhmmRy48mLSeLsfXRuU0E9ujy/IY1049zSiAOvNKUbYsWcvrLvTsuIhx2/DK/GWhGHHfY40/vv6T1iID7L3mYGuv6WzC3okBWj2Wce0Vyr+Hl8B9cQQDQ==

MaxenceMouchard commented 1 month ago

This look like my closed issue

griffinallen commented 1 month ago

This look like my closed issue

Did your solution work for you? I still seem to get the same error with your solution.

If you are already on the last element and add another, it correctly scrolls to the newly added element. However, if you aren't at the bottom of the list, it scrolls to the second to last element.

jflemingframe commented 3 weeks ago

also affecting me

jflemingframe commented 3 weeks ago

what i had going on was after scrolling to bottom, a moment later the scrollHeight would increase by an item's height. The list size wasn't changing. Ended up doing setTimeout 250ms and doing requestAnimationFrame scrollToIndex again after the initial scroll.

griffinallen commented 3 weeks ago

what i had going on was after scrolling to bottom, a moment later the scrollHeight would increase by an item's height. The list size wasn't changing. Ended up doing setTimeout 250ms and doing requestAnimationFrame scrollToIndex again after the initial scroll.

This works for me too. Still hoping the correct fix gets implemented soon, but this works for the time being.