From 33f10fbffe7fb82b65dcfdb12b048c2fc85a0424 Mon Sep 17 00:00:00 2001 From: Bright Lee Date: Sat, 17 Oct 2020 21:32:34 +0200 Subject: [PATCH 1/6] support big header --- example/App.tsx | 20 ++++++++--- example/src/BigHeaderScreen.tsx | 53 +++++++++++++++++++++++++++++ index.ts | 2 ++ src/core.tsx | 59 +++++++++++++++++++++++++++++++-- 4 files changed, 127 insertions(+), 7 deletions(-) create mode 100644 example/src/BigHeaderScreen.tsx diff --git a/example/App.tsx b/example/App.tsx index 433b4eb..584b585 100644 --- a/example/App.tsx +++ b/example/App.tsx @@ -10,6 +10,7 @@ import 'react-native-gesture-handler'; import { DefaultHeaderScreen } from './src/DefaultHeaderScreen'; import { StickyHeaderScreen } from './src/StickyHeaderScreen'; import { BackgroundHeaderScreen } from './src/BackgroundHeaderScreen'; +import { BigHeaderScreen } from './src/BigHeaderScreen'; import { SubHeaderScreen } from './src/SubHeaderScreen'; import { CustomHeaderScreen, @@ -23,6 +24,7 @@ export type StackParamList = { DefaultHeader: undefined; StickyHeader: undefined; BackgroundHeader: undefined; + BigHeader: undefined; SubHeader: undefined; WithCustomHeader: undefined; CustomHeaderDetail: undefined; @@ -36,8 +38,9 @@ const samples: { title: string; routeName: keyof StackParamList }[] = [ { title: 'Sample 1-1: Default Header', routeName: 'DefaultHeader' }, { title: 'Sample 1-2: Sticky Header', routeName: 'StickyHeader' }, { title: 'Sample 1-3: Background Header', routeName: 'BackgroundHeader' }, - { title: 'Sample 2: Sub Header', routeName: 'SubHeader' }, - { title: 'Sample 3: Custom Header', routeName: 'WithCustomHeader' }, + { title: 'Sample 2: Big Header', routeName: 'BigHeader' }, + { title: 'Sample 3: Sub Header', routeName: 'SubHeader' }, + { title: 'Sample 4: Custom Header', routeName: 'WithCustomHeader' }, ]; function HomeScreen({ navigation }: ScreenProps) { @@ -106,7 +109,16 @@ function App() { }} /> - {/* Sample 2: Sub Header */} + {/* Sample 2: Big Header */} + + + {/* Sample 3: Sub Header */} - {/* Sample 3: Custom Header */} + {/* Sample 4: Custom Header */} ; +}; + +const BigHeaderScreen = ({ navigation }: ScreenProps) => { + const { + onScroll, + containerPaddingTop, + scrollIndicatorInsetTop, + } = useCollapsibleBigHeader({ + headerStyle: { + height: 250, + }, + headerBackground: ( + + + + ), + collapsedColor: 'white', + }); + + return ( + navigation.navigate('Detail'))} + keyExtractor={(item: any) => item.toString()} + /> + ); +}; + +export { BigHeaderScreen }; diff --git a/index.ts b/index.ts index b5ca8c5..2124d66 100644 --- a/index.ts +++ b/index.ts @@ -1,5 +1,6 @@ import { useCollapsibleHeader, + useCollapsibleBigHeader, useCollapsibleSubHeader, Collapsible, UseCollapsibleOptions, @@ -14,6 +15,7 @@ import { CollapsibleSubHeaderAnimator } from './src/CollapsibleSubHeaderAnimator export { useCollapsibleHeader, + useCollapsibleBigHeader, useCollapsibleSubHeader, setSafeBounceHeight, disableExpoTranslucentStatusBar, diff --git a/src/core.tsx b/src/core.tsx index b236c62..e643911 100644 --- a/src/core.tsx +++ b/src/core.tsx @@ -21,6 +21,7 @@ import { createCollapsibleCustomHeaderAnimator } from './createCollapsibleCustom enum CollapsibleHeaderType { Default, + BigHeader, SubHeader, } @@ -109,6 +110,10 @@ const useCollapsibleHeader = ( } } const safeBounceHeight = getSafeBounceHeight(); + const minHeaderVisibleHeight = + collapsibleHeaderType === CollapsibleHeaderType.BigHeader + ? getDefaultHeaderHeight(isLandscape) + : 0; const animatedDiffClampY = Animated.diffClamp( positionY, @@ -121,10 +126,14 @@ const useCollapsibleHeader = ( outputRange: [0, 1], extrapolate: 'clamp', }); - const translateY = Animated.multiply(progress, -headerHeight); + const heightMoveTo = -(headerHeight - minHeaderVisibleHeight); + const translateY = Animated.multiply(progress, heightMoveTo); const opacity = Animated.subtract(1, progress); - if (collapsibleHeaderType === CollapsibleHeaderType.Default) { + if ( + collapsibleHeaderType === CollapsibleHeaderType.Default || + collapsibleHeaderType === CollapsibleHeaderType.BigHeader + ) { const options = { ...navigationOptions, headerStyle: { @@ -142,6 +151,7 @@ const useCollapsibleHeader = ( }), headerTransparent: true, }; + if (navigationOptions.header) { Object.assign(options, { header: createCollapsibleCustomHeaderAnimator( @@ -149,6 +159,42 @@ const useCollapsibleHeader = ( ), }); } + + if ( + navigationOptions.headerBackground && + collapsibleHeaderType === CollapsibleHeaderType.BigHeader + ) { + const startToVisible = 0.5; + const defaultHeaderTranslateY = progress.interpolate({ + inputRange: [0, startToVisible, 1], + outputRange: [ + -1000, + heightMoveTo * startToVisible * 0.5, + heightMoveTo * 0.5, + ], + }); + const defaultHeaderOpacity = progress.interpolate({ + inputRange: [0, startToVisible, 1], + outputRange: [0, 0, 1], + }); + options.headerStyle = { + ...options.headerStyle, + opacity: defaultHeaderOpacity, + transform: [{ translateY: new Animated.Value(0) }], + }; + Object.assign(options, { + headerTitleStyle: { + transform: [{ translateY: defaultHeaderTranslateY }], + }, + headerLeftContainerStyle: { + transform: [{ translateY: defaultHeaderTranslateY }], + }, + headerRightContainerStyle: { + transform: [{ translateY: defaultHeaderTranslateY }], + }, + }); + } + navigation.setOptions(options); } @@ -180,7 +226,14 @@ const useCollapsibleHeader = ( ); }; +const useCollapsibleBigHeader = (options?: UseCollapsibleOptions) => + useCollapsibleHeader(options, CollapsibleHeaderType.BigHeader); + const useCollapsibleSubHeader = (options?: UseCollapsibleOptions) => useCollapsibleHeader(options, CollapsibleHeaderType.SubHeader); -export { useCollapsibleHeader, useCollapsibleSubHeader }; +export { + useCollapsibleHeader, + useCollapsibleBigHeader, + useCollapsibleSubHeader, +}; From 55d8338cd2d3fe9d7a4d9bb9b18880a2085008de Mon Sep 17 00:00:00 2001 From: Bright Lee Date: Sat, 17 Oct 2020 22:14:19 +0200 Subject: [PATCH 2/6] design example --- example/src/BigHeaderScreen.tsx | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/example/src/BigHeaderScreen.tsx b/example/src/BigHeaderScreen.tsx index 40e146f..8c57cbe 100644 --- a/example/src/BigHeaderScreen.tsx +++ b/example/src/BigHeaderScreen.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { Animated, Image, TouchableOpacity } from 'react-native'; +import { Animated, View, Text, Image, TouchableOpacity } from 'react-native'; import { StackNavigationProp } from '@react-navigation/stack'; import { useCollapsibleBigHeader } from 'react-navigation-collapsible'; @@ -33,6 +33,30 @@ const BigHeaderScreen = ({ navigation }: ScreenProps) => { }} style={{ flex: 1 }} /> + + + + Hello, Big Header. + + ), collapsedColor: 'white', From ca1595dcd4ff38a5156153bbfb09015538a34a16 Mon Sep 17 00:00:00 2001 From: Bright Lee Date: Sun, 18 Oct 2020 11:27:04 +0200 Subject: [PATCH 3/6] example UI --- example/src/BigHeaderScreen.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/example/src/BigHeaderScreen.tsx b/example/src/BigHeaderScreen.tsx index 8c57cbe..0b4a2ce 100644 --- a/example/src/BigHeaderScreen.tsx +++ b/example/src/BigHeaderScreen.tsx @@ -25,7 +25,7 @@ const BigHeaderScreen = ({ navigation }: ScreenProps) => { height: 250, }, headerBackground: ( - + <> { borderRadius: 50, }} /> - - Hello, Big Header. - + + + Edit Profile + + - + ), collapsedColor: 'white', }); From 14f7b39641c211c90b60255db26754a372387fea Mon Sep 17 00:00:00 2001 From: Bright Lee Date: Sun, 18 Oct 2020 12:45:31 +0200 Subject: [PATCH 4/6] apply breaking change --- example/src/BigHeaderScreen.tsx | 77 ++++++++++++++++++--------------- src/core.tsx | 1 - 2 files changed, 41 insertions(+), 37 deletions(-) diff --git a/example/src/BigHeaderScreen.tsx b/example/src/BigHeaderScreen.tsx index 0b4a2ce..05a974f 100644 --- a/example/src/BigHeaderScreen.tsx +++ b/example/src/BigHeaderScreen.tsx @@ -21,47 +21,52 @@ const BigHeaderScreen = ({ navigation }: ScreenProps) => { containerPaddingTop, scrollIndicatorInsetTop, } = useCollapsibleBigHeader({ - headerStyle: { - height: 250, - }, - headerBackground: ( - <> - - + navigationOptions: { + title: 'John Doe', + headerStyle: { + height: 250, + }, + headerBackground: ( + <> - - - Edit Profile - - - - - ), - collapsedColor: 'white', + + + + + Edit Profile + + + + + ), + }, + config: { + collapsedColor: 'white', + }, }); return ( diff --git a/src/core.tsx b/src/core.tsx index e643911..797ec43 100644 --- a/src/core.tsx +++ b/src/core.tsx @@ -5,7 +5,6 @@ import { NativeScrollEvent, useWindowDimensions, } from 'react-native'; -import { StackHeaderProps } from '@react-navigation/stack'; import { useRoute, useNavigation } from '@react-navigation/native'; import shallowequal from 'shallowequal'; From 4aa23756ed324a9d36f8a278aad5a23fcdb28928 Mon Sep 17 00:00:00 2001 From: Bright Lee Date: Tue, 27 Oct 2020 22:29:26 +0100 Subject: [PATCH 5/6] fix tscroll-touch problem when collapsed --- src/core.tsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/core.tsx b/src/core.tsx index f096e08..f2a2c84 100644 --- a/src/core.tsx +++ b/src/core.tsx @@ -171,11 +171,7 @@ const useCollapsibleHeader = ( const startToVisible = 0.5; const defaultHeaderTranslateY = progress.interpolate({ inputRange: [0, startToVisible, 1], - outputRange: [ - -1000, - heightMoveTo * startToVisible * 0.5, - heightMoveTo * 0.5, - ], + outputRange: [-1000, -heightMoveTo * 0.375, -heightMoveTo * 0.5], }); const defaultHeaderOpacity = progress.interpolate({ inputRange: [0, startToVisible, 1], @@ -184,7 +180,6 @@ const useCollapsibleHeader = ( options.headerStyle = { ...options.headerStyle, opacity: defaultHeaderOpacity, - transform: [{ translateY: new Animated.Value(0) }], }; Object.assign(options, { headerTitleStyle: { From ea4a88427d1e6d965abc91a2f9210ce4e06c2303 Mon Sep 17 00:00:00 2001 From: Bright Lee Date: Tue, 27 Oct 2020 23:28:10 +0100 Subject: [PATCH 6/6] fix position calculation --- src/core.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core.tsx b/src/core.tsx index f2a2c84..f9b4c60 100644 --- a/src/core.tsx +++ b/src/core.tsx @@ -171,7 +171,7 @@ const useCollapsibleHeader = ( const startToVisible = 0.5; const defaultHeaderTranslateY = progress.interpolate({ inputRange: [0, startToVisible, 1], - outputRange: [-1000, -heightMoveTo * 0.375, -heightMoveTo * 0.5], + outputRange: [-1000, -heightMoveTo * 0.25, -heightMoveTo * 0.5], }); const defaultHeaderOpacity = progress.interpolate({ inputRange: [0, startToVisible, 1],