diff --git a/README.md b/README.md index e0caba84..10105a63 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ - [Features](#features) - [Installation](#installation) - [Quick Start](#quick-start) +- [Scroll on header](#scroll-on-header) - [API reference](#api-reference) - [CollapsibleTabView](#collapsibletabview) - [useCollapsibleScene](#usecollapsiblescene) @@ -120,8 +121,10 @@ const SecondScene = () => ; const HEADER_HEIGHT = 250; +// set pointerEvents="none" to allow scroll on header +// see the docs for more information const renderHeader = () => ( - + COLLAPSIBLE ); @@ -194,6 +197,14 @@ const styles = StyleSheet.create({ export default WithReactNavigation; ``` +## Scroll on header + +If you want to allow scrolling from the header: + +- If `renderHeader` **doesn't** contain touchables set `pointerEvents='none'` +- If `renderHeader` **does** contain touchables set `pointerEvents='box-none'` for them to work. + _Note: With this setting any child component that should **not** respond to touches (e.g. ``) needs to have `pointerEvents` set to `'none'`. Otherwise it can become the target of a touch gesture on iOS devices and thereby preventing scrolling._ + ## API reference The package has 3 main exports: diff --git a/example/src/App.tsx b/example/src/App.tsx index 70e1a5d4..bc08b93e 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -8,7 +8,6 @@ import { Text, TouchableOpacity, View, - YellowBox, I18nManager, } from 'react-native'; import { registerRootComponent } from 'expo'; @@ -18,6 +17,7 @@ import Constants from 'expo-constants'; import { Ionicons } from '@expo/vector-icons'; import AsyncStorage from '@react-native-community/async-storage'; import CollapsibleTabViewExample from './CollapsibleTabViewExample'; +import CollapsibleTabViewScrollOnHeaderExample from './CollapsibleTabViewScrollOnHeaderExample'; import CollapsibleTabViewSmallContentExample from './CollapsibleTabViewSmallContentExample'; import CollapsibleTabViewNoSnapExample from './CollapsibleTabViewNoSnapExample'; import CollapsibleTabViewResizeExample from './CollapsibleTabViewResizeExample'; @@ -35,8 +35,6 @@ type State = { I18nManager.forceRTL(false); -YellowBox.ignoreWarnings(['bind():']); - const PERSISTENCE_KEY = 'index_persistence'; const EXAMPLE_COMPONENTS: ExampleComponentType[] = [ @@ -48,6 +46,7 @@ const EXAMPLE_COMPONENTS: ExampleComponentType[] = [ CollapsibleTabViewNoUpfrontHeightExample, MaterialTopTabsCollapsibleTabViewDemoExample, CollapsibleTabViewCenteredEmptyListExample, + CollapsibleTabViewScrollOnHeaderExample, ]; const KeepAwake = () => { diff --git a/example/src/CollapsibleTabViewScrollOnHeaderExample.tsx b/example/src/CollapsibleTabViewScrollOnHeaderExample.tsx new file mode 100644 index 00000000..8b4a833d --- /dev/null +++ b/example/src/CollapsibleTabViewScrollOnHeaderExample.tsx @@ -0,0 +1,101 @@ +import * as React from 'react'; +import { StyleSheet, View, Text } from 'react-native'; +import { SceneMap } from 'react-native-tab-view'; + +import { + CollapsibleTabView, + useCollapsibleScene, + CollapsibleTabViewProps, +} from 'react-native-collapsible-tab-view'; + +import { AnimatedAlbums } from './Shared/Albums'; +import { AnimatedArticle } from './Shared/Article'; +import { AnimatedContacts } from './Shared/Contacts'; +import { ExampleComponentType } from './types'; + +type Route = { + key: string; + title: string; +}; + +export const ContactsScene = () => { + const scenePropsAndRef = useCollapsibleScene('contacts'); + return ; +}; + +export const ArticleScene = () => { + const scenePropsAndRef = useCollapsibleScene('article'); + return ; +}; + +export const AlbumsScene = () => { + const scenePropsAndRef = useCollapsibleScene('albums'); + return ; +}; + +export const HEADER_HEIGHT = 550; + +const renderHeader = () => ( + + + You can set pointerEvents="none" | "box-none" to allow + scrolling on the header. It works as expected, but you can also consider + using disableSnap if your header is too large (like in this example). + + +); + +const renderScene = SceneMap({ + albums: AlbumsScene, + contacts: ContactsScene, + article: ArticleScene, +}); + +const CollapsibleTabViewExample: ExampleComponentType> +>> = (props) => { + const [index, setIndex] = React.useState(0); + const [routes] = React.useState([ + { key: 'article', title: 'Article' }, + { key: 'contacts', title: 'Contacts' }, + { key: 'albums', title: 'Albums' }, + ]); + + const handleIndexChange = (index: number) => { + setIndex(index); + }; + + return ( + + navigationState={{ index, routes }} + renderScene={renderScene} + onIndexChange={handleIndexChange} + renderHeader={renderHeader} + headerHeight={HEADER_HEIGHT} + disableSnap + {...props} + /> + ); +}; + +CollapsibleTabViewExample.title = 'Scroll on header'; +CollapsibleTabViewExample.backgroundColor = '#2196f3'; +CollapsibleTabViewExample.appbarElevation = 0; + +export default CollapsibleTabViewExample; + +const styles = StyleSheet.create({ + header: { + height: HEADER_HEIGHT, + backgroundColor: '#2196f3', + justifyContent: 'center', + alignItems: 'center', + elevation: 4, + }, + headerText: { + color: 'white', + fontSize: 18, + padding: 16, + textAlign: 'center', + }, +}); diff --git a/src/CollapsibleTabView.tsx b/src/CollapsibleTabView.tsx index 46721cfc..f7a7e8ea 100644 --- a/src/CollapsibleTabView.tsx +++ b/src/CollapsibleTabView.tsx @@ -189,7 +189,6 @@ const CollapsibleTabView = ({ offset, animated: false, }); - listOffset.current[item.key] = offset; } else if (itemOffset < headerHeight || !itemOffset) { scrollScene({ @@ -354,6 +353,7 @@ const CollapsibleTabView = ({ ): React.ReactNode => { return (