import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import List from './List.js;'
import './style.css';

ReactDOM.render(<List />, document.getElementById('root'));
{
  "name": "@plnkr/starter-react",
  "version": "1.0.2",
  "description": "React starter template",
  "dependencies": {
    "react": "^16.13.0",
    "react-dom": "^16.13.0",
    "prop-types": "^15.7.2"
  },
  "plnkr": {
    "runtime": "system",
    "useHotReload": true
  }
}
h1,
p {
  font-family: sans-serif;
}

ul.no-bullet {
  list-style-type: none;
  padding: 0;
  margin: 0;
}

.arrow-line {
  border-left: 2px solid #6a6969;
  content: "";
  position: absolute;
  height: 65%;
}

li.arrow {
  background: url("./arrow.png") no-repeat;
}

li.no-arrow {
  display: block;
}
import React from 'react';
import ListElement from './ListElement.js';

const List = () => (
  <>
    <ListElement>
      <ListElement>
        <ListElement>
          <ListElement />
          <ListElement>
            <ListElement />
          </ListElement>
        </ListElement>
        <ListElement />
      </ListElement>
      <ListElement />
    </ListElement>
    <ListElement />
  </>
);

export default List;
import React from 'react';

const ListElement = props => {
  const indentationStyle = { paddingLeft: `${3 * props.indent}rem` };

  const lineStyle = {
    left: `${2 + 3 * (props.indent - 1)}rem`,
    height: '1.25rem',
  };

  const tile = (
    <div style={indentationStyle}>
      {props.indent > 0 ? (
        <div className={'arrow-line'} style={lineStyle} />
      ) : null}
      <div
        style={{
          border: '1px solid black',
          padding: '1rem',
          marginBottom: '1rem',
        }}
      >
        I am a ListElement
      </div>
    </div>
  );

  const getChildren = () => {
    let elements = React.Children.toArray(props.children);

    // increase indent prop of each child and assign what number child it is in the list
    elements = elements.map((element, index) => {
      return React.cloneElement(element, {
        ...element.props,
        indent: props.indent + 1,
        childNumber: index,
      });
    });
    return elements;
  };

  const childTiles = <div className={'child-tile'}>{getChildren()}</div>;

  const arrowStyle = {
    backgroundPosition: `${1.3 + 3 * (props.indent - 1)}rem`,
  };

  return (
    <>
      <ul className={'no-bullet'}>
        <li
          className={props.indent === 0 ? 'no-arrow' : 'arrow'}
          style={arrowStyle}
        >
          {tile}
        </li>
        {props.children ? childTiles : null}
      </ul>
    </>
  );
};

ListElement.defaultProps = {
  childNumber: 0,
  indent: 0,
};

export default ListElement;