import { ref, watch, nextTick, onUpdated, onMounted } from 'vue'; // Utils import { createNamespace } from '../utils'; import { isHidden } from '../utils/dom/style'; // Composition import { useRect } from '../composition/use-rect'; import { useScroller } from '../composition/use-scroller'; import { usePublicApi } from '../composition/use-public-api'; import { useGlobalEvent } from '../composition/use-global-event'; // Components import Loading from '../loading'; const [createComponent, bem, t] = createNamespace('list'); export default createComponent({ props: { error: Boolean, loading: Boolean, finished: Boolean, errorText: String, loadingText: String, finishedText: String, immediateCheck: { type: Boolean, default: true, }, offset: { type: [Number, String], default: 300, }, direction: { type: String, default: 'down', }, }, emits: ['load', 'update:error', 'update:loading'], setup(props, { emit, slots }) { // use sync innerLoading state to avoid repeated loading in some edge cases const loading = ref(false); const rootRef = ref(); const placeholderRef = ref(); const scroller = useScroller(rootRef); const check = () => { nextTick(() => { if (loading.value || props.finished || props.error) { return; } const { offset, direction } = props; let scrollerRect; if (scroller.value.getBoundingClientRect) { scrollerRect = scroller.value.getBoundingClientRect(); } else { scrollerRect = { top: 0, bottom: scroller.value.innerHeight, }; } const scrollerHeight = scrollerRect.bottom - scrollerRect.top; /* istanbul ignore next */ if (!scrollerHeight || isHidden(rootRef.value)) { return false; } let isReachEdge = false; const placeholderRect = useRect(placeholderRef); if (direction === 'up') { isReachEdge = scrollerRect.top - placeholderRect.top <= offset; } else { isReachEdge = placeholderRect.bottom - scrollerRect.bottom <= offset; } if (isReachEdge) { loading.value = true; emit('update:loading', true); emit('load'); } }); }; const renderFinishedText = () => { if (props.finished) { const text = slots.finished ? slots.finished() : props.finishedText; if (text) { return