JSFiddle - React, Tailwind, and code Playground

by Amit Thakkar

HTML

<div ng-app="tree">
    <div ng-controller="TreeController as tc">
          <ul class="tree">
                <node-tree children="tc.tree"></node-tree>
          </ul>
    </div>
    <script type="text/ng-template" id="node.html">
        <li>
            <input ng-click="checkNode(node)" type="checkbox" ng-checked="node.checked">
            <span ng-click="toggleVisibility(node)">
                {{ $index + 1 }}. {{ node.name }}
            </span>
        </li>
    </script>
</div>

CSS

ul.tree {
  list-style: none;
}

ul.tree > li {
  margin: 10px;
}

ul.tree > li > span {
  cursor: pointer;
}

JavaScript

// Tree Controller
(function (ng) {
  var app = ng.module('tree', ['tree.directives']);
  app.controller("TreeController", [function () {
    var tc = this;
    buildTree();
    function buildTree() {
      tc.tree = JSON.parse('[{"name":"Vegetarian Recipes","checked":false,"children":[{"name":"Fruits","checked":false,"children":[{"name":"Dry Fruits","checked":false,"children":[{"name":"Almond","checked":false},{"name":"Apricot","checked":false},{"name":"Cashewnuts","checked":false},{"name":"Dates","checked":false},{"name":"Walnuts","checked":false},{"name":"Peanuts","checked":false},{"name":"Pistachios","checked":false}]},{"name":"Fresh Fruits","checked":false,"children":[{"name":"Apple","checked":false},{"name":"Banana","checked":false},{"name":"Orange","checked":false},{"name":"Mango","checked":false},{"name":"Grapes","checked":false}]}]},{"name":"Soup","checked":false,"children":[{"name":"Tomato Soup","checked":false},{"name":"Loaded Potato Soup","checked":false},{"name":"French Onion Soup","checked":false}]}]},{"name":"Non-vegetarian Recipes","checked":false}]');
    }
  }]);
})(angular);

// Tree directives
(function (ng) {
  var app = ng.module('tree.directives', []);
app.directive('nodeTree', function () {
  return {
    template: '<node ng-repeat="node in tree"></node>',
    replace: true,
    restrict: 'E',
    scope: {
      tree: '=children'
    }
  };
});
app.directive('node', function ($compile) {
  return {
    restrict: 'E',
    replace: true,
    templateUrl: 'node.html', // HTML for a single node.
    link: function (scope, element) {
      /*
       * Here we are checking that if current node has children then compiling/rendering children.
       * */
      if (scope.node && scope.node.children && scope.node.children.length > 0) {
        var childNode = $compile('<ul class="tree" ng-if="!node.visibility"><node-tree children="node.children"></node-tree></ul>')(scope);
        element.append(childNode);
      }
    },
    controller: ["$scope",...