Skip to content

Commit

Permalink
expand search item
Browse files Browse the repository at this point in the history
  • Loading branch information
syedsalehinipg committed Jan 25, 2024
1 parent 9f3c015 commit 51308d5
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 2 deletions.
56 changes: 54 additions & 2 deletions src/TreeViewList/TreeViewList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
TreeNode,
TreeViewListProps
} from "./TreeViewList.types";
import React, { useState } from "react";
import React, { useEffect, useState } from "react";
import { TreeItem, TreeView } from "@mui/x-tree-view";

import AddIcon from "@mui/icons-material/Add";
Expand All @@ -22,14 +22,17 @@ import { alpha } from "@mui/material/styles";
* @property props.selected - The ID of the currently selected item.
* @property props.searchTerm - The term to search for in the items.
* @property [props.defaultExpanded=[]] - The IDs of the items that should be expanded by default.
* @property props.expandSearchTerm - Weather to expand the tree when searching.
* @property props.width - The width of the tree view list.
* @property props.onSelectionChange - The function to call when the selection changes.
* @returns The tree view list component.
*/
const TreeViewList = <T,>({
items,
selected,
searchTerm,
searchTerm = "",
defaultExpanded = [],
expandSearchTerm = false,
width,
onSelectionChange
}: TreeViewListProps<T>) => {
Expand All @@ -43,6 +46,40 @@ const TreeViewList = <T,>({
setExpanded(nodeIds);
};

// search the tree and return an array of matching nodeIds
const searchTree = (
nodes: TreeNode[],
term: string,
isChildSearch: boolean = false // Additional parameter to indicate if we are searching within child nodes
): string[] => {
let result: string[] = [];
const terms = term.toLowerCase().split(" "); // Convert term to lower case and split into words

nodes.forEach(node => {
const nodeNameLower = node.name.toLowerCase(); // Convert node name to lower case
const nodeMatched = terms.some(t => nodeNameLower.includes(t));

// If the current node matches, or if we're in a child search and there's a match in children, add the node ID
if (nodeMatched || isChildSearch) {
result.push(node.id);
}

// If the node has children, search them too
if (node.children) {
const childResult = searchTree(node.children, term, true);
// If there's a match in children, ensure the parent node is included for expansion
if (childResult.length > 0 && !nodeMatched) {
result.push(node.id);
}
// Concatenate the child results (which includes only matching children and their parents)
result = result.concat(childResult);
}
});

// Remove duplicates and return
return Array.from(new Set(result));
};

// tooltip tree item
const TooltipTreeItem = (props: TooltipTreeItemProps) => {
const handleClick = () => {
Expand Down Expand Up @@ -152,6 +189,21 @@ const TreeViewList = <T,>({
</TooltipTreeItem>
));

// expand nodes that match the search term
useEffect(() => {
if (expandSearchTerm) {
// Reset expanded ids
setExpanded([]);

// if the search term is not empty, get the ids of the matching nodes and set them as expanded
if (searchTerm !== "") {
const ids = searchTree(parameters, searchTerm);
setExpanded(ids);
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [searchTerm]);

return (
<TreeView
defaultCollapseIcon={<RemoveIcon />}
Expand Down
5 changes: 5 additions & 0 deletions src/TreeViewList/TreeViewList.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ export type TreeViewListProps<T> = {
*/
searchTerm?: string;

/**
* Flag indicating whether the search term should be expanded in the tree view list. This is optional.
*/
expandSearchTerm?: boolean;

/**
* The IDs of the items that should be expanded by default. This is optional.
*/
Expand Down

0 comments on commit 51308d5

Please sign in to comment.