Browse Source

added Toasts.js & enhanced toasts style
- created Toasts.js
- updated build/js/scss/plugins/_toastr.scss
- added toast-variant mixin in build/scss/_mixinis.scss
- created build/scss/_toasts.scss
- added zindex-toasts variable in build/scss/_variables.scss
- updated build/scss/AdminLTE.scss & build/scss/AdminLTE-raw.scss
- updated pages/UI/modals.html
- created docs/javascript/toasts.md
- updated docs/_config.yml

REJack 5 years ago
parent
commit
ec008a693f

+ 3 - 1
build/js/AdminLTE.js

@@ -7,6 +7,7 @@ import TodoList from './TodoList'
 import CardWidget from './CardWidget'
 import CardRefresh from './CardRefresh'
 import Dropdown from './Dropdown'
+import Toasts from './Toasts'
 
 export {
   ControlSidebar,
@@ -17,5 +18,6 @@ export {
   TodoList,
   CardWidget,
   CardRefresh,
-  Dropdown
+  Dropdown,
+  Toasts
 }

+ 229 - 0
build/js/Toasts.js

@@ -0,0 +1,229 @@
+/**
+ * --------------------------------------------
+ * AdminLTE Toasts.js
+ * License MIT
+ * --------------------------------------------
+ */
+
+const Toasts = (($) => {
+  /**
+   * Constants
+   * ====================================================
+   */
+
+  const NAME               = 'Toasts'
+  const DATA_KEY           = 'lte.toasts'
+  const EVENT_KEY          = `.${DATA_KEY}`
+  const JQUERY_NO_CONFLICT = $.fn[NAME]
+
+  const Event = {
+    INIT: `init${EVENT_KEY}`,
+    CREATED: `created${EVENT_KEY}`,
+    REMOVED: `removed${EVENT_KEY}`,
+  }
+
+  const Selector = {
+    BODY: 'toast-body',
+    CONTAINER_TOP_RIGHT: '#toastsContainerTopRight',
+    CONTAINER_TOP_LEFT: '#toastsContainerTopLeft',
+    CONTAINER_BOTTOM_RIGHT: '#toastsContainerBottomRight',
+    CONTAINER_BOTTOM_LEFT: '#toastsContainerBottomLeft',
+  }
+
+  const ClassName = {
+    TOP_RIGHT: 'toasts-top-right',
+    TOP_LEFT: 'toasts-top-left',
+    BOTTOM_RIGHT: 'toasts-bottom-right',
+    BOTTOM_LEFT: 'toasts-bottom-left',
+    FADE: 'fade',
+  }
+
+  const Position = {
+    TOP_RIGHT: 'topRight',
+    TOP_LEFT: 'topLeft',
+    BOTTOM_RIGHT: 'bottomRight',
+    BOTTOM_LEFT: 'bottomLeft',
+  }
+
+  const Id = {
+    CONTAINER_TOP_RIGHT: 'toastsContainerTopRight',
+    CONTAINER_TOP_LEFT: 'toastsContainerTopLeft',
+    CONTAINER_BOTTOM_RIGHT: 'toastsContainerBottomRight',
+    CONTAINER_BOTTOM_LEFT: 'toastsContainerBottomLeft',
+  }
+
+  const Default = {
+    position: Position.TOP_RIGHT,
+    fixed: true,
+    autohide: false,
+    autoremove: true,
+    delay: 1000,
+    fade: true,
+    icon: null,
+    image: null,
+    imageAlt: null,
+    imageHeight: '25px',
+    title: null,
+    subtitle: null,
+    close: true,
+    body: null,
+    class: null,
+  }
+
+  /**
+   * Class Definition
+   * ====================================================
+   */
+  class Toasts {
+    constructor(element, config) {
+      this._config  = config
+
+      this._prepareContainer();
+
+      const initEvent = $.Event(Event.INIT)
+      $('body').trigger(initEvent)
+    }
+
+    // Public
+
+    create() {
+      var toast = $('<div class="toast" role="alert" aria-live="assertive" aria-atomic="true"/>')
+
+      toast.data('autohide', this._config.autohide)
+      toast.data('animation', this._config.fade)
+      
+      if (this._config.class) {
+        toast.addClass(this._config.class)
+      }
+
+      if (this._config.delay && this._config.delay != 500) {
+        toast.data('delay', this._config.delay)
+      }
+
+      var toast_header = $('<div class="toast-header">')
+
+      if (this._config.image != null) {
+        var toast_image = $('<img />').addClass('rounded mr-2').attr('src', this._config.image).attr('alt', this._config.imageAlt)
+        
+        if (this._config.imageHeight != null) {
+          toast_image.height(this._config.imageHeight).width('auto')
+        }
+
+        toast_header.append(toast_image)
+      }
+
+      if (this._config.icon != null) {
+        toast_header.append($('<i />').addClass('mr-2').addClass(this._config.icon))
+      }
+
+      if (this._config.title != null) {
+        toast_header.append($('<strong />').addClass('mr-auto').html(this._config.title))
+      }
+
+      if (this._config.subtitle != null) {
+        toast_header.append($('<small />').html(this._config.subtitle))
+      }
+
+      if (this._config.close == true) {
+        var toast_close = $('<button data-dismiss="toast" />').attr('type', 'button').addClass('ml-2 mb-1 close').attr('aria-label', 'Close').append('<span aria-hidden="true">&times;</span>')
+        
+        if (this._config.title == null) {
+          toast_close.toggleClass('ml-2 ml-auto')
+        }
+        
+        toast_header.append(toast_close)
+      }
+
+      toast.append(toast_header)
+
+      if (this._config.body != null) {
+        toast.append($('<div class="toast-body" />').html(this._config.body))
+      }
+
+      $(this._getContainerId()).prepend(toast)
+
+      const createdEvent = $.Event(Event.CREATED)
+      $('body').trigger(createdEvent)
+
+      toast.toast('show')
+
+
+      if (this._config.autoremove) {
+        toast.on('hidden.bs.toast', function () {
+          $(this).delay(200).remove();
+
+          const removedEvent = $.Event(Event.REMOVED)
+          $('body').trigger(removedEvent)
+        })
+      }
+
+
+    }
+
+    // Static
+
+    _getContainerId() {
+      if (this._config.position == Position.TOP_RIGHT) {
+        return Selector.CONTAINER_TOP_RIGHT;
+      } else if (this._config.position == Position.TOP_LEFT) {
+        return Selector.CONTAINER_TOP_LEFT;
+      } else if (this._config.position == Position.BOTTOM_RIGHT) {
+        return Selector.CONTAINER_BOTTOM_RIGHT;
+      } else if (this._config.position == Position.BOTTOM_LEFT) {
+        return Selector.CONTAINER_BOTTOM_LEFT;
+      }
+    }
+
+    _prepareContainer() {
+      if ($(this._getContainerId()).length === 0) {
+        var container = $('<div />').attr('id', this._getContainerId().replace('#', ''))
+        if (this._config.position == Position.TOP_RIGHT) {
+          container.addClass(ClassName.TOP_RIGHT)
+        } else if (this._config.position == Position.TOP_LEFT) {
+          container.addClass(ClassName.TOP_LEFT)
+        } else if (this._config.position == Position.BOTTOM_RIGHT) {
+          container.addClass(ClassName.BOTTOM_RIGHT)
+        } else if (this._config.position == Position.BOTTOM_LEFT) {
+          container.addClass(ClassName.BOTTOM_LEFT)
+        }
+
+        $('body').append(container)
+      }
+
+      if (this._config.fixed) {
+        $(this._getContainerId()).addClass('fixed')
+      } else {
+        $(this._getContainerId()).removeClass('fixed')
+      }
+    }
+
+    // Static
+
+    static _jQueryInterface(option, config) {
+      return this.each(function () {
+        const _config = $.extend({}, Default, config)
+        var toast = new Toasts($(this), _config)
+
+        if (option === 'create') {
+          toast[option]()
+        }
+      })
+    }
+  }
+
+  /**
+   * jQuery API
+   * ====================================================
+   */
+
+  $.fn[NAME] = Toasts._jQueryInterface
+  $.fn[NAME].Constructor = Toasts
+  $.fn[NAME].noConflict  = function () {
+    $.fn[NAME] = JQUERY_NO_CONFLICT
+    return Toasts._jQueryInterface
+  }
+
+  return Toasts
+})(jQuery)
+
+export default Toasts

+ 1 - 0
build/scss/AdminLTE-raw.scss

@@ -48,6 +48,7 @@
 @import 'carousel';
 @import 'social-widgets';
 @import 'modals';
+@import 'toasts';
 
 // Pages
 // ---------------------------------------------------

+ 1 - 0
build/scss/AdminLTE.scss

@@ -44,6 +44,7 @@
 @import 'carousel';
 @import 'social-widgets';
 @import 'modals';
+@import 'toasts';
 
 // Pages
 // ---------------------------------------------------

+ 18 - 0
build/scss/_mixins.scss

@@ -437,6 +437,24 @@
   }
 }
 
+// Toast Variant
+@mixin toast-variant($name, $color) {
+  &.bg-#{$name} {
+    background: rgba($color, .9) !important;
+    @if (color-yiq($color) == $yiq-text-light) {
+
+      .close {
+        color: color-yiq($color);
+        text-shadow: 0 1px 0 #000;
+      }
+    }
+
+    .toast-header {
+      background: rgba($color, .85);
+      color: color-yiq($color);
+    }
+  }
+}
 
 // ETC
 @mixin translate($x, $y) {

+ 56 - 0
build/scss/_toasts.scss

@@ -0,0 +1,56 @@
+//
+// Component: Toasts
+//
+
+.toasts-top-right {
+  position: absolute;
+  right: 0;
+  top: 0;
+  z-index: $zindex-toasts;
+
+  &.fixed {
+    position: fixed;
+  }
+}
+
+.toasts-top-left {
+  left: 0;
+  position: absolute;
+  top: 0;
+  z-index: $zindex-toasts;
+
+  &.fixed {
+    position: fixed;
+  }
+}
+
+.toasts-bottom-right {
+  bottom: 0;
+  position: absolute;
+  right: 0;
+  z-index: $zindex-toasts;
+
+  &.fixed {
+    position: fixed;
+  }
+}
+
+.toasts-bottom-left {
+  bottom: 0;
+  left: 0;
+  position: absolute;
+  z-index: $zindex-toasts;
+
+  &.fixed {
+    position: fixed;
+  }
+}
+
+.toast {
+  @each $name, $color in $theme-colors {
+    @include toast-variant($name, $color);
+  }
+  @each $name, $color in $colors {
+    @include toast-variant($name, $color);
+  }
+}

+ 1 - 0
build/scss/_variables.scss

@@ -166,6 +166,7 @@ $zindex-main-sidebar: $zindex-fixed + 8 !default;
 $zindex-main-footer: $zindex-fixed + 2 !default;
 $zindex-control-sidebar: $zindex-fixed + 1 !default;
 $zindex-sidebar-mini-links: 010 !default;
+$zindex-toasts: $zindex-main-sidebar + 2 !default;
 
 // TRANSITIONS SETTINGS
 // --------------------------------------------------------

+ 17 - 15
build/scss/plugins/_toastr.scss

@@ -30,23 +30,25 @@
 // }
 
 
-// Background color
-.toast {
-  background-color: $primary;
-}
+#toast-container {
+  // Background color
+  .toast {
+    background-color: $primary;
+  }
 
-.toast-success {
-  background-color: $success;
-}
+  .toast-success {
+    background-color: $success;
+  }
 
-.toast-error {
-  background-color: $danger;
-}
+  .toast-error {
+    background-color: $danger;
+  }
 
-.toast-info {
-  background-color: $info;
-}
+  .toast-info {
+    background-color: $info;
+  }
 
-.toast-warning {
-  background-color: $warning;
+  .toast-warning {
+    background-color: $warning;
+  }
 }

+ 2 - 0
docs/_config.yml

@@ -80,6 +80,8 @@ navigation:
       url: javascript/direct-chat.html
     - title: Todo List
       url: javascript/todo-list.html
+    - title: Toasts
+      url: javascript/toasts.html
 - title: Browser Support
   url: browser-support.html
   icon: fab fa-chrome

+ 71 - 0
docs/javascript/toasts.md

@@ -0,0 +1,71 @@
+---
+layout: page
+title: Toasts Plugin
+---
+
+The toasts plugin provides simple functionality to create easily a bootstrap toast.
+
+##### Usage
+This plugin can be activated as a jQuery plugin.
+
+###### jQuery
+{: .text-bold }
+The jQuery API provides more customizable options that allows the developer to handle checking and unchecking the todo list checkbox events. 
+```js
+$(document).Toasts('create', {
+  title: 'Toast Title',
+  body: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr.'
+})
+```
+
+
+##### Options
+{: .mt-4}
+
+|---
+| Name | Type | Default | Description
+|-|-|-|-
+|position | String | Position.TOP_RIGHT | Position of the toast, available options: `topRight`, `topLeft`, `bottomRight` & `bottomLeft`
+|fixed | Boolean | true | Whether to set toasts container fixed.
+|autohide | Boolean | false | Whether to auto hide toast
+|autoremove | Boolean | true | Whether to auto remove toast after closing 
+|delay | Integer | 1000 | Auto Hide delay
+|fade | Boolean | true | Whether to fade toast
+|icon | String | null | Icon class (e.g. `fas fa-exclamation-triangle`)
+|image | String | null | Image url
+|imageAlt | String | null | Image alt
+|imageHeight | String | '25px' | Image size of toast
+|title | String | null | Title of toast
+|subtitle | String | null | Subtitle of toast
+|close | Boolean | true | Whether to add close button to toast
+|body | String | null | Body of toast
+|class | String | null | Additional classes for the toast
+|---
+{: .table .table-bordered .bg-light}
+
+
+##### Events
+{: .mt-4}
+All event are sent to `body`.
+
+|---
+| Event Type | Description
+|-|-
+|init.lte.toasts | Fired when constructor is done
+|created.lte.toasts | Fired when the toast is created
+|removed.lte.toasts | Fired when the toast is removed
+{: .table .table-bordered .bg-light}
+
+Example: `$('body').on('created.lte.toast', handleCreateEvent)`
+
+
+##### Methods
+{: .mt-4}
+
+|---
+| Method | Description
+|-|-
+|create | Creates a toast
+{: .table .table-bordered .bg-light}
+
+Example: `$(document).Toasts('create', {title: 'Toast Title'})`

+ 158 - 1
pages/UI/modals.html

@@ -759,6 +759,63 @@
               <!-- /.card -->
             </div>
 
+            <div class="card card-info card-outline">
+              <div class="card-header">
+                <h3 class="card-title">
+                  <i class="fas fa-edit"></i>
+                  Toasts Examples <small>built in AdminLTE</small>
+                </h3>
+              </div>
+              <div class="card-body">
+                <button type="button" class="btn btn-default toastsDefaultDefault">
+                  Launch Default Toast
+                </button>
+                <button type="button" class="btn btn-default toastsDefaultFull">
+                  Launch Full Toast (with icon)
+                </button>
+                <button type="button" class="btn btn-default toastsDefaultFullImage">
+                  Launch Full Toast (with image)
+                </button>
+                <button type="button" class="btn btn-default toastsDefaultAutohide">
+                  Launch Default Toasts with autohide
+                </button>
+                <button type="button" class="btn btn-default toastsDefaultNotFixed">
+                  Launch Default Toasts with not fixed
+                </button>
+                <br />
+                <br />
+                <button type="button" class="btn btn-default toastsDefaultTopLeft">
+                  Launch Default Toast (topLeft)
+                </button>
+                <button type="button" class="btn btn-default toastsDefaultBottomRight">
+                  Launch Default Toast (bottomRight)
+                </button>
+                <button type="button" class="btn btn-default toastsDefaultBottomLeft">
+                  Launch Default Toast (bottomLeft)
+                </button>
+                <br />
+                <br />
+                <button type="button" class="btn btn-success toastsDefaultSuccess">
+                  Launch Success Toast
+                </button>
+                <button type="button" class="btn btn-info toastsDefaultInfo">
+                  Launch Info Toast
+                </button>
+                <button type="button" class="btn btn-warning toastsDefaultWarning">
+                  Launch Warning Toast
+                </button>
+                <button type="button" class="btn btn-danger toastsDefaultDanger">
+                  Launch Danger Toast
+                </button>
+                <button type="button" class="btn btn-default bg-maroon toastsDefaultMaroon">
+                  Launch Maroon Toast
+                </button>
+                <div class="text-muted mt-3">
+
+                </div>
+              </div>
+            </div>
+
             <div class="card card-success card-outline">
               <div class="card-header">
                 <h3 class="card-title">
@@ -789,7 +846,7 @@
               <!-- /.card -->
             </div>
 
-            <div class="card card-success card-outline">
+            <div class="card card-warning card-outline">
               <div class="card-header">
                 <h3 class="card-title">
                   <i class="fas fa-edit"></i>
@@ -1157,6 +1214,106 @@
     $('.toastrDefaultWarning').click(function() {
       toastr.warning('Lorem ipsum dolor sit amet, consetetur sadipscing elitr.')
     });
+
+    $('.toastsDefaultDefault').click(function() {
+      $(document).Toasts('create', {
+        title: 'Toast Title',
+        body: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr.'
+      })
+    });
+    $('.toastsDefaultTopLeft').click(function() {
+      $(document).Toasts('create', {
+        title: 'Toast Title',
+        position: 'topLeft',
+        body: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr.'
+      })
+    });
+    $('.toastsDefaultBottomRight').click(function() {
+      $(document).Toasts('create', {
+        title: 'Toast Title',
+        position: 'bottomRight',
+        body: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr.'
+      })
+    });
+    $('.toastsDefaultBottomLeft').click(function() {
+      $(document).Toasts('create', {
+        title: 'Toast Title',
+        position: 'bottomLeft',
+        body: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr.'
+      })
+    });
+    $('.toastsDefaultAutohide').click(function() {
+      $(document).Toasts('create', {
+        title: 'Toast Title',
+        autohide: true,
+        delay: 750,
+        body: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr.'
+      })
+    });
+    $('.toastsDefaultNotFixed').click(function() {
+      $(document).Toasts('create', {
+        title: 'Toast Title',
+        fixed: false,
+        body: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr.'
+      })
+    });
+    $('.toastsDefaultFull').click(function() {
+      $(document).Toasts('create', {
+        body: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr.',
+        title: 'Toast Title',
+        subtitle: 'Subtitle',
+        icon: 'fas fa-envelope fa-lg',
+      })
+    });
+    $('.toastsDefaultFullImage').click(function() {
+      $(document).Toasts('create', {
+        body: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr.',
+        title: 'Toast Title',
+        subtitle: 'Subtitle',
+        image: '../../dist/img/user3-128x128.jpg',
+        imageAlt: 'User Picture',
+      })
+    });
+    $('.toastsDefaultSuccess').click(function() {
+      $(document).Toasts('create', {
+        class: 'bg-success', 
+        title: 'Toast Title',
+        subtitle: 'Subtitle',
+        body: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr.'
+      })
+    });
+    $('.toastsDefaultInfo').click(function() {
+      $(document).Toasts('create', {
+        class: 'bg-info', 
+        title: 'Toast Title',
+        subtitle: 'Subtitle',
+        body: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr.'
+      })
+    });
+    $('.toastsDefaultWarning').click(function() {
+      $(document).Toasts('create', {
+        class: 'bg-warning', 
+        title: 'Toast Title',
+        subtitle: 'Subtitle',
+        body: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr.'
+      })
+    });
+    $('.toastsDefaultDanger').click(function() {
+      $(document).Toasts('create', {
+        class: 'bg-danger', 
+        title: 'Toast Title',
+        subtitle: 'Subtitle',
+        body: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr.'
+      })
+    });
+    $('.toastsDefaultMaroon').click(function() {
+      $(document).Toasts('create', {
+        class: 'bg-maroon', 
+        title: 'Toast Title',
+        subtitle: 'Subtitle',
+        body: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr.'
+      })
+    });
   });
 
 </script>