@gofynd/nitrozen-vue
Version:
Fynd Design Library for Vue
303 lines (235 loc) • 6.32 kB
JavaScript
import show from './show';
import animations from './animations';
const uuid = require('shortid');
// add Object.assign Polyfill
// require('es6-object-assign').polyfill();
/**
* Toast
* core instance of toast
*
* @param _options
* @returns {Snackbar}
* @constructor
*/
export const Snackbar = function (_options) {
/**
* Unique id of the toast
*/
this.id = uuid.generate();
/**
* Shared Options of the Toast
*/
this.options = _options;
/**
* Cached Options of the Toast
*/
this.cached_options = {};
/**
* Shared Toasts list
*/
this.global = {};
/**
* All Registered Groups
*/
this.groups = [];
/**
* All Registered Toasts
*/
this.toasts = [];
/**
* Element of the Toast Container
*/
this.container = null;
/**
* Initiate toast container
*/
initiateToastContainer(this);
/**
* Initiate custom toasts
*/
initiateCustomToasts(this);
/**
* Create New Group of Toasts
*
* @param o
*/
this.group = (o) => {
if (!o) o = {};
if (!o.globalToasts) {
o.globalToasts = {};
}
// share parents global toasts
Object.assign(o.globalToasts, this.global);
// tell parent about the group
let group = new Snackbar(o);
this.groups.push(group);
return group;
}
/**
* Register a Global Toast
*
* @param name
* @param payload
* @param options
*/
this.register = (name, payload, options) => {
options = options || {};
return register(this, name, payload, options);
}
/**
* Show a Simple Toast
*
* @param message
* @param options
* @returns {*}
*/
this.show = (message, options) => {
return _show(this, message, options);
}
/**
* Show a Toast with Success Style
*
* @param message
* @param options
* @returns {*}
*/
this.success = (message, options) => {
options = options || {};
options.type = "success";
return _show(this, message, options);
}
/**
* Show a Toast with Info Style
*
* @param message
* @param options
* @returns {*}
*/
this.info = (message, options) => {
options = options || {};
options.type = "info";
return _show(this, message, options);
}
/**
* Show a Toast with Error Style
*
* @param message
* @param options
* @returns {*}
*/
this.error = (message, options) => {
options = options || {};
options.type = "error";
return _show(this, message, options);
}
/**
* Remove a Toast
* @param el
*/
this.remove = (el) => {
this.toasts = this.toasts.filter((t) => {
return t.el.hash !== el.hash;
})
if (el.parentNode) el.parentNode.removeChild(el);
}
/**
* Clear All Toasts
*
* @returns {boolean}
*/
this.clear = (onClear) => {
animations.clearAnimation(this.toasts, () => {
onClear && onClear();
});
this.toasts = [];
return true;
}
return this;
};
/**
* Wrapper for show method in order to manipulate options
*
* @param instance
* @param message
* @param options
* @returns {*}
* @private
*/
export const _show = function (instance, message, options) {
options = options || {};
let toast = null;
if (typeof options !== "object") {
console.error("Options should be a type of object. given : " + options);
return null;
}
// singleton feature
if (instance.options.singleton && instance.toasts.length > 0) {
instance.cached_options = options;
instance.toasts[instance.toasts.length - 1].goAway(0);
}
// clone the global options
let _options = Object.assign({}, instance.options);
// merge the cached global options with options
Object.assign(_options, options);
toast = show(instance, message, _options);
instance.toasts.push(toast);
return toast;
};
/**
* Register the Custom Toasts
*/
export const initiateCustomToasts = function (instance) {
let customToasts = instance.options.globalToasts;
// this will initiate toast for the custom toast.
let initiate = (message, options) => {
// check if passed option is a available method if so call it.
if (typeof (options) === 'string' && instance[options]) {
return instance[options].apply(instance, [message, {}]);
}
// or else create a new toast with passed options.
return _show(instance, message, options);
};
if (customToasts) {
instance.global = {};
Object.keys(customToasts).forEach(key => {
// register the custom toast events to the Toast.custom property
instance.global[key] = (payload = {}, options={}) => {
//console.log(payload);
// return the it in order to expose the Toast methods
return customToasts[key].apply(null, [payload, options, initiate]);
};
});
}
};
const initiateToastContainer = function (instance) {
// create notification container
const container = document.createElement('div');
container.id = instance.id;
container.setAttribute('role', 'status');
container.setAttribute('aria-live', 'polite');
container.setAttribute('aria-atomic', 'false');
document.body.appendChild(container);
instance.container = container;
};
const register = function (instance, name, callback, options) {
(!instance.options.globalToasts) ? instance.options.globalToasts = {} : null;
instance.options.globalToasts[name] = function (payload, optionsParams=null, initiate) {
// if call back is string we will keep it that way..
let message = null;
let settings = null
if (typeof callback === 'string') {
message = callback;
}
if (typeof callback === 'function') {
message = callback(payload);
}
if (optionsParams !== null && typeof optionsParams === 'object') {
settings = Object.assign(options, optionsParams)
} else {
settings = options;
}
return initiate(message, settings);
};
initiateCustomToasts(instance);
}
export default { Snackbar };