vue-promise-btn
Version:
Vue.js plugin that handles buttons asynchronous lock and show loading state indicator
2 lines (1 loc) • 5.85 kB
JavaScript
;function _interopDefault(e){return e&&"object"==typeof e&&"default"in e?e.default:e}var Vue=_interopDefault(require("vue")),script={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}}}};function normalizeComponent(e,n,t,i,r,o,s,a,p,l){"boolean"!=typeof s&&(p=a,a=s,s=!1);var d,u="function"==typeof t?t.options:t;if(e&&e.render&&(u.render=e.render,u.staticRenderFns=e.staticRenderFns,u._compiled=!0,r&&(u.functional=!0)),i&&(u._scopeId=i),o?(d=function(e){(e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),n&&n.call(this,p(e)),e&&e._registeredComponents&&e._registeredComponents.add(o)},u._ssrRegister=d):n&&(d=s?function(){n.call(this,l(this.$root.$options.shadowRoot))}:function(e){n.call(this,a(e))}),d)if(u.functional){var c=u.render;u.render=function(e,n){return d.call(n),c(e,n)}}else{var _=u.beforeCreate;u.beforeCreate=_?[].concat(_,d):[d]}return t}var normalizeComponent_1=normalizeComponent,__vue_script__=script,__vue_render__=function(){var e=this.$createElement;return(this._self._c||e)("span",{staticClass:"spinner",style:this.style})},__vue_staticRenderFns__=[],__vue_inject_styles__=void 0,__vue_scope_id__="data-v-cc3e8e04",__vue_module_identifier__=void 0,__vue_is_functional_template__=!1,Spinner=normalizeComponent_1({render:__vue_render__,staticRenderFns:__vue_staticRenderFns__},__vue_inject_styles__,__vue_script__,__vue_scope_id__,__vue_is_functional_template__,__vue_module_identifier__,void 0,void 0),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,stringHTMLRenderer=function(e){return'\n <span class="promise-btn__spinner-wrapper"\n :class="{[options.spinnerHiddenClass]: !show || false}"\n v-show="options.autoHideSpinnerWrapper ? show : true"\n >\n '+e.loader+"\n </span>"},componentRenderer=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 o={el:r,data:{show:!1},props:{parent:{type:Object,default:function(){return t.context}}},render:n.componentRenderer(n)};if(i){var s=n.stringHTMLRenderer(n),a=Vue.compile(s);o=Object.assign({},o,{data:Object.assign({},o.data,{options:n}),render:a.render,staticRenderFns:a.staticRenderFns})}return o},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 o=isObject(i.value),s=t[pluginElPropName]=elementId++,a=o?i.value:{},p=Object.assign({},e,a),l=isString(p.loader),d=t,u=null,c=!1,_=!1,f=!1,m=function(e){c&&_&&(p.showSpinner&&(u.show=!1),c=!1,_=!1,enableBtn(e,p))},v=function(){f=!1,_=!0,m(d)},h=function(e,n){return function(e){f=!0,disableBtn(e,p),p.showSpinner&&(u.show=!0),setTimeout(function(){c=!0,m(e)},p.minTimeout)}(e),n.then(function(){return v()}).catch(function(e){throw v(),e})};if(n.listeners[s]={el:t,eventType:p.action},"submit"===p.action&&!(d=t.querySelector('[type="submit"]')))throw new Error("No submit button found");if(p.showSpinner){var b=initSpinner(d,p,r,l);u=new Vue(b)}if(p.hasOwnProperty("promise"))n.listeners[s].promiseHanlder=h;else{if(!!r.componentInstance){var w=r.componentInstance.$listeners&&r.componentInstance.$listeners[p.action];if(!w)throw new Error("Please, provide proper handler/action for promise-btn");n.listeners[s].eventHandler=w,r.componentInstance.$off(p.action)}else{var g=r.data.on&&r.data.on[p.action]&&(r.data.on[p.action]._withTask||r.data.on[p.action]._wrapper);if(!g)throw new Error("Please, provide proper handler/action for promise-btn");n.listeners[s].eventHandler=g,t.removeEventListener(p.action,g)}n.listener=function(e){var t=n.listeners[s].eventHandler;if(!p.disableBtn||!f){var i=t(e),r="function"==typeof i?function(e){for(var n=e;"function"==typeof n;)n=n();return n}(i):i;return isPromise(r)?h(d,r):void 0}}}},bind:function(e,t,i){var r;(r=t.def).init.apply(r,arguments);var o=!!i.componentInstance,s=e[pluginElPropName],a=n.listeners[s],p=a.eventType;a.promiseHanlder||(o?i.componentInstance.$on(p,n.listener):e.addEventListener(p,n.listener))},unbind:function(e,t,i){var r=!!i.componentInstance,o=e[pluginElPropName],s=n.listeners[o].eventType;r?i.componentInstance.$off(s,n.listener):e.removeEventListener(s,n.listener),delete n.listeners[o],delete e[pluginElPropName]},componentUpdated:function(e,t,i,r){if(t&&t.value&&t.value.promise&&t.value.promise!==t.oldValue.promise){var o=e[pluginElPropName];(0,n.listeners[o].promiseHanlder)(e,t.value.promise)}}};return n},defaultOptions={btnLoadingClass:"loading",showSpinner:!0,action:"click",disableBtn:!0,stringHTMLRenderer:stringHTMLRenderer,componentRenderer:componentRenderer,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;