UNPKG

svelte-tree-view

Version:

Display JSON objects in a customizable tree-view

73 lines (72 loc) 3.21 kB
import { get, writable } from 'svelte/store'; import { createNode, recurseObjectProperties } from '../tree-utils'; export const createTreeStore = (propsStore) => { const defaultRootNode = createNode(0, 'root', [], 0, null); const tree = writable(defaultRootNode); const treeMap = writable(new Map()); const iteratedValues = writable(new Map()); return { tree, treeMap, defaultRootNode, init(newTree, newTreeMap, iterated) { if (newTree) { tree.set(newTree); } else { tree.set(defaultRootNode); } treeMap.set(newTreeMap); iteratedValues.set(iterated); }, getNode(id) { return get(treeMap).get(id); }, toggleCollapse(id) { const node = get(treeMap).get(id); if (!node) { console.warn(`Attempted to collapse non-existent node: ${id}`); return; } const updatedNode = { ...node, collapsed: !node.collapsed }; treeMap.update(m => new Map(m.set(node.id, updatedNode))); const recursionOpts = get(propsStore.recursionOpts); if (recursionOpts) { this.expandNodeChildren(updatedNode, recursionOpts); } }, expandNodeChildren(node, recursionOpts) { const parent = this.getNode((node === null || node === void 0 ? void 0 : node.parentId) || '') || null; if (!parent) { // Only root node has no parent and it should not be expandable throw Error('No parent in expandNodeChildren for node: ' + node); } const newTreeMap = new Map(get(treeMap)); const oldTreeMap = get(treeMap); const previouslyIterated = get(iteratedValues); const nodeWithUpdatedChildren = recurseObjectProperties(node.index, node.key, node.value, node.depth, !node.collapsed, // Ensure that when uncollapsed the node's children are always recursed parent, newTreeMap, oldTreeMap, previouslyIterated, false, // Never recompute shouldExpandNode since it may override the collapsing of this node recursionOpts); if (!nodeWithUpdatedChildren) return; parent.children = parent.children.map(c => c.id === nodeWithUpdatedChildren.id ? nodeWithUpdatedChildren : c); newTreeMap.set(nodeWithUpdatedChildren.id, nodeWithUpdatedChildren); newTreeMap.set(parent.id, parent); treeMap.set(newTreeMap); iteratedValues.set(previouslyIterated); }, expandAllNodesToNode(id) { function recurseNodeUpwards(updated, node) { if (!node) return; updated.set(node.id, { ...node, collapsed: false }); if (node.parentId) { recurseNodeUpwards(updated, updated.get(node.parentId)); } } const updated = new Map(get(treeMap)); recurseNodeUpwards(updated, updated.get(id)); treeMap.set(updated); } }; };