diff --git a/COMPONENT_INDEX.md b/COMPONENT_INDEX.md index a82d811969..ebfbd425bf 100644 --- a/COMPONENT_INDEX.md +++ b/COMPONENT_INDEX.md @@ -4699,21 +4699,21 @@ export interface TreeNode { ### Props -| Prop name | Required | Kind | Reactive | Type | Default value | Description | -| :------------ | :------- | :-------------------- | :------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | -| expandedIds | No | let | Yes | ReadonlyArray | [] | Set the node ids to be expanded | -| selectedIds | No | let | Yes | ReadonlyArray | [] | Set the node ids to be selected | -| activeId | No | let | Yes | TreeNodeId | "" | Set the current active node id
Only one node can be active | -| nodes | No | let | Yes | Array | [] | Provide a nested array of nodes to render | -| nodesFlat | No | let | No | Array | [] | Provide a flat array of nodes to render | -| size | No | let | No | "default" | "compact" | "default" | Specify the TreeView size | -| labelText | No | let | No | string | "" | Specify the label text | -| hideLabel | No | let | No | boolean | false | Set to `true` to visually hide the label text | -| expandAll | No | function | No | () => void | () => { expandedIds = [...nodeIds]; } | Programmatically expand all nodes | -| collapseAll | No | function | No | () => void | () => { expandedIds = []; } | Programmatically collapse all nodes | -| expandNodes | No | function | No | (filterId?: (node: TreeNode) => boolean) => void | () => { expandedIds = flattenedNodes .filter( (node) => filterNode(node) || node.nodes?.some((child) => filterNode(child) && child.nodes), ) .map((node) => node.id); } | Programmatically expand a subset of nodes.
Expands all nodes if no argument is provided | -| collapseNodes | No | function | No | (filterId?: (node: TreeNode) => boolean) => void | () => { expandedIds = flattenedNodes .filter((node) => expandedIds.includes(node.id) && !filterNode(node)) .map((node) => node.id); } | Programmatically collapse a subset of nodes.
Collapses all nodes if no argument is provided | -| showNode | No | function | No | (id: TreeNodeId) => void | () => { for (const child of nodes) { const nodes = findNodeById(child, id); if (nodes) { const ids = nodes.map((node) => node.id); const nodeIds = new Set(ids); expandNodes((node) => nodeIds.has(node.id)); const lastId = ids[ids.length - 1]; activeId = lastId; selectedIds = [lastId]; tick().then(() => { ref?.querySelector(\`[id="${lastId}"]\`)?.focus(); }); break; } } } | Programmatically show a node by `id`.
The matching node will be expanded, selected, and focused | +| Prop name | Required | Kind | Reactive | Type | Default value | Description | +| :------------ | :------- | :-------------------- | :------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | +| expandedIds | No | let | Yes | ReadonlyArray | [] | Set the node ids to be expanded | +| selectedIds | No | let | Yes | ReadonlyArray | [] | Set the node ids to be selected | +| activeId | No | let | Yes | TreeNodeId | "" | Set the current active node id
Only one node can be active | +| nodes | No | let | No | Array | [] | Provide a nested array of nodes to render | +| size | No | let | No | "default" | "compact" | "default" | Specify the TreeView size | +| labelText | No | let | No | string | "" | Specify the label text | +| hideLabel | No | let | No | boolean | false | Set to `true` to visually hide the label text | +| expandAll | No | function | No | () => void | () => { expandedIds = [...nodeIds]; } | Programmatically expand all nodes | +| collapseAll | No | function | No | () => void | () => { expandedIds = []; } | Programmatically collapse all nodes | +| toHierarchy | No | function | No | (flatArray: TreeNode[] & { pid?: any }[]) => TreeNode[] | () => { return th(flatArray); } | Create a nested array from a flat array | +| expandNodes | No | function | No | (filterId?: (node: TreeNode) => boolean) => void | () => { expandedIds = flattenedNodes .filter( (node) => filterNode(node) || node.nodes?.some((child) => filterNode(child) && child.nodes), ) .map((node) => node.id); } | Programmatically expand a subset of nodes.
Expands all nodes if no argument is provided | +| collapseNodes | No | function | No | (filterId?: (node: TreeNode) => boolean) => void | () => { expandedIds = flattenedNodes .filter((node) => expandedIds.includes(node.id) && !filterNode(node)) .map((node) => node.id); } | Programmatically collapse a subset of nodes.
Collapses all nodes if no argument is provided | +| showNode | No | function | No | (id: TreeNodeId) => void | () => { for (const child of nodes) { const nodes = findNodeById(child, id); if (nodes) { const ids = nodes.map((node) => node.id); const nodeIds = new Set(ids); expandNodes((node) => nodeIds.has(node.id)); const lastId = ids[ids.length - 1]; activeId = lastId; selectedIds = [lastId]; tick().then(() => { ref?.querySelector(\`[id="${lastId}"]\`)?.focus(); }); break; } } } | Programmatically show a node by `id`.
The matching node will be expanded, selected, and focused | ### Slots diff --git a/docs/src/COMPONENT_API.json b/docs/src/COMPONENT_API.json index 005acb7678..962830d49a 100644 --- a/docs/src/COMPONENT_API.json +++ b/docs/src/COMPONENT_API.json @@ -17777,18 +17777,6 @@ "isFunctionDeclaration": false, "isRequired": false, "constant": false, - "reactive": true - }, - { - "name": "nodesFlat", - "kind": "let", - "description": "Provide a flat array of nodes to render", - "type": "Array", - "value": "[]", - "isFunction": false, - "isFunctionDeclaration": false, - "isRequired": false, - "constant": false, "reactive": false }, { @@ -17887,6 +17875,18 @@ "constant": false, "reactive": false }, + { + "name": "toHierarchy", + "kind": "function", + "description": "Create a nested array from a flat array", + "type": "(flatArray: TreeNode[] & { pid?: any }[]) => TreeNode[]", + "value": "() => {\n return th(flatArray);\n}", + "isFunction": true, + "isFunctionDeclaration": true, + "isRequired": false, + "constant": false, + "reactive": false + }, { "name": "expandNodes", "kind": "function", diff --git a/docs/src/pages/components/TreeView.svx b/docs/src/pages/components/TreeView.svx index e95b782852..5c639924c2 100644 --- a/docs/src/pages/components/TreeView.svx +++ b/docs/src/pages/components/TreeView.svx @@ -58,14 +58,6 @@ 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`. @@ -116,3 +108,13 @@ Use the `TreeView.showNode` method to show a specific node. If a matching node is found, it will be expanded, selected, and focused. + +## Flat data structure + +Use the `toHierarchy` method to provide a flat data structure to the `nodes` property. + +This method will transform a flat array of objects into the hierarchical array as expected by `nodes`. +The child objects in the flat array need to have a `pid` property to reference its parent. +When `pid` is not provided the object is assumed to be at the root of the tree. + + \ No newline at end of file diff --git a/src/TreeView/TreeView.svelte b/src/TreeView/TreeView.svelte index b07d428dd7..7f3a028ec6 100644 --- a/src/TreeView/TreeView.svelte +++ b/src/TreeView/TreeView.svelte @@ -89,6 +89,14 @@ expandedIds = []; } + /** + * Create a nested array from a flat array + * @type {(flatArray: TreeNode[] & { pid?: any }[]) => TreeNode[]} + */ + export function toHierarchy(flatArray) { + return th(flatArray); + } + /** * Programmatically expand a subset of nodes. * Expands all nodes if no argument is provided @@ -147,6 +155,7 @@ import { createEventDispatcher, setContext, onMount, tick } from "svelte"; import { writable } from "svelte/store"; import TreeViewNodeList from "./TreeViewNodeList.svelte"; + import { toHierarchy as th } from "./treeview"; const dispatch = createEventDispatcher(); const labelId = `label-${Math.random().toString(36)}`; diff --git a/src/TreeView/treeview.js b/src/TreeView/treeview.js index e1ec636695..5804ae92d2 100644 --- a/src/TreeView/treeview.js +++ b/src/TreeView/treeview.js @@ -25,8 +25,6 @@ export function toHierarchy(flatArray) { }); // 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; diff --git a/src/index.js b/src/index.js index ea1a84cf46..75a2c8dcc9 100644 --- a/src/index.js +++ b/src/index.js @@ -127,6 +127,7 @@ export { Tooltip, TooltipFooter } from "./Tooltip"; export { TooltipDefinition } from "./TooltipDefinition"; export { TooltipIcon } from "./TooltipIcon"; export { TreeView } from "./TreeView"; +export { toHierarchy } from "./TreeView/treeview"; export { Truncate } from "./Truncate"; export { default as truncate } from "./Truncate/truncate"; export { diff --git a/tests/TreeView/TreeViewFlatArray.test.svelte b/tests/TreeView/TreeViewFlatArray.test.svelte index 86b7fe718f..005394724b 100644 --- a/tests/TreeView/TreeViewFlatArray.test.svelte +++ b/tests/TreeView/TreeViewFlatArray.test.svelte @@ -1,7 +1,9 @@