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:
- styles(Object)-default({ backgroundColor: #FFFFFF, flex: 1 }): style for header component;
- onHeaderContentLayout(func)):function to return layout props for header content without tab dimensions 3.onLayout(func)):function to return layout props for tabheader
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
- key(string): key same as key in routes
- hasScrollable(boolean)-default(true): set this to fault when the tab content is not a scrollable to properly align items.
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
- @janicduplessis for his excellent medium post
- brilliant tab view from react-native-community
- awesome icon implementation and components from react-native-elements
- recompose - so cool!
- React and ReactNative - just makes a lot of sense :)
PR's are very welcome
- Improve docs perhaps include GIF screenshots
- add examples to expo.
- Improve on components to include propType definitions