react-native-underline-tabbar-no-flow
v1.2.8
Published
Custom Tabbar for https://github.com/skv-headless/react-native-scrollable-tab-view
Downloads
17
Maintainers
Readme
react-native-underline-tabbar
Custom Tabbar for https://github.com/skv-headless/react-native-scrollable-tab-view.
It consists of some features e.g. scrollable content in tabs. Animations are build on matrix transformations and fully compatible with Animated
library.
In a new version there was significant improvement of tabbar behaviour.
Instalation
npm install react-native-underline-tabbar --save
Or using Yarn
yarn add react-native-underline-tabbar
Showcase
Documentation
| Property | Type | Default | Description |
|-----------|---------------------|----------|--------------------------------------------|
| tabs
| {label: string, badge:string, badgeColor?: string, [string]: any}[]
| required
| You don't have to pass this prop directly to tabbar. Istead, it's automatically passed from ScrollableTabView
from tabLabel
of your page. In defaultTabbar it is used only to pass a label, but we use it to pass there information about badges. Example tabLabel={{label: "Page #4", badge: 8, badgeColor: 'violet'}}
. Also you can pass any data you need as it's used as Map
|
| underlineColor
| string
| "navy"
| Set a color for underline. You can use also transparent
to hide underline |
| underlineHeight
| number
| 2
| Set a height for underline |
| underlineBottomPosition
| number
| 0
| Set a bottom for underline |
| tabBarStyle
| Object
| {}
| Set styles to TabBar container |
| activeTabTextStyle
| Object
| {}
| Set styles to text in tabs while tab is active |
| tabBarTextStyle
| Object
| {}
| Set styles to text in tabs |
| tabBadgeColor
| string
| {}
| Set a common color for all badges. To set badgeColor individually use badgeColor
in tab
property |
| tabMargin
| number
| 20
| Set space between tabs |
Warning: It's better to avoid usage of styles which can change the size of your active tab. E.g. font-weight
, font-size
. Underline still work but not as good as you can expect.
Simple Usage
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
import ScrollableTabView from 'react-native-scrollable-tab-view';
import TabBar from "react-native-underline-tabbar";
const Page = ({label}) => (
<View style={styles.container}>
<Text style={styles.welcome}>
{label}
</Text>
<Text style={styles.instructions}>
To get started, edit index.ios.js
</Text>
<Text style={styles.instructions}>
Press Cmd+R to reload,{'\n'}
Cmd+D or shake for dev menu
</Text>
</View>
);
class example extends Component {
render() {
return (
<View style={[styles.container, {paddingTop: 20}]}>
<ScrollableTabView
tabBarActiveTextColor="#53ac49"
renderTabBar={() => <TabBar underlineColor="#53ac49" />}>
<Page tabLabel={{label: "Page #1"}} label="Page #1"/>
<Page tabLabel={{label: "Page #2 aka Long!", badge: 3}} label="Page #2 aka Long!"/>
<Page tabLabel={{label: "Page #3"}} label="Page #3"/>
<Page tabLabel={{label: "Page #4 aka Page"}} label="Page #4 aka Page"/>
<Page tabLabel={{label: "Page #5"}} label="Page #5"/>
</ScrollableTabView>
</View>
);
}
}
Advanced usage
import React, { Component } from 'react';
import { StyleSheet, Text, View, TouchableOpacity, Animated } from 'react-native';
import ScrollableTabView from 'react-native-scrollable-tab-view';
import TabBar from 'react-native-underline-tabbar';
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
fontSize: 28,
},
});
const Page = ({label, text = ''}) => (
<View style={styles.container}>
<Text style={styles.welcome}>
{label}
</Text>
<Text style={styles.instructions}>
{text}
</Text>
</View>
);
const iconsSet = {
hot: require('./images/ic_whatshot.png'),
trending: require('./images/ic_trending_up.png'),
fresh: require('./images/ic_fiber_new.png'),
funny: require('./images/ic_tag_faces.png'),
movieAndTv: require('./images/ic_live_tv.png'),
sport: require('./images/ic_rowing.png'),
};
const Tab = (tab, page, isTabActive, onPressHandler, onTabLayout, styles) => {
const { label, icon } = tab;
const style = {
marginHorizontal: 20,
paddingVertical: 10,
};
const containerStyle = {
paddingHorizontal: 20,
paddingVertical: 5,
borderRadius: 25,
flexDirection: 'row',
alignItems: 'center',
backgroundColor: styles.backgroundColor,
opacity: styles.opacity,
transform: [{ scale: styles.opacity }],
};
const textStyle = {
color: styles.textColor,
fontWeight: '600',
};
const iconStyle = {
tintColor: styles.textColor,
resizeMode: 'contain',
width: 22,
height: 22,
marginLeft: 10,
};
return (
<TouchableOpacity style={style} onPress={onPressHandler} onLayout={onTabLayout} key={page}>
<Animated.View style={containerStyle}>
<Animated.Text style={textStyle}>{label}</Animated.Text>
<Animated.Image style={iconStyle} source={icon} />
</Animated.View>
</TouchableOpacity>
);
};
class UnderlineTabBarExample extends Component {
_scrollX = new Animated.Value(0);
// 6 is a quantity of tabs
interpolators = [...Array(6).keys()].map(idx => ({
scale: this._scrollX.interpolate({
inputRange: [idx - 1, idx, idx + 1],
outputRange: [1, 1.2, 1],
extrapolate: 'clamp',
}),
opacity: this._scrollX.interpolate({
inputRange: [idx - 1, idx, idx + 1],
outputRange: [0.9, 1, 0.9],
extrapolate: 'clamp',
}),
textColor: this._scrollX.interpolate({
inputRange: [idx - 1, idx, idx + 1],
outputRange: ['#000', '#fff', '#000'],
}),
backgroundColor: this._scrollX.interpolate({
inputRange: [idx - 1, idx, idx + 1],
outputRange: ['rgba(0,0,0,0.1)', '#000', 'rgba(0,0,0,0.1)'],
extrapolate: 'clamp',
}),
}));
render() {
return (
<View style={[styles.container, { paddingTop: 20 }]}>
<ScrollableTabView
renderTabBar={() => (
<TabBar
underlineColor="#000"
tabBarStyle={{ backgroundColor: "#fff", borderTopColor: '#d2d2d2', borderTopWidth: 1 }}
renderTab={(...props) => {
return Tab(...props, this.interpolators[props[1]]);
}}
/>
)}
onScroll={(x) => this._scrollX.setValue(x)}
>
<Page tabLabel={{label: "Hot", icon: iconsSet.hot}} label="Page #1 Hot" text="You can pass your own views to TabBar!"/>
<Page tabLabel={{label: "Trending", icon: iconsSet.trending}} label="Page #2 Trending" text="Yehoo!!!"/>
<Page tabLabel={{label: "Fresh", icon: iconsSet.fresh}} label="Page #3 Fresh" text="Hooray!"/>
<Page tabLabel={{label: "Funny", icon: iconsSet.funny}} label="Page #4 Funny"/>
<Page tabLabel={{label: "Movie & TV", icon: iconsSet.movieAndTv}} label="Page #5 Movie & TV"/>
<Page tabLabel={{label: "Sport", icon: iconsSet.sport}} label="Page #6 Sport"/>
</ScrollableTabView>
</View>
);
}
}
Notice! In case of using this tabbar we must pass object into tabLabel property. It is necessary to set labels and badges.
Example
Changelog
- [1.2.8]
- Minor fix
- [1.2.7]
- Types are available for importing
- [1.2.6]
- Improve offset calculations for tabs which are located in the end of TabBar
- Now you can pass more than 10 tabs to component
- [1.2.5]
- Fix bug when
activeTabTextStyle
had lower priority than justtextStyle
- Add customization for underline
- Fix bug when
- [1.2.4]
- Update descriptions.
- [1.2.3]
- Fixed bug when user provide less than two tabs.
- [1.2.2]
- Minor changes
- [1.2.1]
- Now it's possible to pass your own
renderTab
function (hooray!). It opens many opportunities for customization - Type of
Tab
has been changed. Now it's a map where you can pass any data you need to use in your custom Tab view - Example has been added
- Now it's possible to pass your own
- [1.2.0]
- Initial setup now depends on
initialPage
prop. - Calculating of interpolations now doesn't apply transformations to underline. It prevents flickering when tab has styles which resize it
- Better manual scrolling performance of TabBar
- Initial setup now depends on
- [1.1.7]
- Possibly unnecessary transformations to underline have been removed. It improves behaviour on Android
- [1.1.6]
- Change hardcoded marginValue on value from props to calculate scroll positions properly
- [1.1.5]
- Prevent crashing on android devices
- [1.1.4]
- Interpolation values are calculated only when all mandatory views are measured. It prevents incorrect behaviour of tabs scrolling and underline.
- Now you can set default colour for badges using
tabBadgeColor
prop - Now you can set margins between tabs using
tabMargin
prop