Skip to content

ScrollView: scrolling direction when using inverted prop #995

Closed

Description

@tafelito

The problem
When using FlatList with inverted prop, the mouse scrolling direction is also inverted. I'm not sure if this is an issue per se, but I think only the content of the list should be inverted and not the direction of the scroll. I worked on an implementation for the same feature for the RLV and I tried to handle this on the onWheel event reversing the scroll direction of the container. This only happens on desktops, mobiles scroll is different so it works fine there.

How to reproduce
Just using the FlatList with inverted={true}
https://codesandbox.io/s/y21534vlyx

Expected behavior
Invert list content but keep mouse scrolling direction unchanged

Environment (include versions). Did this work in previous versions?

  • OS:
  • Device:
  • Browser: Chrome, Safari
  • React Native for Web (version):^0.8.3
  • React (version): 16.4

Is this something that could be done here as well?

Thanks!

Activity

  1. necolas commented on Jun 14, 2018

    @necolas
    Owner

    Is this something that could be done here as well?

    Sounds like a good idea

  2. tafelito commented on Jun 14, 2018

    @tafelito
    Author

    Sounds like a good idea meaning, I'll implement this at some point, or sounds like a good idea for a PR? 😄

    Pretty much what I did is, in case inverted is true, I listen to the onWheel event and then reverse the scroll by scrolling to Y minus the delta Y (or X in case of horizontal scrolling). Not sure where this should be implemented here, ScrollResponder maybe?

  3. necolas commented on Jun 14, 2018

    @necolas
    Owner

    I'm open to a PR if you feel like it. No worries if not. Off the top of my head, I'm not sure where the best place for this to go is but can help figure that out if you're going to try

  4. tafelito commented on Jun 15, 2018

    @tafelito
    Author
  5. necolas commented on Jun 16, 2018

    @necolas
    Owner
  6. tafelito commented on Jun 19, 2018

    @tafelito
    Author

    So I saw that I can add the onWheel prop to the scrollProps in the VirtualizedList and I could set the this._scrollRef.getScrollableNode().scrollTop but I'm not sure that's the best way of doing it, eve if I can calculate the correct delta for the position.
    I also tried a different approach but didn't work either. Instead of scaling the elements with -1, I used flexDirection to reverse the scrollview entirely but even though the items are reversed, they are still mounted in the same order, so you'll see how the items are pushed down while loading. So it's not a solution.

  7. changed the title [-]scrolling direction when using inverted prop[/-] [+]ScrollView: scrolling direction when using inverted prop[/+] on Jul 7, 2018
  8. mglagola commented on Jul 11, 2018

    @mglagola

    @tafelito did you ever find a solution?

  9. tafelito commented on Jul 11, 2018

    @tafelito
    Author
  10. tafelito commented on Aug 7, 2018

    @tafelito
    Author

    @necolas are you using FlatList at Twitter Lite? Because I saw that the messages window uses an inverted scroll and the direction works fine there.

    Also I noticed that the home page uses some sort of window scroller but on the chat screen you can only scroll on the list and not outside

  11. necolas commented on Aug 7, 2018

    @necolas
    Owner

    No. Twitter PWA uses a custom scroller that isn't integrated with React Native at all, i.e., no support for the responder system etc

  12. danalloway commented on Feb 5, 2019

    @danalloway
    Contributor

    did some work on this over in #1241

  13. added this to the Flare milestone on Mar 4, 2019
  14. unadlib commented on May 3, 2019

    @unadlib

    I've had the same issue, and I'm not sure it doesn't seem to have a fix plan?

  15. raphaelrk commented on Jul 14, 2019

    @raphaelrk

    Here's a version of that same codesandbox example with some scrolljacking (this._scrollNode.scrollTop -= e.deltaY;) to invert the scroll direction and a trick (transform: translate3d(0,0,0) scaleY(-1)) to force hardware acceleration for better scroll performance: https://codesandbox.io/s/react-native-h32if

    Tested on macOS Mojave FF/Safari/Chrome July 14 2019


    Update Dec 14 2020: Hooks version. Still working for me on a new project, not perfect but it's good enough

      // invert scrolling
      const flatlistRef = useRef();
      useEffect(() => {
        let scrollNode = flatlistRef.current && flatlistRef.current.getScrollableNode();
        if (!scrollNode) return;
        const listener = scrollNode.addEventListener("wheel", e => {
          scrollNode.scrollTop -= e.deltaY;
          e.preventDefault();
        });
        flatlistRef.current.setNativeProps({ style: { transform: "translate3d(0,0,0) scaleY(-1)" } });
        return () => scrollNode.removeEventListener("wheel", listener);
      }); // needs to run any time flatlist mounts
  16. shaylew commented on Aug 16, 2019

    @shaylew

    There's also arrow keys, page up/page down, home/end, and mousewheel drag to consider. I think I've come up with a proof of concept for simpler way to do this that doesn't require reimplementing each type of scrolling: https://jsfiddle.net/4t2uyfpz/1/

    The idea is to keep two scrollable elements: a wrapper with a visible scrollbar for the user, and an inverted inner element with position: sticky that gets scrolled by the script. Scroll events -- mousewheel or keyboard -- move the wrapper's scrollbar and we scroll the inner content accordingly. If items get added or removed inside the inverted list we scroll and resize the wrapper to keep it in sync.

    (Right now there's some weird behavior where if you scroll to the top and then remove N elements, Chrome -- and only Chrome -- keeps you stuck to the top until you either scroll manually or add N+1 elements back. I'm not sure exactly what's up with that but there's hopefully a workaround.)

  17. davidfant commented on May 7, 2020

    @davidfant
  18. vmaark commented on May 18, 2020

    @vmaark

    One thing to note is that on Firefox the scroll direction works correctly.

    For the workaround codesandbox, here is the function component version:
    https://codesandbox.io/s/react-native-dsyse

  19. divonelnc commented on Nov 6, 2020

    @divonelnc
  20. removed this from the Flare milestone on Dec 8, 2020
  21. smithydll commented on Feb 10, 2021

    @smithydll

    @raphaelrk I had to add flatlistRef.current to the useEffect dependency otherwise the content in the flatlist would fire the effect several times

    useEffect(() => {
    
    [snip]
    
    }, [flatlistRef.current]); // needs to run any time flatlist mounts
    
  22. added this to the 0.18 milestone on Mar 29, 2021
  23. roryabraham commented on Apr 27, 2022

    @roryabraham
    Contributor

    Heads up @staltz and @necolas – we've been using a workaround for the inverted wheel event thing for a while now. I saw this commit is in the pipeline to fix this issue, and it's more or less the same as the workaround we've been using.

    However, we did have someone report an edge case with this solution though – if the list is in focus then pressing ArrowDown scrolls you up and ArrowUp scrolls you down. Maybe worth fixing for accessibility reasons?

  24. staltz commented on Apr 27, 2022

    @staltz
    Contributor

    @roryabraham We solved the keyboard problem like this: https://github.com/staltz/manyverse/blob/master/patches/react-native-web%2B0.17.6.patch (I think it's too ugly to make an upstream PR)

  25. added a commit that references this issue on Sep 13, 2022
    b42473a
  26. added a commit that references this issue on Feb 22, 2024
    7ec2489
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions