From 2403f832dc23ea9c2d5bc17158c99b541e9c11ae Mon Sep 17 00:00:00 2001 From: Ruben L Date: Fri, 22 Jan 2021 23:47:42 +0100 Subject: [PATCH 1/3] #43 introduces scrollToIndex method --- VirtualList.svelte | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/VirtualList.svelte b/VirtualList.svelte index c92f65a..cb84eb7 100644 --- a/VirtualList.svelte +++ b/VirtualList.svelte @@ -11,7 +11,6 @@ // read-only, but visible to consumers via bind:start export let start = 0; export let end = 0; - // local state let height_map = []; let rows; @@ -33,6 +32,12 @@ $: if (mounted) refresh(items, viewport_height, itemHeight); async function refresh(items, viewport_height, itemHeight) { + const isStartOverflow = items.length < start + + if (isStartOverflow) { + await scrollToIndex(items.length - 1, {behavior: 'auto'}) + } + const { scrollTop } = viewport; await tick(); // wait until the DOM is up to date @@ -105,6 +110,7 @@ bottom = remaining * average_height; // prevent jumping if we scrolled up into unknown territory + return if (start < old_start) { await tick(); @@ -127,6 +133,20 @@ // more. maybe we can just call handle_scroll again? } + export async function scrollToIndex (index, opts) { + const {scrollTop} = viewport; + const itemsDelta = index - start; + const _itemHeight = itemHeight || average_height; + const distance = itemsDelta * _itemHeight; + opts = { + left: 0, + top: scrollTop + distance, + behavior: 'smooth', + ...opts + }; + viewport.scrollTo(opts); + } + // trigger initial refresh onMount(() => { rows = contents.getElementsByTagName('svelte-virtual-list-row'); From b834e770d6b96062484b37416d1c2d4c5dcf59d3 Mon Sep 17 00:00:00 2001 From: Ruben L Date: Sat, 23 Jan 2021 01:10:54 +0100 Subject: [PATCH 2/3] cleanup --- VirtualList.svelte | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/VirtualList.svelte b/VirtualList.svelte index cb84eb7..f9ba0be 100644 --- a/VirtualList.svelte +++ b/VirtualList.svelte @@ -5,9 +5,6 @@ export let items; export let height = '100%'; export let itemHeight = undefined; - - let foo; - // read-only, but visible to consumers via bind:start export let start = 0; export let end = 0; @@ -109,25 +106,6 @@ while (i < items.length) height_map[i++] = average_height; bottom = remaining * average_height; - // prevent jumping if we scrolled up into unknown territory - return - if (start < old_start) { - await tick(); - - let expected_height = 0; - let actual_height = 0; - - for (let i = start; i < old_start; i +=1) { - if (rows[i - start]) { - expected_height += height_map[i]; - actual_height += itemHeight || rows[i - start].offsetHeight; - } - } - - const d = actual_height - expected_height; - viewport.scrollTo(0, scrollTop + d); - } - // TODO if we overestimated the space these // rows would occupy we may need to add some // more. maybe we can just call handle_scroll again? From 9707e2e3f9254391448cd37e22a9f85a04081b5f Mon Sep 17 00:00:00 2001 From: Ruben L Date: Sat, 22 Jan 2022 17:45:43 +0100 Subject: [PATCH 3/3] adds clean logo from initial concept --- logo_svelte-virtual-list-ce.png | Bin 0 -> 5898 bytes logo_svelte-virtual-list-ce.svg | 1 + 2 files changed, 1 insertion(+) create mode 100644 logo_svelte-virtual-list-ce.png create mode 100644 logo_svelte-virtual-list-ce.svg diff --git a/logo_svelte-virtual-list-ce.png b/logo_svelte-virtual-list-ce.png new file mode 100644 index 0000000000000000000000000000000000000000..0562c31a361588d9380c55b13076156efd4d8eb9 GIT binary patch literal 5898 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 \ No newline at end of file