2

What I want to do is adding a new property to my tree that is then passed to its treeNodes. The reason is that I have child nodes that have a secondaryLabel. I want to use that label to dispatch an action to my redux store on click. So, when rendering my component I want to pass this action to my Tree which then passes it to relevant nodes. If this is a bad approach, stop me here!

My nodes are created in a controller (which is a .ts file) like this:

  files.push({
    id: generateKey(fileName), isDirectory: false, label: fileName,
    filePath: fullPath, isExpanded: false, icon: 'document',
    secondaryLabel: React.createElement(Icon, {icon: 'add', className: 'hoverIcon', iconSize: 16})})

Since I am using React.createElement I thought the best way to pass my action to the Icon would be through the tree and then to its nodes when those are rendered.

I am extending the Tree like this:

export interface ICustomTreeProps<T = {}>  {
  onNodeAdd?: TreeEventHandler<T>
}

export class CustomTree<T = {}> extends Tree<ICustomTreeProps> {
}

This is where my problems start: Tree has most of its functions declared as private. I wanted to extend its renderNodes function to pass my action to the nodes. But the function itself and everything it passes is also private (https://github.com/palantir/blueprint/blob/develop/packages/core/src/components/tree/treeNode.tsx)

 private renderNodes(treeNodes: Array<ITreeNode<T>>, currentPath?: number[], className?: string): JSX.Element {
        if (treeNodes == null) {
            return null;
        }

        const nodeItems = treeNodes.map((node, i) => {
            const elementPath = currentPath.concat(i);
            const TypedTreeNode = TreeNode.ofType<T>();
            return (
                <TypedTreeNode
                    {...node}
                    key={node.id}
                    contentRef={this.handleContentRef}
                    depth={elementPath.length - 1}
                    onClick={this.handleNodeClick}
                    onContextMenu={this.handleNodeContextMenu}
                    onCollapse={this.handleNodeCollapse}
                    onDoubleClick={this.handleNodeDoubleClick}
                    onExpand={this.handleNodeExpand}
                    onMouseEnter={this.handleNodeMouseEnter}
                    onMouseLeave={this.handleNodeMouseLeave}
                    path={elementPath}
                >
                    {this.renderNodes(node.childNodes, elementPath)}
                </TypedTreeNode>
            );
        });

        return <ul className={classNames(Classes.TREE_NODE_LIST, className)}>{nodeItems}</ul>;
    }

Since I don't want basically copy paste the whole thing to extend a single property (and afterwards also do the same with TreeNode where the action is supposed to happen), how do I do this correctly?

Shin
  • 678
  • 3
  • 12
  • 22

0 Answers0