mirror of
https://github.com/carbon-design-system/carbon-components-svelte.git
synced 2025-09-15 02:11:05 +00:00
feat: add toHierarchy
utility for TreeView
, RecursiveList
(#2072)
Co-authored-by: Bram <bramhavers@gmail.com>
This commit is contained in:
parent
f1a27ec855
commit
48afd18e5e
19 changed files with 413 additions and 23 deletions
1
src/TreeView/index.d.ts
vendored
Normal file
1
src/TreeView/index.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
export { default as TreeView } from "./TreeView.svelte";
|
|
@ -152,3 +152,4 @@ export {
|
|||
HeaderSearch,
|
||||
} from "./UIShell";
|
||||
export { UnorderedList } from "./UnorderedList";
|
||||
export { toHierarchy } from "./utils/toHierarchy";
|
||||
|
|
21
src/utils/toHierarchy.d.ts
vendored
Normal file
21
src/utils/toHierarchy.d.ts
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
type NodeLike = {
|
||||
id: string | number;
|
||||
nodes?: NodeLike[];
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
/** Create a hierarchical tree from a flat array. */
|
||||
export function toHierarchy<
|
||||
T extends NodeLike,
|
||||
K extends keyof Omit<T, "id" | "nodes">,
|
||||
>(
|
||||
flatArray: T[] | readonly T[],
|
||||
/**
|
||||
* Function that returns the parent ID for a given node.
|
||||
* @example
|
||||
* toHierarchy(flatArray, (node) => node.parentId);
|
||||
*/
|
||||
getParentId: (node: T) => T[K] | null,
|
||||
): (T & { nodes?: (T & { nodes?: T[] })[] })[];
|
||||
|
||||
export default toHierarchy;
|
49
src/utils/toHierarchy.js
Normal file
49
src/utils/toHierarchy.js
Normal file
|
@ -0,0 +1,49 @@
|
|||
// @ts-check
|
||||
/**
|
||||
* Create a nested array from a flat array.
|
||||
* @typedef {Object} NodeLike
|
||||
* @property {string | number} id - Unique identifier for the node
|
||||
* @property {NodeLike[]} [nodes] - Optional array of child nodes
|
||||
* @property {Record<string, any>} [additionalProperties] - Any additional properties
|
||||
*
|
||||
* @param {NodeLike[]} flatArray - Array of flat nodes to convert
|
||||
* @param {function(NodeLike): (string|number|null)} getParentId - Function to get parent ID for a node
|
||||
* @returns {NodeLike[]} Hierarchical tree structure
|
||||
*/
|
||||
export function toHierarchy(flatArray, getParentId) {
|
||||
/** @type {NodeLike[]} */
|
||||
const tree = [];
|
||||
const childrenOf = new Map();
|
||||
const itemsMap = new Map(flatArray.map((item) => [item.id, item]));
|
||||
|
||||
flatArray.forEach((item) => {
|
||||
const parentId = getParentId(item);
|
||||
|
||||
// Only create nodes array if we have children.
|
||||
const children = childrenOf.get(item.id);
|
||||
if (children) {
|
||||
item.nodes = children;
|
||||
}
|
||||
|
||||
// Check if parentId exists using Map instead of array lookup.
|
||||
const parentExists = parentId && itemsMap.has(parentId);
|
||||
|
||||
if (parentId && parentExists) {
|
||||
if (!childrenOf.has(parentId)) {
|
||||
childrenOf.set(parentId, []);
|
||||
}
|
||||
childrenOf.get(parentId).push(item);
|
||||
|
||||
const parent = itemsMap.get(parentId);
|
||||
if (parent) {
|
||||
parent.nodes = childrenOf.get(parentId);
|
||||
}
|
||||
} else {
|
||||
tree.push(item);
|
||||
}
|
||||
});
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
export default toHierarchy;
|
Loading…
Add table
Add a link
Reference in a new issue