Skip to content

Commit

Permalink
fix(VInfiniteScroll): persist load logic until is intersected (#17475)
Browse files Browse the repository at this point in the history
fixes #17358

Co-authored-by: John Leider <john@vuetifyjs.com>
  • Loading branch information
yuwu9145 and johnleider authored Jun 27, 2023
1 parent 4922b2f commit f898404
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 4 deletions.
31 changes: 27 additions & 4 deletions packages/vuetify/src/labs/VInfiniteScroll/VInfiniteScroll.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export const VInfiniteScrollIntersect = defineComponent({
},

emits: {
intersect: (side: InfiniteScrollSide) => true,
intersect: (side: InfiniteScrollSide, isIntersecting: boolean) => true,
},

setup (props, { emit }) {
Expand All @@ -89,7 +89,7 @@ export const VInfiniteScrollIntersect = defineComponent({
} : undefined)

watch(isIntersecting, async val => {
if (val) emit('intersect', props.side)
emit('intersect', props.side, val)
})

useRender(() => (
Expand All @@ -114,6 +114,7 @@ export const VInfiniteScroll = genericComponent<VInfiniteScrollSlots>()({
const startStatus = ref<InfiniteScrollStatus>('ok')
const endStatus = ref<InfiniteScrollStatus>('ok')
const margin = computed(() => convertToUnit(props.margin))
const isIntersecting = ref(false)

function setScrollAmount (amount: number) {
if (!rootEl.value) return
Expand Down Expand Up @@ -166,7 +167,16 @@ export const VInfiniteScroll = genericComponent<VInfiniteScrollSlots>()({
}

let previousScrollSize = 0
function handleIntersect (side: InfiniteScrollSide) {
function handleIntersect (side: InfiniteScrollSide, _isIntersecting: boolean) {
isIntersecting.value = _isIntersecting
if (isIntersecting.value) {
intersecting(side)
}
}

function intersecting (side: InfiniteScrollSide) {
if (props.mode !== 'manual' && !isIntersecting.value) return

const status = getStatus(side)
if (!rootEl.value || status === 'loading') return

Expand All @@ -177,9 +187,22 @@ export const VInfiniteScroll = genericComponent<VInfiniteScrollSlots>()({
setStatus(side, status)

nextTick(() => {
if (status === 'empty' || status === 'error') return

if (status === 'ok' && side === 'start') {
setScrollAmount(getScrollSize() - previousScrollSize + getScrollAmount())
}
if (props.mode !== 'manual') {
nextTick(() => {
window.requestAnimationFrame(() => {
window.requestAnimationFrame(() => {
window.requestAnimationFrame(() => {
intersecting(side)
})
})
})
})
}
})
}

Expand All @@ -191,7 +214,7 @@ export const VInfiniteScroll = genericComponent<VInfiniteScrollSlots>()({
function renderSide (side: InfiniteScrollSide, status: InfiniteScrollStatus) {
if (props.side !== side && props.side !== 'both') return

const onClick = () => handleIntersect(side)
const onClick = () => intersecting(side)
const slotProps = { side, props: { onClick, color: props.color } }

if (status === 'error') return slots.error?.(slotProps)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import { VInfiniteScroll } from '../VInfiniteScroll'

// Utilities
import { ref } from 'vue'
import { createRange } from '@/util'

// Constants
Expand Down Expand Up @@ -76,4 +77,29 @@ describe('VInfiniteScroll', () => {
.get('.v-infinite-scroll .v-progress-circular').should('exist')
.get('@load').should('have.been.calledOnce')
})

// https://github.com/vuetifyjs/vuetify/issues/17358
it('should keep triggering load logic until VInfiniteScrollIntersect disappears', () => {
const loadTracker = cy.spy().as('loadTracker')
const items = ref(Array.from({ length: 3 }, (k, v) => v + 1))

const load = async ({ done }: any) => {
setTimeout(() => {
items.value.push(...Array.from({ length: 3 }, (k, v) => v + items.value.at(-1)! + 1))
loadTracker()
done('ok')
}, 100)
}

cy.viewport(400, 200)
.mount(() => (
<VInfiniteScroll onLoad={ load } mode="intersect">
{ items.value.map(item => (
<div>Item #{ item }</div>
))}
</VInfiniteScroll>
))
.get('.v-infinite-scroll .v-progress-circular').should('exist')
.get('@loadTracker').should('have.been.calledTwice')
})
})

0 comments on commit f898404

Please sign in to comment.