JSFiddle - React, Tailwind, and code Playground

HTML

<div id="example"></div>

CSS

ul
{
	display:inline-block; 0position: relative; float: left; clear: left;
	margin:.25em;
	padding:0;
	background: pink;
}

ul:before
{
	content:""; position: absolute; z-index: 1;
	top:.25em; right:auto; bottom:0; left: 1.75em; 
	margin: auto;
	border-right: dotted black .1em;
	width: 0; height: auto;
	0background: blue;
}

ul:after
{
	content: "-"; position: absolute; z-index: 3;
	top:0; left:-.5em;
	margin:.65em; padding:0;
	width:.8em; height: .8em; 
	text-align:center; line-height: .6em; font-size: 1em;
	background: blue;
}

ul>li
{
	display: block; position: relative; float: left; clear: both;
	right:auto;
	padding-left: 1em;
	width:auto;
	text-align: center; color:white;
	background: gray;
}

ul>li>input
{
	display:block; position: absolute; float: left; z-index: 4;
	margin:0 0 0 -1em; padding:0;
	width:1em; height: 2em;
	font-size: 1em;
	opacity: 0;
	cursor: pointer;
}

ul>li>input:checked~ul:before
{
	display: none;
}

ul>li>input:checked~ul:after
{
	content: "+"
}

ul>li>input:checked~ul *
{
	display: none;
}

ul>li>span
{
	display: block; position: relative; float: left; z-index: 3;
	margin:.25em; padding:.25em;
	background: lightblue;
}

ul>li>span:after
{
	content: ""; display: block; position: absolute;
	left:-1em; top:0; bottom:0;
	margin: auto .25em auto .25em;
	border-top: dotted black .1em;
	width: .75em; height: 0;
}

ul>li:last-child:before
{
	content: ""; display: block; position: absolute; z-index: 2;
	top:1em; left:0; bottom:-.25em;
	width:.75em; height:auto;
	background:lightblue;
}

#tree
{
	position: relative; font-family: "Georgia"; 
}

#tree:before
{
	left:.5em;
}

#tree:after
{
	display: none;
}

/*decoration*/
ul,ul>li:last-child:before
{
	background: white;
}

ul>li
{
	background: transparent;
}

ul:after
{
	background: white;
	color: black;
	border:solid gray 1px;
	border-radius: .1em;
}

ul>li>span
{	
	border-radius: .25em;
	color: black;
	background: white;
}

ul>li>input~span:before
{
	content:""; display: inline-block;
	margin:...

JavaScript

const fileData = {
	"files": ["index.html","panel.html"],
  "directory1": {
    "files": ["foo.html"],
    "subdir1": {
      "files": ["somefile.txt"]
    },
    "subdir2": {
      "files": ["somefile.php","other.php"]
    }
  },
  "directory2": {
    "subdir1": {
      "files": ["you_get_the_idea.txt"]
    }
  }
};

let html = '<ul id="tree">';

let iterations = 0;

const iterate = (fileData) => {
	Object.keys(fileData).forEach(key => {
        // It's a directory
		if (typeof fileData[key] === 'object' && fileData[key] !== null && key != 'files') {
			html += '<li><input type="checkbox"/><span>'+key+'</span><ul>';
			iterations++;
			iterate(fileData[key]);
			last = false;
		}
        // It's a file
		else
		{
			for(let i = 0; i < fileData[key].length; i++)
			{
				html += '<li><span>'+fileData[key][i]+'</span></li>';
			}

			for(let i = 0; i < iterations; i++)
			{
				html += '</ul></li>';
			}
			iterations--;
		}
	});
}

iterate(fileData);

html += '</ul>';

document.addEventListener("DOMContentLoaded", function(){
	document.getElementById('example').innerHTML = html;
});