diff --git a/src/lib/components/tree/ConfigTree.svelte b/src/lib/components/tree/ConfigTree.svelte index 24fc6c5..79371fd 100644 --- a/src/lib/components/tree/ConfigTree.svelte +++ b/src/lib/components/tree/ConfigTree.svelte @@ -38,6 +38,18 @@ let treeProps: TreeProperties; let treeRoot: Tree.Node; let filteredConfigs: Config[] = []; + let manuallyExpanded: string[] = []; + + function sameIds(a: string[], b: string[]) { + if (a.length !== b.length) return false; + const set = new Set(a); + return b.every((id) => set.has(id)); + } + + function handleExpandedChange(event: CustomEvent) { + if (sameIds(manuallyExpanded, event.detail)) return; + manuallyExpanded = event.detail; + } export function debounced(store: Writable, delay = 300) { let timeout: ReturnType; @@ -74,7 +86,12 @@ treeProps = { root: treeRoot, selected: selected?.id, - expanded: treeRoot.getIncludingNodes(selected?.id), + expanded: Array.from( + new Set([ + ...treeRoot.getIncludingNodes(selected?.id), + ...manuallyExpanded, + ]), + ), scrollBehaviour: { scrollToIndex: scrollToSelectionTrigger > 0, scrollTrigger: scrollToSelectionTrigger, @@ -253,7 +270,7 @@ } - + {@const data = getFolderData(item)} {data.type} {#if $item.children.length > 0} -
+
import { createTreeView } from "@melt-ui/svelte"; import type { TreeView } from "@melt-ui/svelte"; - import { setContext, tick } from "svelte"; + import { createEventDispatcher, setContext, tick } from "svelte"; import TreeNode from "./TreeNode.svelte"; import type { AbstractTreeNode } from "./TreeNode.svelte"; import type { FolderSlotProps, ItemSlotProps } from "./TreeChild.svelte"; @@ -27,6 +27,8 @@ item: ItemSlotProps; } + const dispatch = createEventDispatcher<{ expandedChange: string[] }>(); + export let root: AbstractTreeNode; export let expanded: string[] = []; export let selected: string | undefined = undefined; @@ -51,18 +53,21 @@ curr: string[]; next: string[]; }) { + let result: string[]; if (next.length > curr.length) { const diff = next.find((e) => !curr.includes(e))!; const rootNodes = get(root).children.map((e) => get(e).id); if (rootNodes.includes(diff)) { const others = next.filter((e) => !rootNodes.includes(e)); - return [...others, diff]; + result = [...others, diff]; } else { - return next; + result = next; } } else { - return next; + result = next; } + dispatch("expandedChange", result); + return result; } let scrollTimeout: any;