Skip to content

Scroll into view with sticky elements and page scrolling can cause bad-large jumps #10182

@lukpsaxo

Description

@lukpsaxo

Provide a general summary of the issue here

We have a table with the scrolling element above the table (now supported by your virtualizer, thanks!) and some sticky elements.

changing the focussed row down and up works, but when you press up going from the top table row to the table header, the page jumps and focus is now out of view.

🤔 Expected Behavior?

no significant jump when moving through rows

😯 Current Behavior

a big jump moving from the top table row to the table header.

💁 Possible Solution

Take this with a pinch of salt - this is what AI generated as a fix - it appears to work though:

+++ b/node_modules/react-aria/dist/private/utils/scrollIntoView.cjs
@@ -123,10 +123,17 @@ function $9a1324d6ffd8bbb0$export$c826860796309d1b(targetElement, opts = {}) {
             if (Math.abs(originalLeft - newLeft) > 1 || Math.abs(originalTop - newTop) > 1) {
                 scrollParents = containingElement ? (0, $e2a63525475bbd9f$exports.getScrollParents)(containingElement, true) : [];
                 // scroll containing element into view first, then rescroll target element into view like the non chrome flow above
-                for (let scrollParent of scrollParents)$9a1324d6ffd8bbb0$export$53a0910f038337bd(scrollParent, containingElement, {
-                    block: 'center',
-                    inline: 'center'
-                });
+                for (let scrollParent of scrollParents){
+                    // Saxo patch (react-spectrum #9780 edge case): only re-center the containing
+                    // element when it fits within the scroll parent's viewport. Centering a
+                    // containing element larger than the viewport (e.g. a full-height virtualized
+                    // grid using window/parent scrolling) scrolls to its middle and moves a
+                    // sticky focus target unexpectedly, causing the page to jump.
+                    if (containingElement && containingElement.offsetHeight <= scrollParent.clientHeight && containingElement.offsetWidth <= scrollParent.clientWidth) $9a1324d6ffd8bbb0$export$53a0910f038337bd(scrollParent, containingElement, {
+                        block: 'center',
+                        inline: 'center'
+                    });
+                }
                 for (let scrollParent of (0, $e2a63525475bbd9f$exports.getScrollParents)(targetElement, true))$9a1324d6ffd8bbb0$export$53a0910f038337bd(scrollParent, targetElement);
             }
         }

🔦 Context

We have this situation in our app with a table and some sticky elements, so keyboard support for the table appears broken and inaccessible.

🖥️ Steps to Reproduce

Go here:
https://codesandbox.io/p/sandbox/gwl9xx

  1. Click setup repro
  2. press up on the keyboard

or manually:

  1. focus the table
  2. press down until the header is out of view
  3. press up until the top row is in view
  4. press up again to go to the table header <-- Unexpected behaviour

Version

1.18.0

What browsers are you seeing the problem on?

Chrome

If other, please specify.

No response

What operating system are you using?

windows

🧢 Your Company/Team

Saxo Bank

🕷 Tracking Issue

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions