Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement native inverted behaviors for ScrollView #8440

Closed
wants to merge 11 commits into from

Commits on Jan 26, 2023

  1. Implement native inverted behaviors for ScrollView

    This PR modifies ScrollViewManager and VirtualizedList to work around
    the limitations of the RN core approach to list inversion. Specifically,
    the RN core approach to list inversion uses scroll axis transforms to
    flip the list content. While this creates the visual appearance of an
    inverted list, scrolling the list via keyboard or mouse wheel results in
    inverted scroll direction.
    
    To accomplish native inverted scroll behaviors, we focused on four
    expected behaviors of inverted lists:
    1. When content loads "above" the view port in an inverted list, the
    visual content must remain anchored (as if the content renders below it
    in a non-inverted list).
    2. When scrolled to the "start" of an inverted list (in absolute terms,
    the bottom of the scroll view), content appended to the start of the
    list must scroll into view synchronously (i.e., no delay between content
    rendering and view port changing).
    3. When content renders on screen, it must render from bottom to top,
    so render passes that take multiple frames do not appear to scroll to
    the start of the list.
    4. When imperatively scrolling to the "start" of the content, we must
    always scroll to the latest content, even if the content rendered after
    the scroll-to-start animation already began.
    
    For 1., we leverage the XAML `CanBeScrollAnchor` property on each
    top-level item in the list view. While this is an imperfect solution
    (re-rendering of this content while in the view port can result in view
    port shifts as new content renders above), it is a good trade-off of
    performance and functionality.
    
    For 2., we leverage the XAML `HorizontalAnchorRatio` and
    `VerticalAnchorRatio` properties. XAML has a special case for inverted
    lists when setting these property values to `1.0`. It instructs XAML to
    synchronously scroll to and render new content when scrolled to the
    bottom edge of the ScrollViewer.
    
    For 3., we leverage Yoga's implementation of `flexDirection: column-reverse` and `flexDirection: row-reverse` to ensure content is rendered from bottom to top.
    
    For 4., we implemented `ScrollViewViewChanger` to continuously check if
    the target scroll offset has changed since starting an animated
    scroll-to-end operation. If the target scroll offset no longer matches
    the scrollable extent of the ScrollViewer, we update the target offset
    by calling `ChangeView` again.
    
    Fixes microsoft#4098
    rozele committed Jan 26, 2023
    Configuration menu
    Copy the full SHA
    1433041 View commit details
    Browse the repository at this point in the history
  2. Change files

    rozele committed Jan 26, 2023
    Configuration menu
    Copy the full SHA
    2e92792 View commit details
    Browse the repository at this point in the history
  3. Ensure tail spacer is not used as a scroll anchor

    We previously stopped development on the native inverted approach for
    Windows that would use anchoring and flexDirection to implement a truly
    reversed list (as opposed to a list flipped via transform) due to a bug
    where the anchoring would cause the view to "ride" to the top of the
    ScrollViewer when you scrolled into the virtualized tail spacer.
    
    This change introduces a new View prop called `overflowAnchor` and uses
    this prop to ensure that the tail spacer can never be anchored.
    rozele committed Jan 26, 2023
    Configuration menu
    Copy the full SHA
    c7f0aa0 View commit details
    Browse the repository at this point in the history
  4. Configuration menu
    Copy the full SHA
    dee7245 View commit details
    Browse the repository at this point in the history
  5. Configuration menu
    Copy the full SHA
    b181ffd View commit details
    Browse the repository at this point in the history
  6. Configuration menu
    Copy the full SHA
    fba0d4b View commit details
    Browse the repository at this point in the history
  7. yarn format

    rozele committed Jan 26, 2023
    Configuration menu
    Copy the full SHA
    a713bd4 View commit details
    Browse the repository at this point in the history
  8. Configuration menu
    Copy the full SHA
    bf8d65c View commit details
    Browse the repository at this point in the history
  9. Configuration menu
    Copy the full SHA
    a907580 View commit details
    Browse the repository at this point in the history

Commits on Jan 31, 2023

  1. Configuration menu
    Copy the full SHA
    bdd4404 View commit details
    Browse the repository at this point in the history

Commits on Feb 6, 2023

  1. yarn lint:fix

    rozele committed Feb 6, 2023
    Configuration menu
    Copy the full SHA
    282156c View commit details
    Browse the repository at this point in the history