JSFiddle - React, Tailwind, and code Playground

by rich_harris

HTML

<script src="http://cdn.ractivejs.org/edge/ractive.js"></script>
<main></main>

<script id='template' type='text/ractive'>
    <div id="town-hall-content" class="tab-1">
        <div class="tabs-content">
            <div id="tab-content-1" class="tab-content">
                {{#config.buildings:building}}
                <div class="building category_{{category}}" id="building-item-{{building}}">
                    <div class="image-container">
                        <div class="thumbnail" style="background: transparent url({{staticUrl}}/game_images/town/buildings/{{building}}/{{building}}-1-thumbnail.png) no-repeat center center;"></div>
                        <div class="cover"></div>
                        <div class="undercover"></div><div class="level">{{alreadyQueued(building)+village.buildings[building].level}}</div>
                    </div>
                    <div class="big_title">{{lang('buildings',building)}}</div>
                    <p>{{lang('buildings',building+'_description')}}</p>
                    <div on-click="upgradeBuilding:{{building}}" class="upgrade-button" tooltip="{{lang('general','upgrade_building')}}"></div>
                    <div on-click="downgradeBuilding:{{building}}" class="downgrade-button disabled" tooltip="{{lang('general','downgrade_building')}}"></div>
                    <div class="resources">
                        <resource name='wood'/>
                        <resource name='clay'/>
                        <resource name='iron'/>
                        <resource name='workers'/>
                        <resource name='time'/>                        
                    </div>
                    <div class="hr"></div>
                </div>
                {{/config.buildings:building}}
            </div>
        </div>
    </div>
</script>

<script id='resource' type='text/ractive'>
    <div class="resource">
        <img class="thumbnail" src="{{src}}"/>
        <label...

CSS

#town-hall-content div.building {
    height: 200px;
    text-align: left;
    position: relative;
    clear: both;
    font-size: 12px;
    padding: 5px 0 0 0;
    margin: 0;
    color: #66400f;
}
#town-hall-content .hr {
    background: transparent url(http://static.tribul.net/game_images/layout/hr.png) no-repeat center center;
    height: 1px;
    padding: 0;
    position: absolute;
    left: 0;
    bottom: 0px;
    width: 100%;
}
#town-hall-content div.building .image-container {
    padding: 0;
    position: absolute;
    top: 20px;
    left: 0px;
    width: 150px;
}
#town-hall-content div.building .image-container>.cover {
    position: absolute;
    left: 0;
    top: 0;
    background: transparent url(http://static.tribul.net/game_images/layout/building-mask.png) no-repeat 0 0;
    width: 150px;
    height: 150px;
    z-index: 4;
    box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.6);
}
#town-hall-content div.building .image-container>.blocking-text {
    position: absolute;
    left: 0;
    top: 0;
    width: 150px;
    height: 150px;
    z-index: 3;
}
#town-hall-content div.building .image-container>.blocking-text>.message {
    padding: 0 10px;
    position: relative;
    display: table-cell;
    text-align: center;
    width: 150px;
    height: 150px;
    vertical-align: middle;
    z-index: 2;
    line-height: 16px;
    color: #37302a;
    font-size: 11px;
}
#town-hall-content div.building .image-container>.blocking-text>.undercover {
    position: absolute;
    background: rgba(255, 223, 171, 0.7);
    left: 0;
    top: 0;
    width: 150px;
    height: 150px;
    z-index: 1;
}
#town-hall-content div.building .image-container>.undercover {
    position: absolute;
    left: 0;
    top: 0;
    background: transparent url(http://static.tribul.net/game_images/layout/grass.jpg) repeat;
    width: 150px;
    height: 150px;
    z-index: 1;
}
#town-hall-content div.building .image-container>.thumbnail {
    position: absolute;
    left: 0;
    top: 0;
    padding:...

JavaScript

var Resource = Ractive.extend({
    template: '#resource',
    computed: {
        // you can use a string shorthand...
        src: '${staticUrl} + "/game_images/resources/" + ${name} + "B.png"',

        // ...or create a function
        label: function () {
            var buildingId, building, buildings, queue, queued, level, name;
            
            buildingId = this.get( 'building' );
            buildings = this.get( 'village.buildings' );
            building = this.get( 'config.buildings' )[ buildingId ];
            
            queue = this.get( 'village.buildingsQueue' );
            queued = queue.filter( function ( item ) {
                return item === buildingId;
            }).length;
            
            level = buildings[ buildingId ].level + 1 + queued;
            
            name = this.get( 'name' );
            return building[ level ][ name ];
        }
    }
});

// 'register' the component
Ractive.components.resource = Resource;

var worldData = {
    staticUrl: "http://static.tribul.net",
    buildings: {
        1: {
            needed: "none",
            max_level: 4,
            category: 1,
            1: {
                wood: 1,
                clay: 1,
                iron: 1,
                people: 1,
                time: 1,
                improve: 1,
                experience: 1,
                points: 1
            },
            2: {
                wood: 2,
                clay: 2,
                iron: 2,
                people: 2,
                time: 2,
                improve: 2,
                experience: 2,
                points: 2
            },
            3: {
                wood: 3,
                clay: 3,
                iron: 3,
                people: 3,
                time: 3,
                improve: 3,
                experience: 3,
                points: 3
            },
            4: {
                wood: 4,
                clay: 4,
                iron: 4,
               ...