Skip to content

Conversation

@nwidynski
Copy link
Contributor

@nwidynski nwidynski commented Oct 30, 2025

This change aims to break up useScrollView into two generic hooks, designed to be reusable outside of virtualization:

  • useScrollObserver() - built for generic observation of a scrollport inside a scroll container
  • useScrollView - a tiny wrapper on observation, for containers of controlled and uncontrolled content sizes

Along with these hooks, this PR migrates layout utilities, such as Rect/Point/Size, to @react-stately/utils and @react-aria/utils while also expanding upon getRTLOffsetType with support for flex-direction: reverse containers.

Lastly, along with minor bug-fixes, this PR refactors the VIRT_ON flag to be contained to a single place, while providing more realistic measurements in test environments. This should improve the risk of this flag impacting user code.

✅ Pull Request Checklist:

  • Included link to corresponding React Spectrum GitHub Issue.
  • Added/updated unit tests and storybook for this change (for new code or code which already has tests).
  • Filled out test instructions.
  • Updated documentation (if it already exists for this component).
  • Looked at the Accessibility Practices for this feature - Aria Practices

📝 Test Instructions:

🧢 Your Project:

Copy link
Contributor Author

@nwidynski nwidynski left a comment

Choose a reason for hiding this comment

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

This should be in a working state and good for a round of review!


constructor(width = 0, height = 0) {
this.width = Math.min(Math.max(width, 0), Number.MAX_SAFE_INTEGER) || 0;
this.height = Math.min(Math.max(height, 0), Number.MAX_SAFE_INTEGER) || 0;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added an upper bound here, maybe we should do this also for Point and Size?

* @param rect - The rectangle to check.
*/
intersects(rect: IRect): boolean {
return (this.area > 0 && (rect.width * rect.height) > 0)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@LFDanLu Removing the Rect intersection bypass, as scrollWidth is now always set by the stub in useScrollViewRef. This also fixes the regression I mentioned.

rect = this._overscanManager.getOverscannedRect();
}
let layoutInfos = this.layout.getVisibleLayoutInfos(rect);
let layoutInfos = rect.area === 0 ? [] : this.layout.getVisibleLayoutInfos(rect);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This isn't required, but we regressed on this previously, so I think its safer to keep just in case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant