JSFiddle - React, Tailwind, and code Playground

by Walter Rumsby

HTML

<button id="btn-0" class="button primary-button">Save</button>
<button id="btn-1" class="button secondary-button">Cancel</button>
<button id="btn-2" class="button secondary-button">Something Else</button>

CSS

body {
    padding: 6px;
    background-color: #fff;
    color: #333;
    font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
}

.button {
    border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
    border-style: solid;
    border-width: 1px;
    border-radius: 4px;
    padding: 4px 14px;
    box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.2) inset, 0px 1px 2px rgba(0, 0, 0, 0.05);
    font-size: 14px;
    font-weight: bold;
    text-shadow: 0px -1px 0px rgba(0, 0, 0, 0.25);
    text-align: center;
    white-space: nowrap;
    cursor: pointer;
    min-width: 60px;
    -webkit-transition: background-color 200ms;
    -moz-transition: background-color 200ms;
    transition: background-color 200ms;
}

.primary-button {
    background-color: rgb(0, 109, 204);
    background-image: -moz-linear-gradient(center top, rgb(0, 136, 204), rgb(0, 68, 204));
    background-image: linear-gradient(center top, rgb(0, 136, 204), rgb(0, 68, 204));
    background-repeat: repeat-x;
    color: rgb(255, 255, 255);
}

.secondary-button {
    background-color: rgb(245, 245, 245);
    background-image: -moz-linear-gradient(to bottom, rgb(255, 255, 255), rgb(230, 230, 230));
    background-image: linear-gradient(to bottom, rgb(255, 255, 255), rgb(230, 230, 230));
}

.button:hover {
    background-image: none;
}

.primary-button:hover {
    background-color: rgb(0, 68, 204);
}

.secondary-button:hover {
    background-color: rgb(230, 230, 230);
}

.in-progress .button,
.in-progress .button:hover {
    background-color: rgb(230, 230, 230);
    background-image: none;
    cursor: auto;
    color: #bbb;
}


.in-progress .active-button,
.in-progress .active-button:hover {
    background-image:...

JavaScript

/*global YUI */
YUI().use('node-base', 'node-style', 'event-base', 'event-custom', 'node-event-delegate', 'yui-later', function(Y) {
    'use strict';
    
    var body = Y.one('body');
 
    function clickHandler (e) {
        if (body.hasClass('in-progress')) {
            return;
        }
        
        var payload = { node: this };
        
        Y.fire('action:start', payload);
        
        Y.later(2000, this, function() {
            Y.fire('action:end', payload);
        });
    }
    
    Y.one('#btn-0').on('click', clickHandler);        
    Y.one('#btn-1').on('click', clickHandler);        
    Y.one('#btn-2').on('click', clickHandler);        
    
    Y.on('action:start', function(e) {
        var node = e.node,
            width = node.get('offsetWidth');
        
        node.setStyle('width', width);
        body.addClass('in-progress');
        node.addClass('active-button');
    });
    
    Y.on('action:end', function(e) {
        var node = e.node;
        
        body.removeClass('in-progress');
        node.removeClass('active-button');
    });        
    // todo: buttons should have their own thing
});