diff --git a/docs/src/pages/components/TreeView.svx b/docs/src/pages/components/TreeView.svx index c7c97c92..e95b7828 100644 --- a/docs/src/pages/components/TreeView.svx +++ b/docs/src/pages/components/TreeView.svx @@ -58,12 +58,21 @@ To render a node with an icon, define an `icon` property with a Carbon Svelte ic +## Flat data structure + +Provide a flat data structure through the `nodesFlat` property. Child object needs to have a `pid` property +to reference its parent. Optionally the key for the parent can be provided. +When no parent id is available the object is assumed to be at the root of the tree. + + + ## Initial expanded nodes Expanded nodes can be set using `expandedIds`. + ## Initial multiple selected nodes Initial multiple selected nodes can be set using `selectedIds`. diff --git a/docs/src/pages/framed/TreeView/TreeViewFlatArray.svelte b/docs/src/pages/framed/TreeView/TreeViewFlatArray.svelte new file mode 100644 index 00000000..a508b092 --- /dev/null +++ b/docs/src/pages/framed/TreeView/TreeViewFlatArray.svelte @@ -0,0 +1,69 @@ + + + console.log("select", detail)} + on:toggle={({ detail }) => console.log("toggle", detail)} + on:focus={({ detail }) => console.log("focus", detail)} +/> + +
Active node id: {activeId}
+
Selected ids: {JSON.stringify(selectedIds)}
+ + diff --git a/src/TreeView/TreeView.svelte b/src/TreeView/TreeView.svelte index 31e3f267..e32e3c53 100644 --- a/src/TreeView/TreeView.svelte +++ b/src/TreeView/TreeView.svelte @@ -37,11 +37,17 @@ */ /** - * Provide an array of nodes to render + * Provide a nested array of nodes to render * @type {Array} */ export let nodes = []; + /** + * Provide a flat array of nodes to render + * @type {Array[]} + */ + export let nodesFlat = []; + /** * Set the current active node id * Only one node can be active @@ -195,6 +201,48 @@ } } + /** + * Create a nested array from a flat array + * TODO: accept a parent key + * @type {(flatArray: TreeNode[] & { pid: any }[]) => TreeNode[]} + */ + function createNestedArray(flatArray) { + /** @type TreeNode[] */ + const tree = []; + /** @type TreeNode[] */ + const childrenOf = []; + + flatArray.forEach((dstItem) => { + const { id, pid } = dstItem; + childrenOf[id] = childrenOf[id] || []; + dstItem["nodes"] = childrenOf[id]; + + if (pid) { + // objects without pid are root level objects. + childrenOf[pid] = childrenOf[pid] || []; + delete dstItem.pid; // TreeNode type doesn't have pid. + childrenOf[pid].push(dstItem); + } else { + delete dstItem.pid; + tree.push(dstItem); + } + }); + + // Remove the empty nodes props that make TreeView render a twistie. + // Maybe this should actually be taken care of in TreeView itself? It makes + // no sense i think that an empty nodes property render a twistie. + function removeEmptyNodes(element) { + element.forEach((elmt) => { + if (elmt.nodes?.length === 0) delete elmt.nodes; + else { + removeEmptyNodes(elmt.nodes); + } + }); + } + removeEmptyNodes(tree); + return tree; + } + onMount(() => { const firstFocusableNode = ref.querySelector( "li.bx--tree-node:not(.bx--tree-node--disabled)", @@ -220,6 +268,7 @@ }, []); } + $: nodes = createNestedArray(nodesFlat); $: flattenedNodes = traverse(nodes); $: nodeIds = flattenedNodes.map((node) => node.id); $: activeNodeId.set(activeId);