diff --git a/docs/docs/docs/guides/usage-with-react-navigation.mdx b/docs/docs/docs/guides/usage-with-react-navigation.mdx index 260b5a4a..8272217d 100644 --- a/docs/docs/docs/guides/usage-with-react-navigation.mdx +++ b/docs/docs/docs/guides/usage-with-react-navigation.mdx @@ -309,6 +309,20 @@ Badge to show on the tab icon. To display a badge without text (just a dot), you need to pass a string with a space character (`" "`). ::: +#### `tabBarBadgeBackgroundColor` + + - Type: `string` + +Set the background color for the badge on android. +Uses the system color by default. + +#### `tabBarBadgeTextColor` + + - Type: `string` + +Set the text color for the badge on android. +Uses the system color by default. + #### `tabBarItemHidden` Whether the tab bar item is hidden. diff --git a/packages/react-native-bottom-tabs/android/src/main/java/com/rcttabview/RCTTabView.kt b/packages/react-native-bottom-tabs/android/src/main/java/com/rcttabview/RCTTabView.kt index 0cf9cef2..f2147d55 100644 --- a/packages/react-native-bottom-tabs/android/src/main/java/com/rcttabview/RCTTabView.kt +++ b/packages/react-native-bottom-tabs/android/src/main/java/com/rcttabview/RCTTabView.kt @@ -253,6 +253,31 @@ class ReactBottomNavigationView(context: Context) : LinearLayout(context) { if (item.badge != " ") { badge.text = item.badge } + // Apply badge colors if provided, or reset to theme defaults if null + if (item.badgeBackgroundColor != null) { + badge.backgroundColor = item.badgeBackgroundColor + } else { + // Reset to theme default color by resolving the colorError attribute + val typedValue = TypedValue() + context.theme.resolveAttribute( + com.google.android.material.R.attr.colorError, + typedValue, + true + ) + badge.backgroundColor = typedValue.data + } + if (item.badgeTextColor != null) { + badge.badgeTextColor = item.badgeTextColor + } else { + // Reset to theme default text color by resolving the colorOnError attribute + val typedValue = TypedValue() + context.theme.resolveAttribute( + com.google.android.material.R.attr.colorOnError, + typedValue, + true + ) + badge.badgeTextColor = typedValue.data + } } else { bottomNavigation.removeBadge(index) } diff --git a/packages/react-native-bottom-tabs/src/TabView.tsx b/packages/react-native-bottom-tabs/src/TabView.tsx index c68dcfde..41b9cb37 100644 --- a/packages/react-native-bottom-tabs/src/TabView.tsx +++ b/packages/react-native-bottom-tabs/src/TabView.tsx @@ -107,6 +107,14 @@ interface Props { * Get badge for the tab, uses `route.badge` by default. */ getBadge?: (props: { route: Route }) => string | undefined; + /** + * Get badge background color for the tab, uses `route.badgeBackgroundColor` by default. (Android only) + */ + getBadgeBackgroundColor?: (props: { route: Route }) => ColorValue | undefined; + /** + * Get badge text color for the tab, uses `route.badgeTextColor` by default. (Android only) + */ + getBadgeTextColor?: (props: { route: Route }) => ColorValue | undefined; /** * Get active tint color for the tab, uses `route.activeTintColor` by default. */ @@ -206,6 +214,9 @@ const TabView = ({ tabBarActiveTintColor: activeTintColor, tabBarInactiveTintColor: inactiveTintColor, getBadge = ({ route }: { route: Route }) => route.badge, + getBadgeBackgroundColor = ({ route }: { route: Route }) => + route.badgeBackgroundColor, + getBadgeTextColor = ({ route }: { route: Route }) => route.badgeTextColor, getLazy = ({ route }: { route: Route }) => route.lazy, getLabelText = ({ route }: { route: Route }) => route.title, getIcon = ({ route, focused }: { route: Route; focused: boolean }) => @@ -289,6 +300,10 @@ const TabView = ({ title: getLabelText({ route }) ?? route.key, sfSymbol: isSfSymbol ? icon.sfSymbol : undefined, badge: getBadge?.({ route }), + badgeBackgroundColor: processColor( + getBadgeBackgroundColor?.({ route }) + ), + badgeTextColor: processColor(getBadgeTextColor?.({ route })), activeTintColor: processColor(getActiveTintColor({ route })), hidden: getHidden?.({ route }), testID: getTestID?.({ route }), @@ -301,6 +316,8 @@ const TabView = ({ icons, getLabelText, getBadge, + getBadgeBackgroundColor, + getBadgeTextColor, getActiveTintColor, getHidden, getTestID, diff --git a/packages/react-native-bottom-tabs/src/TabViewNativeComponent.ts b/packages/react-native-bottom-tabs/src/TabViewNativeComponent.ts index ddc8beea..7949e156 100644 --- a/packages/react-native-bottom-tabs/src/TabViewNativeComponent.ts +++ b/packages/react-native-bottom-tabs/src/TabViewNativeComponent.ts @@ -27,6 +27,8 @@ export type TabViewItems = ReadonlyArray<{ title: string; sfSymbol?: string; badge?: string; + badgeBackgroundColor?: ProcessedColorValue | null; + badgeTextColor?: ProcessedColorValue | null; activeTintColor?: ProcessedColorValue | null; hidden?: boolean; testID?: string; diff --git a/packages/react-native-bottom-tabs/src/types.ts b/packages/react-native-bottom-tabs/src/types.ts index 4f6e01d2..612dcd4f 100644 --- a/packages/react-native-bottom-tabs/src/types.ts +++ b/packages/react-native-bottom-tabs/src/types.ts @@ -11,6 +11,8 @@ export type BaseRoute = { key: string; title?: string; badge?: string; + badgeBackgroundColor?: string; + badgeTextColor?: string; lazy?: boolean; focusedIcon?: ImageSourcePropType | AppleIcon; unfocusedIcon?: ImageSourcePropType | AppleIcon; diff --git a/packages/react-navigation/src/types.ts b/packages/react-navigation/src/types.ts index c0d89a41..b55afb05 100644 --- a/packages/react-navigation/src/types.ts +++ b/packages/react-navigation/src/types.ts @@ -77,6 +77,16 @@ export type NativeBottomTabNavigationOptions = { */ tabBarBadge?: string; + /** + * Badge background color. (Android only) + */ + tabBarBadgeBackgroundColor?: string; + + /** + * Badge text color. (Android only) + */ + tabBarBadgeTextColor?: string; + /** * Whether this screens should render the first time it's accessed. Defaults to true. Set it to false if you want to render the screen on initial render. */ @@ -142,6 +152,8 @@ export type NativeBottomTabNavigationConfig = Partial< | 'getIcon' | 'getLabelText' | 'getBadge' + | 'getBadgeBackgroundColor' + | 'getBadgeTextColor' | 'onTabLongPress' | 'getActiveTintColor' | 'getTestID' diff --git a/packages/react-navigation/src/views/NativeBottomTabView.tsx b/packages/react-navigation/src/views/NativeBottomTabView.tsx index 75aab81e..9be0922f 100644 --- a/packages/react-navigation/src/views/NativeBottomTabView.tsx +++ b/packages/react-navigation/src/views/NativeBottomTabView.tsx @@ -42,6 +42,12 @@ export default function NativeBottomTabView({ : (route as Route).name; }} getBadge={({ route }) => descriptors[route.key]?.options.tabBarBadge} + getBadgeBackgroundColor={({ route }) => + descriptors[route.key]?.options.tabBarBadgeBackgroundColor + } + getBadgeTextColor={({ route }) => + descriptors[route.key]?.options.tabBarBadgeTextColor + } getHidden={({ route }) => { const options = descriptors[route.key]?.options; return options?.tabBarItemHidden === true;