vue-promise-btn
Advanced tools
Comparing version 1.0.9 to 1.0.10
@@ -1,1 +0,245 @@ | ||
"use strict";function _interopDefault(e){return e&&"object"==typeof e&&"default"in e?e.default:e}var Vue=_interopDefault(require("vue")),Spinner={render:function(){var e=this.$createElement;return(this._self._c||e)("span",{staticClass:"spinner",style:this.style})},staticRenderFns:[],_scopeId:"data-v-39432f99",name:"Spinner",props:{color:{type:String,default:"#3498db"},size:{type:Number,default:18},width:{type:Number,default:4},duration:{type:String,default:"1s"}},computed:{style:function(){return{borderTopColor:this.color,width:this.size+"px",height:this.size+"px",borderWidth:this.width+"px",animationDuration:this.duration}}}},isPromise=function(e){return!!e&&("object"==typeof e||"function"==typeof e)&&"function"==typeof e.then},isString=function(e){return"string"==typeof e},isObject=function(e){return e===Object(e)},pluginElPropName="$promiseBtnId",elementId=0,spinnerWrapper=function(e){return'\n <span class="promise-btn__spinner-wrapper" v-show="show">\n '+e.loader+"\n </span>"},spinnerRenderer=function(e){return function(n){var t;return n("span",{class:(t={"promise-btn__spinner-wrapper":!0},t[e.spinnerHiddenClass]=!!e.spinnerHiddenClass&&!this.show,t),directives:[{name:"show",value:!e.autoHideSpinnerWrapper||this.show}]},[n(e.loader)])}},initSpinner=function(e,n,t,i){var r=document.createElement("SPAN");e.appendChild(r);var s={el:r,data:{show:!1},props:{parent:{type:Object,default:function(){return t.context}}}};return s=i?Object.assign({},s,{template:n.spinnerWrapper(n)}):Object.assign({},s,{render:n.spinnerRenderer(n)})},enableBtn=function(e,n){e.getAttribute("disabled")&&n.disableBtn&&e.removeAttribute("disabled"),e.classList.remove(n.btnLoadingClass)},disableBtn=function(e,n){n.disableBtn&&e.setAttribute("disabled","disabled"),e.classList.add(n.btnLoadingClass)},setupVuePromiseBtn=function(e){var n={listeners:{},init:function(t,i,r){var s=isObject(i.value),a=t[pluginElPropName]=elementId++,o=s?i.value:{},p=Object.assign({},e,o),u=r.data.on&&r.data.on[p.action]&&r.data.on[p.action]._withTask,l=isString(p.loader),d=t,c=null,f=!1,b=!1,m=function(){f&&b&&(c.show=!1,f=!1,b=!1,enableBtn(d,p))},h=function(){w=!1,p.showSpinner&&(b=!0,m())};if(n.listeners[a]={el:t,eventType:p.action,handler:u},t.removeEventListener(p.action,u),!u)throw new Error("Please, provide proper handler/action for promise-btn");if("submit"===p.action&&!(d=t.querySelector('[type="submit"]')))throw new Error("No submit button found");if(p.showSpinner){var v=initSpinner(d,p,r,l);c=new Vue(v)}var w=!1;n.listener=function(e){if(!p.disableBtn||!w){var n=u(e);isPromise(n)&&(w=!0,disableBtn(d,p),p.showSpinner&&(c.show=!0,setTimeout(function(){f=!0,m()},p.minTimeout)),n.then(h).catch(function(e){throw h(),e}))}}},bind:function(e,t,i){var r;(r=t.def).init.apply(r,arguments);var s=e[pluginElPropName],a=n.listeners[s].eventType;e.addEventListener(a,n.listener)},unbind:function(e,t){var i=e[pluginElPropName],r=n.listeners[i].eventType;e.removeEventListener(r,n.listener),delete n.listeners[i],delete e[pluginElPropName]}};return n},defaultOptions={btnLoadingClass:"loading",showSpinner:!0,action:"click",disableBtn:!0,spinnerWrapper:spinnerWrapper,spinnerRenderer:spinnerRenderer,minTimeout:400,spinnerHiddenClass:"hidden",autoHideSpinnerWrapper:!1,loader:Spinner};function install(e,n){var t=Object.assign({},defaultOptions,n);e.directive("promise-btn",setupVuePromiseBtn(t))}var main={install:install,Spinner:Spinner,setupVuePromiseBtn:setupVuePromiseBtn};module.exports=main; | ||
(function(l, i, v, e) { v = l.createElement(i); v.async = 1; v.src = '//' + (location.host || 'localhost').split(':')[0] + ':35729/livereload.js?snipver=1'; e = l.getElementsByTagName(i)[0]; e.parentNode.insertBefore(v, e)})(document, 'script'); | ||
'use strict'; | ||
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } | ||
var Vue = _interopDefault(require('vue')); | ||
var Spinner = {render: function(){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('span',{staticClass:"spinner",style:(_vm.style)})},staticRenderFns: [],_scopeId: 'data-v-39432f99', | ||
name: 'Spinner', | ||
props: { | ||
color: { | ||
type: String, | ||
default: '#3498db' | ||
}, | ||
size: { | ||
type: Number, | ||
default: 18 | ||
}, | ||
width: { | ||
type: Number, | ||
default: 4 | ||
}, | ||
duration: { | ||
type: String, | ||
default: '1s' | ||
} | ||
}, | ||
computed: { | ||
style: function style () { | ||
return { | ||
borderTopColor: this.color, | ||
width: ((this.size) + "px"), | ||
height: ((this.size) + "px"), | ||
borderWidth: ((this.width) + "px"), | ||
animationDuration: this.duration | ||
} | ||
} | ||
} | ||
} | ||
var isPromise = function (obj) { | ||
return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function' | ||
}; | ||
var isString = function (obj) { | ||
return typeof obj === 'string' | ||
}; | ||
var isObject = function (obj) { | ||
return obj === Object(obj) | ||
}; | ||
var pluginElPropName = '$promiseBtnId'; | ||
var elementId = 0; | ||
var spinnerWrapper = function (options) { | ||
return ("\n <span class=\"promise-btn__spinner-wrapper\" v-show=\"show\">\n " + (options.loader) + "\n </span>") | ||
}; | ||
var spinnerRenderer = function (options) { | ||
return function (h) { | ||
var obj; | ||
return h('span', { | ||
class: ( obj = { | ||
'promise-btn__spinner-wrapper': true | ||
}, obj[options.spinnerHiddenClass] = options.spinnerHiddenClass ? !this.show : false, obj), | ||
directives: [{ | ||
name: 'show', | ||
value: options.autoHideSpinnerWrapper ? this.show : true | ||
}] | ||
}, [ | ||
h(options.loader) | ||
]) | ||
} | ||
}; | ||
var initSpinner = function (btnEl, options, vnode, isLoaderString) { | ||
var dummyEl = document.createElement('SPAN'); | ||
btnEl.appendChild(dummyEl); | ||
var vueSpinnerOptions = { | ||
el: dummyEl, | ||
data: { show: false }, | ||
props: { | ||
parent: { | ||
type: Object, | ||
default: function () { return vnode.context; } | ||
} | ||
} | ||
}; | ||
if (isLoaderString) { | ||
vueSpinnerOptions = Object.assign({}, vueSpinnerOptions, | ||
{template: options.spinnerWrapper(options)}); | ||
} else { | ||
vueSpinnerOptions = Object.assign({}, vueSpinnerOptions, | ||
{render: options.spinnerRenderer(options)}); | ||
} | ||
return vueSpinnerOptions | ||
}; | ||
var enableBtn = function (el, options) { | ||
if (el.getAttribute('disabled') && options.disableBtn) { el.removeAttribute('disabled'); } | ||
el.classList.remove(options.btnLoadingClass); | ||
}; | ||
var disableBtn = function (el, options) { | ||
if (options.disableBtn) { el.setAttribute('disabled', 'disabled'); } | ||
el.classList.add(options.btnLoadingClass); | ||
}; | ||
var setupVuePromiseBtn = function (globalOptions) { | ||
var directive = { | ||
listeners: {}, | ||
init: function init (el, binding, vnode) { | ||
var isBindingValueObj = isObject(binding.value); | ||
var id = el[pluginElPropName] = elementId++; | ||
var instanceOptions = isBindingValueObj ? binding.value : {}; | ||
var options = Object.assign({}, globalOptions, | ||
instanceOptions); | ||
var handler = vnode.data.on && vnode.data.on[options.action] && vnode.data.on[options.action]._withTask; | ||
var isLoaderString = isString(options.loader); | ||
var btnEl = el; | ||
var spinnerVM = null; | ||
var minTimeoutDone = false; | ||
var promiseDone = false; | ||
var handleLoadingFinished = function () { | ||
if (minTimeoutDone && promiseDone) { | ||
spinnerVM.show = false; | ||
minTimeoutDone = false; | ||
promiseDone = false; | ||
enableBtn(btnEl, options); | ||
} | ||
}; | ||
var beforeResponseHandler = function () { | ||
scheduled = true; | ||
disableBtn(btnEl, options); | ||
if (options.showSpinner) { | ||
spinnerVM.show = true; | ||
setTimeout(function () { | ||
minTimeoutDone = true; | ||
handleLoadingFinished(minTimeoutDone, promiseDone, spinnerVM); | ||
}, options.minTimeout); | ||
} | ||
}; | ||
var resolveHandler = function () { | ||
scheduled = false; | ||
if (options.showSpinner) { | ||
promiseDone = true; | ||
handleLoadingFinished(minTimeoutDone, promiseDone, spinnerVM); | ||
} | ||
}; | ||
// Register info in listeners object | ||
directive.listeners[id] = { | ||
el: el, | ||
eventType: options.action, | ||
handler: handler | ||
}; | ||
// Remove native event listener | ||
el.removeEventListener(options.action, handler); | ||
if (!handler) { throw new Error('Please, provide proper handler/action for promise-btn') } | ||
if (options.action === 'submit') { | ||
btnEl = el.querySelector('[type="submit"]'); | ||
if (!btnEl) { throw new Error('No submit button found') } | ||
} | ||
if (options.showSpinner) { | ||
var vueSpinnerOptions = initSpinner(btnEl, options, vnode, isLoaderString); | ||
spinnerVM = new Vue(vueSpinnerOptions); | ||
} | ||
var scheduled = false; | ||
// Set custom event that will replace original listener | ||
directive.listener = function (e) { | ||
if (options.disableBtn && scheduled) { return } | ||
var response = handler(e); | ||
if (isPromise(response)) { | ||
beforeResponseHandler(); | ||
response | ||
.then(resolveHandler) | ||
.catch(function (e) { | ||
resolveHandler(); | ||
throw e | ||
}); | ||
} | ||
}; | ||
}, | ||
bind: function bind (el, binding, vnode) { | ||
var ref; | ||
// Init | ||
(ref = binding.def).init.apply(ref, arguments); | ||
// Replace native event listener | ||
var id = el[pluginElPropName]; | ||
var ref$1 = directive.listeners[id]; | ||
var eventType = ref$1.eventType; | ||
el.addEventListener(eventType, directive.listener); | ||
}, | ||
unbind: function unbind (el, binding) { | ||
var id = el[pluginElPropName]; | ||
var ref = directive.listeners[id]; | ||
var eventType = ref.eventType; | ||
el.removeEventListener(eventType, directive.listener); | ||
delete directive.listeners[id]; | ||
delete el[pluginElPropName]; | ||
} | ||
}; | ||
return directive | ||
}; | ||
var defaultOptions = { | ||
btnLoadingClass: 'loading', | ||
showSpinner: true, | ||
action: 'click', | ||
disableBtn: true, | ||
spinnerWrapper: spinnerWrapper, | ||
spinnerRenderer: spinnerRenderer, | ||
minTimeout: 400, | ||
spinnerHiddenClass: 'hidden', | ||
autoHideSpinnerWrapper: false, | ||
loader: Spinner | ||
}; | ||
function install (Vue$$1, options) { | ||
var globalOptions = Object.assign({}, defaultOptions, options); | ||
Vue$$1.directive('promise-btn', setupVuePromiseBtn(globalOptions)); | ||
} | ||
var main = { | ||
install: install, | ||
Spinner: Spinner, | ||
setupVuePromiseBtn: setupVuePromiseBtn | ||
} | ||
module.exports = main; |
@@ -1,1 +0,241 @@ | ||
import Vue from"vue";var Spinner={render:function(){var e=this.$createElement;return(this._self._c||e)("span",{staticClass:"spinner",style:this.style})},staticRenderFns:[],_scopeId:"data-v-39432f99",name:"Spinner",props:{color:{type:String,default:"#3498db"},size:{type:Number,default:18},width:{type:Number,default:4},duration:{type:String,default:"1s"}},computed:{style:function(){return{borderTopColor:this.color,width:this.size+"px",height:this.size+"px",borderWidth:this.width+"px",animationDuration:this.duration}}}},isPromise=function(e){return!!e&&("object"==typeof e||"function"==typeof e)&&"function"==typeof e.then},isString=function(e){return"string"==typeof e},isObject=function(e){return e===Object(e)},pluginElPropName="$promiseBtnId",elementId=0,spinnerWrapper=function(e){return'\n <span class="promise-btn__spinner-wrapper" v-show="show">\n '+e.loader+"\n </span>"},spinnerRenderer=function(e){return function(n){var t;return n("span",{class:(t={"promise-btn__spinner-wrapper":!0},t[e.spinnerHiddenClass]=!!e.spinnerHiddenClass&&!this.show,t),directives:[{name:"show",value:!e.autoHideSpinnerWrapper||this.show}]},[n(e.loader)])}},initSpinner=function(e,n,t,i){var r=document.createElement("SPAN");e.appendChild(r);var s={el:r,data:{show:!1},props:{parent:{type:Object,default:function(){return t.context}}}};return s=i?Object.assign({},s,{template:n.spinnerWrapper(n)}):Object.assign({},s,{render:n.spinnerRenderer(n)})},enableBtn=function(e,n){e.getAttribute("disabled")&&n.disableBtn&&e.removeAttribute("disabled"),e.classList.remove(n.btnLoadingClass)},disableBtn=function(e,n){n.disableBtn&&e.setAttribute("disabled","disabled"),e.classList.add(n.btnLoadingClass)},setupVuePromiseBtn=function(e){var n={listeners:{},init:function(t,i,r){var s=isObject(i.value),a=t[pluginElPropName]=elementId++,o=s?i.value:{},p=Object.assign({},e,o),l=r.data.on&&r.data.on[p.action]&&r.data.on[p.action]._withTask,u=isString(p.loader),d=t,c=null,f=!1,m=!1,b=function(){f&&m&&(c.show=!1,f=!1,m=!1,enableBtn(d,p))},h=function(){w=!1,p.showSpinner&&(m=!0,b())};if(n.listeners[a]={el:t,eventType:p.action,handler:l},t.removeEventListener(p.action,l),!l)throw new Error("Please, provide proper handler/action for promise-btn");if("submit"===p.action&&!(d=t.querySelector('[type="submit"]')))throw new Error("No submit button found");if(p.showSpinner){var v=initSpinner(d,p,r,u);c=new Vue(v)}var w=!1;n.listener=function(e){if(!p.disableBtn||!w){var n=l(e);isPromise(n)&&(w=!0,disableBtn(d,p),p.showSpinner&&(c.show=!0,setTimeout(function(){f=!0,b()},p.minTimeout)),n.then(h).catch(function(e){throw h(),e}))}}},bind:function(e,t,i){var r;(r=t.def).init.apply(r,arguments);var s=e[pluginElPropName],a=n.listeners[s].eventType;e.addEventListener(a,n.listener)},unbind:function(e,t){var i=e[pluginElPropName],r=n.listeners[i].eventType;e.removeEventListener(r,n.listener),delete n.listeners[i],delete e[pluginElPropName]}};return n},defaultOptions={btnLoadingClass:"loading",showSpinner:!0,action:"click",disableBtn:!0,spinnerWrapper:spinnerWrapper,spinnerRenderer:spinnerRenderer,minTimeout:400,spinnerHiddenClass:"hidden",autoHideSpinnerWrapper:!1,loader:Spinner};function install(e,n){var t=Object.assign({},defaultOptions,n);e.directive("promise-btn",setupVuePromiseBtn(t))}var main={install:install,Spinner:Spinner,setupVuePromiseBtn:setupVuePromiseBtn};export default main; | ||
(function(l, i, v, e) { v = l.createElement(i); v.async = 1; v.src = '//' + (location.host || 'localhost').split(':')[0] + ':35729/livereload.js?snipver=1'; e = l.getElementsByTagName(i)[0]; e.parentNode.insertBefore(v, e)})(document, 'script'); | ||
import Vue from 'vue'; | ||
var Spinner = {render: function(){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('span',{staticClass:"spinner",style:(_vm.style)})},staticRenderFns: [],_scopeId: 'data-v-39432f99', | ||
name: 'Spinner', | ||
props: { | ||
color: { | ||
type: String, | ||
default: '#3498db' | ||
}, | ||
size: { | ||
type: Number, | ||
default: 18 | ||
}, | ||
width: { | ||
type: Number, | ||
default: 4 | ||
}, | ||
duration: { | ||
type: String, | ||
default: '1s' | ||
} | ||
}, | ||
computed: { | ||
style: function style () { | ||
return { | ||
borderTopColor: this.color, | ||
width: ((this.size) + "px"), | ||
height: ((this.size) + "px"), | ||
borderWidth: ((this.width) + "px"), | ||
animationDuration: this.duration | ||
} | ||
} | ||
} | ||
} | ||
var isPromise = function (obj) { | ||
return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function' | ||
}; | ||
var isString = function (obj) { | ||
return typeof obj === 'string' | ||
}; | ||
var isObject = function (obj) { | ||
return obj === Object(obj) | ||
}; | ||
var pluginElPropName = '$promiseBtnId'; | ||
var elementId = 0; | ||
var spinnerWrapper = function (options) { | ||
return ("\n <span class=\"promise-btn__spinner-wrapper\" v-show=\"show\">\n " + (options.loader) + "\n </span>") | ||
}; | ||
var spinnerRenderer = function (options) { | ||
return function (h) { | ||
var obj; | ||
return h('span', { | ||
class: ( obj = { | ||
'promise-btn__spinner-wrapper': true | ||
}, obj[options.spinnerHiddenClass] = options.spinnerHiddenClass ? !this.show : false, obj), | ||
directives: [{ | ||
name: 'show', | ||
value: options.autoHideSpinnerWrapper ? this.show : true | ||
}] | ||
}, [ | ||
h(options.loader) | ||
]) | ||
} | ||
}; | ||
var initSpinner = function (btnEl, options, vnode, isLoaderString) { | ||
var dummyEl = document.createElement('SPAN'); | ||
btnEl.appendChild(dummyEl); | ||
var vueSpinnerOptions = { | ||
el: dummyEl, | ||
data: { show: false }, | ||
props: { | ||
parent: { | ||
type: Object, | ||
default: function () { return vnode.context; } | ||
} | ||
} | ||
}; | ||
if (isLoaderString) { | ||
vueSpinnerOptions = Object.assign({}, vueSpinnerOptions, | ||
{template: options.spinnerWrapper(options)}); | ||
} else { | ||
vueSpinnerOptions = Object.assign({}, vueSpinnerOptions, | ||
{render: options.spinnerRenderer(options)}); | ||
} | ||
return vueSpinnerOptions | ||
}; | ||
var enableBtn = function (el, options) { | ||
if (el.getAttribute('disabled') && options.disableBtn) { el.removeAttribute('disabled'); } | ||
el.classList.remove(options.btnLoadingClass); | ||
}; | ||
var disableBtn = function (el, options) { | ||
if (options.disableBtn) { el.setAttribute('disabled', 'disabled'); } | ||
el.classList.add(options.btnLoadingClass); | ||
}; | ||
var setupVuePromiseBtn = function (globalOptions) { | ||
var directive = { | ||
listeners: {}, | ||
init: function init (el, binding, vnode) { | ||
var isBindingValueObj = isObject(binding.value); | ||
var id = el[pluginElPropName] = elementId++; | ||
var instanceOptions = isBindingValueObj ? binding.value : {}; | ||
var options = Object.assign({}, globalOptions, | ||
instanceOptions); | ||
var handler = vnode.data.on && vnode.data.on[options.action] && vnode.data.on[options.action]._withTask; | ||
var isLoaderString = isString(options.loader); | ||
var btnEl = el; | ||
var spinnerVM = null; | ||
var minTimeoutDone = false; | ||
var promiseDone = false; | ||
var handleLoadingFinished = function () { | ||
if (minTimeoutDone && promiseDone) { | ||
spinnerVM.show = false; | ||
minTimeoutDone = false; | ||
promiseDone = false; | ||
enableBtn(btnEl, options); | ||
} | ||
}; | ||
var beforeResponseHandler = function () { | ||
scheduled = true; | ||
disableBtn(btnEl, options); | ||
if (options.showSpinner) { | ||
spinnerVM.show = true; | ||
setTimeout(function () { | ||
minTimeoutDone = true; | ||
handleLoadingFinished(minTimeoutDone, promiseDone, spinnerVM); | ||
}, options.minTimeout); | ||
} | ||
}; | ||
var resolveHandler = function () { | ||
scheduled = false; | ||
if (options.showSpinner) { | ||
promiseDone = true; | ||
handleLoadingFinished(minTimeoutDone, promiseDone, spinnerVM); | ||
} | ||
}; | ||
// Register info in listeners object | ||
directive.listeners[id] = { | ||
el: el, | ||
eventType: options.action, | ||
handler: handler | ||
}; | ||
// Remove native event listener | ||
el.removeEventListener(options.action, handler); | ||
if (!handler) { throw new Error('Please, provide proper handler/action for promise-btn') } | ||
if (options.action === 'submit') { | ||
btnEl = el.querySelector('[type="submit"]'); | ||
if (!btnEl) { throw new Error('No submit button found') } | ||
} | ||
if (options.showSpinner) { | ||
var vueSpinnerOptions = initSpinner(btnEl, options, vnode, isLoaderString); | ||
spinnerVM = new Vue(vueSpinnerOptions); | ||
} | ||
var scheduled = false; | ||
// Set custom event that will replace original listener | ||
directive.listener = function (e) { | ||
if (options.disableBtn && scheduled) { return } | ||
var response = handler(e); | ||
if (isPromise(response)) { | ||
beforeResponseHandler(); | ||
response | ||
.then(resolveHandler) | ||
.catch(function (e) { | ||
resolveHandler(); | ||
throw e | ||
}); | ||
} | ||
}; | ||
}, | ||
bind: function bind (el, binding, vnode) { | ||
var ref; | ||
// Init | ||
(ref = binding.def).init.apply(ref, arguments); | ||
// Replace native event listener | ||
var id = el[pluginElPropName]; | ||
var ref$1 = directive.listeners[id]; | ||
var eventType = ref$1.eventType; | ||
el.addEventListener(eventType, directive.listener); | ||
}, | ||
unbind: function unbind (el, binding) { | ||
var id = el[pluginElPropName]; | ||
var ref = directive.listeners[id]; | ||
var eventType = ref.eventType; | ||
el.removeEventListener(eventType, directive.listener); | ||
delete directive.listeners[id]; | ||
delete el[pluginElPropName]; | ||
} | ||
}; | ||
return directive | ||
}; | ||
var defaultOptions = { | ||
btnLoadingClass: 'loading', | ||
showSpinner: true, | ||
action: 'click', | ||
disableBtn: true, | ||
spinnerWrapper: spinnerWrapper, | ||
spinnerRenderer: spinnerRenderer, | ||
minTimeout: 400, | ||
spinnerHiddenClass: 'hidden', | ||
autoHideSpinnerWrapper: false, | ||
loader: Spinner | ||
}; | ||
function install (Vue$$1, options) { | ||
var globalOptions = Object.assign({}, defaultOptions, options); | ||
Vue$$1.directive('promise-btn', setupVuePromiseBtn(globalOptions)); | ||
} | ||
var main = { | ||
install: install, | ||
Spinner: Spinner, | ||
setupVuePromiseBtn: setupVuePromiseBtn | ||
} | ||
export default main; |
@@ -1,1 +0,249 @@ | ||
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n(require("vue")):"function"==typeof define&&define.amd?define(["vue"],n):e.VuePromiseBtn=n(e.Vue)}(this,function(e){"use strict";e=e&&e.hasOwnProperty("default")?e.default:e;var n={render:function(){var e=this.$createElement;return(this._self._c||e)("span",{staticClass:"spinner",style:this.style})},staticRenderFns:[],_scopeId:"data-v-39432f99",name:"Spinner",props:{color:{type:String,default:"#3498db"},size:{type:Number,default:18},width:{type:Number,default:4},duration:{type:String,default:"1s"}},computed:{style:function(){return{borderTopColor:this.color,width:this.size+"px",height:this.size+"px",borderWidth:this.width+"px",animationDuration:this.duration}}}},t=0,i=function(n){var i={listeners:{},init:function(r,s,o){var a,d=(a=s.value)===Object(a),p=r.$promiseBtnId=t++,u=d?s.value:{},l=Object.assign({},n,u),c=o.data.on&&o.data.on[l.action]&&o.data.on[l.action]._withTask,f=function(e){return"string"==typeof e}(l.loader),h=r,b=null,m=!1,v=!1,w=function(){m&&v&&(b.show=!1,m=!1,v=!1,function(e,n){e.getAttribute("disabled")&&n.disableBtn&&e.removeAttribute("disabled"),e.classList.remove(n.btnLoadingClass)}(h,l))},y=function(){S=!1,l.showSpinner&&(v=!0,w())};if(i.listeners[p]={el:r,eventType:l.action,handler:c},r.removeEventListener(l.action,c),!c)throw new Error("Please, provide proper handler/action for promise-btn");if("submit"===l.action&&!(h=r.querySelector('[type="submit"]')))throw new Error("No submit button found");if(l.showSpinner){var g=function(e,n,t,i){var r=document.createElement("SPAN");e.appendChild(r);var s={el:r,data:{show:!1},props:{parent:{type:Object,default:function(){return t.context}}}};return s=i?Object.assign({},s,{template:n.spinnerWrapper(n)}):Object.assign({},s,{render:n.spinnerRenderer(n)})}(h,l,o,f);b=new e(g)}var S=!1;i.listener=function(e){if(!l.disableBtn||!S){var n,t=c(e);!(n=t)||"object"!=typeof n&&"function"!=typeof n||"function"!=typeof n.then||(S=!0,function(e,n){n.disableBtn&&e.setAttribute("disabled","disabled"),e.classList.add(n.btnLoadingClass)}(h,l),l.showSpinner&&(b.show=!0,setTimeout(function(){m=!0,w()},l.minTimeout)),t.then(y).catch(function(e){throw y(),e}))}}},bind:function(e,n,t){var r;(r=n.def).init.apply(r,arguments);var s=e.$promiseBtnId,o=i.listeners[s].eventType;e.addEventListener(o,i.listener)},unbind:function(e,n){var t=e.$promiseBtnId,r=i.listeners[t].eventType;e.removeEventListener(r,i.listener),delete i.listeners[t],delete e.$promiseBtnId}};return i},r={btnLoadingClass:"loading",showSpinner:!0,action:"click",disableBtn:!0,spinnerWrapper:function(e){return'\n <span class="promise-btn__spinner-wrapper" v-show="show">\n '+e.loader+"\n </span>"},spinnerRenderer:function(e){return function(n){var t;return n("span",{class:(t={"promise-btn__spinner-wrapper":!0},t[e.spinnerHiddenClass]=!!e.spinnerHiddenClass&&!this.show,t),directives:[{name:"show",value:!e.autoHideSpinnerWrapper||this.show}]},[n(e.loader)])}},minTimeout:400,spinnerHiddenClass:"hidden",autoHideSpinnerWrapper:!1,loader:n};return{install:function(e,n){var t=Object.assign({},r,n);e.directive("promise-btn",i(t))},Spinner:n,setupVuePromiseBtn:i}}); | ||
(function(l, i, v, e) { v = l.createElement(i); v.async = 1; v.src = '//' + (location.host || 'localhost').split(':')[0] + ':35729/livereload.js?snipver=1'; e = l.getElementsByTagName(i)[0]; e.parentNode.insertBefore(v, e)})(document, 'script'); | ||
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('vue')) : | ||
typeof define === 'function' && define.amd ? define(['vue'], factory) : | ||
(global.VuePromiseBtn = factory(global.Vue)); | ||
}(this, (function (Vue) { 'use strict'; | ||
Vue = Vue && Vue.hasOwnProperty('default') ? Vue['default'] : Vue; | ||
var Spinner = {render: function(){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('span',{staticClass:"spinner",style:(_vm.style)})},staticRenderFns: [],_scopeId: 'data-v-39432f99', | ||
name: 'Spinner', | ||
props: { | ||
color: { | ||
type: String, | ||
default: '#3498db' | ||
}, | ||
size: { | ||
type: Number, | ||
default: 18 | ||
}, | ||
width: { | ||
type: Number, | ||
default: 4 | ||
}, | ||
duration: { | ||
type: String, | ||
default: '1s' | ||
} | ||
}, | ||
computed: { | ||
style: function style () { | ||
return { | ||
borderTopColor: this.color, | ||
width: ((this.size) + "px"), | ||
height: ((this.size) + "px"), | ||
borderWidth: ((this.width) + "px"), | ||
animationDuration: this.duration | ||
} | ||
} | ||
} | ||
} | ||
var isPromise = function (obj) { | ||
return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function' | ||
}; | ||
var isString = function (obj) { | ||
return typeof obj === 'string' | ||
}; | ||
var isObject = function (obj) { | ||
return obj === Object(obj) | ||
}; | ||
var pluginElPropName = '$promiseBtnId'; | ||
var elementId = 0; | ||
var spinnerWrapper = function (options) { | ||
return ("\n <span class=\"promise-btn__spinner-wrapper\" v-show=\"show\">\n " + (options.loader) + "\n </span>") | ||
}; | ||
var spinnerRenderer = function (options) { | ||
return function (h) { | ||
var obj; | ||
return h('span', { | ||
class: ( obj = { | ||
'promise-btn__spinner-wrapper': true | ||
}, obj[options.spinnerHiddenClass] = options.spinnerHiddenClass ? !this.show : false, obj), | ||
directives: [{ | ||
name: 'show', | ||
value: options.autoHideSpinnerWrapper ? this.show : true | ||
}] | ||
}, [ | ||
h(options.loader) | ||
]) | ||
} | ||
}; | ||
var initSpinner = function (btnEl, options, vnode, isLoaderString) { | ||
var dummyEl = document.createElement('SPAN'); | ||
btnEl.appendChild(dummyEl); | ||
var vueSpinnerOptions = { | ||
el: dummyEl, | ||
data: { show: false }, | ||
props: { | ||
parent: { | ||
type: Object, | ||
default: function () { return vnode.context; } | ||
} | ||
} | ||
}; | ||
if (isLoaderString) { | ||
vueSpinnerOptions = Object.assign({}, vueSpinnerOptions, | ||
{template: options.spinnerWrapper(options)}); | ||
} else { | ||
vueSpinnerOptions = Object.assign({}, vueSpinnerOptions, | ||
{render: options.spinnerRenderer(options)}); | ||
} | ||
return vueSpinnerOptions | ||
}; | ||
var enableBtn = function (el, options) { | ||
if (el.getAttribute('disabled') && options.disableBtn) { el.removeAttribute('disabled'); } | ||
el.classList.remove(options.btnLoadingClass); | ||
}; | ||
var disableBtn = function (el, options) { | ||
if (options.disableBtn) { el.setAttribute('disabled', 'disabled'); } | ||
el.classList.add(options.btnLoadingClass); | ||
}; | ||
var setupVuePromiseBtn = function (globalOptions) { | ||
var directive = { | ||
listeners: {}, | ||
init: function init (el, binding, vnode) { | ||
var isBindingValueObj = isObject(binding.value); | ||
var id = el[pluginElPropName] = elementId++; | ||
var instanceOptions = isBindingValueObj ? binding.value : {}; | ||
var options = Object.assign({}, globalOptions, | ||
instanceOptions); | ||
var handler = vnode.data.on && vnode.data.on[options.action] && vnode.data.on[options.action]._withTask; | ||
var isLoaderString = isString(options.loader); | ||
var btnEl = el; | ||
var spinnerVM = null; | ||
var minTimeoutDone = false; | ||
var promiseDone = false; | ||
var handleLoadingFinished = function () { | ||
if (minTimeoutDone && promiseDone) { | ||
spinnerVM.show = false; | ||
minTimeoutDone = false; | ||
promiseDone = false; | ||
enableBtn(btnEl, options); | ||
} | ||
}; | ||
var beforeResponseHandler = function () { | ||
scheduled = true; | ||
disableBtn(btnEl, options); | ||
if (options.showSpinner) { | ||
spinnerVM.show = true; | ||
setTimeout(function () { | ||
minTimeoutDone = true; | ||
handleLoadingFinished(minTimeoutDone, promiseDone, spinnerVM); | ||
}, options.minTimeout); | ||
} | ||
}; | ||
var resolveHandler = function () { | ||
scheduled = false; | ||
if (options.showSpinner) { | ||
promiseDone = true; | ||
handleLoadingFinished(minTimeoutDone, promiseDone, spinnerVM); | ||
} | ||
}; | ||
// Register info in listeners object | ||
directive.listeners[id] = { | ||
el: el, | ||
eventType: options.action, | ||
handler: handler | ||
}; | ||
// Remove native event listener | ||
el.removeEventListener(options.action, handler); | ||
if (!handler) { throw new Error('Please, provide proper handler/action for promise-btn') } | ||
if (options.action === 'submit') { | ||
btnEl = el.querySelector('[type="submit"]'); | ||
if (!btnEl) { throw new Error('No submit button found') } | ||
} | ||
if (options.showSpinner) { | ||
var vueSpinnerOptions = initSpinner(btnEl, options, vnode, isLoaderString); | ||
spinnerVM = new Vue(vueSpinnerOptions); | ||
} | ||
var scheduled = false; | ||
// Set custom event that will replace original listener | ||
directive.listener = function (e) { | ||
if (options.disableBtn && scheduled) { return } | ||
var response = handler(e); | ||
if (isPromise(response)) { | ||
beforeResponseHandler(); | ||
response | ||
.then(resolveHandler) | ||
.catch(function (e) { | ||
resolveHandler(); | ||
throw e | ||
}); | ||
} | ||
}; | ||
}, | ||
bind: function bind (el, binding, vnode) { | ||
var ref; | ||
// Init | ||
(ref = binding.def).init.apply(ref, arguments); | ||
// Replace native event listener | ||
var id = el[pluginElPropName]; | ||
var ref$1 = directive.listeners[id]; | ||
var eventType = ref$1.eventType; | ||
el.addEventListener(eventType, directive.listener); | ||
}, | ||
unbind: function unbind (el, binding) { | ||
var id = el[pluginElPropName]; | ||
var ref = directive.listeners[id]; | ||
var eventType = ref.eventType; | ||
el.removeEventListener(eventType, directive.listener); | ||
delete directive.listeners[id]; | ||
delete el[pluginElPropName]; | ||
} | ||
}; | ||
return directive | ||
}; | ||
var defaultOptions = { | ||
btnLoadingClass: 'loading', | ||
showSpinner: true, | ||
action: 'click', | ||
disableBtn: true, | ||
spinnerWrapper: spinnerWrapper, | ||
spinnerRenderer: spinnerRenderer, | ||
minTimeout: 400, | ||
spinnerHiddenClass: 'hidden', | ||
autoHideSpinnerWrapper: false, | ||
loader: Spinner | ||
}; | ||
function install (Vue$$1, options) { | ||
var globalOptions = Object.assign({}, defaultOptions, options); | ||
Vue$$1.directive('promise-btn', setupVuePromiseBtn(globalOptions)); | ||
} | ||
var main = { | ||
install: install, | ||
Spinner: Spinner, | ||
setupVuePromiseBtn: setupVuePromiseBtn | ||
} | ||
return main; | ||
}))); |
{ | ||
"name": "vue-promise-btn", | ||
"version": "1.0.9", | ||
"version": "1.0.10", | ||
"description": "Vue.js plugin that handles buttons asynchronous lock and show loading state indicator", | ||
@@ -5,0 +5,0 @@ "scripts": { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
33748
13
853
0
1