jonasgeiler / svelte-tiny-virtual-list

A tiny but mighty list virtualization library for Svelte, with zero dependencies 💪 Supports variable heights/widths, sticky items, scrolling to index, and more!
https://svelte-tiny-virtual-list.jonasgeiler.com
MIT License
405 stars 23 forks source link

Add new item and scroll to it #10

Closed Kr1an closed 2 years ago

Kr1an commented 2 years ago

If I push a new item to the array tracked by VirtualList and change itemCount property on VirtualList component and simultaniosly change scrollToIndex to index of newly added item. Scrolling does not work as expected.

        items = [...items, 'new item']
        scrollToIndex = items.length-1

Expected behavior: Newly created item should appear in the visible area. Actual behavior: Item does not appear there. Instead I see that the list is scrolled to the last element that existed in the array before I pushed a new Item. So it scrolls to the index items.length-2.

It should be related to the fact that scrollTo function can not jump to the item that is not yet placed. Workaround: Wait a moment after updating items and before setting new scrollToIndex.

        items = [...items, 'new item']
        // wait a moment before setting scrollToIndex
    await new Promise(res => setTimeout(res, 0))
        scrollToIndex = items.length-1

This is a demo that demonstrates the issue.

mskocik commented 2 years ago

Svelte has tick for such cases. And it's just how Svelte works internally. It's not really an issue with virtual list. I would rewrite your workaround with tick like this:

items = [...];
// promise like
tick().then(() => {
  scrollToIndex = items.length-1;
});
// or with await
await tick();
scrollToIndex = items.length-1;
Kr1an commented 2 years ago

@mskocik Thanks for your quick reply. Indeed I missed tick helper function in svelte docs. Now everything works as expected. Thanks again.

jonasgeiler commented 2 years ago

Glad you found the problem! Hopefully I can respond sooner next time 😅 Thanks @mskocik for helping out!