From 6429872e9b5ea00a0a5db6e9195178ac6a78b4e0 Mon Sep 17 00:00:00 2001 From: lkuchno Date: Thu, 28 May 2026 13:55:42 +0200 Subject: [PATCH 1/6] refacotred existing screen for test-tabs-item-icon to use it in Android test --- .../tests/single-feature-tests/tabs/index.ts | 2 + .../tabs/test-tabs-item-icon/index.tsx | 327 ++++++++++++++++++ .../scenario-description.ts | 13 + .../tabs/test-tabs-item-icon/scenario.md | 162 +++++++++ 4 files changed, 504 insertions(+) create mode 100644 apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/index.tsx create mode 100644 apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/scenario-description.ts create mode 100644 apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/scenario.md diff --git a/apps/src/tests/single-feature-tests/tabs/index.ts b/apps/src/tests/single-feature-tests/tabs/index.ts index 39584ef9dc..8cae85be13 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 TestTabsItemIcon from './test-tabs-item-icon'; const scenarios = { TestTabBottomAccessory, @@ -38,6 +39,7 @@ const scenarios = { TestTabsTabBarExperimentalUserInterfaceStyle, TestTabsLifecycleEvents, TestTabsItemTitle, + TestTabsItemIcon, }; const TabsScenarioGroup: ScenarioGroup = { diff --git a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/index.tsx b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/index.tsx new file mode 100644 index 0000000000..4bb53fa8bb --- /dev/null +++ b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/index.tsx @@ -0,0 +1,327 @@ +import React from 'react'; +import { Platform, 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'; + +function TintTab() { + return ( + + + Template Source (Host Tint) + + + + Host `tabBarTintColor`:{' '} + GreenDark100 + {'\n'} + `icon`: templateSource icon.png{'\n'} + `selectedIcon`: templateSource icon_fill.png{'\n'} + `tabBarItemIconColor` is NOT set.{'\n'} + {'\n'} + Selected: filled template image, tinted{' '} + GREEN.{'\n'} + Unselected: Titles and icons render in the system theme color. For the last tab, the icon + retains the black color from its source image. + + + + ); +} + +function OverrideTab() { + return ( + + + SF Symbol (Tint Color Override) + + + Host `tabBarTintColor`:{' '} + GreenDark100 + {'\n'} + `selected.tabBarItemIconColor`:{' '} + RedLight100 + {'\n'} + `icon`: SF Symbol "star"{'\n'} + `selectedIcon`: SF Symbol "star.fill"{'\n'} + {'\n'} + Selected: filled star, tinted{' '} + RED{'\n'} title on iOS18:{' '} + GREEN on iOS26:{' '} + RED + {'\n'} + Unselected: Titles and icons render in the system theme color. For the last tab, the icon + retains the black color from its source image. + + + ); +} + +function XcassetTab() { + return ( + + {Platform.OS === 'ios' ? ( + <> + Xcasset (Host Tint) + + Host `tabBarTintColor`:{' '} + GreenDark100 + {'\n'} + `icon`: Xcasset custom-icon-fill{'\n'} + `tabBarItemIconColor` is NOT set.{'\n'} + {'\n'} + Selected: filled template image, tinted{' '} + GREEN.{'\n'} + Unselected: Titles and icons render in the system theme color. For the last tab, the icon + retains the black color from its source image. + + + ) : ( + <> + Drawable Resource + + + `icon`: drawableResource sym_call_missed{'\n'} + `selectedIcon`: drawableResource sym_call_incoming{'\n'} + `tabBarItemIconColor` is NOT set.{'\n'} + {'\n'} + Both icons (for selected and unselected tabs) displayed in the system default color. + + + )} + + ); +} + +function ImageTab() { + return ( + + + {Platform.OS === 'ios' ? 'Image Source (Non-Tintable)' : 'Image Source'} + + + {Platform.OS === 'ios' ? ( + <> + Host `tabBarTintColor`:{' '} + GreenDark100 + {'\n'} + `normal.tabBarItemIconColor`:{' '} + BlueDark100 + {'\n'} + `icon`: imageSource icon.png{'\n'} + `selectedIcon`: imageSource icon_fill.png{'\n'} + {'\n'} + `imageSource` icons render in their original colors and are NOT affected by `tabBarTintColor` + or `tabBarItemIconColor`.{'\n'} + {'\n'} + Selected: filled image in its black color (the host{' '} + green tint is ignored). + {'\n'} + Unselected iOS18: outline icons in BLUE{' '} + color.{'\n'} + Unselected iOS26: icons in system theme color. + + ) : ( + <> + `selected.tabBarItemIconColor`:{' '} + RedDark100 + {'\n'} + `normal.tabBarItemIconColor`:{' '} + GreenDark100 + {'\n'} + `focused.tabBarItemIconColor`:{' '} + NavyLight100 + {'\n'} + `icon`: imageSource icon.png{'\n'} + `selectedIcon`: imageSource icon_fill.png{'\n'} + {'\n'} + Selected: filled image in {' '} + RED color. + {'\n'} + Uselected: outline icons in {' '} + GREEN color. + {'\n'} + Focused (via keyboard navigation Tab key):{'\n'} + icon should appear{' '} + DARK BLUE. + + )} + + + ); +} + +const IOS_ROUTES: TabRouteConfig[] = [ + { + name: 'Tint', + Component: TintTab, + options: { + ...DEFAULT_TAB_ROUTE_OPTIONS, + title: 'Tint', + ios: { + icon: { + type: 'templateSource', + templateSource: require('@assets/variableIcons/icon.png'), + }, + selectedIcon: { + type: 'templateSource', + templateSource: require('@assets/variableIcons/icon_fill.png'), + }, + }, + }, + }, + { + name: 'Override', + Component: OverrideTab, + options: { + ...DEFAULT_TAB_ROUTE_OPTIONS, + title: 'Override', + ios: { + icon: { + type: 'sfSymbol', + name: 'star', + }, + selectedIcon: { + type: 'sfSymbol', + name: 'star.fill', + }, + standardAppearance: { + stacked: { + selected: { + tabBarItemIconColor: Colors.RedLight100, + }, + }, + }, + }, + }, + }, + { + name: 'XcassetIcon', + Component: XcassetTab, + options: { + title: 'Xcasset', ios: { + icon: { + type: 'xcasset', + name: 'custom-icon-fill', + }, + }, + }, + }, + { + name: 'Image', + Component: ImageTab, + options: { + ...DEFAULT_TAB_ROUTE_OPTIONS, + title: 'Image', + ios: { + icon: { + type: 'imageSource', + imageSource: require('@assets/variableIcons/icon.png'), + }, + selectedIcon: { + type: 'imageSource', + imageSource: require('@assets/variableIcons/icon_fill.png'), + }, + standardAppearance: { + stacked: { + normal: { + tabBarItemIconColor: Colors.BlueDark100, + }, + }, + }, + }, + }, + }, +]; + +const ANDROID_ROUTES: TabRouteConfig[] = [ + { + name: 'DrawableResource', + Component: XcassetTab, + options: { + title: 'DrawableResource', + android: { + icon: { + type: 'drawableResource', + name: 'sym_call_missed', + }, + selectedIcon: { + type: 'drawableResource', + name: 'sym_call_incoming', + }, + }, + }, + }, + { + name: 'Image', + Component: ImageTab, + options: { + ...DEFAULT_TAB_ROUTE_OPTIONS, + title: 'Image', + android: { + icon: { + type: 'imageSource', + imageSource: require('@assets/variableIcons/icon.png'), + }, + selectedIcon: { + type: 'imageSource', + imageSource: require('@assets/variableIcons/icon_fill.png'), + }, + standardAppearance: { + selected: { + tabBarItemIconColor: Colors.RedDark100, + }, + normal: { + tabBarItemIconColor: Colors.GreenDark100, + }, + focused: { + tabBarItemIconColor: Colors.NavyLight100, + }, + }, + }, + }, + }, +]; + +export const ROUTE_CONFIGS = Platform.select({ + ios: IOS_ROUTES, + android: ANDROID_ROUTES, + default: IOS_ROUTES, // fallback +}); + +export function App() { + return ( + + ); +} + +const styles = StyleSheet.create({ + screen: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + padding: 24, + gap: 12, + }, + label: { + fontSize: 17, + fontWeight: '600', + textAlign: 'center', + }, + hint: { + fontSize: 13, + color: Colors.LightOffNavy, + textAlign: 'center', + lineHeight: 20, + }, +}); + +export default createScenario(App, scenarioDescription); diff --git a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/scenario-description.ts b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/scenario-description.ts new file mode 100644 index 0000000000..d6876c5349 --- /dev/null +++ b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/scenario-description.ts @@ -0,0 +1,13 @@ +import type { ScenarioDescription } from '@apps/tests/shared/helpers'; + +export const scenarioDescription: ScenarioDescription = { + name: 'Tab Bar Item Icon', + key: 'test-tabs-item-icon', + details: + 'Exercises tab bar item icon props: iOS icon types (templateSource, sfSymbol,' + + ' xcasset, imageSource) with tabBarItemIconColor overrides; Android' + + ' tabBarItemIconColor in normal, selected and focused states.', + platforms: ['ios', 'android'], + e2eCoverage: 'incomplete', + smokeTest: false, +}; diff --git a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/scenario.md b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/scenario.md new file mode 100644 index 0000000000..a08c1a0f93 --- /dev/null +++ b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/scenario.md @@ -0,0 +1,162 @@ +# Test Scenario: Tab Bar Item Icon (iOS) + +## Details + +**Description:** Validates iOS tab bar item icon props: `icon` and +`selectedIcon` (different images for selected vs. unselected states), the +host-level `tabBarTintColor`, and the per-tab +`standardAppearance.stacked.selected.tabBarItemIconColor` override that +takes precedence over the host tint. Covers four `PlatformIconIOS` types: +`templateSource` (tintable), `sfSymbol` (tintable), `xcasset` (tintable), and `imageSource` +(non-tintable). + +**OS test creation version:** iOS 18.6 and iOS 26.5 + +## E2E test + +Incomplete: Not automated. All observable outcomes are purely visual (icon color, selected vs. +unselected glyph). Detox does not expose tint color or rendered image +attributes of native tab bar items, so automated assertion is not feasible. + +## Prerequisites + +- iOS device or simulator running iOS 18 or later. +- The iPhone in portrait orientation is the primary verification surface (stacked layout). + +## Note + +- Scenario steps are divided by platform, as test screens vary between iOS and Android. + +iOS specific notes: +- **Normal (unselected) state ([iOS26 KI](https://github.com/software-mansion/react-native-screens-labs/discussions/395)):** + On iOS 18 and lower, any per-tab + `normal.tabBarItemIconColor` apply to unselected tab icons. On iOS 26, + only the selected tab is tinted by `tabBarItemIconColor`; + unselected tabs adopt the system theme appearance. +- `tabBarTintColor` is applied only to selected tab bar item icon and title. +- **`imageSource` icons are non-tintable:** they render in their original + colors regardless of `tabBarTintColor` or `tabBarItemIconColor`. + `templateSource`, `xcasset` and `sfSymbol` icons are tintable. + +## Steps - iOS + +### Host `tabBarTintColor` applies to a tintable selected icon + +1. Launch the app and navigate to the **Tab Bar Item Icon** screen. + +- [ ] Expected: Four tabs are visible in the tab bar: **Tint**, + **Override**, **Xcasset**, and **Image**. The **Tint** tab is + selected by default. Its icon is the filled template image + tinted **green** by the host + `tabBarTintColor`. The unselected **Override** and **Xcasset** + tabs render their icons and titles in the system theme color. The + unselected **Image** tab title renders in the system theme color, + but its icon keeps its original source colors. + +--- + +### `icon` vs `selectedIcon` swap + +2. Tap the **Override** tab. + +- [ ] Expected: The **Override** tab's icon swaps from the outline + star to the filled star. The + previously selected **Tint** tab swaps from the filled template + image back to the outline template image. + +--- + +### `tabBarItemIconColor` overrides `tabBarTintColor` + +3. With **Override** still selected, observe the selected icon color. + +- [ ] Expected: The filled star is **red**, NOT green. + On iOS 18 the selected title is + green (host tint); on iOS 26 the selected title is red (override - it's native + bug KI linked in Notes section). + +4. Tap the **Tint** tab, then tap **Override** again. + +- [ ] Expected: On re-selection the red filled star reappears + immediately with no visual glitch. The **Tint** tab shows the system-theme + outline template + image. + +--- + +### `xcasset` icon uses host tint, no `selectedIcon` + +5. Tap the **Xcasset** tab. + +- [ ] Expected: The **Xcasset** tab's icon shows the `custom-icon-fill` + xcasset image tinted **green**. Because no `selectedIcon` is configured for this + tab, the same icon asset is used in both selected and unselected + states. The previously selected **Override** tab reverts to the + outline star in system theme color. + +--- + +### `imageSource` icons are non-tintable + +6. Tap the **Image** tab. + +- [ ] Expected: The icon swaps from the outline image to + the filled image. Both renders use the original PNG + colors - the host `tabBarTintColor` (green) have NO effect on the + selected icon. On iOS 18, the unselected icon renders in + **blue**; on iOS 26+ it renders in the system theme + color. + +--- + +### Stability check + +7. Cycle through all four tabs in order + (Tint -> Override -> Xcasset -> Image), then in reverse. + +- [ ] Expected: Each tab swaps between its `icon` and `selectedIcon` + (where configured) consistently on selection. The correct tint + behavior is applied each time: green host tint for **Tint** and + **Xcasset**, red override for **Override**'s selected state, and + no tint effect for **Image**. No crash, layout freeze, or visual + artifact occurs during rapid cycling. + +## Steps - Android + +### Default color settings + +1. Launch the app and navigate to the **Tab Bar Item Icon** screen. + +- [ ] Expected: Two tabs are visible in the tab bar: **DrawableResource** + and **Image**. The **DrawableResource** tab is + selected by default. Its icon is the sym_call_incoming icon. Both + tabs render their icons and titles in the system theme color. + +--- + +### Color settings for different states + +2. Tap the **Image** tab. + +- [ ] Expected: The icon swaps from the outline image to + the filled image. Unselected tab icon change to sym_call_missed. + Selected tab icon is **red** and unselected icon renders in **green**. + +3. While **Image** tab is selected, use the Tab key on keyboard to +switch focus to the **DrawableResource** tab. + +- [ ] Expected: Focused tab title is dark blue while selected tab title +remains red. + +--- + +### Stability check + +4. Switch between two tabs few times. + +- [ ] Expected: Each tab swaps between its `icon` and `selectedIcon` + (where configured) consistently on selection. The correct tint + behavior is applied each time: green host tint for **Tint** and + **Xcasset**, red override for **Override**'s selected state, and + no tint effect for **Image**. No crash, layout freeze, or visual + artifact occurs during rapid cycling. From 46a203031dc776719d45b700702a9f6443a367cd Mon Sep 17 00:00:00 2001 From: lkuchno Date: Thu, 28 May 2026 14:35:23 +0200 Subject: [PATCH 2/6] removing ios from sceanrio title --- .../tabs/test-tabs-item-icon/scenario.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/scenario.md b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/scenario.md index a08c1a0f93..cb4f7169c8 100644 --- a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/scenario.md +++ b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/scenario.md @@ -1,4 +1,4 @@ -# Test Scenario: Tab Bar Item Icon (iOS) +# Test Scenario: Tab Bar Item Icon ## Details @@ -10,7 +10,7 @@ takes precedence over the host tint. Covers four `PlatformIconIOS` types: `templateSource` (tintable), `sfSymbol` (tintable), `xcasset` (tintable), and `imageSource` (non-tintable). -**OS test creation version:** iOS 18.6 and iOS 26.5 +**OS test creation version:** iOS 18.6 and iOS 26.5, Android: API Level 36. ## E2E test @@ -20,8 +20,9 @@ attributes of native tab bar items, so automated assertion is not feasible. ## Prerequisites +- Android device or emulator. - iOS device or simulator running iOS 18 or later. -- The iPhone in portrait orientation is the primary verification surface (stacked layout). +- The device/simulator/emulator portrait orientation is the primary verification surface (stacked layout). ## Note From 61804d6d863ed19a68d9e33c67a61c28112b2151 Mon Sep 17 00:00:00 2001 From: lkuchno Date: Thu, 28 May 2026 14:35:45 +0200 Subject: [PATCH 3/6] removing ios from sceanrio title --- .../tabs/test-tabs-item-icon/scenario.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/scenario.md b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/scenario.md index cb4f7169c8..665f891d41 100644 --- a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/scenario.md +++ b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/scenario.md @@ -2,20 +2,18 @@ ## Details -**Description:** Validates iOS tab bar item icon props: `icon` and -`selectedIcon` (different images for selected vs. unselected states), the -host-level `tabBarTintColor`, and the per-tab -`standardAppearance.stacked.selected.tabBarItemIconColor` override that -takes precedence over the host tint. Covers four `PlatformIconIOS` types: -`templateSource` (tintable), `sfSymbol` (tintable), `xcasset` (tintable), and `imageSource` -(non-tintable). +**Description:** Validates tab bar item icon properties (icon, selectedIcon) and +tinting behaviors for iOS and Android. Covers cross-platform icon types including +templateSource, sfSymbol, xcasset, drawableResource, and imageSource. +Verifies that per-tab appearance color configurations (selected, normal, +Android only: focused) correctly override host-level color tints. **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 (icon color, selected vs. -unselected glyph). Detox does not expose tint color or rendered image +Incomplete: Not automated. All observable outcomes are purely visual (icon color, +selected vs. unselected glyph). Detox does not expose tint color or rendered image attributes of native tab bar items, so automated assertion is not feasible. ## Prerequisites From 70eb289b7cfe4e734bd6d94860eb8e354a9fd4df Mon Sep 17 00:00:00 2001 From: lkuchno <45803783+LKuchno@users.noreply.github.com> Date: Fri, 29 May 2026 12:44:57 +0200 Subject: [PATCH 4/6] Fix typo Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../single-feature-tests/tabs/test-tabs-item-icon/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/index.tsx b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/index.tsx index 4bb53fa8bb..25a39fd6f6 100644 --- a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/index.tsx +++ b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/index.tsx @@ -143,7 +143,7 @@ function ImageTab() { Selected: filled image in {' '} RED color. {'\n'} - Uselected: outline icons in {' '} + Unselected: outline icons in {' '} GREEN color. {'\n'} Focused (via keyboard navigation Tab key):{'\n'} From 9554df8aea43894ec3d2261a64b4a84a44641d4c Mon Sep 17 00:00:00 2001 From: lkuchno Date: Fri, 29 May 2026 13:05:37 +0200 Subject: [PATCH 5/6] restructure expected section and provide corrects --- .../tabs/test-tabs-item-icon/scenario.md | 81 +++++++++---------- 1 file changed, 38 insertions(+), 43 deletions(-) diff --git a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/scenario.md b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/scenario.md index 665f891d41..240742b2ba 100644 --- a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/scenario.md +++ b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/scenario.md @@ -28,11 +28,11 @@ attributes of native tab bar items, so automated assertion is not feasible. iOS specific notes: - **Normal (unselected) state ([iOS26 KI](https://github.com/software-mansion/react-native-screens-labs/discussions/395)):** - On iOS 18 and lower, any per-tab - `normal.tabBarItemIconColor` apply to unselected tab icons. On iOS 26, - only the selected tab is tinted by `tabBarItemIconColor`; - unselected tabs adopt the system theme appearance. -- `tabBarTintColor` is applied only to selected tab bar item icon and title. + On iOS 18 and lower, any per-tab `normal.tabBarItemIconColor` apply to unselected tab icons. + On iOS 26, only the selected tab is tinted by `tabBarItemIconColor`, unselected tabs adopt the system theme appearance. +- On iOS26 setting tabBarItemIconColor overrides tabBarTintColor also for +tabBarItemTitleFontColor - it's reported native bug. +- `tabBarTintColor` is applied only to selected tab bar item icon and title. - **`imageSource` icons are non-tintable:** they render in their original colors regardless of `tabBarTintColor` or `tabBarItemIconColor`. `templateSource`, `xcasset` and `sfSymbol` icons are tintable. @@ -43,13 +43,13 @@ iOS specific notes: 1. Launch the app and navigate to the **Tab Bar Item Icon** screen. -- [ ] Expected: Four tabs are visible in the tab bar: **Tint**, - **Override**, **Xcasset**, and **Image**. The **Tint** tab is - selected by default. Its icon is the filled template image - tinted **green** by the host - `tabBarTintColor`. The unselected **Override** and **Xcasset** - tabs render their icons and titles in the system theme color. The - unselected **Image** tab title renders in the system theme color, +- [ ] Four tabs are visible in the tab bar: **Tint**, + **Override**, **Xcasset**, and **Image**. +- [ ] The **Tint** tab is selected by default. Its icon is the filled template image + tinted **green** by the host `tabBarTintColor`. +- [ ] The unselected **Override** and **Xcasset** tabs render their icons and + titles in the system theme color. +- [ ] The unselected **Image** tab title renders in the system theme color, but its icon keeps its original source colors. --- @@ -58,9 +58,9 @@ iOS specific notes: 2. Tap the **Override** tab. -- [ ] Expected: The **Override** tab's icon swaps from the outline - star to the filled star. The - previously selected **Tint** tab swaps from the filled template +- [ ] The **Override** tab's icon swaps from the outline + star to the filled star. +- [ ] The previously selected **Tint** tab swaps from the filled template image back to the outline template image. --- @@ -69,17 +69,16 @@ iOS specific notes: 3. With **Override** still selected, observe the selected icon color. -- [ ] Expected: The filled star is **red**, NOT green. - On iOS 18 the selected title is - green (host tint); on iOS 26 the selected title is red (override - it's native +- [ ] The filled star is **red**, NOT green. +- [ ] On iOS 18 the selected title is + green (host tint). +- [ ] On iOS 26 the selected title is red (override - it's native bug KI linked in Notes section). 4. Tap the **Tint** tab, then tap **Override** again. -- [ ] Expected: On re-selection the red filled star reappears - immediately with no visual glitch. The **Tint** tab shows the system-theme - outline template - image. +- [ ] On re-selection the red filled star reappears immediately with no visual glitch. +- [ ] The **Tint** tab shows the system-theme outline template image. --- @@ -87,10 +86,10 @@ iOS specific notes: 5. Tap the **Xcasset** tab. -- [ ] Expected: The **Xcasset** tab's icon shows the `custom-icon-fill` - xcasset image tinted **green**. Because no `selectedIcon` is configured for this - tab, the same icon asset is used in both selected and unselected - states. The previously selected **Override** tab reverts to the +- [ ] The **Xcasset** tab's icon shows the `custom-icon-fill` xcasset image + tinted **green**. Because no `selectedIcon` is configured for this + tab, the same icon asset is used in both selected and unselected states. +- [ ] The previously selected **Override** tab reverts to the outline star in system theme color. --- @@ -99,12 +98,10 @@ iOS specific notes: 6. Tap the **Image** tab. -- [ ] Expected: The icon swaps from the outline image to - the filled image. Both renders use the original PNG - colors - the host `tabBarTintColor` (green) have NO effect on the - selected icon. On iOS 18, the unselected icon renders in - **blue**; on iOS 26+ it renders in the system theme - color. +- [ ] The icon swaps from the outline image to the filled image. Both renders use the original PNG + colors - the host `tabBarTintColor` (green) have NO effect on the selected icon. +- [ ] On iOS 18 the unselected icon renders in **blue**. +- [ ] On iOS 26 the unselected icon renders in the system theme color. --- @@ -113,11 +110,12 @@ iOS specific notes: 7. Cycle through all four tabs in order (Tint -> Override -> Xcasset -> Image), then in reverse. -- [ ] Expected: Each tab swaps between its `icon` and `selectedIcon` +- [ ] Each tab swaps between its `icon` and `selectedIcon` (where configured) consistently on selection. The correct tint behavior is applied each time: green host tint for **Tint** and **Xcasset**, red override for **Override**'s selected state, and - no tint effect for **Image**. No crash, layout freeze, or visual + no tint effect for **Image**. +- [ ] No crash, layout freeze, or visual artifact occurs during rapid cycling. ## Steps - Android @@ -126,7 +124,7 @@ iOS specific notes: 1. Launch the app and navigate to the **Tab Bar Item Icon** screen. -- [ ] Expected: Two tabs are visible in the tab bar: **DrawableResource** +- [ ] Two tabs are visible in the tab bar: **DrawableResource** and **Image**. The **DrawableResource** tab is selected by default. Its icon is the sym_call_incoming icon. Both tabs render their icons and titles in the system theme color. @@ -137,14 +135,14 @@ iOS specific notes: 2. Tap the **Image** tab. -- [ ] Expected: The icon swaps from the outline image to +- [ ] The icon swaps from the outline image to the filled image. Unselected tab icon change to sym_call_missed. Selected tab icon is **red** and unselected icon renders in **green**. 3. While **Image** tab is selected, use the Tab key on keyboard to switch focus to the **DrawableResource** tab. -- [ ] Expected: Focused tab title is dark blue while selected tab title +- [ ] Focused tab title is dark blue while selected tab title remains red. --- @@ -153,9 +151,6 @@ remains red. 4. Switch between two tabs few times. -- [ ] Expected: Each tab swaps between its `icon` and `selectedIcon` - (where configured) consistently on selection. The correct tint - behavior is applied each time: green host tint for **Tint** and - **Xcasset**, red override for **Override**'s selected state, and - no tint effect for **Image**. No crash, layout freeze, or visual - artifact occurs during rapid cycling. +- [ ] Each tab swaps between its `icon` and `selectedIcon` consistently on selection. +- [ ] The correct colors are applied each time: red for **Image**'s selected state and green for + **DrawableResource**'s unselected state. From edd123896f37f6c941dbd0c56b2d45f894f6bc35 Mon Sep 17 00:00:00 2001 From: lkuchno Date: Mon, 8 Jun 2026 08:47:27 +0200 Subject: [PATCH 6/6] small changes after review --- .../tabs/test-tabs-item-icon/index.tsx | 13 ++++++++----- .../tabs/test-tabs-item-icon/scenario.md | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/index.tsx b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/index.tsx index 25a39fd6f6..95c80cc4c7 100644 --- a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/index.tsx +++ b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/index.tsx @@ -62,7 +62,7 @@ function OverrideTab() { ); } -function XcassetTab() { +function XcassetDrawableResourceTab() { return ( {Platform.OS === 'ios' ? ( @@ -120,7 +120,7 @@ function ImageTab() { or `tabBarItemIconColor`.{'\n'} {'\n'} Selected: filled image in its black color (the host{' '} - green tint is ignored). + GREEN tint is ignored). {'\n'} Unselected iOS18: outline icons in BLUE{' '} color.{'\n'} @@ -202,9 +202,11 @@ const IOS_ROUTES: TabRouteConfig[] = [ }, { name: 'XcassetIcon', - Component: XcassetTab, + Component: XcassetDrawableResourceTab, options: { - title: 'Xcasset', ios: { + ...DEFAULT_TAB_ROUTE_OPTIONS, + title: 'Xcasset', + ios: { icon: { type: 'xcasset', name: 'custom-icon-fill', @@ -242,8 +244,9 @@ const IOS_ROUTES: TabRouteConfig[] = [ const ANDROID_ROUTES: TabRouteConfig[] = [ { name: 'DrawableResource', - Component: XcassetTab, + Component: XcassetDrawableResourceTab, options: { + ...DEFAULT_TAB_ROUTE_OPTIONS, title: 'DrawableResource', android: { icon: { diff --git a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/scenario.md b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/scenario.md index 240742b2ba..79fd2e6339 100644 --- a/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/scenario.md +++ b/apps/src/tests/single-feature-tests/tabs/test-tabs-item-icon/scenario.md @@ -136,7 +136,7 @@ tabBarItemTitleFontColor - it's reported native bug. 2. Tap the **Image** tab. - [ ] The icon swaps from the outline image to - the filled image. Unselected tab icon change to sym_call_missed. + the filled image. Unselected tab icon changes to sym_call_missed. Selected tab icon is **red** and unselected icon renders in **green**. 3. While **Image** tab is selected, use the Tab key on keyboard to