JSFiddle - React, Tailwind, and code Playground

by fractaloop

HTML

<script src="https://github.com/downloads/wycats/handlebars.js/handlebars-1.0.0.beta.6.js"></script>
<script src="https://github.com/downloads/emberjs/ember.js/ember-latest.js"></script>
<script src="https://github.com/downloads/emberjs/data/ember-data-latest.js"></script>
<script type="text/x-handlebars" data-template-name="flow/templates/application">
    <h1>Flow: {{flow.name}} ({{flow.id}})</h1>
    {{outlet graph}}
    {{outlet inspector}}
</script>
<script type="text/x-handlebars" data-template-name="flow/templates/graph">
    <ul>
        {{#each content.stages}}
            {{view App.StageView}}
        {{/each}}
    </ul>
</script>
<script type="text/x-handlebars" data-template-name="flow/templates/stage">
    <li><a {{action goInspect this href="true"}}>{{name}} ({{id}})</a></li>
</script>
<script type="text/x-handlebars" data-template-name="flow/templates/inspector">
    <h3>Inspector</h3>
    {{view App.IconView contextBinding="selectedStage.name"}}
    {{selectedStage.name}} ({{selectedStage.id}})
</script>
<div id="flow"></div>

SCSS

.inspector { background-color: #ddd; }
.graph { border: 2px solid grey; }

.stage-icon {
    width: 32px;
    height: 32px;
    background-color: rgba(0,0,0,0.1);
    
    &.stage-icon-reader {
            background-color: green;
}
&.stage-icon-writer {
    background-color: red;
}
}

JavaScript

Ember.ENV.VIEW_PRESERVES_CONTEXT = true;

App = Em.Application.create({
    rootElement: '#flow'
});

App.Stage = DS.Model.extend({
    primaryKey: '_id',
    flow: DS.belongsTo('App.Flow'),
    name: DS.attr('string')
});
App.Flow = DS.Model.extend({
    primaryKey: '_id',
    name: DS.attr('string'),
    stages: DS.hasMany('App.Stage', {
        embedded: true
    })
});
App.Flow.reopenClass({
    url: 'gh/gist/response.json'
});

App.store = DS.Store.create({
    revision: 4,
    adapter: DS.RESTAdapter.create({
        plurals: {'gh/gist/response.json': 'gh/gist/response.json'},
        mappings: { flow: 'App.Flow' }
    })
})

App.ApplicationController = Em.Controller.extend();
App.ApplicationView = Em.View.extend({
    templateName: 'flow/templates/application'
});

App.GraphController = Em.ObjectController.extend({
    selectedStage: null
});
App.GraphView = Em.View.extend({
    classNames: ['graph'],
    templateName: 'flow/templates/graph'
});

App.StageController = Em.ObjectController.extend()
App.StageView = Em.View.extend({
    templateName: 'flow/templates/stage'
});

App.IconController = Em.ObjectController.extend();
App.IconView = Em.View.extend({
    classNames: ['stage-icon'],
    classNameBindings: ['isReader', 'isWriter'],

    isReader: function() {
        console.log("context:", this.get('context'));
        if (this.get('context') == 'Reader') return "stage-icon-reader";
    }.property('context'),
    isWriter: function() {
        if (this.get('context') == 'Writer') return "stage-icon-writer";
    }.property('context')
});

App.InspectorController = Em.Controller.extend({});
App.InspectorView = Em.View.extend({
    classNames: ['inspector'],
    templateName: 'flow/templates/inspector'
});
App.Router = Em.Router.extend({
    enableLogging: true,
    location: 'hash',

    root: Em.Route.create({
        index: Em.Route.extend({
            route: '/',
            goShow: Em.Route.transitionTo('show.index')
        }),

        show:...