JSFiddle - React, Tailwind, and code Playground

by _nderscore

HTML

<div id="test"></div>

CSS

* { font-family: Arial; font-size: 12px; }
.mm_closed > .mm_treeblock {
    display: none;
}
.mm_open > .mm_treelabel, .mm_closed > .mm_treelabel { 
    cursor: pointer; 
}
.mm_open > .mm_treelabel:before {
    content: ' – ';
}
.mm_closed > .mm_treelabel:before {
    content: ' + ';
}
.mm_closed > .mm_treelabel:before, .mm_open > .mm_treelabel:before {
    color: #555;
    background: #fff;
    border: 1px solid #999;
    border-radius: 12px;
    width: 15px;
    height: 15px;
    line-height: 15px;
    display: inline-block;
    text-align: center;
    margin-right: 5px;
}
.mm_treeblock {
    padding: 5px;
    border-radius: 5px;
    border: 1px solid #ddd;
    background: #eee;
}
.mm_alt {
    background: #ccc;
}
.mm_treeblock .mm_treeblock {
    margin-left: 25px;
    margin-bottom: 5px;
}
.mm_treelabel {
    font-weight: bold;
}
.mm_childless > .mm_treelabel:after {
    content: ' : ';
}
.mm_treevalue {
    padding: 3px;
    border-radius: 5px;
    border: 1px solid #dd0;
    background: #ff0;
}

JavaScript

var treeMaker = function(obj, name, alt){
    var $el = $('<div class="mm_treeblock"><span class="mm_treelabel">' + name + '</span></div>');
    if(alt) $el.addClass('mm_alt');
    if(obj.splice){
        $el.addClass('mm_closed');
        if(!obj.length)
            $el.append('<div class="mm_treeblock">Empty!</div>');
        else
            for(var i = 0; i < obj.length; i++)
                $el.append( treeMaker(obj[i], i, !alt) );
    } else if(typeof obj == 'object'){
        $el.addClass('mm_closed');
        for(var i in obj)
            $el.append( treeMaker(obj[i], i, !alt) );
    } else {
        $el.addClass('mm_childless');
        $el.append('<span class="mm_treevalue">' + obj +'</span>');
    }
    return $el;
};

var testObj = {
    foo:'bar',
    bool:true,
    list:[1,2,3,'a'],
    child:{
        zzz:'xyz',
        yyy:'abc',
        xxx:[
            {a:1},
            {b:2},
            {c:3, d: [1,2,3] }
        ]
    },
    sibling:{
        a:'asdf',
        anotherArray:[
            { b:1, c:2 },
            2,
            3
        ]
    },
    emptyArray:[]
};

$('#test').append( treeMaker(testObj, 'root') );

$(document).on('click', '.mm_open > .mm_treelabel, .mm_closed > .mm_treelabel', function(e){
    $(this).parent().toggleClass('mm_open').toggleClass('mm_closed');
    e.stopPropogation();
});