Skip to content

fix: Virtualizer should layout items using a consistent size#9889

Merged
devongovett merged 3 commits intomainfrom
fix-virtualizer-size
Apr 8, 2026
Merged

fix: Virtualizer should layout items using a consistent size#9889
devongovett merged 3 commits intomainfrom
fix-virtualizer-size

Conversation

@devongovett
Copy link
Copy Markdown
Member

Fixes an issue caught in our S2 example apps in small viewports where the card view would appear to scroll faster than the rest of the page. This was due to the visibleRect changing size as the window scrolls when the CardView is larger than the window viewport. We need this to implement window scrolling, but the layouts (e.g. GridLayout) also use the visibleRect's size to determine how many columns of items to display etc. This resulted in the layout's contentSize being updated during scrolling, causing the scroll position to be clamped.

To fix this we need to introduce a separate virtualizer.size property to hold the size of the virtualizer regardless of the window scroll position. This way item layout is consistent. ScrollView now has an onSizeChange callback and this gets propagated down to the virtualizer state.

To make this not a breaking change which would require updates to v3, window scrolling support is now opt-in in the hooks, and only enabled by default in RAC. We fall back to the visibleRect size in this case.

Copy link
Copy Markdown
Member

@snowystinger snowystinger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested mobile and desktop, looks like the CardView is now working as expected. Will wait for verdaccio to be disabled again and then I'll approve

This reverts commit be5b1c5.
@rspbot
Copy link
Copy Markdown

rspbot commented Apr 8, 2026

@rspbot
Copy link
Copy Markdown

rspbot commented Apr 8, 2026

## API Changes

@react-aria/virtualizer

/@react-aria/virtualizer:ScrollView

 ScrollView extends HTMLAttributes {
+  allowsWindowScrolling?: boolean
   children?: ReactNode
   contentSize: Size
   innerStyle?: CSSProperties
   onScroll?: (Event) => void
   onScrollEnd?: () => void
   onScrollStart?: () => void
+  onSizeChange?: (Size) => void
   onVisibleRectChange: (Rect) => void
   scrollDirection?: 'horizontal' | 'vertical' | 'both'
 }

@react-stately/virtualizer

/@react-stately/virtualizer:VirtualizerState

 VirtualizerState <T extends {}, V> {
   contentSize: Size
   endScrolling: () => void
   isScrolling: boolean
+  setSize: (Size) => void
   setVisibleRect: (Rect) => void
+  size: Size
   startScrolling: () => void
   virtualizer: Virtualizer<{}, V>
   visibleViews: Array<ReusableView<{}, V>>
 }

@devongovett devongovett added this pull request to the merge queue Apr 8, 2026
Merged via the queue into main with commit 3a98ca0 Apr 8, 2026
29 checks passed
@devongovett devongovett deleted the fix-virtualizer-size branch April 8, 2026 23:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants