From ce8f8bc94dccc1df6a86ff4e122e6882f9ec39eb Mon Sep 17 00:00:00 2001 From: lkuchno Date: Tue, 2 Jun 2026 13:26:44 +0200 Subject: [PATCH 1/8] tabbarbadge draft --- .../tests/single-feature-tests/tabs/index.ts | 2 + .../tabs/test-tabs-item-badge/index.tsx | 344 ++++++++++++++++++ .../scenario-description.ts | 12 + 3 files changed, 358 insertions(+) create mode 100644 apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx create mode 100644 apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/scenario-description.ts diff --git a/apps/src/tests/single-feature-tests/tabs/index.ts b/apps/src/tests/single-feature-tests/tabs/index.ts index 318fadaa08..702963962f 100644 --- a/apps/src/tests/single-feature-tests/tabs/index.ts +++ b/apps/src/tests/single-feature-tests/tabs/index.ts @@ -18,6 +18,7 @@ import TestTabsSpecialEffectsScrollToTop from './test-tabs-special-effects-scrol import TestTabsTabBarExperimentalUserInterfaceStyle from './test-tabs-tab-bar-experimental-user-interface-style-ios'; import TestTabsLifecycleEvents from './test-tabs-lifecycle-events'; import TestTabsItemTitle from './test-tabs-item-title-ios'; +import TestTabsItemBadge from './test-tabs-item-badge'; const scenarios = { TestTabBottomAccessory, @@ -38,6 +39,7 @@ const scenarios = { TestTabsTabBarExperimentalUserInterfaceStyle, TestTabsLifecycleEvents, TestTabsItemTitle, + TestTabsItemBadge, }; const TabsScenarioGroup: ScenarioGroup = { diff --git a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx new file mode 100644 index 0000000000..3b4f8f55ac --- /dev/null +++ b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx @@ -0,0 +1,344 @@ +import React from 'react'; +import { Platform, ScrollView, StyleSheet, Text, View } from 'react-native'; +import { scenarioDescription } from './scenario-description'; +import { createScenario } from '@apps/tests/shared/helpers'; +import { + TabsContainerWithHostConfigContext, + type TabRouteConfig, + DEFAULT_TAB_ROUTE_OPTIONS, +} from '@apps/shared/gamma/containers/tabs'; +import { Colors } from '@apps/shared/styling'; + +// Badge colors, reused so the on-screen legend matches the native rendering. +const BADGE = { + red: Colors.RedLight100, + green: Colors.GreenDark100, + blue: Colors.BlueDark100, + purple: Colors.PurpleDark100, + yellow: Colors.YellowDark100, + white: Colors.White, + navy: Colors.NavyLight100, +}; + +function Tab1Screen() { + return ( + + standardAppearance + + {Platform.OS === 'ios' ? ( + <> + `badgeValue`: "1"{'\n'} + `standardAppearance` badge background color, distinct per layout so + rotation reveals the active size class:{'\n'} + {'\n'} + stacked (portrait){'\n'} + {' '}normal: RED, selected:{' '} + GREEN + {'\n'}{'\n'} + inline (landscape, regular){'\n'} + {' '}normal: BLUE, selected:{' '} + PURPLE + {'\n'}{'\n'} + compactInline (landscape, compact){'\n'} + {' '}normal: YELLOW, + selected: GREEN + {'\n'} + {'\n'} + Android: badge background{' '} + RED + badge text{' '} + WHITE (not per layout). + + ) : ( + <> + Font + + `tabBarItemTitleFontFamily`: "monospace"{'\n'} + `tabBarItemTitleSmallLabelFontSize`: 8{'\n'} + `tabBarItemTitleLargeLabelFontSize`: 18{'\n'} + `tabBarItemTitleFontStyle`: "italic"{'\n'} + `tabBarItemTitleFontWeight`: "700"{'\n'} + {'\n'} + {'\n'} + Title should render in bold italic monospace. Unselected tabs use the italic + small label size (8sp); the selected tab scales up to the large label + size (18sp). + + + )} + + + ); +} + +// Tab 2 needs scrollable content so the bottom edge can align with the tab bar +// and trigger `scrollEdgeAppearance`. +function ScrollableInfoScreen() { + return ( + + + scrollEdgeAppearance + {Platform.OS === 'ios' ? ( + <> + + `badgeValue`: "99"{'\n'} + `standardAppearance` badge background:{' '} + BLUE + {'\n'} + `scrollEdgeAppearance` badge background:{' '} + RED + {'\n'} + {'\n'} + iOS only — Android has no `scrollEdgeAppearance`, so it falls back to + its `standardAppearance` badge background{' '} + GREEN + text{' '} + NAVY. + + + + + Scroll all the way down so the list edge meets the tab bar to apply + `scrollEdgeAppearance`. Scroll back up to restore `standardAppearance`. + + + + ) : ( + <> + + Title Color + + `selected.tabBarItemTitleFontColor`:{' '} + RedLight100 + {'\n'} + `normal.tabBarItemTitleFontColor`:{' '} + BlueDark100 + {'\n'} + `focused.tabBarItemTitleFontColor`:{' '} + YellowDark100 + {'\n'} + {'\n'} + When this tab is selected its title should render in{' '} + RED; in the + unselected (normal) state it should render in{' '} + BLUE; and while + keyboard-focused it should render in{' '} + YELLOW. + + + + )} + + + ); +} + +const ROUTE_CONFIGS: TabRouteConfig[] = [ + // Tab 1 — standardAppearance, badge background color per layout & state. + { + name: 'Standard', + Component: Tab1Screen, + options: { + ...DEFAULT_TAB_ROUTE_OPTIONS, + title: 'Standard', + badgeValue: '1', + ios: { + ...DEFAULT_TAB_ROUTE_OPTIONS.ios, + standardAppearance: { + stacked: { + normal: { tabBarItemBadgeBackgroundColor: BADGE.red }, + selected: { tabBarItemBadgeBackgroundColor: BADGE.green }, + }, + inline: { + normal: { tabBarItemBadgeBackgroundColor: BADGE.blue }, + selected: { tabBarItemBadgeBackgroundColor: BADGE.purple }, + }, + compactInline: { + normal: { tabBarItemBadgeBackgroundColor: BADGE.yellow }, + selected: { tabBarItemBadgeBackgroundColor: BADGE.green }, + }, + }, + }, + android: { + ...DEFAULT_TAB_ROUTE_OPTIONS.android, + standardAppearance: { + tabBarItemBadgeBackgroundColor: BADGE.red, + tabBarItemBadgeTextColor: BADGE.white, + }, + }, + }, + }, + { + name: 'ScrollEdge', + Component: ScrollableInfoScreen, + options: { + ...DEFAULT_TAB_ROUTE_OPTIONS, + title: 'ScrollEdge', + badgeValue: '1234567890', + ios: { + ...DEFAULT_TAB_ROUTE_OPTIONS.ios, + standardAppearance: { + stacked: { normal: { tabBarItemBadgeBackgroundColor: BADGE.blue } }, + inline: { normal: { tabBarItemBadgeBackgroundColor: BADGE.blue } }, + compactInline: { + normal: { tabBarItemBadgeBackgroundColor: BADGE.blue }, + }, + }, + scrollEdgeAppearance: { + stacked: { normal: { tabBarItemBadgeBackgroundColor: BADGE.red } }, + inline: { normal: { tabBarItemBadgeBackgroundColor: BADGE.red } }, + compactInline: { + normal: { tabBarItemBadgeBackgroundColor: BADGE.red }, + }, + }, + }, + android: { + ...DEFAULT_TAB_ROUTE_OPTIONS.android, + standardAppearance: { + tabBarItemBadgeBackgroundColor: BADGE.green, + tabBarItemBadgeTextColor: BADGE.navy, + }, + }, + }, + }, + // Tab 3 — per-state badge background color (normal / selected / focused / disabled). + // { + // name: 'States', + // Component: () => ( + // + // `badgeValue`: "NEW"{'\n'} + // `standardAppearance` badge background per state (iOS, applied to all + // layouts):{'\n'} + // {'\n'} + // {' '}normal: BLUE + // {'\n'} + // {' '}selected: GREEN + // {'\n'} + // {' '}focused: PURPLE + // {'\n'} + // {' '}disabled: YELLOW + // {'\n'} + // {'\n'} + // Select / unselect this tab to compare normal vs selected. Focused + // applies during keyboard / hardware focus.{'\n'} + // {'\n'} + // Android: badge colors are global (not per state) — background{' '} + // PURPLE + text{' '} + // WHITE. + // + // } + // /> + // ), + // options: { + // ...DEFAULT_TAB_ROUTE_OPTIONS, + // title: 'States', + // badgeValue: 'NEW', + // ios: { + // ...DEFAULT_TAB_ROUTE_OPTIONS.ios, + // standardAppearance: { + // stacked: { + // normal: { tabBarItemBadgeBackgroundColor: BADGE.blue }, + // selected: { tabBarItemBadgeBackgroundColor: BADGE.green }, + // focused: { tabBarItemBadgeBackgroundColor: BADGE.purple }, + // disabled: { tabBarItemBadgeBackgroundColor: BADGE.yellow }, + // }, + // inline: { + // normal: { tabBarItemBadgeBackgroundColor: BADGE.blue }, + // selected: { tabBarItemBadgeBackgroundColor: BADGE.green }, + // focused: { tabBarItemBadgeBackgroundColor: BADGE.purple }, + // disabled: { tabBarItemBadgeBackgroundColor: BADGE.yellow }, + // }, + // compactInline: { + // normal: { tabBarItemBadgeBackgroundColor: BADGE.blue }, + // selected: { tabBarItemBadgeBackgroundColor: BADGE.green }, + // focused: { tabBarItemBadgeBackgroundColor: BADGE.purple }, + // disabled: { tabBarItemBadgeBackgroundColor: BADGE.yellow }, + // }, + // }, + // }, + // android: { + // ...DEFAULT_TAB_ROUTE_OPTIONS.android, + // standardAppearance: { + // tabBarItemBadgeBackgroundColor: BADGE.purple, + // tabBarItemBadgeTextColor: BADGE.white, + // }, + // }, + // }, + // }, + // // Tab 4 — control: badgeValue with default (system) badge colors on iOS, + // // and a strong text/background contrast on Android. + // { + // name: 'Default', + // Component: () => ( + // + // `badgeValue`: "42"{'\n'} + // No `tabBarItemBadgeBackgroundColor` override on iOS — the badge uses + // the default system (red) background. Control for the other tabs. + // {'\n'} + // {'\n'} + // Android: high-contrast badge — background{' '} + // YELLOW + text{' '} + // NAVY, to verify + // `tabBarItemBadgeTextColor` is honored. + // + // } + // /> + // ), + // options: { + // ...DEFAULT_TAB_ROUTE_OPTIONS, + // title: 'Default', + // badgeValue: '42', + // android: { + // ...DEFAULT_TAB_ROUTE_OPTIONS.android, + // standardAppearance: { + // tabBarItemBadgeBackgroundColor: BADGE.yellow, + // tabBarItemBadgeTextColor: BADGE.navy, + // }, + // }, + // }, + // }, +]; + +export function App() { + return ; +} + +const styles = StyleSheet.create({ + screen: { + flex: 1, + margin: 24, + padding: 24, + gap: 12, + + }, + scrollContent: { + paddingBottom: 24, + gap: 12, + }, + spacer: { + height: 220, + }, + label: { + fontSize: 17, + fontWeight: '600', + marginBottom: 12, + marginTop: 24, + alignSelf: 'center', + }, + hint: { + fontSize: 13, + color: Colors.LightOffNavy, + lineHeight: 20, + textAlign: 'center', + }, + platformHeader: { + fontWeight: '700', + color: Colors.LightOffNavy, + }, +}); + +export default createScenario(App, scenarioDescription); diff --git a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/scenario-description.ts b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/scenario-description.ts new file mode 100644 index 0000000000..ebeb7412c7 --- /dev/null +++ b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/scenario-description.ts @@ -0,0 +1,12 @@ +import type { ScenarioDescription } from '@apps/tests/shared/helpers'; + +export const scenarioDescription: ScenarioDescription = { + name: 'Tab Bar Item Badge', + key: 'test-tabs-item-badge', + details: + 'Exercises tab bar item badge props: badgeValue, badgeBackgroundColor (iOS & Android), and badgeTextColor (Android only). ' + + 'Tests badge appearance across different layout modes (stacked, inline, compactInline) and states (normal, selected, focused, disabled).', + platforms: ['ios', 'android'], + e2eCoverage: 'incomplete', + smokeTest: false, +}; From 8a0d7266be5189977027dee3876cf294a3e55036 Mon Sep 17 00:00:00 2001 From: lkuchno Date: Tue, 2 Jun 2026 15:22:51 +0200 Subject: [PATCH 2/8] chore(test): screen test for test-tabs-item-badge tests --- .../tabs/test-tabs-item-badge/index.tsx | 376 ++++++++---------- 1 file changed, 163 insertions(+), 213 deletions(-) diff --git a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx index 3b4f8f55ac..a649148973 100644 --- a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx +++ b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx @@ -23,284 +23,231 @@ const BADGE = { function Tab1Screen() { return ( - standardAppearance - + Default badge appearance + {Platform.OS === 'ios' ? ( + <> + + `badgeValue`: "1"{'\n'}{'\n'} + `standardAppearance` and `scrollEdgeAppearance` are not defined.{'\n'}{'\n'} + Badges render with the default iOS appearance: + badge background{' '} + RED with white text. + + + ) : ( + <> + + `badgeValue`: "1"{'\n'}{'\n'} + Badge appearance is not defined.{'\n'}{'\n'} + Badges render with the default system appearance: + badge background{' '} + RED with white text. + + + )} + + ); +} + +function Tab2Screen() { + return ( + + + Long Badge Value {Platform.OS === 'ios' ? ( <> - `badgeValue`: "1"{'\n'} - `standardAppearance` badge background color, distinct per layout so - rotation reveals the active size class:{'\n'} - {'\n'} - stacked (portrait){'\n'} - {' '}normal: RED, selected:{' '} - GREEN - {'\n'}{'\n'} - inline (landscape, regular){'\n'} - {' '}normal: BLUE, selected:{' '} - PURPLE - {'\n'}{'\n'} - compactInline (landscape, compact){'\n'} - {' '}normal: YELLOW, - selected: GREEN - {'\n'} - {'\n'} - Android: badge background{' '} - RED + badge text{' '} - WHITE (not per layout). + + `badgeValue`: "1234567890"{'\n'}{'\n'} + `standardAppearance`{'\n'} + `tabBarItemBadgeBackgroundColor`:{' '} + BLUE + {'\n'}{'\n'} + `scrollEdgeAppearance`{'\n'} + `tabBarItemBadgeBackgroundColor`:{' '} + YELLOW + {'\n'}{'\n'} + + + + Scroll all the way down so the list edge meets the tab bar to apply + `scrollEdgeAppearance`. Scroll back up to restore `standardAppearance`. + + ) : ( <> - Font - `tabBarItemTitleFontFamily`: "monospace"{'\n'} - `tabBarItemTitleSmallLabelFontSize`: 8{'\n'} - `tabBarItemTitleLargeLabelFontSize`: 18{'\n'} - `tabBarItemTitleFontStyle`: "italic"{'\n'} - `tabBarItemTitleFontWeight`: "700"{'\n'} - {'\n'} + `badgeValue`: "1234567890" displayed as "999+"{'\n'}{'\n'} + `tabBarItemBadgeBackgroundColor`:{' '} + BLUE {'\n'} - Title should render in bold italic monospace. Unselected tabs use the italic - small label size (8sp); the selected tab scales up to the large label - size (18sp). + `tabBarItemBadgeTextColor`:{' '} + YELLOW )} - - + + ); } -// Tab 2 needs scrollable content so the bottom edge can align with the tab bar -// and trigger `scrollEdgeAppearance`. -function ScrollableInfoScreen() { +function Tab3Screen() { return ( - - - scrollEdgeAppearance + + String Badge Value {Platform.OS === 'ios' ? ( <> - `badgeValue`: "99"{'\n'} - `standardAppearance` badge background:{' '} + `badgeValue`: "NEW!"{'\n'}{'\n'} + selected: `tabBarItemBadgeBackgroundColor`:{' '} BLUE - {'\n'} - `scrollEdgeAppearance` badge background:{' '} - RED - {'\n'} - {'\n'} - iOS only — Android has no `scrollEdgeAppearance`, so it falls back to - its `standardAppearance` badge background{' '} - GREEN + text{' '} - NAVY. + {'\n'}{'\n'} + normal: `tabBarItemBadgeBackgroundColor`:{' '} + PURPLE + {'\n'}{'\n'} - - - - Scroll all the way down so the list edge meets the tab bar to apply - `scrollEdgeAppearance`. Scroll back up to restore `standardAppearance`. - - ) : ( <> - - Title Color - - `selected.tabBarItemTitleFontColor`:{' '} - RedLight100 - {'\n'} - `normal.tabBarItemTitleFontColor`:{' '} - BlueDark100 - {'\n'} - `focused.tabBarItemTitleFontColor`:{' '} - YellowDark100 - {'\n'} - {'\n'} - When this tab is selected its title should render in{' '} - RED; in the - unselected (normal) state it should render in{' '} - BLUE; and while - keyboard-focused it should render in{' '} - YELLOW. - - + + `badgeValue`: "NEW!"{'\n'}{'\n'} + `tabBarItemBadgeBackgroundColor`:{' '} + PURPLE + {'\n'} + `tabBarItemBadgeTextColor`:{' '} + NAVY + )} - + ); +} + +function Tab4Screen() { + return ( + + Default badge appearance + {Platform.OS === 'ios' ? ( + <> + + `badgeValue`: "⚠️"{'\n'}{'\n'} + Badge appearance is defined only for selected tab: setting background to `transparent` value.{'\n'}{'\n'} + Unselected badges render with the default system appearance: + badge background{' '} + RED with white text. + + + ) : ( + <> + + `badgeValue`: "⚠️"{'\n'}{'\n'} + `tabBarItemBadgeBackgroundColor`: `transparent` + {'\n'} + `tabBarItemBadgeTextColor`:{' '} + RED + + + )} + ); } const ROUTE_CONFIGS: TabRouteConfig[] = [ - // Tab 1 — standardAppearance, badge background color per layout & state. { - name: 'Standard', + name: 'Tab1', Component: Tab1Screen, options: { ...DEFAULT_TAB_ROUTE_OPTIONS, - title: 'Standard', + title: 'Tab1', badgeValue: '1', ios: { ...DEFAULT_TAB_ROUTE_OPTIONS.ios, - standardAppearance: { - stacked: { - normal: { tabBarItemBadgeBackgroundColor: BADGE.red }, - selected: { tabBarItemBadgeBackgroundColor: BADGE.green }, - }, - inline: { - normal: { tabBarItemBadgeBackgroundColor: BADGE.blue }, - selected: { tabBarItemBadgeBackgroundColor: BADGE.purple }, - }, - compactInline: { - normal: { tabBarItemBadgeBackgroundColor: BADGE.yellow }, - selected: { tabBarItemBadgeBackgroundColor: BADGE.green }, - }, - }, }, android: { ...DEFAULT_TAB_ROUTE_OPTIONS.android, standardAppearance: { - tabBarItemBadgeBackgroundColor: BADGE.red, - tabBarItemBadgeTextColor: BADGE.white, + tabBarItemLabelVisibilityMode: 'labeled', }, }, }, }, { - name: 'ScrollEdge', - Component: ScrollableInfoScreen, + name: 'Tab2', + Component: Tab2Screen, options: { ...DEFAULT_TAB_ROUTE_OPTIONS, - title: 'ScrollEdge', + title: 'Tab2', badgeValue: '1234567890', ios: { ...DEFAULT_TAB_ROUTE_OPTIONS.ios, standardAppearance: { stacked: { normal: { tabBarItemBadgeBackgroundColor: BADGE.blue } }, - inline: { normal: { tabBarItemBadgeBackgroundColor: BADGE.blue } }, - compactInline: { - normal: { tabBarItemBadgeBackgroundColor: BADGE.blue }, - }, }, scrollEdgeAppearance: { - stacked: { normal: { tabBarItemBadgeBackgroundColor: BADGE.red } }, - inline: { normal: { tabBarItemBadgeBackgroundColor: BADGE.red } }, - compactInline: { - normal: { tabBarItemBadgeBackgroundColor: BADGE.red }, + stacked: { normal: { tabBarItemBadgeBackgroundColor: BADGE.yellow } }, + }, + }, + android: { + ...DEFAULT_TAB_ROUTE_OPTIONS.android, + standardAppearance: { + tabBarItemLabelVisibilityMode: 'labeled', + tabBarItemBadgeBackgroundColor: BADGE.blue, + tabBarItemBadgeTextColor: BADGE.yellow, + }, + }, + }, + }, + { + name: 'Tab3', + Component: Tab3Screen, + options: { + ...DEFAULT_TAB_ROUTE_OPTIONS, + title: 'Tab3', + badgeValue: 'NEW!', + ios: { + ...DEFAULT_TAB_ROUTE_OPTIONS.ios, + standardAppearance: { + stacked: { + normal: { tabBarItemBadgeBackgroundColor: BADGE.purple }, + selected: { tabBarItemBadgeBackgroundColor: BADGE.blue }, }, }, }, android: { ...DEFAULT_TAB_ROUTE_OPTIONS.android, standardAppearance: { - tabBarItemBadgeBackgroundColor: BADGE.green, + tabBarItemLabelVisibilityMode: 'labeled', + tabBarItemBadgeBackgroundColor: BADGE.purple, tabBarItemBadgeTextColor: BADGE.navy, }, }, }, }, - // Tab 3 — per-state badge background color (normal / selected / focused / disabled). - // { - // name: 'States', - // Component: () => ( - // - // `badgeValue`: "NEW"{'\n'} - // `standardAppearance` badge background per state (iOS, applied to all - // layouts):{'\n'} - // {'\n'} - // {' '}normal: BLUE - // {'\n'} - // {' '}selected: GREEN - // {'\n'} - // {' '}focused: PURPLE - // {'\n'} - // {' '}disabled: YELLOW - // {'\n'} - // {'\n'} - // Select / unselect this tab to compare normal vs selected. Focused - // applies during keyboard / hardware focus.{'\n'} - // {'\n'} - // Android: badge colors are global (not per state) — background{' '} - // PURPLE + text{' '} - // WHITE. - // - // } - // /> - // ), - // options: { - // ...DEFAULT_TAB_ROUTE_OPTIONS, - // title: 'States', - // badgeValue: 'NEW', - // ios: { - // ...DEFAULT_TAB_ROUTE_OPTIONS.ios, - // standardAppearance: { - // stacked: { - // normal: { tabBarItemBadgeBackgroundColor: BADGE.blue }, - // selected: { tabBarItemBadgeBackgroundColor: BADGE.green }, - // focused: { tabBarItemBadgeBackgroundColor: BADGE.purple }, - // disabled: { tabBarItemBadgeBackgroundColor: BADGE.yellow }, - // }, - // inline: { - // normal: { tabBarItemBadgeBackgroundColor: BADGE.blue }, - // selected: { tabBarItemBadgeBackgroundColor: BADGE.green }, - // focused: { tabBarItemBadgeBackgroundColor: BADGE.purple }, - // disabled: { tabBarItemBadgeBackgroundColor: BADGE.yellow }, - // }, - // compactInline: { - // normal: { tabBarItemBadgeBackgroundColor: BADGE.blue }, - // selected: { tabBarItemBadgeBackgroundColor: BADGE.green }, - // focused: { tabBarItemBadgeBackgroundColor: BADGE.purple }, - // disabled: { tabBarItemBadgeBackgroundColor: BADGE.yellow }, - // }, - // }, - // }, - // android: { - // ...DEFAULT_TAB_ROUTE_OPTIONS.android, - // standardAppearance: { - // tabBarItemBadgeBackgroundColor: BADGE.purple, - // tabBarItemBadgeTextColor: BADGE.white, - // }, - // }, - // }, - // }, - // // Tab 4 — control: badgeValue with default (system) badge colors on iOS, - // // and a strong text/background contrast on Android. - // { - // name: 'Default', - // Component: () => ( - // - // `badgeValue`: "42"{'\n'} - // No `tabBarItemBadgeBackgroundColor` override on iOS — the badge uses - // the default system (red) background. Control for the other tabs. - // {'\n'} - // {'\n'} - // Android: high-contrast badge — background{' '} - // YELLOW + text{' '} - // NAVY, to verify - // `tabBarItemBadgeTextColor` is honored. - // - // } - // /> - // ), - // options: { - // ...DEFAULT_TAB_ROUTE_OPTIONS, - // title: 'Default', - // badgeValue: '42', - // android: { - // ...DEFAULT_TAB_ROUTE_OPTIONS.android, - // standardAppearance: { - // tabBarItemBadgeBackgroundColor: BADGE.yellow, - // tabBarItemBadgeTextColor: BADGE.navy, - // }, - // }, - // }, - // }, + { + name: 'Tab4', + Component: Tab4Screen, + options: { + ...DEFAULT_TAB_ROUTE_OPTIONS, + title: 'Tab4', + badgeValue: '⚠️', + ios: { + ...DEFAULT_TAB_ROUTE_OPTIONS.ios, + standardAppearance: { + stacked: { + selected: { tabBarItemBadgeBackgroundColor: 'transparent' }, + } + }, + }, + android: { + ...DEFAULT_TAB_ROUTE_OPTIONS.android, + standardAppearance: { + tabBarItemLabelVisibilityMode: 'labeled', + tabBarItemBadgeBackgroundColor: 'transparent', + tabBarItemBadgeTextColor: BADGE.red, + }, + }, + }, + }, ]; export function App() { @@ -308,6 +255,9 @@ export function App() { } const styles = StyleSheet.create({ + scrollView: { + flex: 1, + }, screen: { flex: 1, margin: 24, From e006b74e6b36c8f9d08822a0ed20e62557df09e5 Mon Sep 17 00:00:00 2001 From: lkuchno Date: Wed, 3 Jun 2026 08:59:23 +0200 Subject: [PATCH 3/8] changing color and fontWeight on screens --- .../tabs/test-tabs-item-badge/index.tsx | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx index a649148973..b43e2e2a2d 100644 --- a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx +++ b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx @@ -31,7 +31,7 @@ function Tab1Screen() { `standardAppearance` and `scrollEdgeAppearance` are not defined.{'\n'}{'\n'} Badges render with the default iOS appearance: badge background{' '} - RED with white text. + RED with white text. ) : ( @@ -41,7 +41,7 @@ function Tab1Screen() { Badge appearance is not defined.{'\n'}{'\n'} Badges render with the default system appearance: badge background{' '} - RED with white text. + DARK RED with white text. )} @@ -60,11 +60,11 @@ function Tab2Screen() { `badgeValue`: "1234567890"{'\n'}{'\n'} `standardAppearance`{'\n'} `tabBarItemBadgeBackgroundColor`:{' '} - BLUE + BLUE {'\n'}{'\n'} `scrollEdgeAppearance`{'\n'} `tabBarItemBadgeBackgroundColor`:{' '} - YELLOW + YELLOW {'\n'}{'\n'} @@ -79,10 +79,10 @@ function Tab2Screen() { `badgeValue`: "1234567890" displayed as "999+"{'\n'}{'\n'} `tabBarItemBadgeBackgroundColor`:{' '} - BLUE + BLUE {'\n'} `tabBarItemBadgeTextColor`:{' '} - YELLOW + YELLOW )} @@ -100,10 +100,10 @@ function Tab3Screen() { `badgeValue`: "NEW!"{'\n'}{'\n'} selected: `tabBarItemBadgeBackgroundColor`:{' '} - BLUE + BLUE {'\n'}{'\n'} normal: `tabBarItemBadgeBackgroundColor`:{' '} - PURPLE + PURPLE {'\n'}{'\n'} @@ -112,10 +112,10 @@ function Tab3Screen() { `badgeValue`: "NEW!"{'\n'}{'\n'} `tabBarItemBadgeBackgroundColor`:{' '} - PURPLE + PURPLE {'\n'} `tabBarItemBadgeTextColor`:{' '} - NAVY + NAVY )} @@ -134,7 +134,7 @@ function Tab4Screen() { Badge appearance is defined only for selected tab: setting background to `transparent` value.{'\n'}{'\n'} Unselected badges render with the default system appearance: badge background{' '} - RED with white text. + RED with white text. ) : ( @@ -144,7 +144,7 @@ function Tab4Screen() { `tabBarItemBadgeBackgroundColor`: `transparent` {'\n'} `tabBarItemBadgeTextColor`:{' '} - RED + RED )} From 32c753943b51c3b931d1cc1e62cffcc8d8ae804d Mon Sep 17 00:00:00 2001 From: lkuchno Date: Wed, 3 Jun 2026 14:43:53 +0200 Subject: [PATCH 4/8] corrected screen and scenario --- .../tabs/test-tabs-item-badge/index.tsx | 5 +- .../scenario-description.ts | 3 +- .../tabs/test-tabs-item-badge/scenario.md | 196 ++++++++++++++++++ 3 files changed, 200 insertions(+), 4 deletions(-) create mode 100644 apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/scenario.md diff --git a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx index b43e2e2a2d..efafe486cb 100644 --- a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx +++ b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx @@ -37,7 +37,8 @@ function Tab1Screen() { ) : ( <> - `badgeValue`: "1"{'\n'}{'\n'} + `badgeValue`: " "{'\n'} + Empty string badge value renders as "small dot" badge.{'\n'}{'\n'} Badge appearance is not defined.{'\n'}{'\n'} Badges render with the default system appearance: badge background{' '} @@ -159,7 +160,7 @@ const ROUTE_CONFIGS: TabRouteConfig[] = [ options: { ...DEFAULT_TAB_ROUTE_OPTIONS, title: 'Tab1', - badgeValue: '1', + badgeValue: Platform.OS === 'ios' ? '1' : '', ios: { ...DEFAULT_TAB_ROUTE_OPTIONS.ios, }, diff --git a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/scenario-description.ts b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/scenario-description.ts index ebeb7412c7..2d21c04b64 100644 --- a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/scenario-description.ts +++ b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/scenario-description.ts @@ -4,8 +4,7 @@ export const scenarioDescription: ScenarioDescription = { name: 'Tab Bar Item Badge', key: 'test-tabs-item-badge', details: - 'Exercises tab bar item badge props: badgeValue, badgeBackgroundColor (iOS & Android), and badgeTextColor (Android only). ' + - 'Tests badge appearance across different layout modes (stacked, inline, compactInline) and states (normal, selected, focused, disabled).', + 'Exercises tab bar item badge props: badgeValue, badgeBackgroundColor, and badgeTextColor (Android only).', platforms: ['ios', 'android'], e2eCoverage: 'incomplete', smokeTest: false, diff --git a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/scenario.md b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/scenario.md new file mode 100644 index 0000000000..560dfd2c7b --- /dev/null +++ b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/scenario.md @@ -0,0 +1,196 @@ +# Test Scenario: Tab Bar Item Badge + +## Details + +**Description:** Validates the `badgeValue` prop on `TabsScreen` and the +badge appearance props (`tabBarItemBadgeBackgroundColor` and Android only: `tabBarItemBadgeTextColor`). The scenario covers +four badge cases: a badge with default system appearance, a +long numeric string that overflows the max display width, a custom string +badge, and an emoji badge. For iOS, it also exercises +`scrollEdgeAppearance` badge color. On Android, all badge color +customisation is driven by `standardAppearance`. + +**OS test creation version:** iOS: 18.6 and iOS 26.5, Android: API Level 36. + +## E2E test + +Incomplete: Not automated. All observable +outcomes are purely visual (badge color, text color, displayed string). +Detox does not expose color or text-content attributes of native tab bar +badge items, so automated assertion requires a screenshot-diff approach +not yet in place. + +## Prerequisites + +- iOS device or simulator. +- Android emulator. + +## Note + +`badgeValue`: + +- On Android the maximum badge string length rendered verbatim is 4 + characters; longer numeric strings are capped and shown as `999+`. + When `badgeValue` is set to an empty string it renders as "small dot" badge if + `tabBarItemBadgeBackgroundColor` is not `transparent`. +- On iOS 18: badges render the full `badgeValue` string without truncation; +because the badge text color is white, any characters overflowing the badge's colored +background will blend into a white screen background and become invisible. +- On iOS 26: long badges render the `badgeValue` string with truncation, ending with "...". + +`tabBarItemBadgeBackgroundColor`: + +- Setting a transparent `tabBarItemBadgeBackgroundColor` removes the badge's pill +background. On iOS, only the selected tab's badgeValue floats without a colored +background, while the background color of unselected badges remains visible. +On Android, this property makes the background fully transparent for all tabs, +effectively making Tab1 appear badgeless. +- On iOS 26 ([KI 1072](https://github.com/software-mansion/react-native-screens-labs/issues/1072)) +When `tabBarItemBadgeBackgroundColor` is defined with different colors for the +normal and selected states, the badge color of the selected tab breaks and +partially uses the normal state's background color. Additionally, if a tab on +the left side has a long badge value, it can be affected as well, causing its +color to partially break and incorrectly inherit the selected state's background color. + +--- + +## Steps (iOS) + +### Baseline + +1. Launch the app and navigate to the **Tab Bar Item Badge** screen. + +- [ ] Four tabs are visible - **Tab1**, **Tab2**, **Tab3**, **Tab4**. +- [ ] Tab1 is active. Each tab shows a badge in the tab bar. +- [ ] Tab1: badge reads **1**. +- [ ] Tab2: on iOS 26 badge reads **12345...**; on iOS 18 **23456789** is visible. +- [ ] Tab3's badge reads **NEW!**. +- [ ] Tab4's badge reads **⚠️**. + +--- + +### Tab1 - default badge appearance + +2. Confirm Tab1 is active. Observe the Tab1 badge in the tab bar. + +- [ ] Badge shows **1**. +- [ ] The badge renders with the iOS system default: red background with white text. + +--- + +### Tab2 - long badge value and scrollEdgeAppearance + +3. Tap **Tab2** in the tab bar. + +- [ ] Tab2 is selected. The badge in the tab bar reads: + - on iOS 26 badge reads **12345...**; + - on iOS 18 **23456789** is visible. +- [ ] The badge pill is blue. + +4. iOS 26 only: Scroll the Tab2 content all the way to the bottom until the scroll + edge meets the tab bar. + +- [ ] The badge pill color transitions from blue to yellow for all tabs. + +5. iOS 26 only: Scroll back up so the content edge no longer touches the tab bar. + +- [ ] The badge pill returns to blue. + +--- + +### Tab3 - string badge value and normal/selected state colors + +6. Tap **Tab3** in the tab bar. + +- [ ] Tab3 is selected. The badge in the tab bar reads **NEW!**. +- [ ] The selected tab badge pill is blue, other tabs badges pills are purple. +- [ ] On iOS 26 selected badge pill color is divided into selected (blue) and +normal (purple), also Tab2 badge is affected and its badge color is partially blue +(see KI from Note section) + +--- + +### Tab4 - emoji badge and transparent selected state + +7. Tap **Tab4** in the tab bar. + +- [ ] Tab4 is selected. The badge in the tab bar shows **⚠️**. +- [ ] The selected state has `tabBarItemBadgeBackgroundColor: transparent`, + so the badge background is invisible - the emoji floats without a + colored pill. +- [ ] The badge background for unselected tabs is default red. + +--- + +### Stability check + +8. Cycle through all four tabs in order (Tab1 → Tab2 → Tab3 → Tab4), + then in reverse (Tab4 → Tab3 → Tab2 → Tab1). + +- [ ] Each badge updates correctly for the selected vs. unselected state on every tab switch. + +--- + +## Steps (Android) + +### Baseline + +1. Launch the app and navigate to the **Tab Bar Item Badge** screen. + +- [ ] Four tabs are visible - **Tab1**, **Tab2**, **Tab3**, **Tab4**. +- [ ] Tab1 is active. Each tab shows a badge in the tab bar. +- [ ] Tab1: small dot is visible as badge value is set to an empty string. +- [ ] Tab2's badge is capped at **999+** (the string "1234567890" exceeds the +maximum and is truncated by the system). +- [ ] Tab3's badge reads **NEW!**. +- [ ] Tab4's badge reads **⚠️**. + +--- + +### Tab1 - default badge appearance + +2. Confirm Tab1 is active. Observe the Tab1 badge in the tab bar. + +- [ ] Badge shows as a small dot. +- [ ] The badge renders with the Android system default: red background with white text. + +--- + +### Tab2 - long badge value and custom colors + +3. Tap **Tab2** in the tab bar. + +- [ ] Tab2 is selected. The badge in the tab bar is shown + as **999+**. +- [ ] The badge background is blue and the badge text is + yellow for all tabs. + +--- + +### Tab3 - string badge value and custom colors + +4. Tap **Tab3** in the tab bar. + +- [ ] Tab3 is selected. The badge in the tab bar reads **NEW!**. +- [ ] The badge background is purple and the badge text is navy for all tabs. + +--- + +### Tab4 - emoji badge and transparent background + +5. Tap **Tab4** in the tab bar. + +- [ ] Tab4 is selected. The badge in the tab bar shows emoji **⚠️**. +- [ ] The badge background is transparent for all tabs, so the emoji and text +floats without a colored pill. +- [ ] The badge text color is red. + +--- + +### Stability check + +6. Cycle through all four tabs in order (Tab1 → Tab2 → Tab3 → Tab4), + then in reverse (Tab4 → Tab3 → Tab2 → Tab1). + +- [ ]Each badge is displayed correctly on every tab switch. The colors, text +values, and transparent states remain stable. From c3e49862915180c189ed6a8a871ef62be3521238 Mon Sep 17 00:00:00 2001 From: lkuchno Date: Wed, 3 Jun 2026 15:32:15 +0200 Subject: [PATCH 5/8] refactor test screen --- .../tabs/test-tabs-item-badge/index.tsx | 124 +++++++----------- 1 file changed, 49 insertions(+), 75 deletions(-) diff --git a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx index efafe486cb..03f8c4d554 100644 --- a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx +++ b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx @@ -9,17 +9,6 @@ import { } from '@apps/shared/gamma/containers/tabs'; import { Colors } from '@apps/shared/styling'; -// Badge colors, reused so the on-screen legend matches the native rendering. -const BADGE = { - red: Colors.RedLight100, - green: Colors.GreenDark100, - blue: Colors.BlueDark100, - purple: Colors.PurpleDark100, - yellow: Colors.YellowDark100, - white: Colors.White, - navy: Colors.NavyLight100, -}; - function Tab1Screen() { return ( @@ -30,7 +19,7 @@ function Tab1Screen() { `badgeValue`: "1"{'\n'}{'\n'} `standardAppearance` and `scrollEdgeAppearance` are not defined.{'\n'}{'\n'} Badges render with the default iOS appearance: - badge background{' '} + `tabBarItemBadgeBackgroundColor`{' '} RED with white text. @@ -38,10 +27,10 @@ function Tab1Screen() { <> `badgeValue`: " "{'\n'} - Empty string badge value renders as "small dot" badge.{'\n'}{'\n'} + Empty string badge value renders as "small dot" with color define in `tabBarItemBadgeBackgroundColor` or system default if not set.{'\n'}{'\n'} Badge appearance is not defined.{'\n'}{'\n'} Badges render with the default system appearance: - badge background{' '} + background{' '} DARK RED with white text. @@ -52,7 +41,7 @@ function Tab1Screen() { function Tab2Screen() { return ( - + Long Badge Value {Platform.OS === 'ios' ? ( @@ -61,11 +50,11 @@ function Tab2Screen() { `badgeValue`: "1234567890"{'\n'}{'\n'} `standardAppearance`{'\n'} `tabBarItemBadgeBackgroundColor`:{' '} - BLUE + BLUE {'\n'}{'\n'} `scrollEdgeAppearance`{'\n'} `tabBarItemBadgeBackgroundColor`:{' '} - YELLOW + YELLOW {'\n'}{'\n'} @@ -80,10 +69,10 @@ function Tab2Screen() { `badgeValue`: "1234567890" displayed as "999+"{'\n'}{'\n'} `tabBarItemBadgeBackgroundColor`:{' '} - BLUE + BLUE {'\n'} `tabBarItemBadgeTextColor`:{' '} - YELLOW + YELLOW )} @@ -94,40 +83,40 @@ function Tab2Screen() { function Tab3Screen() { return ( - - String Badge Value - {Platform.OS === 'ios' ? ( - <> - - `badgeValue`: "NEW!"{'\n'}{'\n'} - selected: `tabBarItemBadgeBackgroundColor`:{' '} - BLUE - {'\n'}{'\n'} - normal: `tabBarItemBadgeBackgroundColor`:{' '} - PURPLE - {'\n'}{'\n'} - - - ) : ( - <> - - `badgeValue`: "NEW!"{'\n'}{'\n'} - `tabBarItemBadgeBackgroundColor`:{' '} - PURPLE - {'\n'} - `tabBarItemBadgeTextColor`:{' '} - NAVY - - - )} - + + String Badge Value + {Platform.OS === 'ios' ? ( + <> + + `badgeValue`: "NEW!"{'\n'}{'\n'} + selected: `tabBarItemBadgeBackgroundColor`:{' '} + BLUE + {'\n'}{'\n'} + normal: `tabBarItemBadgeBackgroundColor`:{' '} + PURPLE + {'\n'}{'\n'} + + + ) : ( + <> + + `badgeValue`: "NEW!"{'\n'}{'\n'} + `tabBarItemBadgeBackgroundColor`:{' '} + PURPLE + {'\n'} + `tabBarItemBadgeTextColor`:{' '} + NAVY + + + )} + ); } function Tab4Screen() { return ( - Default badge appearance + Transparent badge background {Platform.OS === 'ios' ? ( <> @@ -143,10 +132,10 @@ function Tab4Screen() { `badgeValue`: "⚠️"{'\n'}{'\n'} `tabBarItemBadgeBackgroundColor`: `transparent` - {'\n'} - `tabBarItemBadgeTextColor`:{' '} - RED - + {'\n'} + `tabBarItemBadgeTextColor`:{' '} + RED + )} @@ -158,7 +147,6 @@ const ROUTE_CONFIGS: TabRouteConfig[] = [ name: 'Tab1', Component: Tab1Screen, options: { - ...DEFAULT_TAB_ROUTE_OPTIONS, title: 'Tab1', badgeValue: Platform.OS === 'ios' ? '1' : '', ios: { @@ -176,24 +164,23 @@ const ROUTE_CONFIGS: TabRouteConfig[] = [ name: 'Tab2', Component: Tab2Screen, options: { - ...DEFAULT_TAB_ROUTE_OPTIONS, title: 'Tab2', badgeValue: '1234567890', ios: { ...DEFAULT_TAB_ROUTE_OPTIONS.ios, standardAppearance: { - stacked: { normal: { tabBarItemBadgeBackgroundColor: BADGE.blue } }, + stacked: { normal: { tabBarItemBadgeBackgroundColor: Colors.BlueDark100 } }, }, scrollEdgeAppearance: { - stacked: { normal: { tabBarItemBadgeBackgroundColor: BADGE.yellow } }, + stacked: { normal: { tabBarItemBadgeBackgroundColor: Colors.YellowDark100 } }, }, }, android: { ...DEFAULT_TAB_ROUTE_OPTIONS.android, standardAppearance: { tabBarItemLabelVisibilityMode: 'labeled', - tabBarItemBadgeBackgroundColor: BADGE.blue, - tabBarItemBadgeTextColor: BADGE.yellow, + tabBarItemBadgeBackgroundColor: Colors.BlueDark100, + tabBarItemBadgeTextColor: Colors.YellowDark100, }, }, }, @@ -202,15 +189,14 @@ const ROUTE_CONFIGS: TabRouteConfig[] = [ name: 'Tab3', Component: Tab3Screen, options: { - ...DEFAULT_TAB_ROUTE_OPTIONS, title: 'Tab3', badgeValue: 'NEW!', ios: { ...DEFAULT_TAB_ROUTE_OPTIONS.ios, standardAppearance: { stacked: { - normal: { tabBarItemBadgeBackgroundColor: BADGE.purple }, - selected: { tabBarItemBadgeBackgroundColor: BADGE.blue }, + normal: { tabBarItemBadgeBackgroundColor: Colors.PurpleDark100 }, + selected: { tabBarItemBadgeBackgroundColor: Colors.BlueDark100 }, }, }, }, @@ -218,8 +204,8 @@ const ROUTE_CONFIGS: TabRouteConfig[] = [ ...DEFAULT_TAB_ROUTE_OPTIONS.android, standardAppearance: { tabBarItemLabelVisibilityMode: 'labeled', - tabBarItemBadgeBackgroundColor: BADGE.purple, - tabBarItemBadgeTextColor: BADGE.navy, + tabBarItemBadgeBackgroundColor: Colors.PurpleDark100, + tabBarItemBadgeTextColor: Colors.NavyLight100, }, }, }, @@ -228,7 +214,6 @@ const ROUTE_CONFIGS: TabRouteConfig[] = [ name: 'Tab4', Component: Tab4Screen, options: { - ...DEFAULT_TAB_ROUTE_OPTIONS, title: 'Tab4', badgeValue: '⚠️', ios: { @@ -244,7 +229,7 @@ const ROUTE_CONFIGS: TabRouteConfig[] = [ standardAppearance: { tabBarItemLabelVisibilityMode: 'labeled', tabBarItemBadgeBackgroundColor: 'transparent', - tabBarItemBadgeTextColor: BADGE.red, + tabBarItemBadgeTextColor: Colors.RedLight100, }, }, }, @@ -256,9 +241,6 @@ export function App() { } const styles = StyleSheet.create({ - scrollView: { - flex: 1, - }, screen: { flex: 1, margin: 24, @@ -266,10 +248,6 @@ const styles = StyleSheet.create({ gap: 12, }, - scrollContent: { - paddingBottom: 24, - gap: 12, - }, spacer: { height: 220, }, @@ -286,10 +264,6 @@ const styles = StyleSheet.create({ lineHeight: 20, textAlign: 'center', }, - platformHeader: { - fontWeight: '700', - color: Colors.LightOffNavy, - }, }); export default createScenario(App, scenarioDescription); From 08cf8054f54877ec0b93b56b84007e1dcb42e1d2 Mon Sep 17 00:00:00 2001 From: lkuchno Date: Wed, 3 Jun 2026 16:01:28 +0200 Subject: [PATCH 6/8] review suggestions --- .../tabs/test-tabs-item-badge/index.tsx | 8 ++++---- .../tabs/test-tabs-item-badge/scenario-description.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx index 03f8c4d554..211f056344 100644 --- a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx +++ b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx @@ -26,8 +26,8 @@ function Tab1Screen() { ) : ( <> - `badgeValue`: " "{'\n'} - Empty string badge value renders as "small dot" with color define in `tabBarItemBadgeBackgroundColor` or system default if not set.{'\n'}{'\n'} + `badgeValue`: ""{'\n'} + An empty string badge value renders as a "small dot" using the color defined in `tabBarItemBadgeBackgroundColor`, or the system default if not set.{'\n'}{'\n'} Badge appearance is not defined.{'\n'}{'\n'} Badges render with the default system appearance: background{' '} @@ -35,7 +35,7 @@ function Tab1Screen() { )} - + ); } @@ -138,7 +138,7 @@ function Tab4Screen() { )} - + ); } diff --git a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/scenario-description.ts b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/scenario-description.ts index 2d21c04b64..4709bf84bb 100644 --- a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/scenario-description.ts +++ b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/scenario-description.ts @@ -4,7 +4,7 @@ export const scenarioDescription: ScenarioDescription = { name: 'Tab Bar Item Badge', key: 'test-tabs-item-badge', details: - 'Exercises tab bar item badge props: badgeValue, badgeBackgroundColor, and badgeTextColor (Android only).', + 'Exercises tab bar item badge props: badgeValue, tabBarItemBadgeBackgroundColor, and tabBarItemBadgeTextColor (Android only).', platforms: ['ios', 'android'], e2eCoverage: 'incomplete', smokeTest: false, From 6481ae8c929c0c34d80bd33cac36451c7bd866e8 Mon Sep 17 00:00:00 2001 From: lkuchno Date: Mon, 8 Jun 2026 10:32:12 +0200 Subject: [PATCH 7/8] refactor after code review --- .../tabs/test-tabs-item-badge/index.tsx | 20 +++---------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx index 211f056344..210f91f940 100644 --- a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx +++ b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Platform, ScrollView, StyleSheet, Text, View } from 'react-native'; +import { Platform, PlatformColor, ScrollView, StyleSheet, Text, View } from 'react-native'; import { scenarioDescription } from './scenario-description'; import { createScenario } from '@apps/tests/shared/helpers'; import { @@ -14,17 +14,14 @@ function Tab1Screen() { Default badge appearance {Platform.OS === 'ios' ? ( - <> `badgeValue`: "1"{'\n'}{'\n'} `standardAppearance` and `scrollEdgeAppearance` are not defined.{'\n'}{'\n'} Badges render with the default iOS appearance: `tabBarItemBadgeBackgroundColor`{' '} - RED with white text. + RED with white text. - ) : ( - <> `badgeValue`: ""{'\n'} An empty string badge value renders as a "small dot" using the color defined in `tabBarItemBadgeBackgroundColor`, or the system default if not set.{'\n'}{'\n'} @@ -33,7 +30,6 @@ function Tab1Screen() { background{' '} DARK RED with white text. - )} ); @@ -65,7 +61,6 @@ function Tab2Screen() { ) : ( - <> `badgeValue`: "1234567890" displayed as "999+"{'\n'}{'\n'} `tabBarItemBadgeBackgroundColor`:{' '} @@ -74,7 +69,6 @@ function Tab2Screen() { `tabBarItemBadgeTextColor`:{' '} YELLOW - )} @@ -86,7 +80,6 @@ function Tab3Screen() { String Badge Value {Platform.OS === 'ios' ? ( - <> `badgeValue`: "NEW!"{'\n'}{'\n'} selected: `tabBarItemBadgeBackgroundColor`:{' '} @@ -96,9 +89,7 @@ function Tab3Screen() { PURPLE {'\n'}{'\n'} - ) : ( - <> `badgeValue`: "NEW!"{'\n'}{'\n'} `tabBarItemBadgeBackgroundColor`:{' '} @@ -107,7 +98,6 @@ function Tab3Screen() { `tabBarItemBadgeTextColor`:{' '} NAVY - )} ); @@ -118,17 +108,14 @@ function Tab4Screen() { Transparent badge background {Platform.OS === 'ios' ? ( - <> `badgeValue`: "⚠️"{'\n'}{'\n'} Badge appearance is defined only for selected tab: setting background to `transparent` value.{'\n'}{'\n'} Unselected badges render with the default system appearance: badge background{' '} - RED with white text. + RED with white text. - ) : ( - <> `badgeValue`: "⚠️"{'\n'}{'\n'} `tabBarItemBadgeBackgroundColor`: `transparent` @@ -136,7 +123,6 @@ function Tab4Screen() { `tabBarItemBadgeTextColor`:{' '} RED - )} ); From 8656ea3325b5c8e2173762cecf0db2b0b448dfbb Mon Sep 17 00:00:00 2001 From: lkuchno Date: Mon, 8 Jun 2026 10:38:55 +0200 Subject: [PATCH 8/8] adding comma and fixing formating for tab2 routconfig --- .../tabs/test-tabs-item-badge/index.tsx | 116 +++++++++--------- 1 file changed, 60 insertions(+), 56 deletions(-) diff --git a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx index 210f91f940..d7f56567a2 100644 --- a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx +++ b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-badge/index.tsx @@ -14,22 +14,22 @@ function Tab1Screen() { Default badge appearance {Platform.OS === 'ios' ? ( - - `badgeValue`: "1"{'\n'}{'\n'} - `standardAppearance` and `scrollEdgeAppearance` are not defined.{'\n'}{'\n'} - Badges render with the default iOS appearance: - `tabBarItemBadgeBackgroundColor`{' '} - RED with white text. - + + `badgeValue`: "1"{'\n'}{'\n'} + `standardAppearance` and `scrollEdgeAppearance` are not defined.{'\n'}{'\n'} + Badges render with the default iOS appearance: + `tabBarItemBadgeBackgroundColor`{' '} + RED with white text. + ) : ( - - `badgeValue`: ""{'\n'} - An empty string badge value renders as a "small dot" using the color defined in `tabBarItemBadgeBackgroundColor`, or the system default if not set.{'\n'}{'\n'} - Badge appearance is not defined.{'\n'}{'\n'} - Badges render with the default system appearance: - background{' '} - DARK RED with white text. - + + `badgeValue`: ""{'\n'} + An empty string badge value renders as a "small dot" using the color defined in `tabBarItemBadgeBackgroundColor`, or the system default if not set.{'\n'}{'\n'} + Badge appearance is not defined.{'\n'}{'\n'} + Badges render with the default system appearance: + background{' '} + DARK RED with white text. + )} ); @@ -61,14 +61,14 @@ function Tab2Screen() { ) : ( - - `badgeValue`: "1234567890" displayed as "999+"{'\n'}{'\n'} - `tabBarItemBadgeBackgroundColor`:{' '} - BLUE - {'\n'} - `tabBarItemBadgeTextColor`:{' '} - YELLOW - + + `badgeValue`: "1234567890" displayed as "999+"{'\n'}{'\n'} + `tabBarItemBadgeBackgroundColor`:{' '} + BLUE + {'\n'} + `tabBarItemBadgeTextColor`:{' '} + YELLOW + )} @@ -80,24 +80,24 @@ function Tab3Screen() { String Badge Value {Platform.OS === 'ios' ? ( - - `badgeValue`: "NEW!"{'\n'}{'\n'} - selected: `tabBarItemBadgeBackgroundColor`:{' '} - BLUE - {'\n'}{'\n'} - normal: `tabBarItemBadgeBackgroundColor`:{' '} - PURPLE - {'\n'}{'\n'} - + + `badgeValue`: "NEW!"{'\n'}{'\n'} + selected: `tabBarItemBadgeBackgroundColor`:{' '} + BLUE + {'\n'}{'\n'} + normal: `tabBarItemBadgeBackgroundColor`:{' '} + PURPLE + {'\n'}{'\n'} + ) : ( - - `badgeValue`: "NEW!"{'\n'}{'\n'} - `tabBarItemBadgeBackgroundColor`:{' '} - PURPLE - {'\n'} - `tabBarItemBadgeTextColor`:{' '} - NAVY - + + `badgeValue`: "NEW!"{'\n'}{'\n'} + `tabBarItemBadgeBackgroundColor`:{' '} + PURPLE + {'\n'} + `tabBarItemBadgeTextColor`:{' '} + NAVY + )} ); @@ -108,21 +108,21 @@ function Tab4Screen() { Transparent badge background {Platform.OS === 'ios' ? ( - - `badgeValue`: "⚠️"{'\n'}{'\n'} - Badge appearance is defined only for selected tab: setting background to `transparent` value.{'\n'}{'\n'} - Unselected badges render with the default system appearance: - badge background{' '} - RED with white text. - + + `badgeValue`: "⚠️"{'\n'}{'\n'} + Badge appearance is defined only for selected tab: setting background to `transparent` value.{'\n'}{'\n'} + Unselected badges render with the default system appearance: + badge background{' '} + RED with white text. + ) : ( - - `badgeValue`: "⚠️"{'\n'}{'\n'} - `tabBarItemBadgeBackgroundColor`: `transparent` - {'\n'} - `tabBarItemBadgeTextColor`:{' '} - RED - + + `badgeValue`: "⚠️"{'\n'}{'\n'} + `tabBarItemBadgeBackgroundColor`: `transparent` + {'\n'} + `tabBarItemBadgeTextColor`:{' '} + RED + )} ); @@ -155,10 +155,14 @@ const ROUTE_CONFIGS: TabRouteConfig[] = [ ios: { ...DEFAULT_TAB_ROUTE_OPTIONS.ios, standardAppearance: { - stacked: { normal: { tabBarItemBadgeBackgroundColor: Colors.BlueDark100 } }, + stacked: { + normal: { tabBarItemBadgeBackgroundColor: Colors.BlueDark100 }, + }, }, scrollEdgeAppearance: { - stacked: { normal: { tabBarItemBadgeBackgroundColor: Colors.YellowDark100 } }, + stacked: { + normal: { tabBarItemBadgeBackgroundColor: Colors.YellowDark100 }, + }, }, }, android: {