Skip to content

Commit

Permalink
fix(gridSystem.ts): call onEndReached when the data is less than cont… (
Browse files Browse the repository at this point in the history
#1166)

* fix(gridSystem.ts): call onEndReached when the data is less than container size

* chore(gridSystem.ts): code refactor

* chore(gridStstem): update only endReached fn

* chore(gridSystem): use totalCount instead of data.length

* chore(gridSystem): avoid usage of `data` in endReached fn
  • Loading branch information
prasannamestha authored Dec 1, 2024
1 parent fa4934d commit 7a80ea2
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 5 deletions.
32 changes: 32 additions & 0 deletions examples/grid-infinite-data.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import * as React from 'react'
import { useState } from 'react'
import { VirtuosoGrid } from '../src'

function generateItems(length: number) {
return Array.from({ length }, (_, index) => `My Item ${index}`)
}

const itemContent = (_: number, data: string) => {
return <div style={{ height: 30 }}>{data}</div>
}
export function Example() {
const [data, setData] = useState(() => generateItems(5))

const loadMore = () => {
setTimeout(() => {
setData((prevData) => {
return generateItems(prevData.length + 5)
})
}, 100)
}

return (
<div
style={{
border: '1px solid',
}}
>
<VirtuosoGrid data={data} itemContent={itemContent} style={{ height: 300 }} endReached={loadMore} />
</div>
)
}
24 changes: 19 additions & 5 deletions src/gridSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,11 +310,25 @@ export const gridSystem = /*#__PURE__*/ u.system(

const endReached = u.streamFromEmitter(
u.pipe(
u.duc(gridState),
u.filter(({ items }) => items.length > 0),
u.withLatestFrom(totalCount, hasScrolled),
u.filter(([{ items }, totalCount, hasScrolled]) => hasScrolled && items[items.length - 1].index === totalCount - 1),
u.map(([, totalCount]) => totalCount - 1),
u.combineLatest(gridState, totalCount),
u.filter(([{ items }]) => items.length > 0),
u.withLatestFrom(hasScrolled),
u.filter(([[gridState, totalCount], hasScrolled]) => {
const lastIndex = gridState.items[gridState.items.length - 1].index
const isLastItemRendered = lastIndex === totalCount - 1

// User has scrolled
if (hasScrolled) return isLastItemRendered

// User has not scrolled, so check whether grid is fully rendered
const isFullyRendered =
gridState.bottom > 0 && gridState.itemHeight > 0 && gridState.offsetBottom === 0 && gridState.items.length === totalCount

return isFullyRendered && isLastItemRendered
}),
u.map(([[, totalCount]]) => {
return totalCount - 1
}),
u.distinctUntilChanged()
)
)
Expand Down

0 comments on commit 7a80ea2

Please sign in to comment.