JSFiddle - React, Tailwind, and code Playground

HTML

<ul id="treeExample">
  <li><a href="javascript:void(0);">item 1</a>
    <ul>
      <li><a href="javascript:void(0);">item 1.1</a></li>
      <li><a href="javascript:void(0);">item 1.2</a></li>
      <li><a href="javascript:void(0);">item 1.3</a></li>
    </ul>
  </li>
  <li><a href="javascript:void(0);">item 2</a>
    <ul>
      <li><a href="javascript:void(0);">item 2.1</a>
        <ul>
          <li><a href="javascript:void(0);">item 2.1.1</a></li>
          <li><a href="javascript:void(0);">item 2.2.2</a></li>
        </ul>
      </li>
    </ul>
  </li>
  <li><a href="javascript:void(0);">item 3</a></li>
</ul>

CSS

body { font-size:62.5%; margin:20px; }
#treeExample { margin:2em 0 5em; width:400px; }
.tree { font-size:1.5em; }
.tree,.tree ul,.tree li { list-style:none; margin:0; padding:0; zoom: 1; }
.tree ul { margin-left:8px; }
.tree li a { color:#555; padding:.1em 7px .1em 27px; display:block; text-decoration:none; border:1px dashed #fff; background:url(../images/icon-file.gif) 5px 50% no-repeat; }
.tree li a.tree-parent { background:url(../images/icon-folder-open.gif) 5px 50% no-repeat; }
.tree li a.tree-parent-collapsed { background:url(../images/icon-folder.gif) 5px 50% no-repeat; }
.tree li a:hover,.tree li a.tree-parent:hover,.tree li a:focus,.tree li a.tree-parent:focus,.tree li a.tree-item-active { color:#000; border:1px solid#eee; background-color:#fafafa; -moz-border-radius:4px; -webkit-border-radius:4px; border-radius:4px; }
.tree li a:focus,.tree li a.tree-parent:focus,.tree li a.tree-item-active { border:1px solid #e2f3fb; background-color:#f2fafd; }
.tree ul.tree-group-collapsed { display:none; }

JavaScript

/**
 * --------------------------------------------------------------------
 * jQuery tree plugin
 * Author: Scott Jehl, [email protected]
 * Copyright (c) 2009 Filament Group 
 * licensed under MIT (filamentgroup.com/examples/mit-license.txt)
 * --------------------------------------------------------------------
 */
$.fn.tree = function(settings){
    var o = $.extend({
        expanded: ''
    },settings);

    return $(this).each(function(){
        if( !$(this).parents('.tree').length ){
        //save reference to tree UL
        var tree = $(this);

        //add the role and default state attributes
        if( !$('body').is('[role]') ){ $('body').attr('role','application'); }
        //add role and class of tree
        tree.attr({'role': 'tree'}).addClass('tree');
        //set first node's tabindex to 0
        tree.find('a:eq(0)').attr('tabindex','0');
        //set all others to -1
        tree.find('a:gt(0)').attr('tabindex','-1');
        //add group role and tree-group-collapsed class to all ul children
        tree.find('ul').attr('role','group').addClass('tree-group-collapsed');
        //add treeitem role to all li children
        tree.find('li').attr('role','treeitem');
        //find tree group parents
        tree.find('li:has(ul)')
                .attr('aria-expanded', 'false')
                .find('>a')
                .addClass('tree-parent tree-parent-collapsed');

        //expanded at load        
        tree
            .find(o.expanded)
            .attr('aria-expanded', 'true')
                .find('>a')
                .removeClass('tree-parent-collapsed')
                .next()
                .removeClass('tree-group-collapsed');


        //bind the custom events
        tree
            //expand a tree node
            .bind('expand',function(event){
                var target = $(event.target) || tree.find('a[tabindex=0]');
                target.removeClass('tree-parent-collapsed');
               ...