Prechádzať zdrojové kódy

Notification System (AKA Sugar.Growl)

soyjavi 14 rokov pred
rodič
commit
a9c924a3f1

+ 211 - 0
src/Lungo.Notification.js

@@ -0,0 +1,211 @@
+/**
+ * Growl Notification system in CSS3
+ *
+ * @namespace LUNGO
+ * @class Notification
+ *
+ * @author Javier Jimenez Villar <javi@tapquo.com> || @soyjavi
+ */
+
+LUNGO.Notification = (function(lng, undefined) {
+
+    var _options = [];
+    var _el = null;
+    var _window = null;
+
+    var DELAY_TIME = 1;
+    var ANIMATION_MILISECONDS = 300;
+    var ATTRIBUTE = lng.Constants.ATTRIBUTE;
+    var BINDING = lng.Constants.BINDING;
+
+    var SELECTOR = {
+        BODY: 'body',
+        GROWL: '.growl',
+        MODAL: '.growl .window',
+        MODAL_HREF: '.growl .window a',
+        WINDOW_CLOSABLE: '.growl > .url .close',
+        CONFIRM_BUTTONS: '.growl .confirm a.button'
+    };
+
+    var STYLE = {
+        MODAL: 'modal',
+        VISIBLE: 'visible',
+        SHOW: 'show',
+        WORKING: 'working',
+        INPUT: 'input'
+    };
+
+    var CALLBACK_HIDE = 'LUNGO.Sugar.Growl.hide()';
+    var MARKUP_GROWL = '<div class="growl"><div class="window"></div></div>';
+
+    /**
+     *
+     */
+    var show = function(title, description, icon, animate, seconds, callback) {
+        _new_instance(true, animate);
+
+        _show(_markup(title, description, icon));
+        _hide(seconds, callback);
+    };
+
+    /**
+     *
+     */
+    var hide = function() {
+        _window.removeClass(STYLE.SHOW);
+
+        setTimeout(function() {
+            _el.style('display', 'none').removeClass('url').removeClass('confirm').removeClass('modal');
+        }, ANIMATION_MILISECONDS - 10);
+    };
+
+    /**
+     *
+     */
+    var confirm = function(options) {
+        _options = options;
+        _new_instance(false);
+
+        var markup = '<p>' + _markup(options.title, options.description, options.icon) + '</p><hr/>';
+        markup += _button_markup(options.accept, 'accept');
+        markup += _button_markup(options.cancel, 'cancel');
+
+        _window.addClass('special confirm');
+        _show(markup);
+    };
+
+    /**
+     *
+     */
+    var alert = function(title, description, icon, seconds, callback) {
+        _notify(title, description, icon, 'alert', seconds, callback);
+    };
+
+    /**
+     *
+     */
+    var success = function(title, description, icon, seconds, callback) {
+        _notify(title, description, icon, 'success', seconds, callback);
+    };
+
+    /**
+     *
+     */
+    var error = function(title, description, icon, seconds, callback) {
+        _notify(title, description, icon, 'error', seconds, callback);
+    };
+
+    /**
+     *
+     */
+    var _notify = function(title, description, icon, type, seconds, callback) {
+        _new_instance(false);
+
+        _window.addClass(type || 'info').addClass('special notify');
+        _show(_markup(title, description, icon));
+        _hide(seconds, callback);
+    };
+
+    /**
+     *
+     */
+    var html = function(markup, closable) {
+        _new_instance(true);
+
+        _window.addClass('url');
+        markup += (closable) ? '<span class="icon close"></span>' : '';
+        _show(markup);
+    };
+
+    /**
+     *
+     */
+    var loading = function() {
+        _new_instance(true);
+
+        var data_loading = lng.Attributes.Data.Loading.html;
+        var html_binded = data_loading.replace(BINDING.START + BINDING.KEY + BINDING.END, 'icon loading white');
+        _show(html_binded);
+    };
+
+
+
+
+    var _init = function() {
+        lng.dom(SELECTOR.BODY).append(MARKUP_GROWL);
+        _el = lng.dom(SELECTOR.GROWL);
+        _window = _el.children('.window');
+
+        _subscribeEvents();
+    };
+
+    var _new_instance = function(modal, animate) {
+        _el.style('display') === 'none' && _el.show();
+        modal && _el.addClass(STYLE.MODAL) || _el.removeClass(STYLE.MODAL);
+
+        _window.removeClass(STYLE.SHOW).removeClass(STYLE.WORKING);
+        _window.removeClass('url').removeClass('notify').removeClass('confirm').removeClass('special').removeClass('working');
+        _window.removeClass('error').removeClass('alert').removeClass('success');
+        if (animate) {
+            _window.addClass(STYLE.WORKING);
+        }
+    };
+
+    var _show = function(html) {
+        _window.html(html);
+        setTimeout(function() {
+            _window.addClass(STYLE.SHOW);
+        }, DELAY_TIME);
+    };
+
+    var _hide = function(seconds, callback) {
+        if (seconds !== undefined && seconds !== 0) {
+            var miliseconds = seconds * 1000;
+            setTimeout(function() {
+                hide();
+                // if (callback) callback.apply(callback);
+                if (callback) setTimeout(callback, ANIMATION_MILISECONDS);
+
+            }, miliseconds);
+        }
+    };
+
+    var _markup = function(title, description, icon) {
+        return '<span class="icon ' + icon + '"></span><strong>' + title + '</strong><small>' + description + '</small>';
+    };
+
+    var _button_markup = function(options, callback) {
+        return '<a href="#" data-callback="' + callback + '" class="button ' + options.color + '" data-icon="' + options.icon + '">' + options.label + '</a>';
+    };
+
+    var _subscribeEvents = function() {
+        _window.tap(function(event) {
+            if (_window.hasClass('notify')) {
+                hide();
+            }
+        });
+
+        lng.dom(SELECTOR.CONFIRM_BUTTONS).tap(function(event) {
+            var button = lng.dom(this);
+            var callback = _options[button.data('callback')].callback;
+            if (callback) callback.call(callback);
+            hide();
+        });
+
+        lng.dom(SELECTOR.WINDOW_CLOSABLE).tap( hide );
+    };
+
+    _init();
+
+    return {
+        show: show,
+        hide: hide,
+        error: error,
+        alert: alert,
+        success: success,
+        confirm: confirm,
+        html: html,
+        loading: loading
+    };
+
+})(LUNGO);

+ 191 - 0
src/stylesheets/css/lungo.widgets.notification.css

@@ -0,0 +1,191 @@
+.growl {
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  z-index: 3;
+  background: none;
+  font-size: 0.9em;
+  color: #ffffff;
+  display: none;
+}
+.growl .window {
+  position: relative;
+  opacity: 0;
+  -webkit-transition: all 300ms cubic-bezier(0.39, 0.575, 0.565, 1);
+  -moz-transition: all 300ms cubic-bezier(0.39, 0.575, 0.565, 1);
+  -ms-transition: all 300ms cubic-bezier(0.39, 0.575, 0.565, 1);
+  -o-transition: all 300ms cubic-bezier(0.39, 0.575, 0.565, 1);
+  transition: all 300ms cubic-bezier(0.39, 0.575, 0.565, 1);
+}
+.growl .window.show {
+  opacity: 1;
+}
+.growl .window:not(.special) {
+  left: 50%;
+  top: 50%;
+  width: 114px;
+  margin: -64px auto auto -64px;
+  padding: 8px;
+  background-color: rgba(0, 0, 0, 0.8);
+  text-align: center;
+  -webkit-border-radius: 1px;
+  -moz-border-radius: 1px;
+  border-radius: 1px;
+  -webkit-background-clip: padding-box;
+  -moz-background-clip: padding;
+  background-clip: padding-box;
+  -webkit-transform: scale(0.85);
+  -moz-transform: scale(0.85);
+  -ms-transform: scale(0.85);
+  -o-transform: scale(0.85);
+  transform: scale(0.85);
+}
+.growl .window:not(.special).show {
+  -webkit-transform: translate3d(0, 0%, 0);
+  -moz-transform: translate3d(0, 0%, 0);
+  -ms-transform: translate3d(0, 0%, 0);
+  -o-transform: translate3d(0, 0%, 0);
+  transform: translate3d(0, 0%, 0);
+}
+.growl .window:not(.special) .icon {
+  display: block;
+  font-size: 5.0em;
+}
+.growl .window:not(.special) .icon.loading {
+  margin-bottom: 24px;
+}
+.growl .window:not(.special) strong {
+  display: block;
+  margin-bottom: 4px;
+}
+.growl .window.confirm,
+.growl .window.notify {
+  -webkit-transform: translate3d(0, -150%, 0);
+  -moz-transform: translate3d(0, -150%, 0);
+  -ms-transform: translate3d(0, -150%, 0);
+  -o-transform: translate3d(0, -150%, 0);
+  transform: translate3d(0, -150%, 0);
+}
+.growl .window.confirm.show,
+.growl .window.notify.show {
+  -webkit-transform: translate3d(0, 0%, 0);
+  -moz-transform: translate3d(0, 0%, 0);
+  -ms-transform: translate3d(0, 0%, 0);
+  -o-transform: translate3d(0, 0%, 0);
+  transform: translate3d(0, 0%, 0);
+}
+.growl .window.confirm .icon,
+.growl .window.notify .icon {
+  float: left;
+  font-size: 2.5em;
+  margin-right: 8px;
+}
+.growl .window.confirm strong,
+.growl .window.notify strong {
+  line-height: 1.5em;
+}
+.growl .window.confirm {
+  opacity: 1;
+  padding: 10px 12px;
+  top: 0;
+  top: 43px;
+  background: #333;
+}
+.growl .window.confirm hr {
+  margin: 10px 0;
+  height: 1px;
+  background: rgba(0, 0, 0, 0.75);
+  -webkit-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);
+  -moz-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);
+  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);
+}
+.growl .window.confirm .button {
+  width: 42%;
+  font-size: 15px;
+  line-height: 40px;
+}
+.growl .window.confirm .button:last-child {
+  float: right;
+}
+.growl .window.notify {
+  padding: 3px 0px 7px 7px;
+  top: 0;
+  color: #555555;
+  text-shadow: 0 1px 0px #ffffff;
+  background-image: -webkit-linear-gradient(top , #e8e8e8 0% , #f6f6f6 50%);
+  background-image: -moz-linear-gradient(top , #e8e8e8 0% , #f6f6f6 50%);
+  background-image: -ms-linear-gradient(top , #e8e8e8 0% , #f6f6f6 50%);
+  background-image: -o-linear-gradient(top , #e8e8e8 0% , #f6f6f6 50%);
+  background-image: linear-gradient(top , #e8e8e8 0% , #f6f6f6 50%);
+  -webkit-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.5);
+  -moz-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.5);
+  box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.5);
+}
+.growl .window.notify.error,
+.growl .window.notify.alert,
+.growl .window.notify.success {
+  color: #ffffff;
+  text-shadow: 0 1px 0px rgba(0, 0, 0, 0.1);
+}
+.growl .window.notify.error {
+  background-image: -webkit-linear-gradient(top , #ff4444 0% , #cc0000 50%);
+  background-image: -moz-linear-gradient(top , #ff4444 0% , #cc0000 50%);
+  background-image: -ms-linear-gradient(top , #ff4444 0% , #cc0000 50%);
+  background-image: -o-linear-gradient(top , #ff4444 0% , #cc0000 50%);
+  background-image: linear-gradient(top , #ff4444 0% , #cc0000 50%);
+}
+.growl .window.notify.alert {
+  background-image: -webkit-linear-gradient(top , #ffbb33 0% , #ff8800 50%);
+  background-image: -moz-linear-gradient(top , #ffbb33 0% , #ff8800 50%);
+  background-image: -ms-linear-gradient(top , #ffbb33 0% , #ff8800 50%);
+  background-image: -o-linear-gradient(top , #ffbb33 0% , #ff8800 50%);
+  background-image: linear-gradient(top , #ffbb33 0% , #ff8800 50%);
+}
+.growl .window.notify.success {
+  background-image: -webkit-linear-gradient(top , #99cc00 0% , #669900 50%);
+  background-image: -moz-linear-gradient(top , #99cc00 0% , #669900 50%);
+  background-image: -ms-linear-gradient(top , #99cc00 0% , #669900 50%);
+  background-image: -o-linear-gradient(top , #99cc00 0% , #669900 50%);
+  background-image: linear-gradient(top , #99cc00 0% , #669900 50%);
+}
+.growl .window.url {
+  left: 0%;
+  top: 00%;
+  width: 280px;
+  height: auto;
+  margin: 64px auto 0px;
+  padding: 0px;
+  -webkit-transform: translate3d(0, 75%, 0);
+  -moz-transform: translate3d(0, 75%, 0);
+  -ms-transform: translate3d(0, 75%, 0);
+  -o-transform: translate3d(0, 75%, 0);
+  transform: translate3d(0, 75%, 0);
+}
+.growl .window.url .close {
+  position: absolute;
+  top: -14px;
+  right: -14px;
+  font-size: 16px;
+  line-height: 24px;
+  font-weight: normal;
+  width: 24px;
+  height: 24px;
+  background: #000;
+  border-radius: 14px;
+  border: solid 2px #fff;
+  box-shadow: 0 0 4px black;
+}
+.growl .window.working span {
+  -webkit-animation: growl-working 1s infinite;
+}
+@-webkit-keyframes growl-working {
+  0% {
+    opacity: 1;
+  }
+  50% {
+    opacity: 0;
+  }
+  100% {
+    opacity: 1;
+  }
+}

+ 168 - 0
src/stylesheets/lungo.widgets.notification.less

@@ -0,0 +1,168 @@
+@import "mixins.less";
+
+@growl_opacity: rgba(0,0,0,0.5);
+@defaultTrasition : @easeOutSine;
+@keyframe: 300ms;
+
+@modal_opacity: rgba(0,0,0,0.8);
+@modal_size: 114px;
+    @modal_size_middle: 64px;
+    @modal_border_radius: 1px;
+
+@notify_font_color: #555;
+@notify_font_shadow: 0 1px 0px #fff;
+
+@font_color: #fff;
+
+.growl {
+    position: absolute;
+    width: 100%;
+    height: 100%;
+    z-index: 3;
+    background: none;
+    font-size: 0.9em;
+    color: @font_color;
+    display: none;
+
+    &.modal {
+        // background-color: @growl_opacity;
+    }
+
+    & .window {
+        position: relative;
+        opacity: 0;
+
+        //transition-property: -webkit-transform, transform, opacity;
+        .transition(all @keyframe @defaultTrasition);
+
+        &.show {
+            opacity: 1;
+            // .transition(all @keyframe @defaultTrasition);
+        }
+
+        &:not(.special) {
+            left: 50%;
+            top: 50%;
+            width: @modal_size;
+            margin: -@modal_size_middle auto auto -@modal_size_middle;
+            padding: 8px;
+            background-color: @modal_opacity;
+            text-align: center;
+
+            .border-radius(@modal_border_radius);
+            // .transform(translate3d(0, 100%, 0));
+
+
+            .transform(scale(0.85));
+
+            &.show {
+                .transform(translate3d(0, 0%, 0));
+            }
+
+            & .icon {
+                display: block;
+                font-size: 5.0em;
+                &.loading {
+                    margin-bottom: 24px;
+                }
+            }
+
+            & strong {
+                display: block;
+                margin-bottom: 4px;
+            }
+        }
+
+        &.confirm, &.notify {
+            .transform(translate3d(0, -150%, 0));
+            &.show { .transform(translate3d(0, 0%, 0)); }
+
+            & .icon {
+                float: left;
+                font-size: 2.5em;
+                margin-right: 8px;
+            }
+
+            & strong {
+                line-height: 1.5em;
+            }
+        }
+
+        &.confirm {
+            opacity: 1;
+            padding: 10px 12px;
+            top: 0;
+            top: 43px;
+            background: #333;
+
+            & hr {
+                margin: 10px 0;
+                height: 1px;
+                background: rgba(0,0,0,0.75);
+                .box-shadow(0 1px 0 rgba(255,255,255,0.25));
+            }
+
+            & .button {
+                width: 42%;
+                font-size: 15px;
+                line-height: 40px;
+               &:last-child {float: right;}
+            }
+        }
+
+        &.notify {
+            padding: 3px 0px 7px 7px;
+            top:  0;
+            color: @notify_font_color;
+            text-shadow: @notify_font_shadow;
+
+            .linear-gradient(top, ~','#e8e8e8 0%, ~','#f6f6f6 50%);
+
+            .box-shadow(0px 1px 3px rgba(0,0,0,0.5));
+
+            &.error, &.alert, &.success {
+                color: @font_color;
+                text-shadow: 0 1px 0px rgba(0,0,0,0.1);
+            }
+            &.error { .linear-gradient(top, ~','#FF4444 0%, ~','#CC0000 50%); }
+            &.alert { .linear-gradient(top, ~','#FFBB33 0%, ~','#FF8800 50%); }
+            &.success { .linear-gradient(top, ~','#99CC00 0%, ~','#669900 50%); }
+        }
+
+        &.url {
+            left: 0%;
+            top: 00%;
+            width: 280px;
+            height: auto;
+            margin: 64px auto 0px;
+            padding: 0px;
+            .transform(translate3d(0, 75%, 0));
+
+            & .close {
+                position: absolute;
+                top: -14px;
+                right: -14px;
+
+                font-size: 16px;
+                line-height: 24px;
+                font-weight: normal;
+                width: 24px;
+                height: 24px;
+                background: #000;
+                border-radius: 14px;
+                border: solid 2px #fff;
+                box-shadow: 0 0 4px black;
+            }
+        }
+    }
+}
+
+.growl .window.working span{
+    -webkit-animation: growl-working 1s infinite;
+}
+
+@-webkit-keyframes growl-working {
+    0% {opacity: 1;}
+    50% {opacity: 0;}
+    100% {opacity: 1;}
+}