feat(Tabs, Android): handle colorScheme (dark mode)#3723
Conversation
There was a problem hiding this comment.
Pull request overview
Adds Android support for the TabsHost colorScheme prop (dark mode), including a reusable native color-scheme propagation mechanism that mirrors iOS trait propagation, and updates the single-feature test to run on Android.
Changes:
- Adds
colorSchemeto the publicTabsHostPropsAPI for Android (and positions it as a general prop). - Implements Android-side
colorSchemehandling inTabsHostvia a reusableColorSchemeCoordinator+ listener/provider interfaces. - Updates the
test-tabs-color-schemesingle-feature test to run on Android and adjusts layout/safe-area behavior accordingly.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/fabric/tabs/TabsHostNativeComponent.ts | Exposes colorScheme in the native props interface as a general prop. |
| src/components/tabs/TabsHost.types.ts | Documents colorScheme as supported on Android + iOS (general section). |
| apps/src/tests/single-feature-tests/tabs/test-tabs-color-scheme.tsx | Runs the scenario on Android and adjusts padding/safe-area config for Android layout. |
| android/src/main/java/com/swmansion/rnscreens/gamma/tabs/host/TabsHostViewManager.kt | Wires colorScheme prop from JS to native TabsHost. |
| android/src/main/java/com/swmansion/rnscreens/gamma/tabs/host/TabsHost.kt | Applies resolved night mode to Material theme + tab appearance; integrates coordinator lifecycle hooks. |
| android/src/main/java/com/swmansion/rnscreens/gamma/common/colorscheme/* | Introduces reusable coordinator + interfaces/enums for night-mode resolution/propagation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
android/src/main/java/com/swmansion/rnscreens/gamma/tabs/host/TabsHostViewManager.kt
Show resolved
Hide resolved
...oid/src/main/java/com/swmansion/rnscreens/gamma/common/colorscheme/ColorSchemeCoordinator.kt
Outdated
Show resolved
Hide resolved
Sure! |
kkafar
left a comment
There was a problem hiding this comment.
Good job.
I've left few remarks. Please answer them.
...oid/src/main/java/com/swmansion/rnscreens/gamma/common/colorscheme/ColorSchemeCoordinator.kt
Outdated
Show resolved
Hide resolved
...oid/src/main/java/com/swmansion/rnscreens/gamma/common/colorscheme/ColorSchemeCoordinator.kt
Outdated
Show resolved
Hide resolved
android/src/main/java/com/swmansion/rnscreens/gamma/tabs/host/TabsHost.kt
Outdated
Show resolved
Hide resolved
… param to setup; clear callback in detach
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
...oid/src/main/java/com/swmansion/rnscreens/gamma/common/colorscheme/ColorSchemeCoordinator.kt
Show resolved
Hide resolved
| private var parentProvider: ColorSchemeProviding? = null | ||
| private var systemUiNightMode: Int = Configuration.UI_MODE_NIGHT_NO | ||
| private var lastAppliedUiNightMode: Int? = null | ||
| private val childListeners = mutableListOf<ColorSchemeListener>() |
There was a problem hiding this comment.
I think that we usually used list instead of a set for a small amount of entities but I guess that after we renamed onAttachedToWindow to setup the intention might not be as clear and somebody might call setup multiple times and create duplicates. We can use a set or maybe just throw an error if setup is called when parentProvider is not null? Not sure what's better here.
cc @kkafar
There was a problem hiding this comment.
that setup looks risky with internal access modifier, so as you already mentioned, maybe it would be possible to handle it when we don't expect it to be called subsequent times
There was a problem hiding this comment.
Let's throw an error in case setup is called multiple times before teardown is called
There was a problem hiding this comment.
I used separate property because I can't determine in other way whether setup has been run (callback might be nullable, parent might also be null if we're top-level provider).
kkafar
left a comment
There was a problem hiding this comment.
Let's apply the last few remarks and proceed.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
src/components/tabs/TabsHost.ios.tsx:60
TabsHost.ios.tsxno longer forwardsios?.colorSchemeto the native component. If you decide to preserve backward compatibility for the previous iOS-only API, you’ll need to mapios?.colorSchemeinto the new basecolorSchemeprop whenprops.colorSchemeisn’t provided, otherwise existing apps will silently stop applying the theme override.
ref={componentNodeRef}
{...filteredBaseProps}
// iOS-specific
controlNavigationStateInJS={controlNavigationStateInJS}
layoutDirection={direction}
tabBarControllerMode={ios?.tabBarControllerMode}
tabBarMinimizeBehavior={ios?.tabBarMinimizeBehavior}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
|
As discussed internally, I'm merging it to have this API in the PRs related to Tabs stabilization |
Description
Adds support for
colorSchemeprop forTabsHoston Android.This is a follow-up to #3716 and it follows RFC-0996.
Color scheme will be propagated down the hierarchy via custom solution that mimics trait propagation on iOS. This solution is meant to be reusable so that it can be later used in Stack v5 and Split.
Changes
colorSchemefor AndroidColorSchemeProviding,ColorSchemeListenerinterfacesColorSchemeCoordinatorColorSchemeCoordinatorinTabsHostBefore & after - visual documentation
Before
N/A - tabs would use system's or react-native's color scheme.
After
test_color_scheme_android.mp4
Test plan
Run
single-feature-tests/test-tabs-color-scheme.tsx.To test theme propagation you can use this test:
Theme propagation test
Checklist