diff --git a/example/App.tsx b/example/App.tsx
index a42805e..56c215c 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,
@@ -24,6 +25,7 @@ export type StackParamList = {
DefaultHeader: undefined;
StickyHeader: undefined;
BackgroundHeader: undefined;
+ BigHeader: undefined;
SubHeader: undefined;
WithCustomHeader: undefined;
CustomHeaderDetail: undefined;
@@ -38,9 +40,10 @@ 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 4: Show Header Manually', routeName: 'ShowHeaderScreen' },
+ { title: 'Sample 2: Big Header', routeName: 'BigHeader' },
+ { title: 'Sample 3: Sub Header', routeName: 'SubHeader' },
+ { title: 'Sample 4: Custom Header', routeName: 'WithCustomHeader' },
+ { title: 'Sample 5: Show Header Manually', routeName: 'ShowHeaderScreen' },
];
function HomeScreen({ navigation }: ScreenProps) {
@@ -109,7 +112,16 @@ function App() {
}}
/>
- {/* Sample 2: Sub Header */}
+ {/* Sample 2: Big Header */}
+
+
+ {/* Sample 3: Sub Header */}
- {/* Sample 3: Custom Header */}
+ {/* Sample 4: Custom Header */}
+ {/* Sample 5: Show Header Manually */}
diff --git a/example/src/BigHeaderScreen.tsx b/example/src/BigHeaderScreen.tsx
new file mode 100644
index 0000000..05a974f
--- /dev/null
+++ b/example/src/BigHeaderScreen.tsx
@@ -0,0 +1,84 @@
+import * as React from 'react';
+import { Animated, View, Text, Image, TouchableOpacity } from 'react-native';
+import { StackNavigationProp } from '@react-navigation/stack';
+import { useCollapsibleBigHeader } from 'react-navigation-collapsible';
+
+import { StackParamList } from '../App';
+import { createRow } from './Row';
+
+const data: number[] = [];
+for (let i = 0; i < 100; i++) {
+ data.push(i);
+}
+
+type ScreenProps = {
+ navigation: StackNavigationProp;
+};
+
+const BigHeaderScreen = ({ navigation }: ScreenProps) => {
+ const {
+ onScroll,
+ containerPaddingTop,
+ scrollIndicatorInsetTop,
+ } = useCollapsibleBigHeader({
+ navigationOptions: {
+ title: 'John Doe',
+ headerStyle: {
+ height: 250,
+ },
+ headerBackground: (
+ <>
+
+
+
+
+
+ Edit Profile
+
+
+
+ >
+ ),
+ },
+ config: {
+ 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 f510dde..f9b4c60 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';
@@ -21,6 +20,7 @@ import { createCollapsibleCustomHeaderAnimator } from './createCollapsibleCustom
enum CollapsibleHeaderType {
Default,
+ BigHeader,
SubHeader,
}
@@ -114,6 +114,10 @@ const useCollapsibleHeader = (
}
}
const safeBounceHeight = getSafeBounceHeight();
+ const minHeaderVisibleHeight =
+ collapsibleHeaderType === CollapsibleHeaderType.BigHeader
+ ? getDefaultHeaderHeight(isLandscape)
+ : 0;
const animatedDiffClampY = Animated.diffClamp(
positionY,
@@ -126,10 +130,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: {
@@ -147,6 +155,7 @@ const useCollapsibleHeader = (
}),
headerTransparent: true,
};
+
if (navigationOptions.header) {
Object.assign(options, {
header: createCollapsibleCustomHeaderAnimator(
@@ -154,6 +163,37 @@ const useCollapsibleHeader = (
),
});
}
+
+ if (
+ navigationOptions.headerBackground &&
+ collapsibleHeaderType === CollapsibleHeaderType.BigHeader
+ ) {
+ const startToVisible = 0.5;
+ const defaultHeaderTranslateY = progress.interpolate({
+ inputRange: [0, startToVisible, 1],
+ outputRange: [-1000, -heightMoveTo * 0.25, -heightMoveTo * 0.5],
+ });
+ const defaultHeaderOpacity = progress.interpolate({
+ inputRange: [0, startToVisible, 1],
+ outputRange: [0, 0, 1],
+ });
+ options.headerStyle = {
+ ...options.headerStyle,
+ opacity: defaultHeaderOpacity,
+ };
+ Object.assign(options, {
+ headerTitleStyle: {
+ transform: [{ translateY: defaultHeaderTranslateY }],
+ },
+ headerLeftContainerStyle: {
+ transform: [{ translateY: defaultHeaderTranslateY }],
+ },
+ headerRightContainerStyle: {
+ transform: [{ translateY: defaultHeaderTranslateY }],
+ },
+ });
+ }
+
navigation.setOptions(options);
}
@@ -187,7 +227,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,
+};
diff --git a/yarn.lock b/yarn.lock
index 7dde3e4..af4c0cf 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -33,10 +33,10 @@
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7"
integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==
-"@types/react-native@^0.63.25":
- version "0.63.30"
- resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.63.30.tgz#a0bd61e61b7a020a538ea22901be2f5d178fe02f"
- integrity sha512-8/PrOjuUaPTCfMeW12ubseZPUGdbRhxYDa/aT+0D0KWVTe60b4H/gJrcfJmBXC6EcCFcimuTzQCv8/S03slYqA==
+"@types/react-native@0.63.25":
+ version "0.63.25"
+ resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.63.25.tgz#a08bbe17a75cce993f52655a8fe75f30bf77e965"
+ integrity sha512-cRm+1iQecewpFYOArYJoM1qGd0JpFJ6f97KqIy9H2GawAdWkgyarSk8CBy4SMt2WOtPkysCu2EG7UwIT3vNeaA==
dependencies:
"@types/react" "*"