Group of react-native components to ease implementation of collapsible headers with tabs
yarn add react-native-collapsible-tab-header
Create your custom scrollable
// @flow
import React from 'react';
import { ScrollView,Animated } from 'react-native';
import { defaultProps } from 'recompose';
import { ListItem, List } from 'react-native-elements';
import { Scrollable } from 'react-native-collapsible-tab-header';
import createData from '../data';
import type { dataType } from '../types';
const AnimatedScrollable = Animated.createAnimatedComponent(ScrollView);
const MyCustomScrollView = Scrollable(AnimatedScrollable);
const Component = ({ data }: {data: Array<dataType>}) => (
<List>
<MyCustomScrollView>
{data.map(item => (
<ListItem
key={item.id}
subtitle={item.subtitle}
title={item.title}
/>
))}
</MyCustomScrollView>
</List>
);
Component.propTypes = {};
Component.defaultProps = {};
export default defaultProps({
data: createData(25),
})(Component);
or use one of in built scrollables like the flatlist or scrollview
// @flow
import React from 'react';
import { defaultProps } from 'recompose';
import { ListItem, List } from 'react-native-elements';
import { FlatList } from 'react-native-collapsible-tab-header';
import createData from '../data';
import type { dataType } from '../types';
const Component = ({ data }: {data: Array<dataType>}) => (
<List>
<FlatList
data={data}
keyExtractor={(item: dataType) => item.id}
renderItem={({ item }: {item: dataType}) => (
<ListItem
subtitle={item.subtitle}
title={item.title}
/>
)}
/>
</List>
);
Component.propTypes = {};
Component.defaultProps = {};
export default defaultProps({
data: createData(25),
})(Component);
create your collapsible tab component
// @flow
import React from 'react';
import { View, Text } from 'react-native';
import { compose, defaultProps } from 'recompose';
import { ItemsScrollView, ItemsFlatList, ItemsCustomList } from '../components/index';
import { Collapsible, Tabs, TabHeader, Tab } from 'react-native-collapsible-tab-header';
import styles from '../style';
const ICON_TYPE = 'simple-line-icon';
const USERS_ICON = 'people';
const ROUTE_ICON = 'location-pin';
const PRODUCT_ICON = 'grid';
const REPORT_ICON = 'chart';
const Component = ({ style }: {style: Object}) => (
<Collapsible hasNavBar={false} style={{ backgroundColor: 'snow' }} height={'35%'}>
<View style={style.container} >
<Tabs
style={style.tabs}
tabStyle={style.tab}
labelStyle={style.label}
routes={[
{ key: 'flat-list', title: 'FlatList', icon: { type: ICON_TYPE, name: USERS_ICON } },
{ key: 'scroll-view', title: 'ScrollView', icon: { type: ICON_TYPE, name: PRODUCT_ICON } },
{ key: 'custom', title: 'Custom', icon: { type: ICON_TYPE, name: ROUTE_ICON } },
{ key: 'content', title: 'Content', icon: { type: ICON_TYPE, name: REPORT_ICON } },
]}
>
<TabHeader>
<View>
<Text>This is a header content</Text>
</View>
</TabHeader>
<Tab key={'flat-List'}>
<ItemsFlatList />
</Tab>
<Tab key={'scroll-view'}>
<ItemsScrollView />
</Tab>
<Tab key={'custom'}>
<ItemsCustomList />
</Tab>
<Tab hasScrollable={false} key={'content'}>
<Text> this is just a content </Text>
</Tab>
</Tabs>
</View>
</Collapsible>
);
export default compose(
defaultProps({ style: styles }),
)(Component);
or without tabs
// @flow
import React from 'react';
import { View, Text } from 'react-native';
import { compose, defaultProps } from 'recompose';
import { ItemsCustomList } from '../components/index';
import { Collapsible, Header } from 'react-native-collapsible-tab-header';
import styles from '../style';
const Component = ({ style }: {style: Object}) => (
<Collapsible hasNavBar={false} style={{ backgroundColor: 'snow' }} height={'35%'}>
<View style={style.container} >
<Header>
<View>
<Text>This is a header content</Text>
</View>
</Header>
<ItemsCustomList />
</View>
</Collapsible>
);
export default compose(
defaultProps({ style: styles }),
)(Component);
learn more from the examples folder
React native parent component to create collapsible component
Props
height(number | string)-default('30%'): height of collapsible header in either percentage or fixed length.
collapseHeight(string)-default('50%): height in header to respond with closing or opening header during a scroll.
offsetFromTop(number)-default(20 for android 24 for ios,0 when hasNavBar is false): offset to from top when collapsed to manage situations such as when there is no navbar,or you wish to keep a part of the header showing when collapsed.
hasNavBar(bool)-default(true) helps with offsetFromTop for determining offset for status bar of device.
Parent Component to manage tabs for collapsible
Props
routes(Array of Routes ({icon:{name:string,type:string, ...propsFrom react-native-elements icon}))-default([]):
iconStyle (object)-default({ fontSize: 18, color:#FFFFFF }) :style for icons
activeIconStyle (object)-default({ fontSize: 18, color:#FFFFFF }) :style for active icons
inactiveIconStyle (object)-default({ fontSize: 18, color:#FFFFFF }) :style for in-active icons
labelStyle (object)-default({ fontSize: 12, color:#FFFFFF }) :style for in-active icons
indicatorStyle (object)-default({backgroundColor: #FFFFFF }) :style for in-active icons
swipeEnabled (bool)-default(true) : enable/disable tab swipe navigation
tabsProps (object)-default(undefined) : props for tabs, same as props for tabViewAnimated
All props from the excellent react-native-tab-view tabBar
Header component for tabs
children:
react component for header
Props:
Tab component to display tab content
note this is a pure component and will update
contents when hasScrollable changes to improve performance: it should generally work well
Props
Method to create a scrollable component to control collapsible header
Scrollable flatlist component from Scrollable() method, same as RN FlatList
Scrollable Scrollview component from Scrollable() method, same as RN ScrollView
Needed an easy way to implement collapsible tab headers and headers for a project and could not find one .. so I created this to ease the burden for myself and perhaps others.
Indeed I could not have achieved this without the excellent contributions from others such as
PR's are very welcome