react-spectrum icon indicating copy to clipboard operation
react-spectrum copied to clipboard

Implement scroll anchoring for overlay positioning

Open devongovett opened this issue 1 year ago • 12 comments

Closes https://github.com/orgs/adobe/projects/19/views/4?pane=issue&itemId=63064435

I think this fixes #3944 as well.

When an overlay repositions, its height might change, causing the focused item to go out of view. Even if the height didn't change, this might occur because we change the max-height before positioning in order to get the correct intrinsic size. This causes the browser to lose the previous scroll position. This happens during auto focus as well, when focusing happens prior to positioning.

This PR implements scroll anchoring. We save the offset of the focused element from the scroll container before positioning, and adjust the scroll position afterward so that it appears to remain in the same place relative to the viewport, even if the height of the scroll container changed.

Test instructions:

  1. Open Picker story
  2. resize the window to be small and select an item at the bottom
  3. re-open the picker. Should scroll the auto focused item into view
  4. Resize the height of the browser window. Focused item should remain anchored in view.
  5. Repeat the same steps with RAC Select many items story.

devongovett avatar Jun 11 '24 20:06 devongovett

I'm not getting the item scrolled into view for https://reactspectrum.blob.core.windows.net/reactspectrum/a7d75fc6e8e32b6fcf1997a4fa15138c2f5e9bee/storybook/index.html?path=/story/picker--dynamic-sections&providerSwitcher-express=false

Steps:

  1. Open picker
  2. Select Ross
  3. Close picker
  4. Open picker

observe Ross is not scrolled into view

snowystinger avatar Jun 11 '24 21:06 snowystinger

hmm this looks like a different problem with ListLayout not including the persisted key...

devongovett avatar Jun 12 '24 00:06 devongovett

@snowystinger added a commit to address it. Needed to clean up some old layout infos that should have been removed when we relayout from scratch (when Picker re-opens) so that we don't think the persisted keys are available when they are not.

devongovett avatar Jun 12 '24 01:06 devongovett

@snowystinger added a commit to address it. Needed to clean up some old layout infos that should have been removed when we relayout from scratch (when Picker re-opens) so that we don't think the persisted keys are available when they are not.

~It doesn't appear to have fixed it, in Chrome MacOS. Happy to help debug tomorrow.~

~The scroll anchoring seems to help, but I think it can jitter sometimes because we constantly flip the overlay to see if it can fit better one way or the other.~ UPDATE: it started working when we tested together, must've been bad cache or something

snowystinger avatar Jun 12 '24 04:06 snowystinger

hmm it's working for me...

devongovett avatar Jun 12 '24 16:06 devongovett

I believe this one should be fixed also: https://github.com/orgs/adobe/projects/19/views/4?pane=issue&itemId=66042530 Specifically by these lines https://github.com/adobe/react-spectrum/pull/6527/commits/c7e714598a3ba3093990ec8b053fe06c063ee2f3#diff-2eb943b500782eb9da514ad98c5fb7855a412a495cb133e9a8e81cf656dff9f6R196-R197

devongovett avatar Jun 12 '24 18:06 devongovett

This doesn't seem to work after selecting of a long item below the fold in stories like: https://reactspectrum.blob.core.windows.net/reactspectrum/c7e714598a3ba3093990ec8b053fe06c063ee2f3/storybook/index.html?path=/story/picker--long-item-text&providerSwitcher-express=false or https://reactspectrum.blob.core.windows.net/reactspectrum/c7e714598a3ba3093990ec8b053fe06c063ee2f3/storybook/index.html?path=/story/picker--long-item-text&providerSwitcher-express=false, and focus does not seem to go to the open listbox.

majornista avatar Jun 12 '24 20:06 majornista

## API Changes

unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any', access: 'private' } unknown top level export { type: 'any', access: 'private' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'identifier', name: 'Column' } unknown top level export { type: 'identifier', name: 'Column' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown type { type: 'link' } unknown type { type: 'link' } unknown type { type: 'link' } unknown type { type: 'link' } unknown type { type: 'link' } unknown type { type: 'link' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' }

rspbot avatar Jul 09 '24 23:07 rspbot