JSFiddle - React, Tailwind, and code Playground

by maxtern

HTML

<script src="http://angularlight.org/bin/alight.last.min.js"></script>
<script src="http://angularlight.org/bin/animate.min.js"></script>
<main al-app="mainCtrl">
    <div style="width:600px" id="comments">
        <button class="add_comment" al-click="append()">Добавить комментарий</button>
        
        <div al-comment="base"></div>
        
    </div>
</main>

<script id="comments_template" type="html/text">
<article class="wave comment" al-repeat="comment in base.list">
    <header>
        <img class="avatar" al-src="{{comment.user.image}}">
        <span class="author">{{comment.user.username}}</span>
            <time>{{comment.when | date:yyyy/mm/dd HH:MM}}</time>
        <button class="delete" al-click="remove(comment)">Удалить</button>
    </header>

    <form al-if="comment.is_new" al-submit="save(comment)">
        <textarea placeholder="Ваш комментарий" al-value="comment.text"></textarea>
        <button type="submit">Комментировать</button>
        <button al-click="remove(comment)">Отменить</button>
    </form>

    <p>{{comment.text}}</p>
    <footer>
        <button al-ifnot="comment.is_new" al-click="append(comment)">Ответить</button>            
    </footer>
    <div al-comment="comment"></div>
</article>
</script>

CSS

.fotorama__arr:focus:after,.fotorama__fullscreen-icon:focus:after,.fotorama__html,.fotorama__img,.fotorama__nav__frame:focus .fotorama__dot:after,.fotorama__nav__frame:focus .fotorama__thumb:after,.fotorama__stage__frame,.fotorama__stage__shaft,.fotorama__video iframe{position:absolute;width:100%;height:100%;top:0;right:0;left:0;bottom:0}.fotorama--fullscreen,.fotorama__img{max-width:99999px!important;max-height:99999px!important;min-width:0!important;min-height:0!important;border-radius:0!important;box-shadow:none!important;padding:0!important}.fotorama__wrap .fotorama__grab{cursor:-webkit-grab;cursor:-o-grab;cursor:-ms-grab;cursor:grab}.fotorama__grabbing *{cursor:-webkit-grabbing;cursor:-o-grabbing;cursor:-ms-grabbing;cursor:grabbing}.fotorama__spinner{position:absolute!important;top:50%!important;left:50%!important}.fotorama__wrap--css3 .fotorama__arr,.fotorama__wrap--css3 .fotorama__fullscreen-icon,.fotorama__wrap--css3 .fotorama__nav__shaft,.fotorama__wrap--css3 .fotorama__stage__shaft,.fotorama__wrap--css3 .fotorama__thumb-border,.fotorama__wrap--css3 .fotorama__video-play{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.fotorama__caption,.fotorama__nav:after,.fotorama__nav:before,.fotorama__stage:after,.fotorama__stage:before,.fotorama__wrap--css3 .fotorama__html,.fotorama__wrap--css3 .fotorama__nav,.fotorama__wrap--css3 .fotorama__spinner,.fotorama__wrap--css3 .fotorama__stage,.fotorama__wrap--css3 .fotorama__stage .fotorama__img,.fotorama__wrap--css3 .fotorama__stage__frame{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.fotorama__arr:focus,.fotorama__fullscreen-icon:focus,.fotorama__nav__frame{outline:0}.fotorama__arr:focus:after,.fotorama__fullscreen-icon:focus:after,.fotorama__nav__frame:focus .fotorama__dot:after,.fotorama__nav__frame:focus .fotorama__thumb:after{content:'';border-radius:inherit;background-color:rgba(0,175,234,.5)}.fotorama__wrap--video .fotorama__stage,.fotorama__wrap--video...

JavaScript

var current_user =  {
    username: 'setdvd',
	image: 'https://lh3.googleusercontent.com/-sc13-gev9ns/AAAAAAAAAAI/AAAAAAAAAAA/JoBI29emM5c/s48-c/photo.jpg'
};

alight.controllers.mainCtrl = function(scope) {
    window.app = scope;
    scope.base = {
        list: [{
            text: 'Hello',
            user: current_user,
            when: new Date(2014,9,2),
            list: []
        }]
    };
    scope.append = function() {
        scope.base.list.push({                
            is_new: true,
            user: current_user,
            list: []
        })
    };
};

alight.directives.al.comment = {
    scope: true,
    template: f$.find(document.body, '#comments_template')[0].innerHTML,
    link: function(el, name, scope) {
        scope.base = scope.$eval(name);
        
        scope.append = function(comment) {
            comment.list.push({                
                is_new: true,
                user: current_user,
                list: []
            })
        };
        
        scope.remove = function(comment) {
            var lst = scope.base.list;
            lst.splice(lst.indexOf(comment), 1)
        };
        scope.save = function(comment) {
            comment.is_new = false;
            comment.when = new Date();
        };
        
    }
};