Skip to content

Conversation

@nwidynski
Copy link
Contributor

This PR refactors scrollIntoView and scrollIntoViewport to support scrollMargin, while working around the regressions mentioned in #8689 (comment). Additionally, a new inline & block option for alignment of a container element has been added.

By leveraging bounding rectangles, the internal calculations are now streamlined with DOMLayoutDelegate and significantly simplified.

✅ 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:

Comment on lines +145 to +152
let {left: newLeft, top: newTop} = targetElement.getBoundingClientRect();
// Account for sub pixel differences from rounding
if ((Math.abs(originalLeft - newLeft) > 1) || (Math.abs(originalTop - newTop) > 1)) {
scrollParents = containingElement ? getScrollParents(containingElement, true) : [];
for (let scrollParent of scrollParents) {
scrollIntoView(scrollParent as HTMLElement, containingElement as HTMLElement, {block: 'center', inline: 'center'});
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since we added the bypass for chrome, this now also supports alternative alignments, to center the containingElement. This was missing in the previous PR also 👍

if (!isScrollPrevented) {
scrollParents.push(root);
}
let scrollParents = getScrollParents(targetElement, true);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just noting that this does not behave like the native equivalent, since it skips overflow:hidden scroll parents. This potential issue also existed before this PR, so I don't think it's a blocker.

Comment on lines +80 to +84
if (shouldScrollBlock && block === 'start') {
y += scrollAreaLeft - scrollPortLeft;
} else if (shouldScrollBlock && block === 'center') {
y += (scrollAreaTop + scrollAreaBottom) / 2 - (scrollPortTop + scrollPortBottom) / 2;
} else if (shouldScrollBlock && block === 'end') {
Copy link
Contributor Author

@nwidynski nwidynski Nov 5, 2025

Choose a reason for hiding this comment

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

Native scrollIntoView only checks for shouldScroll with the nearest alignment option. Should we also do that?

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