React Treebeard: Data-Driven Tree View

3.2.4 · maintenance · verified Tue Apr 21

React Treebeard is a highly customizable and performant React component for rendering tree structures. It is data-driven, allowing developers to define the tree's structure and state through a simple data object. The current stable version is 3.2.4, released in 2019, with a beta version (4.2.4-beta.0) indicating potential future development, though the stable release cadence has been slow. Key differentiators include its robust animation capabilities, extensive styling options through decorators (leveraging `@emotion/styled`), and its programmatic approach to managing tree state, making it suitable for displaying complex hierarchical data with interactive features like toggling nodes and active states.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates a basic interactive tree view with custom styling, default decorators, and state management for node toggling.

import React, { useState } from 'react';
import { Treebeard, decorators } from 'react-treebeard';

interface Node {
  id: string;
  name: string;
  toggled?: boolean;
  children?: Node[];
}

const initialData: Node = {
  id: 'root',
  name: 'root',
  toggled: true,
  children: [
    { id: 'parent1', name: 'Parent 1', children: [{ id: 'child1a', name: 'Child 1A' }, { id: 'child1b', name: 'Child 1B' }] },
    { id: 'parent2', name: 'Parent 2', toggled: true, children: [{ id: 'child2a', name: 'Child 2A' }] }
  ]
};

const customStyles = {
  tree: {
    base: { listStyle: 'none', backgroundColor: '#fdfdfd', margin: 0, padding: 0, color: '#333' },
    node: {
      base: { position: 'relative' },
      link: { cursor: 'pointer', position: 'relative', padding: '0px 5px', display: 'block' },
      activeLink: { background: '#e0e0e0' },
      toggle: { base: { position: 'relative', display: 'inline-block', verticalAlign: 'top', marginLeft: '-5px', height: '24px', width: '24px' }, wrapper: { position: 'absolute', top: '50%', left: '50%', margin: '-7px 0 0 -7px', height: '14px', width: '14px' }, height: 14, width: 14, arrow: { fill: '#333', strokeWidth: 0 } },
      header: { base: { display: 'inline-block', verticalAlign: 'top', color: '#333' }, connector: { width: '2px', height: '12px', borderLeft: 'solid 2px black', borderBottom: 'solid 2px black', position: 'absolute', top: '0px', left: '-21px' }, title: { lineHeight: '24px', verticalAlign: 'middle' } },
      subtree: { listStyle: 'none', paddingLeft: '19px' },
      loading: { color: '#E2C089' }
    }
  }
};

const MyTreeComponent: React.FC = () => {
  const [treeData, setTreeData] = useState<Node>(initialData);

  const onToggle = (node: Node, toggled: boolean) => {
    const nextData = { ...treeData };
    const findAndToggle = (currentNodes: Node[], targetNodeId: string): boolean => {
      for (const n of currentNodes) {
        if (n.id === targetNodeId) {
          n.toggled = toggled;
          return true;
        }
        if (n.children && findAndToggle(n.children, targetNodeId)) {
          return true;
        }
      }
      return false;
    };

    if (nextData.id === node.id) {
      nextData.toggled = toggled;
    } else if (nextData.children) {
      findAndToggle(nextData.children, node.id);
    }

    setTreeData(nextData);
  };

  return (
    <Treebeard
      data={treeData}
      onToggle={onToggle}
      decorators={decorators}
      style={customStyles}
    />
  );
};

export default MyTreeComponent;

view raw JSON →