Skip to content

Commit

Permalink
Add Badge support (#70)
Browse files Browse the repository at this point in the history
* badge support

added badge support

* remove react-native-material-ui

removed react-native-material-ui as dependency. implemented importing local badge component.

* Added Badge.js

Added Badge component to use instead of react-native-material-ui badge

* updated prop types

updated prop types

* removed old prop type

removed old prop type

* documented badge changes

documented badge changes

* fixed isBadgeVisible documentation

fixed isBadgeVisible documentation

* Final changes

final changes

* final changes

final changes

* removed extra dependencies

removed extra dependencies

* android compatibility 

android compatibility

* android compatibility

android compatibility
  • Loading branch information
ShayanJavadi authored and timomeh committed Feb 11, 2018
1 parent fe0547a commit 689133d
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 6 deletions.
5 changes: 4 additions & 1 deletion README.md
Expand Up @@ -128,7 +128,10 @@ Don't skip this part. You will be happy to know about all the good stuff you can
| **`activeLabelColor`** | Text Color of the Label when the Tab is active. | `string` | `activeLabelColor` of BottomNavigation |
| **`barBackgroundColor`** | Background color for the whole component, if the tab is active. | `string` | `backgroundColor` of BottomNavigation |
| **`onPress`** | Function to be called when the Tab was pressed. **When you use this, the pressed tab won't be active automatically. You need to set it to active by updating `BottomNavigation.activeTab`.** This function will be called with the parameter `(newTabIndex) => {}` | `function` ||

| **`badgeText`** | Text for the tab's badge. **The badge will be hidden if no badgeText is passed. isBadgeVisible can be used to override this**. | `string` | - |
| **`badgeSize`** | Size of the badge. Will be used to calculate the height, width, and border radius (height: size, width: size, borderRadius: size/2) | `number` | 20 |
| **`badgeStyle`** | Style for the badge. `badgeStyle.container` will be used to determine the badge's container style, and `badgeStyle.text` will be used to determine the badge's text style | `object` | `{ container: { position: "relative", width: 20, height: 20, borderRadius: 20 / 2, alignItems: "center", justifyContent: "center", backgroundColor: "#F50057", zIndex: 9999, bottom: 5, right: 10 }, text: { color: "#fff", fontWeight: "500", fontSize: 12 } }` |
| **`isBadgeVisible`** | Determines if the badge is visible or not | `boolean` | - |

## Behind the Navigation Bar

Expand Down
81 changes: 81 additions & 0 deletions lib/Badge.js
@@ -0,0 +1,81 @@
/**
* Material badge for showing notifications, maybe more functionality in the future
* @flow
*/

import React, { Component } from 'react'
import {
View,
Text,
StyleSheet
} from 'react-native';

type BProps = {
text: string,
size: number,
children: Array<ReactElement<*>>,
style: any,
isVisible: boolean,
}

const defaultProps = {
size: 20,
isVisible: true,
style: {},
}

export default class Badge extends Component {
static defaultProps: typeof defaultProps
props: BProps
static defaultProps = defaultProps

createStyles() {
const { size, style } = this.props;
const container = Object.assign(
{},
{
position: "absolute",
width: size,
height: size,
borderRadius: size / 2,
alignItems: "center",
justifyContent: "center",
backgroundColor: "#F50057",
zIndex: 9999,
bottom: 10,
},
style.container
);

const text = Object.assign(
{},
{
color: "#fff",
fontWeight: "500",
fontSize: 12,
},
style.text
)

return StyleSheet.create({
container,
text,
})
}

render() {
const { children, text, isVisible } = this.props;
const styles = this.createStyles();
if (!isVisible) {
return null;
}

return (
<View>
<View style={styles.container}>
<Text style={styles.text}>{text}</Text>
</View>
</View>
)
}
}
36 changes: 31 additions & 5 deletions lib/Tab.js
Expand Up @@ -14,6 +14,7 @@ import {
StyleSheet,
TouchableWithoutFeedback
} from 'react-native'
import Badge from "./Badge"
import { easeInOut } from './utils/easing'


Expand All @@ -30,7 +31,11 @@ type TabProps = {
labelColor: string,
activeLabelColor?: string,
onTabPress: () => void,
onPress: () => void
onPress: () => void,
badgeText: string,
badgeSize: number,
badgeStyle: any,
isBadgeVisible: boolean,
}

type TabState = {
Expand Down Expand Up @@ -115,15 +120,33 @@ export default class Tab extends Component {
]}
>
{this._renderIcon()}
{this._renderBadge()}
{this._renderLabel()}
</View>
</TouchableWithoutFeedback>
)
}

_renderBadge = () => {
const { badgeText, badgeSize, badgeStyle, isBadgeVisible } = this.props;

if (badgeText === undefined && !isBadgeVisible) {
return null;
}

return (
<Badge
text={badgeText}
size={badgeSize}
style={badgeStyle}
isVisible={isBadgeVisible}
/>
)
}

_renderIcon = () => {
const mode = this._getModeString()
const { active, icon, activeIcon } = this.props
const mode = this._getModeString();
const { active, icon, activeIcon } = this.props;

return (
<Animated.View
Expand All @@ -133,6 +156,7 @@ export default class Tab extends Component {
{ opacity: this.state[mode].iconOpacity }
]}
>

<View ref="_bnic" collapsable={false}>
{active && activeIcon ? activeIcon : icon}
</View>
Expand Down Expand Up @@ -276,7 +300,8 @@ const styles = StyleSheet.create({
paddingBottom: 10,
paddingLeft: 12,
paddingRight: 12,
backgroundColor: 'transparent'
backgroundColor: 'transparent',
position: "relative",
},
shiftingInactiveContainer: {
maxWidth: 96,
Expand All @@ -298,6 +323,7 @@ const styles = StyleSheet.create({
includeFontPadding: false,
textAlignVertical: 'center',
justifyContent: 'flex-end',
backgroundColor: 'transparent'
backgroundColor: 'transparent',
zIndex: 0
}
})

0 comments on commit 689133d

Please sign in to comment.