Hey.
It would be great if you added the ability to add to Bottom Navigation
"Badge".
https://imgur.com/bKniATG
https://react-native-elements.github.io/react-native-elements/docs/badge.html
Hi @stanislavpoleshuk, thanks for the proposal. Is there any workaround to achieve this currently?
Yes, it turned out to be done.
Created a wrapper over the BottomNavigationTab component
interface ComponentProps {
badgeText?: string;
}
export type EmptyDataProps = ThemedComponentProps & BottomNavigationTabProps & ComponentProps;
interface State {
}
class EmptyDataContainer extends React.PureComponent<EmptyDataProps, State> {
constructor(props: EmptyDataProps) {
super(props);
this.state = {};
}
public render(): React.ReactNode {
const {themedStyle, title, icon, titleStyle, selected, badgeText, onSelect} = this.props;
return (
<View style={themedStyle.container}>
<BottomNavigationTab
titleStyle={titleStyle}
selected={selected}
onSelect={onSelect}
title={title}
icon={icon}
/>
{
badgeText &&
<View style={themedStyle.badge}>
<Text style={themedStyle.badgeText}>
{badgeText}
</Text>
</View>
}
</View>
);
}
}
export const CustomBottomNavigationTab = withStyles(EmptyDataContainer, (theme: ThemeType) => ({
container: {
flex: 1,
},
badge: {
position: 'absolute',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
width: '100%'
},
badgeText: {
...textStyle.headline,
borderWidth: 2,
borderColor: Colors.white,
padding: 2,
backgroundColor: 'red',
borderRadius: 20,
fontSize: 9,
lineHeight: 11,
color: Colors.white,
minWidth: 19,
textAlignVertical: 'center',
textAlign: 'center',
left: 10,
top: -2,
},
}));
Yes, it turned out to be done.
Created a wrapper over the BottomNavigationTab componentinterface ComponentProps { badgeText?: string; } export type EmptyDataProps = ThemedComponentProps & BottomNavigationTabProps & ComponentProps; interface State { } class EmptyDataContainer extends React.PureComponent<EmptyDataProps, State> { constructor(props: EmptyDataProps) { super(props); this.state = {}; } public render(): React.ReactNode { const {themedStyle, title, icon, titleStyle, selected, badgeText, onSelect} = this.props; return ( <View style={themedStyle.container}> <BottomNavigationTab titleStyle={titleStyle} selected={selected} onSelect={onSelect} title={title} icon={icon} /> { badgeText && <View style={themedStyle.badge}> <Text style={themedStyle.badgeText}> {badgeText} </Text> </View> } </View> ); } } export const CustomBottomNavigationTab = withStyles(EmptyDataContainer, (theme: ThemeType) => ({ container: { flex: 1, }, badge: { position: 'absolute', flexDirection: 'row', justifyContent: 'center', alignItems: 'center', width: '100%' }, badgeText: { ...textStyle.headline, borderWidth: 2, borderColor: Colors.white, padding: 2, backgroundColor: 'red', borderRadius: 20, fontSize: 9, lineHeight: 11, color: Colors.white, minWidth: 19, textAlignVertical: 'center', textAlign: 'center', left: 10, top: -2, }, }));
Has anyone actually made this work? For me it displays, but clicking the Tab does nothing.
You don't actually need any fancy stuff to add a badge (as it turns out). Consider something like this:
// ...
const selectedIndex: number = 0;
const colors = {primary: 'blue'};
const unreadNotifications: number = 3;
// ...
<BottomNavigationTab
icon={(props) => (
<View>
<Icon
{...props}
name="bell-outline"
fill={selectedIndex == 0 ? colors.primary : "grey"}
/>
<View
style={{
height: 15,
width: 15,
backgroundColor: "red",
borderRadius: 10,
position: "absolute",
right: 0,
}}
>
<Text
style={{ color: "#fff", textAlign: "center", fontSize: 10 }}
>
{unreadNotifications}
</Text>
</View>
</View>
)}
/>
unreadNotifications is a number, and in this example the icon fill is determined by the footer state. But the point remains: you can just make the BottomNavigationTab render a custom View with its icon prop.
As such, you can make the presence of the badge view and the unreadNotifications to be functions of state.
Most helpful comment
Yes, it turned out to be done.
Created a wrapper over the BottomNavigationTab component