UNPKG

baseframe-js

Version:

Baseframe JS is a comprehensive suite of modular plugins and utilities designed for front-end development

140 lines (139 loc) 4.83 kB
import $be from "base-elem-js"; import { getDataOptions, setParams, oa } from "./util/helpers"; import Store from "./core/Store"; const VERSION = "1.0.0"; const DATA_NAME = 'Toastr'; const EVENT_NAME = 'toastr'; const DEFAULTS = { duration: 3000, appendTo: document.body, animationDuration: 500, content: '', outerCss: 'toastr', enabledCss: 'toastr--enabled', dismissCss: 'toastr--dismiss', btnDismissCss: 'toastr__btn-dismiss', closeIconCss: 'ico i-close', ariaLive: 'polite', closeTextCopy: 'Dismiss', cssGroupKey: 'std', oneOnly: false }; const toastContainers = new Map(); const { make } = $be; let currentlyToastingGlobal = false; export default class Toastr { static defaults = DEFAULTS; static version = VERSION; static pluginName = DATA_NAME; static DismissedEventName = 'toastDismissed'; toastrFinallyTimer; active; toasterBodyBuilt; $element; $toastrBody; $toastrWrap; params; constructor(element, options) { const s = this; const dataOptions = getDataOptions(element, EVENT_NAME); //state s.$element = $be(element); s.toastrFinallyTimer = null; s.$toastrBody = null; s.$toastrWrap = null; s.active = false; s.params = setParams(Toastr.defaults, options, dataOptions); s.$element.on([`click.${EVENT_NAME}`, `[${EVENT_NAME}]`], () => s.launch()); return s; } dismiss() { const s = this; const p = s.params; s.toastrFinallyTimer && clearTimeout(s.toastrFinallyTimer); s.$toastrWrap.addClass(p.dismissCss); setTimeout(() => { const $toatrContainer = s.#getToasterContainer(); s.$toastrWrap.rmClass(p.dismissCss).remove(); if (!$toatrContainer.find('div').hasEls) { s.#getToasterContainer().remove(); } s.active = false; currentlyToastingGlobal = false; }, p.animationDuration); } setContent(content, updateNow = false) { const s = this; oa(s.params, { content }); if (updateNow) { s.#updateContent(s.params.content); } } launch() { const s = this; const p = s.params; if (!s.active) { if (currentlyToastingGlobal && p.oneOnly) { return; } if (!s.toasterBodyBuilt) s.#buildElems(); s.$toastrWrap.rmClass([p.dismissCss, p.enabledCss]); s.#updateContent(p.content); $be(document.body).insert(s.#getToasterContainer().insert(s.$toastrWrap)); setTimeout(() => s.$toastrWrap.addClass(p.enabledCss), 0); // Auto remove if not dismissed s.toastrFinallyTimer = setTimeout(() => s.dismiss(), p.duration); s.active = true; currentlyToastingGlobal = true; } } #getToasterContainer() { const { cssGroupKey, outerCss } = this.params; const toasterWrapCss = `${outerCss}-wrap ${outerCss}-wrap--${cssGroupKey}`; if (!toastContainers.has(toasterWrapCss)) { toastContainers.set(toasterWrapCss, $be(make(`div.${toasterWrapCss}`))); } return toastContainers.get(toasterWrapCss); } #buildElems() { const s = this; const p = s.params; const $btn = $be(make(`button.${p.btnDismissCss}`, { type: 'button' })); const $icon = $be(make(`i.${p.closeIconCss}`, `<span class="sr-only">${p.closeTextCopy}</span>`)); s.$toastrBody = $be(make(`div.${p.outerCss}__body`)); s.$toastrWrap = $be(make(`div.${p.outerCss}`, { role: 'alert', ariaLive: p.ariaLive })).insert([ s.$toastrBody, $btn.insert($icon) ]); s.toasterBodyBuilt = true; // click event to dismiss s.$toastrWrap.on('click.dismiss', () => s.dismiss(), 'button'); } #updateContent(content) { const s = this; if (s.$toastrBody) { s.$toastrBody.empty(); if ('string' === typeof content) { s.$toastrBody.html(content); } else s.$toastrBody.insert(content); } } static setContent(element, content, updateNow = false) { $be(element).each((elem) => { const s = Store(elem, DATA_NAME); Object.assign(s.params, { content }); if (updateNow) s.#updateContent(s.params.content); }); } static remove(element, plugin) { $be(element).each((elem) => { const s = plugin || Store(elem, DATA_NAME); s.$element.off([`click.${EVENT_NAME}`, `[${EVENT_NAME}]`]); Store(elem, DATA_NAME, null); }); } }