JSFiddle - React, Tailwind, and code Playground

by Graham Dixon

HTML

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dottie.min.js"></script>
<script src="https://leeoniya.github.io/domvm/dist/micro/domvm.micro.min.js"></script>

CSS

/*!
 * domvm Collapsible List Plugin
 *
 * Based on the Collapsible library by Stephen Morley
 * http://code.stephenmorley.org/javascript/collapsible-lists/
 *
 */
body {
  margin: 0px;
}

.collapsibleList li {
    list-style-image: url('http://localhost:8000/assets/images/button.png');
    list-style-position: inside;
    cursor: auto;
}
.collapsibleList li > a > span > a {
    min-height: 24px;
    display: inline-block;
}
li.collapsibleListOpen {
    list-style-image: url('http://localhost:8000/assets/images/button-open.png');
    cursor: pointer;
}
li.collapsibleListClosed {
    list-style-image: url('http://localhost:8000/assets/images/button-closed.png');
    cursor: pointer;
}
li.collapsibleListClosed.forcedClosed {
    list-style-image: url('http://localhost:8000/assets/images/button-closed.png')!important;
    background: none!important;
    padding-left: 0px;
    margin-left:0px;
}
li.collapsibleListOpen.forcedOpen {
    list-style-image: url('http://localhost:8000/assets/images/button-open.png')!important;
    background: url('http://localhost:8000/assets/images/list-item-root.png') no-repeat top left!important;
    padding-left: 0px;
    margin-left:0px;
}
li.collapsibleListClosed ul {
    display: none;
}
.collapsibleList ul {
    padding-left: 20px;
}
.treeView {
    line-height: 1.5em;
}
.treeView ul {
    margin: 0 0 0 -20px;
    padding: 0 0 0 20px;
}
.treeView ul ul {
    background: url('http://localhost:8000/assets/images/list-item-contents.png') repeat-y left;
}
.treeView li.lastChild> ul {
    background-image: none;
}
.treeView li {
    margin: 0;
    padding: 0;
    background: no-repeat top left;
    list-style-position: inside;
}
.treeView li li {
    background-image: url('http://localhost:8000/assets/images/list-item.png');
    padding-left: 20px;
}
.treeView li.lastChild {
    background-image: url('http://localhost:8000/assets/images/list-item-last.png');
}
.treeView li.collapsibleListOpen {
    background-image:...

JavaScript

// create a uuid to uniquely identify data
var uuid = function() {

    var lut = Array(256).fill().map(function(_, i) {
        return (i < 16 ? '0' : '') + i.toString(16);
    });

    var formatUuid = function formatUuid(_ref) {
        var d0 = _ref.d0;
        var d1 = _ref.d1;
        var d2 = _ref.d2;
        var d3 = _ref.d3;
        return lut[d0 & 0xff] + lut[d0 >> 8 & 0xff] + lut[d0 >> 16 & 0xff] + lut[d0 >> 24 & 0xff] + '-' + lut[d1 & 0xff] + lut[d1 >> 8 & 0xff] + '-' + lut[d1 >> 16 & 0x0f | 0x40] + lut[d1 >> 24 & 0xff] + '-' + lut[d2 & 0x3f | 0x80] + lut[d2 >> 8 & 0xff] + '-' + lut[d2 >> 16 & 0xff] + lut[d2 >> 24 & 0xff] + lut[d3 & 0xff] + lut[d3 >> 8 & 0xff] + lut[d3 >> 16 & 0xff] + lut[d3 >> 24 & 0xff];
    };

    var getRandomValuesFunc = window.crypto && window.crypto.getRandomValues ? function() {
        var dvals = new Uint32Array(4);
        window.crypto.getRandomValues(dvals);
        return {
            d0: dvals[0],
            d1: dvals[1],
            d2: dvals[2],
            d3: dvals[3]
        };
    } : function() {
        return {
            d0: Math.random() * 0x100000000 >>> 0,
            d1: Math.random() * 0x100000000 >>> 0,
            d2: Math.random() * 0x100000000 >>> 0,
            d3: Math.random() * 0x100000000 >>> 0
        };
    };

    return formatUuid(getRandomValuesFunc());
}

// global collapsibleList class (call for instance)
var collapsibleList = function() {
    // set reference to instance state
    var list = this,
        // require domvm methods into the scope
        el = domvm.defineElement,
        vw = domvm.defineView,
        // object to fill with vm nodes used against the pub/sub
        roots = [],
        // all data objects recorded by scope
        allItems = [],
        // set an item to the topVms obj by scope
        allTopVms = [];

    // object of default properties
    this.defaults = {
        // dom element where we are going to mount the domvm element
        'target':...