JSFiddle - React, Tailwind, and code Playground

by stevebeauge

HTML

<button class="foldall">Fold all</button>
<button class="unfoldall">Unfold all</button>
<div class="root">
    <div class="foldable d0">
        <div class="foldable-title">Title</div>
        <div class="foldable-content">Content
            <div class="foldable">
                <div class="foldable-title">Title</div>
                <div class="foldable-content">Content</div>
            </div>
            <div class="foldable d1">
                <div class="foldable-title">Title</div>
                <div class="foldable-content">Content
                    <div class="foldable">
                        <div class="foldable-title">Title</div>
                        <div class="foldable-content">Content</div>
                    </div>
                    <div class="foldable d2">
                        <div class="foldable-title">Title</div>
                        <div class="foldable-content">Content
                            <div class="foldable d3">
                                <div class="foldable-title">Title</div>
                                <div class="foldable-content">Content</div>
                            </div>
                            <div class="foldable d3">
                                <div class="foldable-title">Title</div>
                                <div class="foldable-content">Content</div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="foldable d0">
        <div class="foldable-title">Title</div>
        <div class="foldable-content">Content
            <div class="foldable">
                <div class="foldable-title">Title</div>
                <div class="foldable-content">Content</div>
            </div>
            <div class="foldable d1">
                <div class="foldable-title">Title</div>
                <div class="foldable-content">Content
                    <div...

CSS

.foldable {
    margin:2px;
    border: solid 1px silver;
}
.d0 {
    border-color:red;
}
.d1 {
    border-color:green;
}
.d2 {
    border-color:blue;
}
.d3 {
    border-color:yellow;
}
.foldable-folded > .foldable-content {
    display:none;
}
.foldable-unfolded > .foldable-content {
    display:inherit;
}

JavaScript

(function ($) {
    var methods = {
        init: function (options) {
            var opts = $.extend({}, $.fn.foldable.defaults, options);
            this.each(function () {

                var $this = $(this);
                var $title = $this.find(opts.title).first();
                var $content = $this.find(opts.content).first();

                $this.data("foldable", opts);

                $title.css("cursor", "pointer");
                if (!$this.hasClass(opts.foldedClass) && !$this.hasClass(opts.unfoldedClass)) {
                    $this.addClass(opts.unfoldedClass);
                    //$content.hide();
                }
                $title.click(function () {
                    $content.slideToggle(function () {
                        $this.toggleClass(opts.unfoldedClass).toggleClass(opts.foldedClass);
                        if (opts.complete) opts.complete(this);
                    });
                });
            });
            return this;
        },
        foldall: function () {
            var opts = this.data("foldable");
            var unfolded = this.find("." + opts.unfoldedClass).andSelf();
            return $.when(unfolded.children(opts.content).slideUp()).done(function () {
                unfolded.addClass(opts.foldedClass).removeClass(opts.unfoldedClass);
                if (opts.complete) opts.complete(this);
            });
        },
        unfoldall: function () {
            var opts = this.data("foldable");
            var folded = this.find("." + opts.foldedClass).andSelf();
            return  $.when(folded.children(opts.content).slideDown()).done(function () {
                folded.addClass(opts.unfoldedClass).removeClass(opts.foldedClass);
                if (opts.complete) opts.complete(this);
            });
        }
    };

    $.fn.foldable = function (methodOrOptions) {
        if (methods[methodOrOptions]) {
            return methods[methodOrOptions].apply(this,...