react-native-web icon indicating copy to clipboard operation
react-native-web copied to clipboard

Enable window/body based scrolling for all ScrollViews

Open EyMaddis opened this issue 4 years ago • 15 comments

I am always impressed by this project and today is finally the day to give a little bit back! 😃

This PR is the first version of using the full page scrolling with React Native Web apps. In the past, people could only use <ScrollViews /> with fixed heights wrapped around the full page.

This has multiple restrictions, for example it blocks mobile browsers (both Chrome on Android and iOS) from hiding the navigation bars if the page is scrolled down, blocking a lot of the screen. Generally, this leads to the pages feeling less like proper websites.

My proposed solution allows for any ScrollView component to use a new prop useWindowScrolling={true} to let itself grow freely and use the scroll events of document.body. This also works for VirtualizedLists (including FlatList).

I added a <FlatList Window Scroll> example to show its functionality.

windowscroll-smaller

I am sure that there are more issues to tackle. For example I am unsure wether scroll positions should be normalized such that the position of the <ScrollView /> on the page is used to subtract from the scroll position x/y values.

EyMaddis avatar Nov 09 '19 15:11 EyMaddis

The idea is to wrap the whole app in a <ScrollView useWindowScrolling> or possibly<FlatList useWindowScrolling> if you want to nest other virtualized list.

(Hacky tip for people who want to use nested Flatlists: use A Flatlist without data and put everything in the header element. This way nested Lists will work properly, because simple ScrollViews do not work here)

EyMaddis avatar Nov 09 '19 16:11 EyMaddis

I’m playing with react-native-web and so far, everything works extremely well and I'm in love with the general idea & quality of this library.

I'm facing some issues related to the fact that the web is designed to have the <body> being the main <ScrollView> which is not the case in mobile development.

Here are some of the issues I'm facing without this PR because of the previously stated problem:

  • The Web Browser header won't collapse (as shown in the PR description).

  • The ScrollComponents (ScrollView, FlatList, SectionList, ...) ScrollBars won't take the full window height thus making their content being offset. (This happens where ScrollBars are visible like on a Mac without a trackpad or on Windows. Mobile & MacOs with a trackpad are not subject to this problem because the ScrollBar is floating & hides when inactive). Here is a Snack for demonstration (https://snack.expo.io/@mathieuurstein/react-native-web-window-scroll-issues). Screenshot 2019-11-19 at 21 45 22

  • This is all I found for now, but we can expect more of those problems because of the browsers expecting the

    to scroll the main content.

I haven't looked into this PR code but I think the general idea of an useWindowScroll props on ScrollComponents could be a great idea to fix the previously stated issues.

MathieuUrstein avatar Nov 19 '19 20:11 MathieuUrstein

@MathieuUrstein Did you test the code of the PR or of the general React Native Web version. If you used Expo Snack you unfortunately cannot test this PR (as far as I know).

I'm facing some issues related to the fact that the web is designed to have the

being the main <ScrollView> which is not the case in mobile development.

This is all I found for now, but we can expect more of those problems because of the browsers expecting the to scroll the main content.

This PR tries to solve exactly that. It disables the default scroll behaviour of the <ScrollView> and allows it to grow and resize the <body>, while using the scroll tracking and event which are compatible with ScrollViews.

Did you use the exact Snack, because this neither uses my PR nor the useWindowScroll prop. If you checkout the PR locally, compile it, set useWindowScroll the page would scroll via the body. However the header and footer would not be sticky. An easy fix would be to set position: fixed on these elements.

I think that designing for body scrolling will always have some caveats, but is generally an improvement. Body scrolling is not something that people would use who just want to put their mobile app on the web with whatever means but instead tailors to people who want to build a proper web app.

EyMaddis avatar Nov 19 '19 21:11 EyMaddis

@necolas I rebased the PR on the current master with the new and fancy storybook. I had to completely remove my example as it does not work in storybook as it itself is not window scrollable.

EyMaddis avatar Nov 19 '19 22:11 EyMaddis

@MathieuUrstein Did you test the code of the PR or of the general React Native Web version. If you used Expo Snack you unfortunately cannot test this PR (as far as I know).

No I was demonstrating some issues we currently have with react-native-web that your PR can solve. My comment was targeted to prove that your PR is a great idea :)

P:S: I have edited my previous comment to clarify my point.

MathieuUrstein avatar Nov 20 '19 08:11 MathieuUrstein

wow, any update on this pr?

blackbing avatar Jan 14 '20 15:01 blackbing

What about working this feature as a external component? A drop-in replacement for the native ScrollView...

piranna avatar Mar 11 '20 10:03 piranna

@piranna My changes are mostly in ScrollViewBase.js. I don't see an easy way to avoid duplicating the whole code and reexporting every ScrollView (incl. FlatList, ListView, ...). This would be a way better fit.

EyMaddis avatar Mar 11 '20 10:03 EyMaddis

@piranna My changes are mostly in ScrollViewBase.js. I don't see an easy way to avoid duplicating the whole code and reexporting every ScrollView (incl. FlatList, ListView, ...). This would be a way better fit.

This is a valid solution for me...

piranna avatar Mar 11 '20 10:03 piranna

That sounds like a fantastic feature, thanks! Any way to help?

@EyMaddis - do you have any example to share to test your proposal?

pierreis avatar May 06 '20 08:05 pierreis

I am actually really interested in this. What is the status of this, does this work with the new responder system?

jfrolich avatar Jul 01 '20 06:07 jfrolich

Before I invest any more time into supporting this, I would like to know whether this has a chance of getting merged at all. Could you comment on that, @necolas? Thanks

EyMaddis avatar Feb 15 '21 10:02 EyMaddis

looking forward to this feature

blackbing avatar May 06 '21 02:05 blackbing

I don't think this is necessary anymore in the new version of react-native-web. You can just put components in the root of your document now with the new gesture responder system.

jfrolich avatar May 07 '21 01:05 jfrolich

@jfrolich do you mean AppRegistery on <body> ?

blackbing avatar May 07 '21 03:05 blackbing