Skip to content

Commit 10bbcb7

Browse files
committed
Support PlatformColor in Android StatusBar backgroundColor
Passing a PlatformColor to StatusBar.backgroundColor previously tripped an invariant in _updatePropsStack because processColor returns an object for PlatformColor and the native setColor TurboModule only accepted a number. Adds a setColorObject TurboModule method that accepts a resource-paths object and resolves it on the native side via ColorPropConverter.getColor. StatusBar.js now dispatches to setColor for numeric colors and to setColorObject for PlatformColor values. Fixes #48402
1 parent 083fd99 commit 10bbcb7

6 files changed

Lines changed: 79 additions & 6 deletions

File tree

packages/react-native/Libraries/Components/StatusBar/StatusBar.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -477,15 +477,17 @@ class StatusBar extends React.Component<StatusBarProps> {
477477
console.warn(
478478
`\`StatusBar._updatePropsStack\`: Color ${mergedProps.backgroundColor.value} parsed to null or undefined`,
479479
);
480-
} else {
481-
invariant(
482-
typeof processedColor === 'number',
483-
'Unexpected color given in StatusBar._updatePropsStack',
484-
);
480+
} else if (typeof processedColor === 'number') {
485481
NativeStatusBarManagerAndroid.setColor(
486482
processedColor,
487483
mergedProps.backgroundColor.animated,
488484
);
485+
} else {
486+
NativeStatusBarManagerAndroid.setColorObject(
487+
// $FlowFixMe[incompatible-type] - Opaque NativeColorValue on Android matches the spec shape {resource_paths: Array<string>}.
488+
processedColor,
489+
mergedProps.backgroundColor.animated,
490+
);
489491
}
490492
if (!oldProps || oldProps.hidden?.value !== mergedProps.hidden.value) {
491493
NativeStatusBarManagerAndroid.setHidden(mergedProps.hidden.value);

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/statusbar/StatusBarModule.kt

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ import androidx.core.view.WindowCompat
1616
import androidx.core.view.WindowInsetsCompat
1717
import com.facebook.common.logging.FLog
1818
import com.facebook.fbreact.specs.NativeStatusBarManagerAndroidSpec
19+
import com.facebook.react.bridge.ColorPropConverter
1920
import com.facebook.react.bridge.GuardedRunnable
2021
import com.facebook.react.bridge.NativeModule
2122
import com.facebook.react.bridge.ReactApplicationContext
23+
import com.facebook.react.bridge.ReadableMap
2224
import com.facebook.react.bridge.UiThreadUtil
2325
import com.facebook.react.common.ReactConstants
2426
import com.facebook.react.interfaces.ExtraWindowEventListener
@@ -79,7 +81,24 @@ internal class StatusBarModule(reactContext: ReactApplicationContext?) :
7981

8082
@Suppress("DEPRECATION")
8183
override fun setColor(colorDouble: Double, animated: Boolean) {
82-
val color = colorDouble.toInt()
84+
applyStatusBarColor(colorDouble.toInt(), animated)
85+
}
86+
87+
@Suppress("DEPRECATION")
88+
override fun setColorObject(color: ReadableMap, animated: Boolean) {
89+
val resolved = ColorPropConverter.getColor(color, reactApplicationContext)
90+
if (resolved == null) {
91+
FLog.w(
92+
ReactConstants.TAG,
93+
"StatusBarModule: Ignored status bar change, unable to resolve color.",
94+
)
95+
return
96+
}
97+
applyStatusBarColor(resolved, animated)
98+
}
99+
100+
@Suppress("DEPRECATION")
101+
private fun applyStatusBarColor(color: Int, animated: Boolean) {
83102
val activity = reactApplicationContext.getCurrentActivity()
84103
if (activity == null) {
85104
FLog.w(

packages/react-native/src/private/specs_DEPRECATED/modules/NativeStatusBarManagerAndroid.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,20 @@ import type {TurboModule} from '../../../../Libraries/TurboModule/RCTExport';
1212

1313
import * as TurboModuleRegistry from '../../../../Libraries/TurboModule/TurboModuleRegistry';
1414

15+
export type NativePlatformColorValue = {
16+
+resource_paths: Array<string>,
17+
};
18+
1519
export interface Spec extends TurboModule {
1620
readonly getConstants: () => {
1721
readonly HEIGHT: number,
1822
readonly DEFAULT_BACKGROUND_COLOR: number,
1923
};
2024
readonly setColor: (color: number, animated: boolean) => void;
25+
readonly setColorObject: (
26+
color: NativePlatformColorValue,
27+
animated: boolean,
28+
) => void;
2129
readonly setTranslucent: (translucent: boolean) => void;
2230

2331
/**
@@ -47,6 +55,10 @@ const NativeStatusBarManager = {
4755
NativeModule.setColor(color, animated);
4856
},
4957

58+
setColorObject(color: NativePlatformColorValue, animated: boolean): void {
59+
NativeModule.setColorObject(color, animated);
60+
},
61+
5062
setTranslucent(translucent: boolean): void {
5163
NativeModule.setTranslucent(translucent);
5264
},

scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8591,6 +8591,12 @@ struct facebook::react::NativeSourceCodeSourceCodeConstants {
85918591
public bool operator==(const facebook::react::NativeSourceCodeSourceCodeConstants& other) const;
85928592
}
85938593

8594+
template <typename P0>
8595+
struct facebook::react::NativeStatusBarManagerAndroidNativePlatformColorValue {
8596+
public P0 resource_paths;
8597+
public bool operator==(const facebook::react::NativeStatusBarManagerAndroidNativePlatformColorValue& other) const;
8598+
}
8599+
85948600
template <typename R, typename... Args>
85958601
class facebook::react::SyncCallback<R(Args...)> {
85968602
public R call(Args... args) const;
@@ -9433,6 +9439,14 @@ struct facebook::react::NativeSourceCodeSourceCodeConstantsBridging {
94339439
public static facebook::jsi::String scriptURLToJs(facebook::jsi::Runtime& rt, decltype(types.scriptURL) value);
94349440
}
94359441

9442+
template <typename T>
9443+
struct facebook::react::NativeStatusBarManagerAndroidNativePlatformColorValueBridging {
9444+
public static T fromJs(facebook::jsi::Runtime& rt, const facebook::jsi::Object& value, const std::shared_ptr<facebook::react::CallInvoker>& jsInvoker);
9445+
public static T types;
9446+
public static facebook::jsi::Array resource_pathsToJs(facebook::jsi::Runtime& rt, decltype(types.resource_paths) value);
9447+
public static facebook::jsi::Object toJs(facebook::jsi::Runtime& rt, const T& value, const std::shared_ptr<facebook::react::CallInvoker>& jsInvoker);
9448+
}
9449+
94369450
template <typename T>
94379451
struct facebook::react::RectangleCorners {
94389452
public T bottomLeft;

scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8367,6 +8367,12 @@ struct facebook::react::NativeSourceCodeSourceCodeConstants {
83678367
public bool operator==(const facebook::react::NativeSourceCodeSourceCodeConstants& other) const;
83688368
}
83698369

8370+
template <typename P0>
8371+
struct facebook::react::NativeStatusBarManagerAndroidNativePlatformColorValue {
8372+
public P0 resource_paths;
8373+
public bool operator==(const facebook::react::NativeStatusBarManagerAndroidNativePlatformColorValue& other) const;
8374+
}
8375+
83708376
template <typename R, typename... Args>
83718377
class facebook::react::SyncCallback<R(Args...)> {
83728378
public R call(Args... args) const;
@@ -9071,6 +9077,13 @@ struct facebook::react::NativeSourceCodeSourceCodeConstantsBridging {
90719077
public static facebook::jsi::Object toJs(facebook::jsi::Runtime& rt, const T& value, const std::shared_ptr<facebook::react::CallInvoker>& jsInvoker);
90729078
}
90739079

9080+
template <typename T>
9081+
struct facebook::react::NativeStatusBarManagerAndroidNativePlatformColorValueBridging {
9082+
public static T fromJs(facebook::jsi::Runtime& rt, const facebook::jsi::Object& value, const std::shared_ptr<facebook::react::CallInvoker>& jsInvoker);
9083+
public static T types;
9084+
public static facebook::jsi::Object toJs(facebook::jsi::Runtime& rt, const T& value, const std::shared_ptr<facebook::react::CallInvoker>& jsInvoker);
9085+
}
9086+
90749087
template <typename T>
90759088
struct facebook::react::RectangleCorners {
90769089
public T bottomLeft;

scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8582,6 +8582,12 @@ struct facebook::react::NativeSourceCodeSourceCodeConstants {
85828582
public bool operator==(const facebook::react::NativeSourceCodeSourceCodeConstants& other) const;
85838583
}
85848584

8585+
template <typename P0>
8586+
struct facebook::react::NativeStatusBarManagerAndroidNativePlatformColorValue {
8587+
public P0 resource_paths;
8588+
public bool operator==(const facebook::react::NativeStatusBarManagerAndroidNativePlatformColorValue& other) const;
8589+
}
8590+
85858591
template <typename R, typename... Args>
85868592
class facebook::react::SyncCallback<R(Args...)> {
85878593
public R call(Args... args) const;
@@ -9286,6 +9292,13 @@ struct facebook::react::NativeSourceCodeSourceCodeConstantsBridging {
92869292
public static facebook::jsi::Object toJs(facebook::jsi::Runtime& rt, const T& value, const std::shared_ptr<facebook::react::CallInvoker>& jsInvoker);
92879293
}
92889294

9295+
template <typename T>
9296+
struct facebook::react::NativeStatusBarManagerAndroidNativePlatformColorValueBridging {
9297+
public static T fromJs(facebook::jsi::Runtime& rt, const facebook::jsi::Object& value, const std::shared_ptr<facebook::react::CallInvoker>& jsInvoker);
9298+
public static T types;
9299+
public static facebook::jsi::Object toJs(facebook::jsi::Runtime& rt, const T& value, const std::shared_ptr<facebook::react::CallInvoker>& jsInvoker);
9300+
}
9301+
92899302
template <typename T>
92909303
struct facebook::react::RectangleCorners {
92919304
public T bottomLeft;

0 commit comments

Comments
 (0)