@codog/vue3-infinite-loading
Version:
An infinite scroll plugin for Vue.js
796 lines (703 loc) • 35.4 kB
JavaScript
(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 ="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;
}));