Wednesday, February 7, 2018

React Tree using PrimeReact

Long time no post!

Recently I've been struggling to create or locate a decent-looking side menu tree in React.

I had a few requirements:


  • Navigation links, naturally
  • Selected link highlighted by colour
  • Variable row expansion
Turns out most of these are easy enough, once you get the tree expansion bit going.

To do this, I took advantage of the PrimeReact suite of components (https://www.primefaces.org/primereact), specifically the DataTable. This has an expansion capability already.

I realised some simple recursion would work nicely for me. Firstly, a Tree component was needed:

class Tree extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
    this.rowExpansionTemplate = this.rowExpansionTemplate.bind(this);
  }

  rowExpansionTemplate(subTreeData) {
    return (
      <div style={{paddingLeft: '1em'}}><Tree data={subTreeData.nodes}/></div>
    );
  }

  render() {
    return (
      <DataTable value={this.props.data} expandedRows={this.state.expandedRows}
                 onRowToggle={(e) => this.setState({expandedRows: e.data})}
                 rowExpansionTemplate={this.rowExpansionTemplate}>
        <Column expander={true} style={{width: '2em'}}/>
        <Column field="text"/>
      </DataTable>
    );
  }
}



This sets up a Tree component, displaying the Expander button, and the property called text. When the expander is clicked, the subtree, consisting of the property called nodes, is displayed.

This is called using a simple:

<Tree data={YOURDATAHERE}/>


and the data format is, at minimum:

[
  {
    "text": "fred"
  },
  {
    "text": "group",
    "nodes": [
      {
        "text": "bill"
      },
      {
        "text": "george"
      },
      {
        "text": "simon"
      }
    ]
  }
]


To add things like selection colouring and links can be added simply use a template to render the text column, and add all your requirements in there!