Skip to content

Commit 4978134

Browse files
alanleedevfacebook-github-bot
authored andcommitted
Add listener API to OverrideColorScheme for dynamic dark mode updates (facebook#54791)
Summary: This change adds a listener mechanism to the `OverrideColorScheme` interface to enable dynamic updates when the user's dark mode preference changes via `OverrideColorScheme`. Previously, `AppearanceModule` would only reflect the initial color scheme state when instantiated. If a user toggled dark mode through an `OverrideColorScheme` implementation, React Native JavaScript would not be notified of the change, causing UI inconsistencies. This implementation adds: 1. An optional `addSchemeChangeListener()` method to the `OverrideColorScheme` interface with a default no-op implementation for backward compatibility. Also adding matching `removeSchemeChangeListener()`. 2. Automatic listener registration in `AppearanceModule`'s init block that triggers `onConfigurationChanged()` when the color scheme changes Changelog: [Android][Added] - Add `addSchemeChangeListener()` function to `OverrideColorScheme` interface to support dynamic appearance updates via override Reviewed By: mdvacca Differential Revision: D88427482
1 parent 95cc1e7 commit 4978134

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

packages/react-native/ReactAndroid/api/ReactAndroid.api

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2475,7 +2475,14 @@ public final class com/facebook/react/modules/appearance/AppearanceModule$Compan
24752475
}
24762476

24772477
public abstract interface class com/facebook/react/modules/appearance/AppearanceModule$OverrideColorScheme {
2478+
public abstract fun addSchemeChangeListener (Lkotlin/jvm/functions/Function0;)V
24782479
public abstract fun getScheme ()Ljava/lang/String;
2480+
public abstract fun removeSchemeChangeListener (Lkotlin/jvm/functions/Function0;)V
2481+
}
2482+
2483+
public final class com/facebook/react/modules/appearance/AppearanceModule$OverrideColorScheme$DefaultImpls {
2484+
public static fun addSchemeChangeListener (Lcom/facebook/react/modules/appearance/AppearanceModule$OverrideColorScheme;Lkotlin/jvm/functions/Function0;)V
2485+
public static fun removeSchemeChangeListener (Lcom/facebook/react/modules/appearance/AppearanceModule$OverrideColorScheme;Lkotlin/jvm/functions/Function0;)V
24792486
}
24802487

24812488
public abstract interface class com/facebook/react/modules/appregistry/AppRegistry : com/facebook/react/bridge/JavaScriptModule {

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/appearance/AppearanceModule.kt

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,40 @@ constructor(
2828

2929
private var lastEmittedColorScheme: String? = null
3030

31+
init {
32+
// Register as a listener for color scheme changes if override is provided
33+
overrideColorScheme?.addSchemeChangeListener {
34+
val activity = reactApplicationContext.getCurrentActivity()
35+
onConfigurationChanged(activity ?: reactApplicationContext)
36+
}
37+
}
38+
3139
/** Optional override to the current color scheme */
32-
public fun interface OverrideColorScheme {
40+
public interface OverrideColorScheme {
3341
/**
3442
* Color scheme will use the return value instead of the current system configuration. Available
3543
* scheme: {light, dark}
3644
*/
3745
public fun getScheme(): String
46+
47+
/**
48+
* Register a listener to be notified when the color scheme changes. The listener will be
49+
* invoked whenever the underlying theme preference changes.
50+
*
51+
* Default implementation does nothing. Override this method if you want to support dynamic
52+
* color scheme updates.
53+
*/
54+
public fun addSchemeChangeListener(listener: () -> Unit) {
55+
// no-op
56+
}
57+
58+
/**
59+
* Unregisters a previously added color scheme change listener. Default implementation is a
60+
* no-op; override to remove the listener from your source.
61+
*/
62+
public fun removeSchemeChangeListener(listener: () -> Unit) {
63+
// no-op
64+
}
3865
}
3966

4067
private fun colorSchemeForCurrentConfiguration(context: Context): String {

0 commit comments

Comments
 (0)