Skip to content

Conversation

anupriya13
Copy link
Contributor

@anupriya13 anupriya13 commented Jul 8, 2025

Description

Type of Change

  • New feature (non-breaking change which adds functionality)

Why

Implement snapToInterval property for ScrollView in Fabric

Resolves #13150

What

https://reactnative.dev/docs/scrollview#snaptointerval
image

The snapToInterval property was available in the Paper implementation via ScrollViewManager.cpp but was missing from the Fabric implementation in ScrollViewComponentView.cpp. This meant that developers using the new architecture couldn't use interval-based snapping behavior.

Refer IOS https://github.com/facebook/react-native/blob/618279508159191f2b11c0b20446f91e82a27abf/packages/react-native/React/Views/ScrollView/RCTScrollView.m#L810C5-L813C8

Solution

Added comprehensive support for snapToInterval that:

  1. Detects property changes: Modified updateProps() to check for snapToInterval changes alongside existing snap properties
  2. Generates snap points: Created updateSnapPoints() helper method that converts interval values to discrete snap point offsets
  3. Handles content changes: Modified updateContentVisualSize() to recalculate snap points when content size changes
  4. Respects priority: Follows React Native behavior where snapToOffsets takes priority over snapToInterval

Implementation Details

updateSnapPoints() function sets up where the scroll view should snap when scrolling stops. It first checks if explicit snap positions (snapToOffsets) are provided and uses them. If not, and a snap interval is set (snapToInterval), it generates evenly spaced snap points across the content size. Finally, it updates the scroll visual to use these snap points.

// Property priority (matches React Native behavior)
if (viewProps.snapToOffsets.size() > 0) {
  // Use explicit snapToOffsets
} else if (viewProps.snapToInterval > 0) {
  // Generate snap points at regular intervals
  float interval = viewProps.snapToInterval * pointScaleFactor;
  for (float offset = 0; offset <= contentLength; offset += interval) {
    snapToOffsets.Append(offset);
  }
}

Step by Step:

✅ 1. Get the snap configuration from props

snapToOffsets: a list of exact positions to snap to

snapToInterval: a distance between each snap point

horizontal: whether the scroll is sideways

✅ 2. Decide which to use:

If snapToOffsets is provided and has items, it takes priority.

If not, but snapToInterval > 0, it generates snap points by repeating the interval.

✅ 3. Calculate how big the scrollable content is:

If horizontal, use the content width.

If vertical, use the content height.

Multiply by pointScaleFactor (to handle screen scaling).

✅ 4. Create snap points every interval distance:

For example, every 100 pixels, 200 pixels, etc.

Stop when you reach the end of content or hit a safety limit (max 1000 snap points).

✅ 5. Save the snap points in m_scrollVisual:

These will be used when scrolling stops to snap to the nearest position.

Testing

Playground tested

Changelog

Should this change be included in the release notes: yes

Add a brief summary of the change to use in the release notes for the next release.
Implement snapToInterval property for ScrollView in Fabric

Microsoft Reviewers: Open in CodeFlow

* Initial plan

* Implement snapToInterval property for Fabric ScrollView

Co-authored-by: anupriya13 <[email protected]>

* Add safety checks to snapToInterval implementation and remove duplication

Co-authored-by: anupriya13 <[email protected]>

* Change files

* Run yarn change prerelease, lint:fix, and format as requested

Co-authored-by: anupriya13 <[email protected]>

* Remove changes in vnext/codegen files as requested

Co-authored-by: anupriya13 <[email protected]>

* Restore original inline snap points logic while preserving snapToInterval support

Co-authored-by: anupriya13 <[email protected]>

* Optimize snapToInterval performance by reducing recalculation frequency

Co-authored-by: anupriya13 <[email protected]>

* Revert commit 4bbc0b9 as requested

Co-authored-by: anupriya13 <[email protected]>

* Update ScrollViewComponentView.cpp

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: anupriya13 <[email protected]>
@anupriya13 anupriya13 marked this pull request as ready for review July 8, 2025 09:49
@anupriya13 anupriya13 requested a review from a team as a code owner July 8, 2025 09:49
@anupriya13 anupriya13 changed the title Implement snapToInterval property for ScrollView in Fabric [Fabric] Implement snapToInterval property for ScrollView Jul 9, 2025
@anupriya13
Copy link
Contributor Author

Waiting on review since long time > assigned to @sharath2727 for iteration 2507-02
Let's discuss any issues in PR here rather than offline so that it's documented

m_scrollVisual.ContentSize(contentSize);

// Update snap points if snapToInterval is being used, as content size affects the number of snap points
updateSnapPoints();
Copy link
Contributor

Choose a reason for hiding this comment

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

what is the scenario for this? In the sense when would this be called? is it during initialization?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's whenever the content size is changed the offsets / intervals would be updated as per new dimensions

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah I see. so basically if layout size changes during runtime and then this gets triggered. Got it. Thank you for helping me understand this code better. I hope all the tests are validated to the best of your knowledge.

Copy link
Contributor

@sharath2727 sharath2727 left a comment

Choose a reason for hiding this comment

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

Approved with one pending question.

@anupriya13
Copy link
Contributor Author

Merging as discussed in the meeting

@anupriya13 anupriya13 merged commit 2cde3f1 into main Jul 15, 2025
58 checks passed
@anupriya13 anupriya13 deleted the user/anuverma/snapToInterval branch August 8, 2025 05:03
anupriya13 added a commit to anupriya13/react-native-windows that referenced this pull request Sep 29, 2025
anupriya13 added a commit to anupriya13/react-native-windows that referenced this pull request Sep 29, 2025
anupriya13 added a commit that referenced this pull request Sep 30, 2025
* Revert "[Fabric] Implement snapToAlignment property for ScrollView  (#14841)"

This reverts commit 6bd0793.

* Revert "[Fabric] Implement snapToInterval property for ScrollView  (#14847)"

This reverts commit 2cde3f1.

* Change files
anupriya13 added a commit that referenced this pull request Sep 30, 2025
… stable 0.80 (#15183)

* Revert "[Fabric] Implement snapToAlignment property for ScrollView  (#14841)"

This reverts commit 6bd0793.

* Revert "[Fabric] Implement snapToInterval property for ScrollView  (#14847)"

This reverts commit 2cde3f1.

* Implement onMomentumScrollEnd and onMomentumScrollBegin for Fabric ScrollView (#15104)

* Initial plan

* Implement onMomentumScrollEnd and onMomentumScrollBegin for Fabric ScrollView

Co-authored-by: anupriya13 <[email protected]>

* Add change file for momentum scroll implementation

Co-authored-by: anupriya13 <[email protected]>

* Add momentum scroll events test to playground ScrollView sample

Co-authored-by: anupriya13 <[email protected]>

* Remove vnext/codegen directory changes as requested

Co-authored-by: anupriya13 <[email protected]>

* Update CompositionContextHelper.cpp

* Update CompositionContextHelper.cpp

* Update CompositionContextHelper.cpp

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: anupriya13 <[email protected]>

---------

Co-authored-by: Copilot <[email protected]>
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.

Implement snapToInterval property for ScrollView for fabric

3 participants