Skip to content

Commit

Permalink
fix: don't show list before location reached
Browse files Browse the repository at this point in the history
  • Loading branch information
petyosi committed Mar 20, 2024
1 parent f4add10 commit 02d258d
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 11 deletions.
13 changes: 11 additions & 2 deletions examples/initial-topmost-item-default-height.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export function BombProps() {
// const [channelId, setChannelId] = React.useState(1);
useSuppressResizeObserverError()
const [bogus, setBogus] = React.useState(0)
const [key, setKey] = React.useState(0)

React.useEffect(() => {
setTimeout(() => {
Expand All @@ -45,10 +46,17 @@ export function BombProps() {
}, 2)
}, 2)
}, 2)
}, [])
}, [key])

return (
<div className="App">
<button
onClick={() => {
setKey((k) => k + 1)
}}
>
Change channel
</button>
{/*
<button
onClick={() => {
Expand Down Expand Up @@ -76,6 +84,7 @@ export function BombProps() {
*/}

<Virtuoso
key={`channel-${key}`}
logLevel={LogLevel.DEBUG}
totalCount={15}
context={{ bogus }}
Expand All @@ -84,7 +93,7 @@ export function BombProps() {
return (
<div
style={{
height: index % 2 ? 200 : 100,
height: index % 2 ? 450 : 560,
background: index % 2 ? 'red' : 'blue',
}}
>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "react-virtuoso",
"author": "Petyo Ivanov",
"sideEffects": false,
"version": "0.0.0-development",
"version": "4.8.0-development",
"homepage": "https://virtuoso.dev/",
"license": "MIT",
"source": "src/index.tsx",
Expand Down
4 changes: 2 additions & 2 deletions src/Virtuoso.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ const Items = /*#__PURE__*/ React.memo(function VirtuosoItems({ showTopList = fa
const isSeeking = useEmitterValue('isSeeking')
const hasGroups = useEmitterValue('groupIndices').length > 0
const alignToBottom = useEmitterValue('alignToBottom')
const scrolledToInitialItem = useEmitterValue('scrolledToInitialItem')
const initialItemFinalLocationReached = useEmitterValue('initialItemFinalLocationReached')

const containerStyle: React.CSSProperties = showTopList
? {}
Expand All @@ -121,7 +121,7 @@ const Items = /*#__PURE__*/ React.memo(function VirtuosoItems({ showTopList = fa
paddingTop: listState.offsetTop,
paddingBottom: listState.offsetBottom,
marginTop: deviation !== 0 ? deviation : alignToBottom ? 'auto' : 0,
...(scrolledToInitialItem ? {} : { visibility: 'hidden' }),
...(initialItemFinalLocationReached ? {} : { visibility: 'hidden' }),
}

if (!showTopList && listState.totalCount === 0 && EmptyPlaceholder) {
Expand Down
25 changes: 20 additions & 5 deletions src/initialTopMostItemIndexSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ export function getInitialTopMostItemIndexNumber(location: number | FlatIndexLoc
}

export const initialTopMostItemIndexSystem = u.system(
([{ sizes, listRefresh, defaultItemSize }, { scrollTop }, { scrollToIndex }, { didMount }]) => {
([{ sizes, listRefresh, defaultItemSize }, { scrollTop }, { scrollToIndex, scrollTargetReached }, { didMount }]) => {
const scrolledToInitialItem = u.statefulStream(true)
const initialTopMostItemIndex = u.statefulStream<number | FlatIndexLocationWithAlign>(0)
const scrollScheduled = u.statefulStream(false)
const initialItemFinalLocationReached = u.statefulStream(true)

u.connect(
u.pipe(
Expand All @@ -28,20 +28,34 @@ export const initialTopMostItemIndexSystem = u.system(
),
scrolledToInitialItem
)
u.connect(
u.pipe(
didMount,
u.withLatestFrom(initialTopMostItemIndex),
u.filter(([_, location]) => !!location),
u.mapTo(false)
),
initialItemFinalLocationReached
)

u.subscribe(
u.pipe(
u.combineLatest(listRefresh, didMount),
u.withLatestFrom(scrolledToInitialItem, sizes, defaultItemSize, scrollScheduled),
u.withLatestFrom(scrolledToInitialItem, sizes, defaultItemSize, initialItemFinalLocationReached),
u.filter(([[, didMount], scrolledToInitialItem, { sizeTree }, defaultItemSize, scrollScheduled]) => {
return didMount && (!empty(sizeTree) || u.isDefined(defaultItemSize)) && !scrolledToInitialItem && !scrollScheduled
}),
u.withLatestFrom(initialTopMostItemIndex)
),
([, initialTopMostItemIndex]) => {
u.publish(scrollScheduled, true)
u.handleNext(scrollTargetReached, () => {
u.publish(initialItemFinalLocationReached, true)
})

skipFrames(3, () => {
u.handleNext(scrollTop, () => u.publish(scrolledToInitialItem, true))
u.handleNext(scrollTop, () => {
u.publish(scrolledToInitialItem, true)
})
u.publish(scrollToIndex, initialTopMostItemIndex)
})
}
Expand All @@ -50,6 +64,7 @@ export const initialTopMostItemIndexSystem = u.system(
return {
scrolledToInitialItem,
initialTopMostItemIndex,
initialItemFinalLocationReached,
}
},
u.tup(sizeSystem, domIOSystem, scrollToIndexSystem, propsReadySystem),
Expand Down
3 changes: 2 additions & 1 deletion src/listSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export const listSystem = u.system(
gap,
sizes,
},
{ initialTopMostItemIndex, scrolledToInitialItem },
{ initialTopMostItemIndex, scrolledToInitialItem, initialItemFinalLocationReached },
domIO,
stateLoad,
followOutput,
Expand Down Expand Up @@ -104,6 +104,7 @@ export const listSystem = u.system(
sizeRanges,
initialTopMostItemIndex,
scrolledToInitialItem,
initialItemFinalLocationReached,
topItemsIndexes,
topItemCount,
groupCounts,
Expand Down
3 changes: 3 additions & 0 deletions src/scrollToIndexSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export const scrollToIndexSystem = u.system(
{ log },
]) => {
const scrollToIndex = u.stream<IndexLocation>()
const scrollTargetReached = u.stream<true>()
const topListHeight = u.statefulStream(0)

let unsubscribeNextListRefresh: any = null
Expand Down Expand Up @@ -106,6 +107,7 @@ export const scrollToIndexSystem = u.system(
log('retrying to scroll to', { location }, LogLevel.DEBUG)
u.publish(scrollToIndex, location)
} else {
u.publish(scrollTargetReached, true)
log('list did not change, scroll successful', {}, LogLevel.DEBUG)
}
}
Expand Down Expand Up @@ -142,6 +144,7 @@ export const scrollToIndexSystem = u.system(

return {
scrollToIndex,
scrollTargetReached,
topListHeight,
}
},
Expand Down

0 comments on commit 02d258d

Please sign in to comment.