UNPKG

@codog/vue3-infinite-loading

Version:
796 lines (703 loc) 35.4 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('vue'), require('tiny-emitter/instance')) : typeof define === 'function' && define.amd ? define(['vue', 'tiny-emitter/instance'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Vue3InfiniteLoading = factory(global.vue, global.emitter)); })(this, (function (vue, emitter) { 'use strict'; /* * default property values */ const props = { // the default spinner type spinner: 'default', // the default critical distance distance: 100, // the default force use infinite wrapper flag forceUseInfiniteWrapper: false, }; /** * default system settings */ const system = { // the default throttle space of time throttleLimit: 50, // the timeout for check infinite loop, unit: ms loopCheckTimeout: 1000, // the max allowed number of continuous calls, unit: ms loopCheckMaxCalls: 10, }; /** * default slot messages */ const slots = { noResults: 'No results :(', noMore: 'No more data :)', error: 'Opps, something went wrong :(', errorBtnText: 'Retry', spinner: '', }; /** * the 3rd argument for event bundler * @see https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md */ const evt3rdArg = (() => { let result = false; try { const arg = Object.defineProperty({}, 'passive', { get() { result = { passive: true }; return true; }, }); window.addEventListener('testpassive', arg, arg); window.remove('testpassive', arg, arg); } catch (e) { /* */ } return result; })(); /** * warning messages */ const WARNINGS = { STATE_CHANGER: [ 'emit `loaded` and `complete` event through component instance of `$refs` may cause error, so it will be deprecated soon, please use the `$state` argument instead (`$state` just the special `$event` variable):', '\ntemplate:', '<infinite-loading @infinite="infiniteHandler"></infinite-loading>', ` script: ... infiniteHandler($state) { ajax('https://www.example.com/api/news') .then((res) => { if (res.data.length) { $state.loaded(); } else { $state.complete(); } }); } ...`, '', 'more details: https://github.com/PeachScript/vue-infinite-loading/issues/57#issuecomment-324370549', ].join('\n'), IDENTIFIER: 'the `reset` event will be deprecated soon, please reset this component by change the `identifier` property.', }; /** * error messages */ const ERRORS = { INFINITE_LOOP: [ `executed the callback function more than ${system.loopCheckMaxCalls} times for a short time, it looks like searched a wrong scroll wrapper that doest not has fixed height or maximum height, please check it. If you want to force to set a element as scroll wrapper ranther than automatic searching, you can do this:`, ` <!-- add a special attribute for the real scroll wrapper --> <div infinite-wrapper> ... <!-- set force-use-infinite-wrapper --> <infinite-loading force-use-infinite-wrapper></infinite-loading> </div> or <div class="infinite-wrapper"> ... <!-- set force-use-infinite-wrapper as css selector of the real scroll wrapper --> <infinite-loading force-use-infinite-wrapper=".infinite-wrapper"></infinite-loading> </div> `, 'more details: https://github.com/PeachScript/vue-infinite-loading/issues/55#issuecomment-316934169', ].join('\n'), }; /** * plugin status constants */ const STATUS = { READY: 0, LOADING: 1, COMPLETE: 2, ERROR: 3, }; /** * default slot styles */ const SLOT_STYLES = { color: '#666', fontSize: '14px', padding: '10px 0', }; var config = { mode: 'development', props, system, slots}; const SPINNERS = { BUBBLES: { render() { return vue.h('span', { class: 'loading-bubbles' }, Array.apply(Array, Array(8)).map(() => vue.h('span', { class: 'bubble-item', }))); }, }, CIRCLES: { render() { return vue.h('span', { class: 'loading-circles', }, Array.apply(Array, Array(8)).map(() => vue.h('span', { class: 'circle-item', }))); }, }, DEFAULT: { render() { return vue.h('i', { class: 'loading-default' }); }, }, SPIRAL: { render() { return vue.h('i', { class: 'loading-spiral' }); }, }, WAVEDOTS: { render() { return vue.h('span', { class: 'loading-wave-dots' }, Array.apply(Array, Array(5)).map(() => vue.h('span', { class: 'wave-item' }))); }, }, }; var script$1 = { name: 'Spinner', computed: { spinnerView() { return ( SPINNERS[(this.$attrs.spinner || '').toUpperCase()] || this.spinnerInConfig // fallback to spinner of config ); }, spinnerInConfig() { let result; if (config.slots.spinner && typeof config.slots.spinner === 'string') { // as spinner slot config a pure text spinner result = { render() { return this._v(config.slots.spinner); // eslint-disable-line no-underscore-dangle }, }; } else if (typeof config.slots.spinner === 'object') { // as spinner slot config a Vue component result = config.slots.spinner; } else { // fallback to spinner property config /* istanbul ignore next */ result = SPINNERS[config.props.spinner.toUpperCase()] || SPINNERS.DEFAULT; } return result; }, }, }; function render$1(_ctx, _cache, $props, $setup, $data, $options) { return (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent($options.spinnerView))) } function styleInject(css, ref) { if ( ref === void 0 ) ref = {}; var insertAt = ref.insertAt; if (!css || typeof document === 'undefined') { return; } var head = document.head || document.getElementsByTagName('head')[0]; var style = document.createElement('style'); style.type = 'text/css'; if (insertAt === 'top') { if (head.firstChild) { head.insertBefore(style, head.firstChild); } else { head.appendChild(style); } } else { head.appendChild(style); } if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } } var css_248z$1 = ".loading-wave-dots[data-v-39432f99] {\n position: relative;\n}\n.loading-wave-dots[data-v-39432f99] .wave-item {\n position: absolute;\n top: 50%;\n left: 50%;\n display: inline-block;\n margin-top: -4px;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n animation: loading-wave-dots-39432f99 linear 2.8s infinite;\n}\n.loading-wave-dots[data-v-39432f99] .wave-item:first-child {\n margin-left: -36px;\n}\n.loading-wave-dots[data-v-39432f99] .wave-item:nth-child(2) {\n margin-left: -20px;\n animation-delay: 0.14s;\n}\n.loading-wave-dots[data-v-39432f99] .wave-item:nth-child(3) {\n margin-left: -4px;\n animation-delay: 0.28s;\n}\n.loading-wave-dots[data-v-39432f99] .wave-item:nth-child(4) {\n margin-left: 12px;\n animation-delay: 0.42s;\n}\n.loading-wave-dots[data-v-39432f99] .wave-item:last-child {\n margin-left: 28px;\n animation-delay: 0.56s;\n}\n@keyframes loading-wave-dots-39432f99 {\n0% {\n transform: translateY(0);\n background: #bbb;\n}\n10% {\n transform: translateY(-6px);\n background: #999;\n}\n20% {\n transform: translateY(0);\n background: #bbb;\n}\n100% {\n transform: translateY(0);\n background: #bbb;\n}\n}\n.loading-circles[data-v-39432f99] .circle-item {\n width: 5px;\n height: 5px;\n animation: loading-circles-39432f99 linear 0.75s infinite;\n}\n.loading-circles[data-v-39432f99] .circle-item:first-child {\n margin-top: -14.5px;\n margin-left: -2.5px;\n}\n.loading-circles[data-v-39432f99] .circle-item:nth-child(2) {\n margin-top: -11.26px;\n margin-left: 6.26px;\n}\n.loading-circles[data-v-39432f99] .circle-item:nth-child(3) {\n margin-top: -2.5px;\n margin-left: 9.5px;\n}\n.loading-circles[data-v-39432f99] .circle-item:nth-child(4) {\n margin-top: 6.26px;\n margin-left: 6.26px;\n}\n.loading-circles[data-v-39432f99] .circle-item:nth-child(5) {\n margin-top: 9.5px;\n margin-left: -2.5px;\n}\n.loading-circles[data-v-39432f99] .circle-item:nth-child(6) {\n margin-top: 6.26px;\n margin-left: -11.26px;\n}\n.loading-circles[data-v-39432f99] .circle-item:nth-child(7) {\n margin-top: -2.5px;\n margin-left: -14.5px;\n}\n.loading-circles[data-v-39432f99] .circle-item:last-child {\n margin-top: -11.26px;\n margin-left: -11.26px;\n}\n@keyframes loading-circles-39432f99 {\n0% {\n background: rgb(222.8, 222.8, 222.8);\n}\n90% {\n background: #505050;\n}\n100% {\n background: rgb(222.8, 222.8, 222.8);\n}\n}\n.loading-bubbles[data-v-39432f99] .bubble-item {\n background: #666;\n animation: loading-bubbles-39432f99 linear 0.75s infinite;\n}\n.loading-bubbles[data-v-39432f99] .bubble-item:first-child {\n margin-top: -12.5px;\n margin-left: -0.5px;\n}\n.loading-bubbles[data-v-39432f99] .bubble-item:nth-child(2) {\n margin-top: -9.26px;\n margin-left: 8.26px;\n}\n.loading-bubbles[data-v-39432f99] .bubble-item:nth-child(3) {\n margin-top: -0.5px;\n margin-left: 11.5px;\n}\n.loading-bubbles[data-v-39432f99] .bubble-item:nth-child(4) {\n margin-top: 8.26px;\n margin-left: 8.26px;\n}\n.loading-bubbles[data-v-39432f99] .bubble-item:nth-child(5) {\n margin-top: 11.5px;\n margin-left: -0.5px;\n}\n.loading-bubbles[data-v-39432f99] .bubble-item:nth-child(6) {\n margin-top: 8.26px;\n margin-left: -9.26px;\n}\n.loading-bubbles[data-v-39432f99] .bubble-item:nth-child(7) {\n margin-top: -0.5px;\n margin-left: -12.5px;\n}\n.loading-bubbles[data-v-39432f99] .bubble-item:last-child {\n margin-top: -9.26px;\n margin-left: -9.26px;\n}\n@keyframes loading-bubbles-39432f99 {\n0% {\n width: 1px;\n height: 1px;\n box-shadow: 0 0 0 3px #666;\n}\n90% {\n width: 1px;\n height: 1px;\n box-shadow: 0 0 0 0 #666;\n}\n100% {\n width: 1px;\n height: 1px;\n box-shadow: 0 0 0 3px #666;\n}\n}\n.loading-default[data-v-39432f99] {\n position: relative;\n border: 1px solid #999;\n animation: loading-rotating-39432f99 ease 1.5s infinite;\n}\n.loading-default[data-v-39432f99]:before {\n content: \"\";\n position: absolute;\n display: block;\n top: 0;\n left: 50%;\n margin-top: -3px;\n margin-left: -3px;\n width: 6px;\n height: 6px;\n background-color: #999;\n border-radius: 50%;\n}\n.loading-spiral[data-v-39432f99] {\n border: 2px solid #777;\n border-right-color: transparent;\n animation: loading-rotating-39432f99 linear 0.85s infinite;\n}\n@keyframes loading-rotating-39432f99 {\n0% {\n transform: rotate(0);\n}\n100% {\n transform: rotate(360deg);\n}\n}\n.loading-bubbles[data-v-39432f99],\n.loading-circles[data-v-39432f99] {\n position: relative;\n}\n.loading-circles[data-v-39432f99] .circle-item,\n.loading-bubbles[data-v-39432f99] .bubble-item {\n position: absolute;\n top: 50%;\n left: 50%;\n display: inline-block;\n border-radius: 50%;\n}\n.loading-circles[data-v-39432f99] .circle-item:nth-child(2),\n.loading-bubbles[data-v-39432f99] .bubble-item:nth-child(2) {\n animation-delay: 0.093s;\n}\n.loading-circles[data-v-39432f99] .circle-item:nth-child(3),\n.loading-bubbles[data-v-39432f99] .bubble-item:nth-child(3) {\n animation-delay: 0.186s;\n}\n.loading-circles[data-v-39432f99] .circle-item:nth-child(4),\n.loading-bubbles[data-v-39432f99] .bubble-item:nth-child(4) {\n animation-delay: 0.279s;\n}\n.loading-circles[data-v-39432f99] .circle-item:nth-child(5),\n.loading-bubbles[data-v-39432f99] .bubble-item:nth-child(5) {\n animation-delay: 0.372s;\n}\n.loading-circles[data-v-39432f99] .circle-item:nth-child(6),\n.loading-bubbles[data-v-39432f99] .bubble-item:nth-child(6) {\n animation-delay: 0.465s;\n}\n.loading-circles[data-v-39432f99] .circle-item:nth-child(7),\n.loading-bubbles[data-v-39432f99] .bubble-item:nth-child(7) {\n animation-delay: 0.558s;\n}\n.loading-circles[data-v-39432f99] .circle-item:last-child,\n.loading-bubbles[data-v-39432f99] .bubble-item:last-child {\n animation-delay: 0.651s;\n}"; styleInject(css_248z$1); script$1.render = render$1; script$1.__scopeId = "data-v-39432f99"; script$1.__file = "src/components/Spinner.vue"; /* eslint-disable no-console */ /** * console warning in production * @param {String} msg console content */ function warn(msg) { /* istanbul ignore else */ if (config.mode !== 'production') { console.warn(`[Vue-infinite-loading warn]: ${msg}`); } } /** * console error * @param {String} msg console content */ function error(msg) { console.error(`[Vue-infinite-loading error]: ${msg}`); } const throttleer = { timers: [], caches: [], throttle(fn) { if (this.caches.indexOf(fn) === -1) { // cache current handler this.caches.push(fn); // save timer for current handler this.timers.push(setTimeout(() => { fn(); // empty cache and timer this.caches.splice(this.caches.indexOf(fn), 1); this.timers.shift(); }, config.system.throttleLimit)); } }, reset() { // reset all timers this.timers.forEach((timer) => { clearTimeout(timer); }); this.timers.length = 0; // empty caches this.caches = []; }, }; const loopTracker = { isChecked: false, timer: null, times: 0, track() { // record track times this.times += 1; // try to mark check status clearTimeout(this.timer); this.timer = setTimeout(() => { this.isChecked = true; }, config.system.loopCheckTimeout); // throw warning if the times of continuous calls large than the maximum times if (this.times > config.system.loopCheckMaxCalls) { error(ERRORS.INFINITE_LOOP); this.isChecked = true; } }, }; const scrollBarStorage = { key: '_infiniteScrollHeight', getScrollElm(elm) { return elm === window ? document.documentElement : elm; }, save(elm) { const target = this.getScrollElm(elm); // save scroll height on the scroll parent target[this.key] = target.scrollHeight; }, restore(elm) { const target = this.getScrollElm(elm); /* istanbul ignore else */ if (typeof target[this.key] === 'number') { target.scrollTop = target.scrollHeight - target[this.key] + target.scrollTop; } this.remove(target); }, remove(elm) { if (elm[this.key] !== undefined) { // remove scroll height delete elm[this.key]; // eslint-disable-line no-param-reassign } }, }; /** * kebab-case a camel-case string * @param {String} str source string * @return {String} */ function kebabCase(str) { return str.replace(/[A-Z]/g, s => `-${s.toLowerCase()}`); } /** * get visibility for element * @param {DOM} elm * @return {Boolean} */ function isVisible(elm) { return (elm.offsetWidth + elm.offsetHeight) > 0; } var eventBus = { $on: (...args) => emitter.on(...args), $once: (...args) => emitter.once(...args), $off: (...args) => emitter.off(...args), $emit: (...args) => emitter.emit(...args) }; var script = vue.defineComponent({ name: 'InfiniteLoading', components: { Spinner: script$1, }, props: { distance: { type: Number, default: config.props.distance, }, spinner: String, direction: { type: String, default: 'bottom', }, forceUseInfiniteWrapper: { type: [Boolean, String], default: config.props.forceUseInfiniteWrapper, }, identifier: { type: [Number, String], default: +new Date(), }, onInfinite: Function, }, emits: ['infinite'], setup(props, { emit }) { return { props, emit, }; }, data() { return { scrollParent: null, scrollHandler: null, isFirstLoad: true, // save the current loading whether it is the first loading status: STATUS.READY, slots: config.slots, }; }, computed: { isShowSpinner() { return this.status === STATUS.LOADING; }, isShowError() { return this.status === STATUS.ERROR; }, isShowNoResults() { return ( this.status === STATUS.COMPLETE && this.isFirstLoad ); }, isShowNoMore() { return ( this.status === STATUS.COMPLETE && !this.isFirstLoad ); }, slotStyles() { const styles = {}; Object.keys(config.slots).forEach((key) => { const name = kebabCase(key); if ( // no slot and the configured default slot is not a Vue component ( !this.$slots[name] && !config.slots[key].render ) // has slot and slot is pure text node || ( this.$slots[name] && !this.$slots[name]()[0].tag ) ) { // only apply default styles for pure text slot styles[key] = SLOT_STYLES; } }); return styles; }, }, watch: { identifier() { this.stateChanger.reset(); }, }, created() { this.bus = eventBus; }, mounted() { this.$watch('forceUseInfiniteWrapper', () => { this.scrollParent = this.getScrollParent(); }, { immediate: true }); this.scrollHandler = (ev) => { if (this.status === STATUS.READY) { if (ev && ev.constructor === Event && isVisible(this.$el)) { throttleer.throttle(this.attemptLoad); } else { this.attemptLoad(); } } }; setTimeout(() => { this.scrollHandler(); this.scrollParent.addEventListener('scroll', this.scrollHandler, evt3rdArg); }, 1); this.bus.$on('$InfiniteLoading:loaded', (ev) => { this.isFirstLoad = false; if (this.direction === 'top') { // wait for DOM updated this.$nextTick(() => { scrollBarStorage.restore(this.scrollParent); }); } if (this.status === STATUS.LOADING) { this.$nextTick(this.attemptLoad.bind(null, true)); } if (!ev || ev.target !== this) { warn(WARNINGS.STATE_CHANGER); } }); this.bus.$on('$InfiniteLoading:complete', (ev) => { this.status = STATUS.COMPLETE; // force re-complation computed properties to fix the problem of get slot text delay this.$nextTick(() => { this.$forceUpdate(); }); this.scrollParent.removeEventListener('scroll', this.scrollHandler, evt3rdArg); if (!ev || ev.target !== this) { warn(WARNINGS.STATE_CHANGER); } }); this.bus.$on('$InfiniteLoading:reset', (ev) => { this.status = STATUS.READY; this.isFirstLoad = true; scrollBarStorage.remove(this.scrollParent); this.scrollParent.addEventListener('scroll', this.scrollHandler, evt3rdArg); // wait for list to be empty and the empty action may trigger a scroll event setTimeout(() => { throttleer.reset(); this.scrollHandler(); }, 1); if (!ev || ev.target !== this) { warn(WARNINGS.IDENTIFIER); } }); /** * change state for this component, pass to the callback */ this.stateChanger = { loaded: () => { this.bus.$emit('$InfiniteLoading:loaded', { target: this }); }, complete: () => { this.bus.$emit('$InfiniteLoading:complete', { target: this }); }, reset: () => { this.bus.$emit('$InfiniteLoading:reset', { target: this }); }, error: () => { this.status = STATUS.ERROR; throttleer.reset(); }, }; }, /** * To adapt to keep-alive feature, but only work on Vue 2.2.0 and above, see: https://vuejs.org/v2/api/#keep-alive */ deactivated() { /* istanbul ignore else */ if (this.status === STATUS.LOADING) { this.status = STATUS.READY; } this.scrollParent.removeEventListener('scroll', this.scrollHandler, evt3rdArg); }, activated() { this.scrollParent.addEventListener('scroll', this.scrollHandler, evt3rdArg); }, unmounted() { /* istanbul ignore else */ if (!this.status !== STATUS.COMPLETE) { throttleer.reset(); scrollBarStorage.remove(this.scrollParent); this.scrollParent.removeEventListener('scroll', this.scrollHandler, evt3rdArg); } }, methods: { /** * attempt trigger load * @param {Boolean} isContinuousCall the flag of continuous call, it will be true * if this method be called in the `loaded` * event handler */ attemptLoad(isContinuousCall) { if ( this.status !== STATUS.COMPLETE && isVisible(this.$el) && this.getCurrentDistance() <= this.distance ) { this.status = STATUS.LOADING; if (this.direction === 'top') { // wait for spinner display this.$nextTick(() => { scrollBarStorage.save(this.scrollParent); }); } if (typeof this.onInfinite === 'function') { this.onInfinite.call(null, this.stateChanger); } else { this.$emit('infinite', this.stateChanger); } if (isContinuousCall && !this.forceUseInfiniteWrapper && !loopTracker.isChecked) { // check this component whether be in an infinite loop if it is not checked // more details: https://github.com/PeachScript/vue-infinite-loading/issues/55#issuecomment-316934169 loopTracker.track(); } } else if (this.status === STATUS.LOADING) { this.status = STATUS.READY; } }, /** * get current distance from the specified direction * @return {Number} distance */ getCurrentDistance() { let distance; if (this.direction === 'top') { distance = typeof this.scrollParent.scrollTop === 'number' ? this.scrollParent.scrollTop : this.scrollParent.pageYOffset; } else { const infiniteElmOffsetTopFromBottom = this.$el.getBoundingClientRect().top; const scrollElmOffsetTopFromBottom = this.scrollParent === window ? window.innerHeight : this.scrollParent.getBoundingClientRect().bottom; distance = infiniteElmOffsetTopFromBottom - scrollElmOffsetTopFromBottom; } return distance; }, /** * get the first scroll parent of an element * @param {DOM} elm cache element for recursive search * @return {DOM} the first scroll parent */ getScrollParent(elm = this.$el) { let result; if (typeof this.forceUseInfiniteWrapper === 'string') { result = document.querySelector(this.forceUseInfiniteWrapper); } if (!result) { if (!elm || elm.tagName === 'BODY') { result = window; } else if (!this.forceUseInfiniteWrapper && ['scroll', 'auto'].indexOf(getComputedStyle(elm).overflowY) > -1) { result = elm; } else if (elm.hasAttribute('infinite-wrapper') || elm.hasAttribute('data-infinite-wrapper')) { result = elm; } } return result || this.getScrollParent(elm.parentNode); }, }, }); const _hoisted_1 = { class: "infinite-loading-container" }; const _hoisted_2 = ["textContent"]; function render(_ctx, _cache, $props, $setup, $data, $options) { const _component_spinner = vue.resolveComponent("spinner"); return (vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [ vue.withDirectives(vue.createElementVNode("div", { class: "infinite-status-prompt", style: vue.normalizeStyle(_ctx.slotStyles.spinner) }, [ vue.renderSlot(_ctx.$slots, "spinner", vue.normalizeProps(vue.guardReactiveProps({ isFirstLoad: _ctx.isFirstLoad })), () => [ vue.createVNode(_component_spinner, { spinner: _ctx.spinner }, null, 8 /* PROPS */, ["spinner"]) ]) ], 4 /* STYLE */), [ [vue.vShow, _ctx.isShowSpinner] ]), vue.withDirectives(vue.createElementVNode("div", { class: "infinite-status-prompt", style: vue.normalizeStyle(_ctx.slotStyles.noResults) }, [ vue.renderSlot(_ctx.$slots, "no-results", {}, () => [ (_ctx.slots.noResults.render) ? (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.slots.noResults), { key: 0 })) : (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 1 }, [ vue.createTextVNode(vue.toDisplayString(_ctx.slots.noResults), 1 /* TEXT */) ], 64 /* STABLE_FRAGMENT */)) ]) ], 4 /* STYLE */), [ [vue.vShow, _ctx.isShowNoResults] ]), vue.withDirectives(vue.createElementVNode("div", { class: "infinite-status-prompt", style: vue.normalizeStyle(_ctx.slotStyles.noMore) }, [ vue.renderSlot(_ctx.$slots, "no-more", {}, () => [ (_ctx.slots.noMore.render) ? (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.slots.noMore), { key: 0 })) : (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 1 }, [ vue.createTextVNode(vue.toDisplayString(_ctx.slots.noMore), 1 /* TEXT */) ], 64 /* STABLE_FRAGMENT */)) ]) ], 4 /* STYLE */), [ [vue.vShow, _ctx.isShowNoMore] ]), vue.withDirectives(vue.createElementVNode("div", { class: "infinite-status-prompt", style: vue.normalizeStyle(_ctx.slotStyles.error) }, [ vue.renderSlot(_ctx.$slots, "error", { trigger: _ctx.attemptLoad }, () => [ (_ctx.slots.error.render) ? (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.slots.error), { key: 0, trigger: _ctx.attemptLoad }, null, 8 /* PROPS */, ["trigger"])) : (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 1 }, [ vue.createTextVNode(vue.toDisplayString(_ctx.slots.error) + " ", 1 /* TEXT */), _cache[1] || (_cache[1] = vue.createElementVNode("br", null, null, -1 /* CACHED */)), vue.createElementVNode("button", { class: "btn-try-infinite", onClick: _cache[0] || (_cache[0] = (...args) => (_ctx.attemptLoad && _ctx.attemptLoad(...args))), textContent: vue.toDisplayString(_ctx.slots.errorBtnText) }, null, 8 /* PROPS */, _hoisted_2) ], 64 /* STABLE_FRAGMENT */)) ]) ], 4 /* STYLE */), [ [vue.vShow, _ctx.isShowError] ]) ])) } var css_248z = ".loading-wave-dots[data-v-231b1688] {\n position: relative;\n}\n.loading-wave-dots[data-v-231b1688] .wave-item {\n position: absolute;\n top: 50%;\n left: 50%;\n display: inline-block;\n margin-top: -4px;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n animation: loading-wave-dots-231b1688 linear 2.8s infinite;\n}\n.loading-wave-dots[data-v-231b1688] .wave-item:first-child {\n margin-left: -36px;\n}\n.loading-wave-dots[data-v-231b1688] .wave-item:nth-child(2) {\n margin-left: -20px;\n animation-delay: 0.14s;\n}\n.loading-wave-dots[data-v-231b1688] .wave-item:nth-child(3) {\n margin-left: -4px;\n animation-delay: 0.28s;\n}\n.loading-wave-dots[data-v-231b1688] .wave-item:nth-child(4) {\n margin-left: 12px;\n animation-delay: 0.42s;\n}\n.loading-wave-dots[data-v-231b1688] .wave-item:last-child {\n margin-left: 28px;\n animation-delay: 0.56s;\n}\n@keyframes loading-wave-dots-231b1688 {\n0% {\n transform: translateY(0);\n background: #bbb;\n}\n10% {\n transform: translateY(-6px);\n background: #999;\n}\n20% {\n transform: translateY(0);\n background: #bbb;\n}\n100% {\n transform: translateY(0);\n background: #bbb;\n}\n}\n.loading-circles[data-v-231b1688] .circle-item {\n width: 5px;\n height: 5px;\n animation: loading-circles-231b1688 linear 0.75s infinite;\n}\n.loading-circles[data-v-231b1688] .circle-item:first-child {\n margin-top: -14.5px;\n margin-left: -2.5px;\n}\n.loading-circles[data-v-231b1688] .circle-item:nth-child(2) {\n margin-top: -11.26px;\n margin-left: 6.26px;\n}\n.loading-circles[data-v-231b1688] .circle-item:nth-child(3) {\n margin-top: -2.5px;\n margin-left: 9.5px;\n}\n.loading-circles[data-v-231b1688] .circle-item:nth-child(4) {\n margin-top: 6.26px;\n margin-left: 6.26px;\n}\n.loading-circles[data-v-231b1688] .circle-item:nth-child(5) {\n margin-top: 9.5px;\n margin-left: -2.5px;\n}\n.loading-circles[data-v-231b1688] .circle-item:nth-child(6) {\n margin-top: 6.26px;\n margin-left: -11.26px;\n}\n.loading-circles[data-v-231b1688] .circle-item:nth-child(7) {\n margin-top: -2.5px;\n margin-left: -14.5px;\n}\n.loading-circles[data-v-231b1688] .circle-item:last-child {\n margin-top: -11.26px;\n margin-left: -11.26px;\n}\n@keyframes loading-circles-231b1688 {\n0% {\n background: rgb(222.8, 222.8, 222.8);\n}\n90% {\n background: #505050;\n}\n100% {\n background: rgb(222.8, 222.8, 222.8);\n}\n}\n.loading-bubbles[data-v-231b1688] .bubble-item {\n background: #666;\n animation: loading-bubbles-231b1688 linear 0.75s infinite;\n}\n.loading-bubbles[data-v-231b1688] .bubble-item:first-child {\n margin-top: -12.5px;\n margin-left: -0.5px;\n}\n.loading-bubbles[data-v-231b1688] .bubble-item:nth-child(2) {\n margin-top: -9.26px;\n margin-left: 8.26px;\n}\n.loading-bubbles[data-v-231b1688] .bubble-item:nth-child(3) {\n margin-top: -0.5px;\n margin-left: 11.5px;\n}\n.loading-bubbles[data-v-231b1688] .bubble-item:nth-child(4) {\n margin-top: 8.26px;\n margin-left: 8.26px;\n}\n.loading-bubbles[data-v-231b1688] .bubble-item:nth-child(5) {\n margin-top: 11.5px;\n margin-left: -0.5px;\n}\n.loading-bubbles[data-v-231b1688] .bubble-item:nth-child(6) {\n margin-top: 8.26px;\n margin-left: -9.26px;\n}\n.loading-bubbles[data-v-231b1688] .bubble-item:nth-child(7) {\n margin-top: -0.5px;\n margin-left: -12.5px;\n}\n.loading-bubbles[data-v-231b1688] .bubble-item:last-child {\n margin-top: -9.26px;\n margin-left: -9.26px;\n}\n@keyframes loading-bubbles-231b1688 {\n0% {\n width: 1px;\n height: 1px;\n box-shadow: 0 0 0 3px #666;\n}\n90% {\n width: 1px;\n height: 1px;\n box-shadow: 0 0 0 0 #666;\n}\n100% {\n width: 1px;\n height: 1px;\n box-shadow: 0 0 0 3px #666;\n}\n}\n.loading-default[data-v-231b1688] {\n position: relative;\n border: 1px solid #999;\n animation: loading-rotating-231b1688 ease 1.5s infinite;\n}\n.loading-default[data-v-231b1688]:before {\n content: \"\";\n position: absolute;\n display: block;\n top: 0;\n left: 50%;\n margin-top: -3px;\n margin-left: -3px;\n width: 6px;\n height: 6px;\n background-color: #999;\n border-radius: 50%;\n}\n.loading-spiral[data-v-231b1688] {\n border: 2px solid #777;\n border-right-color: transparent;\n animation: loading-rotating-231b1688 linear 0.85s infinite;\n}\n@keyframes loading-rotating-231b1688 {\n0% {\n transform: rotate(0);\n}\n100% {\n transform: rotate(360deg);\n}\n}\n.loading-bubbles[data-v-231b1688],\n.loading-circles[data-v-231b1688] {\n position: relative;\n}\n.loading-circles[data-v-231b1688] .circle-item,\n.loading-bubbles[data-v-231b1688] .bubble-item {\n position: absolute;\n top: 50%;\n left: 50%;\n display: inline-block;\n border-radius: 50%;\n}\n.loading-circles[data-v-231b1688] .circle-item:nth-child(2),\n.loading-bubbles[data-v-231b1688] .bubble-item:nth-child(2) {\n animation-delay: 0.093s;\n}\n.loading-circles[data-v-231b1688] .circle-item:nth-child(3),\n.loading-bubbles[data-v-231b1688] .bubble-item:nth-child(3) {\n animation-delay: 0.186s;\n}\n.loading-circles[data-v-231b1688] .circle-item:nth-child(4),\n.loading-bubbles[data-v-231b1688] .bubble-item:nth-child(4) {\n animation-delay: 0.279s;\n}\n.loading-circles[data-v-231b1688] .circle-item:nth-child(5),\n.loading-bubbles[data-v-231b1688] .bubble-item:nth-child(5) {\n animation-delay: 0.372s;\n}\n.loading-circles[data-v-231b1688] .circle-item:nth-child(6),\n.loading-bubbles[data-v-231b1688] .bubble-item:nth-child(6) {\n animation-delay: 0.465s;\n}\n.loading-circles[data-v-231b1688] .circle-item:nth-child(7),\n.loading-bubbles[data-v-231b1688] .bubble-item:nth-child(7) {\n animation-delay: 0.558s;\n}\n.loading-circles[data-v-231b1688] .circle-item:last-child,\n.loading-bubbles[data-v-231b1688] .bubble-item:last-child {\n animation-delay: 0.651s;\n}\n.infinite-loading-container[data-v-231b1688] {\n clear: both;\n text-align: center;\n}\n.infinite-loading-container[data-v-231b1688] *[class^=loading-] {\n display: inline-block;\n margin: 5px 0;\n width: 28px;\n height: 28px;\n font-size: 28px;\n line-height: 28px;\n border-radius: 50%;\n}\n.btn-try-infinite[data-v-231b1688] {\n margin-top: 5px;\n padding: 5px 10px;\n color: #999;\n font-size: 14px;\n line-height: 1;\n background: transparent;\n border: 1px solid #ccc;\n border-radius: 3px;\n outline: none;\n cursor: pointer;\n}\n.btn-try-infinite[data-v-231b1688]:not(:active):hover {\n opacity: 0.8;\n}"; styleInject(css_248z); script.render = render; script.__scopeId = "data-v-231b1688"; script.__file = "src/components/InfiniteLoading.vue"; function syncModeFromVue(Vue) { config.mode = Vue.config.productionTip ? 'development' : 'production'; } Object.defineProperty(script, 'install', { configurable: false, enumerable: false, value(Vue, options) { // override default props Object.assign(config.props, options && options.props); // override default slots Object.assign(config.slots, options && options.slots); // override default system settings Object.assign(config.system, options && options.system); // register component Vue.component('InfiniteLoading', script); syncModeFromVue(Vue); }, }); // register component automatically if there has global Vue /* istanbul ignore else */ if (typeof window !== 'undefined' && window.Vue) { window.Vue.component('infinite-loading', script); syncModeFromVue(window.Vue); } return script; }));