@nguyenshort/vue3-loading-indicator
Version:
Vue 3 Loading Indicator bar. Support typescript, composable API, option API
176 lines (175 loc) • 5.68 kB
JavaScript
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
import { inject, defineComponent, computed, ref, openBlock, createBlock, Teleport, unref, createElementBlock, normalizeStyle, createElementVNode, createCommentVNode, reactive } from "vue";
const useLoadingIndicator = () => {
return inject("$loading");
};
var VueLoadingIndicator_vue_vue_type_style_index_0_scoped_true_lang = /* @__PURE__ */ (() => ".vue-process-bar[data-v-6c70920e]{position:fixed;z-index:999999}\n")();
var _export_sfc = (sfc, props) => {
const target = sfc.__vccOpts || sfc;
for (const [key, val] of props) {
target[key] = val;
}
return target;
};
const __default__ = defineComponent({
name: "VueLoadingIndicator"
});
const _sfc_main = /* @__PURE__ */ defineComponent(__spreadProps(__spreadValues({}, __default__), {
setup(__props) {
const $loading = useLoadingIndicator();
const style = computed(() => {
return {
top: 0,
left: 0,
right: 0,
height: `${$loading == null ? void 0 : $loading.config.throttle}px`
};
});
const container = ref();
const _width = computed(() => {
var _a;
return ((_a = container.value) == null ? void 0 : _a.scrollWidth) || 0;
});
const style2 = computed(() => {
return {
background: $loading == null ? void 0 : $loading.state.color,
height: "100%",
width: (($loading == null ? void 0 : $loading.state.process) || 0) * _width.value / 100 + "px",
transition: `width ${$loading == null ? void 0 : $loading.config.duration}ms, opacity .6s`
};
});
return (_ctx, _cache) => {
return openBlock(), createBlock(Teleport, { to: "body" }, [
unref($loading).state.show ? (openBlock(), createElementBlock("div", {
key: 0,
ref_key: "container",
ref: container,
class: "vue-process-bar",
style: normalizeStyle(unref(style))
}, [
createElementVNode("div", {
class: "_process",
style: normalizeStyle(unref(style2))
}, null, 4)
], 4)) : createCommentVNode("", true)
]);
};
}
}));
var VueLoadingIndicator = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-6c70920e"]]);
const plugin = {
install(app, options) {
let DEFAULT_CONFIG = {
color: "#3b66f5",
errorColor: "#d50000",
duration: 200,
timeGap: 100,
throttle: 2,
skipDuplicate: true,
autoFinish: true,
delay: 800
};
const CONFIG = Object.assign({}, DEFAULT_CONFIG, options);
const state = {
color: CONFIG.color,
process: 0,
type: "normal",
show: false
};
const instance = reactive({
config: CONFIG,
state,
start(options2) {
if (options2) {
Object.assign(this.config, options2);
this.state.color = this.config.color;
}
if (this.config.skipDuplicate && this.state.show) {
return;
} else if (this.state.show) {
this.clear();
}
this.state.show = true;
this.continue();
},
finish() {
if (!this.state.show) {
return;
}
clearInterval(this.state.timer);
this.state.process = 100;
if (this.config.autoFinish) {
setTimeout(() => {
this.clear();
}, this.config.duration + this.config.delay);
}
},
fail() {
this.state.color = this.config.errorColor;
this.finish();
},
pause() {
clearInterval(this.state.timer);
},
continue() {
this.state.timer = setInterval(() => {
this.increase(10);
if (this.state.process >= 100) {
if (this.config.autoFinish) {
this.finish();
} else {
clearInterval(this.state.timer);
}
}
}, this.config.timeGap);
},
clear() {
this.state.show = false;
clearInterval(this.state.timer);
this.state.timer = null;
this.state.process = 0;
Object.assign(this.config, CONFIG);
this.state.color = this.config.color;
},
set(process) {
this.state.process = process;
},
increase(amount) {
if (this.state.process + amount > 100) {
this.set(100);
} else {
this.set(this.state.process + amount);
}
},
decrease(amount) {
if (this.state.process - amount < 0) {
this.set(0);
} else {
this.set(this.state.process - amount);
}
}
});
app.provide("$loading", instance);
app.component("VueLoadingIndicator", VueLoadingIndicator);
app.config.globalProperties.$loading = instance;
}
};
export { VueLoadingIndicator, plugin as default, useLoadingIndicator };