@@ -15,6 +15,7 @@ import { polyfill } from 'react-lifecycles-compat';
1515import color from 'color' ;
1616import Icon from './Icon' ;
1717import Surface from './Surface' ;
18+ import Badge from './Badge' ;
1819import TouchableRipple from './TouchableRipple' ;
1920import Text from './Typography/Text' ;
2021import { black , white } from '../styles/colors' ;
@@ -28,6 +29,7 @@ type Route = $Shape<{
2829 key : string ,
2930 title : string ,
3031 icon : IconSource ,
32+ badge : string | number | boolean ,
3133 color : string ,
3234 accessibilityLabel : string ,
3335 testID : string ,
@@ -60,6 +62,7 @@ type Props<T> = {
6062 * - `title`: title of the route to use as the tab label
6163 * - `icon`: icon to use as the tab icon, can be a string, an image source or a react component
6264 * - `color`: color to use as background color for shifting bottom navigation
65+ * - `badge`: badge to show on the tab icon, can be `true` to show a dot, `string` or `number` to show text.
6366 * - `accessibilityLabel`: accessibility label for the tab button
6467 * - `testID`: test id for the tab button
6568 *
@@ -153,6 +156,11 @@ type Props<T> = {
153156 * Get the id to locate this tab button in tests, uses `route.testID` by default.
154157 */
155158 getTestID ?: ( props : { route : T } ) => ?string ,
159+ /**
160+ * Get badge for the tab, uses `route.badge` by default.
161+ */
162+ getBadge ?: ( props : { route : T } ) => boolean | number | string ,
163+ /**
156164 /**
157165 * Get color for the tab, uses `route.color` by default.
158166 */
@@ -535,6 +543,7 @@ class BottomNavigation<T: *> extends React.Component<Props<T>, State> {
535543 renderIcon,
536544 renderLabel,
537545 getLabelText = ( { route } : Object ) => route . title ,
546+ getBadge = ( { route } : Object ) => route . badge ,
538547 getColor = ( { route } : Object ) => route . color ,
539548 getAccessibilityLabel = ( { route } : Object ) => route . accessibilityLabel ,
540549 getTestID = ( { route } : Object ) => route . testID ,
@@ -734,6 +743,8 @@ class BottomNavigation<T: *> extends React.Component<Props<T>, State> {
734743 outputRange : [ 1 , 0 ] ,
735744 } ) ;
736745
746+ const badge = getBadge ( { route } ) ;
747+
737748 return (
738749 < Touchable
739750 key = { route . key }
@@ -797,6 +808,25 @@ class BottomNavigation<T: *> extends React.Component<Props<T>, State> {
797808 />
798809 ) }
799810 </ Animated . View >
811+ < View
812+ style = { [
813+ styles . badgeContainer ,
814+ {
815+ right :
816+ ( badge != null && typeof badge !== 'boolean'
817+ ? String ( badge ) . length * - 2
818+ : 0 ) - 2 ,
819+ } ,
820+ ] }
821+ >
822+ { typeof badge === 'boolean' ? (
823+ < Badge visible = { badge } size = { 8 } />
824+ ) : (
825+ < Badge visible = { badge != null } size = { 16 } >
826+ { badge }
827+ </ Badge >
828+ ) }
829+ </ View >
800830 </ Animated . View >
801831 { labeled ? (
802832 < Animated . View
@@ -924,4 +954,9 @@ const styles = StyleSheet.create({
924954 textAlign : 'center' ,
925955 backgroundColor : 'transparent' ,
926956 } ,
957+ badgeContainer : {
958+ position : 'absolute' ,
959+ left : 0 ,
960+ top : - 2 ,
961+ } ,
927962} ) ;
0 commit comments