An extension of react-navigation that makes your header collapsible.
Try out on Expo Snack
react-navigation |
react-navigation-collapsible |
Documentation |
---|---|---|
β₯ v5 (latest ) |
v5 (latest ) |
current |
β₯ v3 | v3 | v3-4 branch |
v2 | v2 | v2 branch |
π The Collapsible Tab-navigator is no longer supported due to the Android bug from react-native.
import {
createCollapsibleStack,
// disableExpoTranslucentStatusBar,
} from 'react-navigation-collapsible';
/* Expo only: If you disabled Expo's default translucent statusBar, please call this function as well.
disableExpoTranslucentStatusBar();
*/
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
/* Wrap your Stack.Screen */
{createCollapsibleStack(
<Stack.Screen
name="HomeScreen"
component={MyScreen}
options={{
headerStyle: { backgroundColor: 'green' },
title: 'Home',
}}
/>,
{
collapsedColor: 'red' /* Optional */,
useNativeDriver: true /* Optional, default: true */,
key:
'HomeScreen' /* Optional, a key for your Stack.Screen element */,
elevation: 4 /* Optional */,
}
)}
</Stack.Navigator>
</NavigationContainer>
);
}
import { Animated } from 'react-native';
import { useCollapsibleStack } from 'react-navigation-collapsible';
const MyScreen = ({ navigation, route }) => {
const {
onScroll /* Event handler */,
onScrollWithListener /* Event handler creator */,
containerPaddingTop /* number */,
scrollIndicatorInsetTop /* number */,
/* Animated.AnimatedInterpolation by scrolling */
translateY /* 0.0 ~ -headerHeight */,
progress /* 0.0 ~ 1.0 */,
opacity /* 1.0 ~ 0.0 */,
} = useCollapsibleStack();
/* in case you want to use your listener
const listener = ({nativeEvent}) => {
console.log(nativeEvent);
};
const onScroll = onScrollWithListener(listener);
*/
return (
<Animated.FlatList
onScroll={onScroll}
contentContainerStyle={{ paddingTop: containerPaddingTop }}
scrollIndicatorInsets={{ top: scrollIndicatorInsetTop }}
/* rest of your stuff */
/>
);
};
See /example/App.tsx and /example/src/DefaultHeaderScreen.tsx
See /example/src/StickyHeaderScreen.tsx
import { createCollapsibleStackSub } from 'react-navigation-collapsible';
/* use 'createCollapsibleStackSub' instead of 'createCollapsibleStack' */
/* The rest are the same with the default header. */
import { Animated } from 'react-native';
import {
useCollapsibleStack,
CollapsibleStackSub,
} from 'react-navigation-collapsible';
const MySearchBar = () => (
<View style={{ padding: 15, width: '100%', height: 60 }}>
<TextInput placeholder="search here" />
</View>
);
const MyScreen = ({ navigation, route }) => {
const {
onScroll /* Event handler */,
containerPaddingTop /* number */,
scrollIndicatorInsetTop /* number */,
} = useCollapsibleStack();
return (
<>
<Animated.FlatList
onScroll={onScroll}
contentContainerStyle={{ paddingTop: containerPaddingTop }}
scrollIndicatorInsets={{ top: scrollIndicatorInsetTop }}
/* rest of your stuff */
/>
/* Wrap your component with `CollapsibleStackSub` */
<CollapsibleStackSub>
<MySearchBar />
</CollapsibleStackSub>
</>
);
};
See /example/App.tsx and /example/src/SubHeaderScreen.tsx
function App() {
return (
<NavigationContainer
/* Add headerMode="screen" to prevent the custom header from clashing with subsequent headers.
If you don't do this, you will have to make sure the header is applied consistently.
You can check the Custom Header implementation example to see a possible configuration for this */
headerMode="screen"
>
<Stack.Navigator>
/* Wrap your Stack.Screen */
{createCollapsibleStack(
<Stack.Screen
name="HomeScreen"
component={MyScreen}
options={{
title: 'Home',
}}
/>,
{
/* Add a custom header to the createCollapsibleStack options the same way
you would add it to the Stack.Screen options */
header: ({ scene, previous, navigation }) => {
const { options } = scene.descriptor;
const title =
options.headerTitle !== undefined
? options.headerTitle
: options.title !== undefined
? options.title
: scene.route.name;
return (
<MyHeader
title={title}
leftButton={
previous ? <MyBackButton onPress={navigation.goBack} /> : undefined
}
style={options.headerStyle}
/>
);
};
}
)}
</Stack.Navigator>
</NavigationContainer>
);
}
See /example/App.tsx and /example/src/CustomHeaderScreen.tsx
# install module
yarn add react-navigation-collapsible
PR is welcome!
/example imports the library directly from the root folder, configured with babel-plugin-module-resolver.
So, just turn the watch
option on at the root folder while you're making changes on the library, and check them on the example.
yarn tsc -w