JSFiddle - React, Tailwind, and code Playground

by Minko Gechev

HTML

<div data-ng-app="ui" id="asd">
    <ui-alertbox title="Important" width="140px" height="140px">
        This is an important notification!
        <div style="margin-top: 30px; text-align: center;">
            <button ui-alertbox-close>Close</button>
        </div>
    </ui-alertbox>
    <span id="test"></span>
</div>

CSS

.ui-alertbox {
    background-color: #ccc;
    border-radius: 3px;
    overflow: hidden;
    box-shadow: 0px 0px 20px #000;
}
.ui-alertbox-header {
    background-color: #222;
    color: #fff;
    padding: 7px;
    border-top-left-radius: 3px;
    border-top-right-radius: 3px;
    cursor: move;
}
.ui-alertbox-content {
    background-color: #fff;
    border-bottom-left-radius: 3px;
    border-bottom-right-radius: 3px;   
    padding: 5px;
    font-family: Verdana;
    font-size: 12px;
}
html, body {
    width: 100%;
    height: 100%;
    background-color: #fff;
}

JavaScript

angular.module('ui', []).
directive('uiAlertbox', function () {
    return {
        restrict: 'EA',
        template: '<div class="ui-alertbox">\
        <div class="ui-alertbox-header"></div>\
        <div class="ui-alertbox-content" ng-transclude></div>\
        </div>',
        transclude: true,
        replace: true,
        link: function (scope, dialog, attrs) {
            var header = dialog.children()[0],
                content = dialog.children()[1],
                mouseDown = false,
                lastMouse = {};
            header.innerText = attrs.title;
            dialog.css({
                position: 'absolute',
                width: attrs.width,
                height: attrs.height
            });
            content.style.height = (dialog[0].offsetHeight - header.offsetHeight) + 'px';
            header.addEventListener('mousedown', function () {
                mouseDown = true;
            }, false);
            document.addEventListener('mouseup', function () {
                mouseDown = false;
            }, false);
            document.addEventListener('mousemove', function (e) {
                if (mouseDown) {
                    var dialogX = parseInt(dialog[0].style.left, 10) || 0,
                        dialogY = parseInt(dialog[0].style.top, 10) || 0;
                    document.getElementById('test').innerText = dialogX + ', ' + dialogY;
                    dialog.css({
                        top: dialogY + (e.pageY - lastMouse.y) + 'px',
                        left: dialogX + (e.pageX - lastMouse.x) + 'px'
                    });
                }
                lastMouse.x = e.pageX;
                lastMouse.y = e.pageY;
            }, true);
        }
    };
}).directive('uiAlertboxClose', function () {
    return {
        link: function (scope, elem) {
            var parentNode = elem.parent();
            while (parentNode && !(/ui-alertbox\s*$/).test(parentNode[0].className)) {
                parentNode =...