Search

Ctrl + K

TreeView

This document outlines the steps to create TreeView component styled withTailwind CSS and using some npm dependency libraries.

Prerequisites

  • Node.js and npm installed on your machine.
  • Tailwind CSS installed in your project.
  • CVA(class-variance-authority) is a utility for managing CSS class names based on various conditions.
  • clsx is a tiny utility for constructing className strings conditionally.
Step 1: Create TreeNode component
1// tree-node.tsx
2import clsx from "clsx";
3import { FileIcon, FolderIcon } from "lucide-react";
4import { useState } from "react";
5import { TreeView } from ".";
6
7export interface TreeInfo {
8  key: string;
9  label: string;
10  iconType?: string;
11  childNodes?: TreeInfo[];
12}
13
14export interface Icons {
15  [key: string]: React.ReactNode;
16}
17
18interface Props {
19  node: TreeInfo;
20  icons?: Icons;
21  expandAll?: boolean;
22  showIcon?: boolean;
23  showVerticalLine?: boolean;
24}
25
26const TreeNode: React.FC<Props> = ({
27  node,
28  icons,
29  expandAll,
30  showIcon,
31  showVerticalLine,
32}) => {
33  const [showChildren, setShowChildren] = useState<boolean>(expandAll || false);
34
35  const handleClick = () => {
36    setShowChildren(!showChildren);
37  };
38
39  return (
40    <>
41      <div className="mb-2.5 flex items-center">
42        {showIcon && (
43          <div className="w-8 text-neutral-500">
44            {icons?.[node.iconType as string] ||
45              (node.childNodes === undefined ? (
46                <FileIcon width={16} height={16} />
47              ) : (
48                <FolderIcon width={16} height={16} />
49              ))}
50          </div>
51        )}
52        <span className="cursor-pointer select-none" onClick={handleClick}>
53          {node.label}
54        </span>
55      </div>
56      <ul
57        className={clsx("pl-2.5", {
58          "border-l border-neutral-200 dark:border-neutral-600": showVerticalLine,
59        })}
60      >
61        {showChildren && node.childNodes && (
62          <TreeView
63            data={node.childNodes}
64            icons={icons}
65            expandAll={expandAll}
66            showIcon={showIcon}
67            showVerticalLine={showVerticalLine}
68          />
69        )}
70      </ul>
71    </>
72  );
73};
74
75export default TreeNode;
76
Step 2: Create TreeView component
1// tree-view.component.tsx
2import TreeNode, { Icons, TreeInfo } from "./tree-node";
3
4export interface TreeViewProps {
5  data: TreeInfo[];
6  icons?: Icons;
7  expandAll?: boolean;
8  showIcon?: boolean;
9  showVerticalLine?: boolean;
10  className?: string;
11}
12
13const TreeView: React.FC<TreeViewProps> = ({
14  data,
15  icons,
16  expandAll = false,
17  showIcon = true,
18  showVerticalLine = true,
19  className,
20}) => {
21  return (
22    <ul className={className}>
23      {data.map((node) => (
24        <TreeNode
25          key={node.key}
26          node={node}
27          icons={icons}
28          expandAll={expandAll}
29          showIcon={showIcon}
30          showVerticalLine={showVerticalLine}
31        />
32      ))}
33    </ul>
34  );
35};
36
37export default TreeView;
38