diff --git a/src/components/FileTreeFolder.svelte b/src/components/FileTreeFolder.svelte index d30370d9f..27682c45f 100644 --- a/src/components/FileTreeFolder.svelte +++ b/src/components/FileTreeFolder.svelte @@ -11,6 +11,10 @@ currentPath: string; name: string; prefix: string; + // Expansion state lives in Tree.svelte so it survives the virtualizer + // unmounting off-screen rows. + isExpanded: (prefix: string) => boolean; + toggleExpanded: (prefix: string) => void; indent?: number; } @@ -19,10 +23,12 @@ fetchBlob, currentPath, prefix, + isExpanded, + toggleExpanded, fetchTree, indent = 0.5, }: Props = $props(); - let expanded = $derived(currentPath.indexOf(prefix) === 0); + const expanded = $derived(isExpanded(prefix)); const treePromise = $derived( expanded ? fetchTree(prefix) : Promise.resolve(undefined), @@ -46,7 +52,7 @@ class="folder" style:padding-left="{indent}rem" style:padding-right="0.5rem" - onclick={() => (expanded = !expanded)}> + onclick={() => toggleExpanded(prefix)}>
@@ -68,6 +74,8 @@ {fetchBlob} name={entry.name} {currentPath} + {isExpanded} + {toggleExpanded} prefix={`${entry.path}/`} indent={indent + 1.5} /> {:else if entry.kind === "blob"} diff --git a/src/components/Tree.svelte b/src/components/Tree.svelte index 085edd33a..3e5d3a331 100644 --- a/src/components/Tree.svelte +++ b/src/components/Tree.svelte @@ -1,8 +1,11 @@ -
- {#each tree.entries as entry (entry.name)} + entry.path} + estimatedItemSize={28}> + {#snippet row(entry)} {#if entry.kind === "tree"} {:else} @@ -29,5 +57,5 @@ fetchBlob={() => fetchBlob(entry.path)} active={entry.path === currentPath} /> {/if} - {/each} -
+ {/snippet} +