From 3d33401d351ee072a16d7b88c12e03bdaad74839 Mon Sep 17 00:00:00 2001 From: Brent Vatne Date: Tue, 23 Oct 2018 11:46:18 -0700 Subject: [PATCH] Add createNavigationAwareScrollable, ScrollView, FlatList, and SectionList --- packages/native/package.json | 1 + packages/native/src/Scrollables.js | 28 +++++++++ .../src/createNavigationAwareScrollable.js | 61 +++++++++++++++++++ packages/native/src/index.js | 21 ++++++- 4 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 packages/native/src/Scrollables.js create mode 100644 packages/native/src/createNavigationAwareScrollable.js diff --git a/packages/native/package.json b/packages/native/package.json index 366ba84c..0ef0fcb9 100644 --- a/packages/native/package.json +++ b/packages/native/package.json @@ -90,6 +90,7 @@ "singleQuote": true }, "dependencies": { + "hoist-non-react-statics": "^3.0.1", "react-native-safe-area-view": "^0.11.0" } } diff --git a/packages/native/src/Scrollables.js b/packages/native/src/Scrollables.js new file mode 100644 index 00000000..9180a764 --- /dev/null +++ b/packages/native/src/Scrollables.js @@ -0,0 +1,28 @@ +import React from 'react'; +import { FlatList, SectionList } from 'react-native'; +import { ScrollView } from 'react-native-gesture-handler'; +import createNavigationAwareScrollable from './createNavigationAwareScrollable'; + +const WrappedScrollView = createNavigationAwareScrollable(ScrollView); + +const WrappedFlatList = React.forwardRef((props, ref) => ( + } + /> +)); + +const WrappedSectionList = React.forwardRef((props, ref) => ( + } + /> +)); + +module.exports = { + ScrollView: WrappedScrollView, + FlatList: WrappedFlatList, + SectionList: WrappedSectionList, +}; diff --git a/packages/native/src/createNavigationAwareScrollable.js b/packages/native/src/createNavigationAwareScrollable.js new file mode 100644 index 00000000..67ef43a2 --- /dev/null +++ b/packages/native/src/createNavigationAwareScrollable.js @@ -0,0 +1,61 @@ +import React from 'react'; +import hoistStatics from 'hoist-non-react-statics'; +import { withNavigation } from '@react-navigation/core'; + +export default function createNavigationAwareScrollable(Component: any) { + class ComponentWithNavigationScrolling extends React.PureComponent { + static displayName = `NavigationAwareScrollable(${Component.displayName || + Component.name})`; + + _subscription: any; + + componentDidMount() { + this._subscription = this.props.navigation.addListener('refocus', () => { + const scrollableNode = this.getNode(); + if (this.props.navigation.isFocused() && scrollableNode !== null) { + if (scrollableNode.scrollToTop != null) { + scrollableNode.scrollToTop(); + } else if (scrollableNode.scrollTo != null) { + scrollableNode.scrollTo({ y: 0 }); + } + } + }); + } + + getNode() { + if (this._scrollRef === null) { + return null; + } + + if (this._scrollRef.getScrollResponder) { + return this._scrollRef.getScrollResponder(); + } else if (this._scrollRef.getNode) { + return this._scrollRef.getNode(); + } else { + return this._scrollRef; + } + } + + componentWillUnmount() { + if (this._subscription != null) { + this._subscription.remove(); + } + } + + render() { + return ( + { + this._scrollRef = view; + }} + {...this.props} + /> + ); + } + } + + return hoistStatics( + withNavigation(ComponentWithNavigationScrolling), + Component + ); +} diff --git a/packages/native/src/index.js b/packages/native/src/index.js index d22381d3..4f150827 100644 --- a/packages/native/src/index.js +++ b/packages/native/src/index.js @@ -4,19 +4,36 @@ module.exports = { get createAppContainer() { return require('./createAppContainer').default; }, + get createKeyboardAwareNavigator() { return require('./createKeyboardAwareNavigator').default; }, - get ResourceSavingSceneView() { - return require('./ResourceSavingSceneView').default; + get createNavigationAwareScrollable() { + return require('./createNavigationAwareScrollable').default; }, get withOrientation() { return require('./withOrientation').default; }, + get ResourceSavingSceneView() { + return require('./ResourceSavingSceneView').default; + }, + get SafeAreaView() { return require('react-native-safe-area-view').default; }, + + get ScrollView() { + return require('./Scrollables').ScrollView; + }, + + get FlatList() { + return require('./Scrollables').FlatList; + }, + + get SectionList() { + return require('./Scrollables').SectionList; + }, };