Skip to content

Commit 4e96832

Browse files
[Web] Stop layout shift / scroll bounce in TrackLineup
Two follow-ups to the smoother infinite-scroll work, both visible while scrolling Trending: 1. Skeleton tiles in ordered lineups now reserve the order column. The desktop TrackTile previously hid the rank number and crown when `isLoading`, so the order column collapsed to ~0 width on a skeleton and the artwork shifted left when real data arrived. With the skeleton now rendering the index it's been told (`tiles.length + i`), the number / crown stay visible and the layout doesn't jump on load. 2. Skeleton tail is now constant while `hasNextPage`. Before, skeletons were gated on `isFetching || isLoadMoreTriggered`, so the page ballooned by ~one threshold's worth of skeletons when fetching, then shrank back when the page resolved. On a fast scroll deep into that shrinking region, the browser had to clamp `scrollTop`, which felt like the page "bouncing" mid-scroll. Keeping a constant skeleton tail until the end of the lineup means the scroll height only ever grows (smoothly, by `pageSize` tile-heights per resolved page) until `hasNextPage` flips to false at end-of-lineup. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 9b2ee3c commit 4e96832

2 files changed

Lines changed: 6 additions & 8 deletions

File tree

packages/web/src/components/lineup/TrackLineup.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ export const TrackLineup = ({
282282
}, [hasNextPage, isFetching, isLoadMoreTriggered, loadNextPage])
283283

284284
const renderSkeletons = useCallback(
285-
(skeletonCount: number | undefined) => {
285+
(skeletonCount: number | undefined, indexOffset = 0) => {
286286
if (!skeletonCount) return null
287287
return (
288288
<>
@@ -301,7 +301,7 @@ export const TrackLineup = ({
301301
<Flex direction={isSmallTrackTile ? 'row' : 'column'} w='100%'>
302302
{/* @ts-ignore - TrackTile types don't fully cover loading state */}
303303
<TrackTile
304-
index={index}
304+
index={indexOffset + index}
305305
size={tileSize}
306306
ordered={ordered}
307307
isLoading
@@ -435,8 +435,8 @@ export const TrackLineup = ({
435435
</Flex>
436436
))}
437437

438-
{(isFetching || isLoadMoreTriggered) && tiles.length > 0
439-
? renderSkeletons(loadingSkeletonCount)
438+
{hasNextPage && tiles.length > 0
439+
? renderSkeletons(loadingSkeletonCount, tiles.length)
440440
: null}
441441
</InfiniteScroll>
442442
</div>

packages/web/src/components/track/desktop/TrackTile.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -336,11 +336,9 @@ export const TrackTile = ({
336336
{/* prefix ordering */}
337337
{tileOrder && (
338338
<Flex column gap='2xs' alignItems='center' justifyContent='center'>
339-
{!isLoading && tileOrder <= 10 && (
340-
<IconCrown color='default' size='s' />
341-
)}
339+
{tileOrder <= 10 && <IconCrown color='default' size='s' />}
342340
<Text variant='label' color='default'>
343-
{!isLoading && tileOrder}
341+
{tileOrder}
344342
</Text>
345343
</Flex>
346344
)}

0 commit comments

Comments
 (0)