JSFiddle - React, Tailwind, and code Playground

Fliplet Toasts and Snackbars

by tonytlwu

HTML

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.11/handlebars.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
<div class="trigger-holder">
  <p><label><input type="checkbox" id="overlay" /> Show overlay</label></p>
  <p>Top</p>
  <p><span class="btn btn-default trigger" data-position="top" data-type="regular">Regular</span>&nbsp;
  <span class="btn btn-default trigger" data-position="top" data-type="minimal">Minimal</span>
  </p>
  <p>Center</p>
  <p><span class="btn btn-default trigger" data-position="center" data-type="regular">Regular</span>&nbsp;
  <span class="btn btn-default trigger" data-position="center" data-type="minimal">Minimal</span></p>
  <p>Bottom</p>
  <p><span class="btn btn-default trigger" data-position="bottom" data-type="regular">Regular</span>&nbsp;
  <span class="btn btn-default trigger" data-position="bottom" data-type="minimal">Minimal</span></p>
  <p>Examples</p>
  <p><span class="btn btn-default in-app-notification">Message received</span>&nbsp;
  <span class="btn btn-default bookmark">Bookmark</span>&nbsp;
  <span class="btn btn-default download">Download update</span>
  </p>
</div>

CSS

@import url('https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700');
html,
body {
  height: 100%;
}

body {
  font-family: 'Open Sans', sans-serif;
  color: #333;
  background: url('http://media.idownloadblog.com/wp-content/uploads/2018/01/Facebook-iOS-11-Wallpaper-3.jpeg');
  background-size: cover;
  background-position: center center;
  background-repeat: no-repeat;
}

.trigger-holder {
  position: fixed;
  left: 0;
  right: 0;
  top: 50%;
  transform: translate3d(0, -50%, 0);
  text-align: center;
}

/* Toast UI */

.fl-toast-overlay {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 20;
  background: #000;
  opacity: 0;
  -webkit-transition: opacity 0.1s linear;
  -ms-transition: opacity 0.1s linear;
  transition: opacity 0.1s linear;
}

.fl-toast-overlay.active {
  opacity: 0.6;
}

.fl-toast {
  position: fixed;
  left: 15px;
  right: 15px;
  padding: 15px;
  overflow: hidden;
  max-width: 700px;
  margin-left: auto;
  margin-right: auto;
  opacity: 0;
  pointer-events: none;
  z-index: 21;
  -webkit-transition: -webkit-transform 0.15s cubic-bezier(0.500, 0.055, 0.555, 1.370), opacity 0.1s linear;
  -ms-transition: -ms-transform 0.15s cubic-bezier(0.500, 0.055, 0.555, 1.370), opacity 0.1s linear;
  transition: transform 0.15s cubic-bezier(0.500, 0.055, 0.555, 1.370), opacity 0.1s linear;
  -webkit-box-shadow: 0 5px 15px rgba(0,0,0,.5);
  -ms-box-shadow: 0 5px 15px rgba(0,0,0,.5);
  box-shadow: 0 5px 15px rgba(0,0,0,.5);
  font-size: 14px;
  /* Theme-able settings */
  background-color: #fff;
  color: #333;
  border-radius: 4px;
}

.fl-toast.active {
  opacity: 1;
  pointer-events: all;
}

.fl-toast-top {
  top: 15px;
  top: calc(15px + constant(safe-area-inset-top));
  top: calc(15px + env(safe-area-inset-top));
  -webkit-transform-origin: center top;
  -ms-transform-origin: center top;
  transform-origin: center top;
  -webkit-transform: scale(0.8) translate3d(0, -30px, 0) rotateX(-90deg) perspective(500px);
 ...

JavaScript

/* eslint-disable */
/* eslint-disable */
(function (w) {
  w.Fliplet = w.Fliplet || {};
  var Fliplet = w.Fliplet;

  Fliplet.UI = Fliplet.UI || {};
  Fliplet.UI.Toast = (function () {
    var _this;
    var dismissTimeout;
    var source = [
      '{{#if overlay}}<div class="fl-toast-overlay"></div>{{/if}}',
      '<div class="fl-toast fl-toast-{{type}} fl-toast-{{position}}">',
        '{{#if html}}',
          '{{{html}}}',
        '{{else}}',
          '{{#if title}}',
            '<div class="fl-toast-title">{{title}}</div>',
          '{{/if}}',
          '{{#if message}}',
            '<div class="fl-toast-body">{{message}}</div>',
          '{{/if}}',
          '{{#if progress}}',
            '<div class="fl-toast-progress">',
              '<div class="progress"><div class="progress-bar"></div></div>',
            '</div>',
          '{{/if}}',
          '{{#if actions}}',
            '<div class="fl-toast-links">',
              '{{#each actions}}',
                '<span class="link {{#if type}}text-{{type}}{{/if}}">{{label}}</span>',
              '{{/each}}',
            '</div>',
          '{{/if}}',
        '{{/if}}',
      '</div>'
    ].join('');
    var tpl = Handlebars.compile(source);
    var $toast;
    var data;
    var swipeDirections = {
      top: 'swipeup',
      bottom: 'swipedown'
    };
    var positions = ['top', 'center', 'bottom'];
    var typePositions = {
      regular: 'top',
      minimal: 'bottom'
    };
    var initialProgress = 0.05;

    function Toast(options) {
      _this = this;
      if (typeof options === 'string') {
        options = { message: options };
      }
      options = options || {};
      data = options;

      this.data = data;
      this.dismiss = dismiss;
      this.open = open;
      this.setProgress = setProgress;

      return new Promise(function (resolve) {
        var reset;

        data.type = ['regular', 'minimal'].indexOf(data.type) > -1
          ? data.type
          : 'minimal';

       ...