JSFiddle - React, Tailwind, and code Playground

by tonyleeper

HTML

<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/3.0.0/knockout-min.js"></script>
<section data-bind="onDocumentClick: hideOverflowList">
    <nav tabindex="0">
        <ul class="tabs" data-bind="tabs: tabs">
            <li data-bind="css: { active: active, fixed: fixed }">
                <div data-bind="event: { mousedown: $root.activateTab.bind($root) }"> 
                    <span data-bind="text: name"></span>
                </div>
            </li>
        </ul>
        <div class="overflow" data-bind="visible: tabsOverflowing, event: { mousedown: toggleOverflowList }, preventEventBubbling: 'click'"> 
            <i>...</i>
        </div>
        <ul class="overflow" data-bind="visible: overflowListActive, foreach: tabs">
            <li data-bind="css: { active: active, fixed: fixed }">
                <div data-bind="click: $root.activateTab.bind($root)"> <span data-bind="text: name"></span>

                </div>
            </li>
        </ul>
    </nav>
    <!-- TODO: use nighthawk to data bind this article to the dashboard view -->
    <!-- ko foreach: tabs -->
    <article class="active" data-bind="visible: active"> <span class="dashboard-name" data-bind="text: name"></span>

    </article>
    <!-- /ko -->
</section>

CSS

* {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}
html, body {
    height: 100%;
}
body {
    font-family: arial;
    background-color: #5f6570;
    padding: 15px;
}
section {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 400px;
    min-width: 500px;
}
ul.tabs {
    height: 70px;
    list-style: none;
    font-size: 0;
    flex: 1 1;
    padding-left: 10px;
    -webkit-transform: translateZ(0); /* faster repaints */
}
ul.tabs > li {
    display: inline-block;
    vertical-align: top;
    margin-right: 10px;
    margin-bottom: 10px;
    /* we don't want to see the overflowing tabs across the bottom */
}
ul.tabs > li > div {
    font-family: arial;
    font-weight: normal;
    font-size: 16px;
    color: #fff;
    text-shadow: 0 1px #000;
    display: inline-block;
    height: 60px;
    line-height: 60px;
    text-align: center;
    width: 100px;
    background-color: #454a51;
    border: 0;
    border-radius: 3px;
    padding: 0 10px;
}
ul.tabs > li.fixed > div {
    width: 150px;
}
ul.tabs > li.fixed:not(.active) > div {
    border: 1px solid black;
    box-shadow: inset 0px 0px 0px 1px rgba(255,255,255,0.4)
}
ul > li > div > span {
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
ul.tabs > li.active > div {
    position: relative;
    font-size: 18px;
    color: #454b54;
    text-shadow: 0 1px #fff;
    background-color: #fff;
    height: 70px;
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
}
ul.tabs > li.active > div:before {
    content:"";
    display: block;
    position: absolute;
    left: -6px;
    bottom: 0;
    width: 6px;
    height: 6px;
    background-color: #5f6570;
    border-bottom-right-radius: 4px;
}
ul.tabs > li.active > div:after {
    content:"";
    display: block;
    position: absolute;
    right: -4px;
    bottom: -1px;
    width: 5px;
    height: 5px;
    background-color: #fff;
}
ul.tabs > li.active {
    position:...

JavaScript

// http://css3.bradshawenterprises.com/transforms/

var utils = {
        /**
            String utility methods
        */
        string: {
            /**
                Capitalizes a string
                @param {string} value The string value to capitalize
            */
            capitalize: function (value) {
                return value.charAt(0).toUpperCase() + value.slice(1);
            },
            
            /**
                Returns true if the value is null or an empty string, otherwise returns false
                @param {string} string The string value to test
                @return {boolean} true if value is null or an empty string, otherwise false
            */
            isNullOrEmpty: function (value) {
                return value === null || value === "";
            },
            
            /**
                Returns true if the string starts with the supplied value
                @param {string} string The string to test
                @param {string} value The value to look for at the start of the string
            */
            startsWith: function (string, value) {
                return string.slice(0, string.length) === value;
            },

            /**
                Returns true if the string ends with the supplied value
                @param {string} string The string to test
                @param {string} value The value to look for at the end of the string
            */
            endsWith: function (string, value) {
                return string.slice(string.length - value.length) === value;
            }
        },

        /**
            Array utility methods
        */
        array: {
            /**
                returns the index of the first element that satisfies the predicate condition
                @param {array} the array to search
                @param {function} predicate The predicate function to test against each element
            */
            firstIndexWhere: function...