Added nodesFlat property and updated docs

This commit is contained in:
Bram 2024-11-26 21:51:07 +01:00 committed by Eric Liu
commit 87102776ab
3 changed files with 128 additions and 1 deletions

View file

@ -58,12 +58,21 @@ To render a node with an icon, define an `icon` property with a Carbon Svelte ic
<FileSource src="/framed/TreeView/TreeViewIcons" />
## 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.
<FileSource src="/framed/TreeView/TreeViewFlatArray" />
## Initial expanded nodes
Expanded nodes can be set using `expandedIds`.
<FileSource src="/framed/TreeView/TreeViewExpanded" />
## Initial multiple selected nodes
Initial multiple selected nodes can be set using `selectedIds`.

View file

@ -0,0 +1,69 @@
<script>
import { TreeView } from "carbon-components-svelte";
import WatsonMachineLearning from "carbon-icons-svelte/lib/WatsonMachineLearning.svelte";
import Analytics from "carbon-icons-svelte/lib/Analytics.svelte";
import Blockchain from "carbon-icons-svelte/lib/Blockchain.svelte";
import DataBase from "carbon-icons-svelte/lib/DataBase.svelte";
import SignalStrength from "carbon-icons-svelte/lib/SignalStrength.svelte";
let activeId = "";
let selectedIds = [];
let nodesFlat = [
{ id: 0, text: "AI / Machine learning", icon: WatsonMachineLearning },
{ id: 1, text: "Analytics", icon: Analytics },
{ id: 2, text: "IBM Analytics Engine", pid: 1, icon: Analytics },
{ id: 3, text: "Apache Spark", pid: 2, icon: Analytics },
{ id: 4, text: "Hadoop", icon: Analytics, pid: 2 },
{ id: 5, text: "IBM Cloud SQL Query", icon: Analytics, pid: 1 },
{ id: 6, text: "IBM Db2 Warehouse on Cloud", icon: Analytics, pid: 1 },
{ id: 7, text: "Blockchain", icon: Blockchain },
{ id: 8, text: "IBM Blockchain Platform", icon: Blockchain, pid: 7 },
{ id: 9, text: "Databases", icon: DataBase },
{
id: 10,
text: "IBM Cloud Databases for Elasticsearch",
icon: DataBase,
pid: 9,
},
{
id: 11,
text: "IBM Cloud Databases for Enterprise DB",
icon: DataBase,
pid: 9,
},
{ id: 12, text: "IBM Cloud Databases for MongoDB", icon: DataBase, pid: 9 },
{
id: 13,
text: "IBM Cloud Databases for PostgreSQL",
icon: DataBase,
pid: 9,
},
{ id: 14, text: "Integration", icon: SignalStrength, disabled: true },
{
id: 15,
text: "IBM API Connect",
icon: SignalStrength,
disabled: true,
pid: 14,
},
];
</script>
<TreeView
labelText="Cloud Products"
{nodesFlat}
bind:activeId
bind:selectedIds
on:select={({ detail }) => console.log("select", detail)}
on:toggle={({ detail }) => console.log("toggle", detail)}
on:focus={({ detail }) => console.log("focus", detail)}
/>
<div>Active node id: {activeId}</div>
<div>Selected ids: {JSON.stringify(selectedIds)}</div>
<style>
div {
margin-top: var(--cds-spacing-05);
}
</style>

View file

@ -37,11 +37,17 @@
*/
/**
* Provide an array of nodes to render
* Provide a nested array of nodes to render
* @type {Array<TreeNode>}
*/
export let nodes = [];
/**
* Provide a flat array of nodes to render
* @type {Array<TreeNode>[]}
*/
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);