Skip to content

Commit 1a9c4c0

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 b0a6386 commit 1a9c4c0

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
@@ -529,15 +529,17 @@ class StatusBar extends React.Component<StatusBarProps> {
529529
console.warn(
530530
`\`StatusBar._updatePropsStack\`: Color ${mergedProps.backgroundColor.value} parsed to null or undefined`,
531531
);
532-
} else {
533-
invariant(
534-
typeof processedColor === 'number',
535-
'Unexpected color given in StatusBar._updatePropsStack',
536-
);
532+
} else if (typeof processedColor === 'number') {
537533
NativeStatusBarManagerAndroid.setColor(
538534
processedColor,
539535
mergedProps.backgroundColor.animated,
540536
);
537+
} else {
538+
NativeStatusBarManagerAndroid.setColorObject(
539+
// $FlowFixMe[incompatible-type] - Opaque NativeColorValue on Android matches the spec shape {resource_paths: Array<string>}.
540+
processedColor,
541+
mergedProps.backgroundColor.animated,
542+
);
541543
}
542544
if (!oldProps || oldProps.hidden?.value !== mergedProps.hidden.value) {
543545
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+
readonly 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
@@ -8615,6 +8615,12 @@ struct facebook::react::NativeSourceCodeSourceCodeConstants {
86158615
public bool operator==(const facebook::react::NativeSourceCodeSourceCodeConstants& other) const;
86168616
}
86178617

8618+
template <typename P0>
8619+
struct facebook::react::NativeStatusBarManagerAndroidNativePlatformColorValue {
8620+
public P0 resource_paths;
8621+
public bool operator==(const facebook::react::NativeStatusBarManagerAndroidNativePlatformColorValue& other) const;
8622+
}
8623+
86188624
template <typename R, typename... Args>
86198625
class facebook::react::SyncCallback<R(Args...)> {
86208626
public R call(Args... args) const;
@@ -9457,6 +9463,14 @@ struct facebook::react::NativeSourceCodeSourceCodeConstantsBridging {
94579463
public static facebook::jsi::String scriptURLToJs(facebook::jsi::Runtime& rt, decltype(types.scriptURL) value);
94589464
}
94599465

9466+
template <typename T>
9467+
struct facebook::react::NativeStatusBarManagerAndroidNativePlatformColorValueBridging {
9468+
public static T fromJs(facebook::jsi::Runtime& rt, const facebook::jsi::Object& value, const std::shared_ptr<facebook::react::CallInvoker>& jsInvoker);
9469+
public static T types;
9470+
public static facebook::jsi::Array resource_pathsToJs(facebook::jsi::Runtime& rt, decltype(types.resource_paths) value);
9471+
public static facebook::jsi::Object toJs(facebook::jsi::Runtime& rt, const T& value, const std::shared_ptr<facebook::react::CallInvoker>& jsInvoker);
9472+
}
9473+
94609474
template <typename T>
94619475
struct facebook::react::RectangleCorners {
94629476
public T bottomLeft;

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

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

8394+
template <typename P0>
8395+
struct facebook::react::NativeStatusBarManagerAndroidNativePlatformColorValue {
8396+
public P0 resource_paths;
8397+
public bool operator==(const facebook::react::NativeStatusBarManagerAndroidNativePlatformColorValue& other) const;
8398+
}
8399+
83948400
template <typename R, typename... Args>
83958401
class facebook::react::SyncCallback<R(Args...)> {
83968402
public R call(Args... args) const;
@@ -9095,6 +9101,13 @@ struct facebook::react::NativeSourceCodeSourceCodeConstantsBridging {
90959101
public static facebook::jsi::Object toJs(facebook::jsi::Runtime& rt, const T& value, const std::shared_ptr<facebook::react::CallInvoker>& jsInvoker);
90969102
}
90979103

9104+
template <typename T>
9105+
struct facebook::react::NativeStatusBarManagerAndroidNativePlatformColorValueBridging {
9106+
public static T fromJs(facebook::jsi::Runtime& rt, const facebook::jsi::Object& value, const std::shared_ptr<facebook::react::CallInvoker>& jsInvoker);
9107+
public static T types;
9108+
public static facebook::jsi::Object toJs(facebook::jsi::Runtime& rt, const T& value, const std::shared_ptr<facebook::react::CallInvoker>& jsInvoker);
9109+
}
9110+
90989111
template <typename T>
90999112
struct facebook::react::RectangleCorners {
91009113
public T bottomLeft;

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

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

8609+
template <typename P0>
8610+
struct facebook::react::NativeStatusBarManagerAndroidNativePlatformColorValue {
8611+
public P0 resource_paths;
8612+
public bool operator==(const facebook::react::NativeStatusBarManagerAndroidNativePlatformColorValue& other) const;
8613+
}
8614+
86098615
template <typename R, typename... Args>
86108616
class facebook::react::SyncCallback<R(Args...)> {
86118617
public R call(Args... args) const;
@@ -9310,6 +9316,13 @@ struct facebook::react::NativeSourceCodeSourceCodeConstantsBridging {
93109316
public static facebook::jsi::Object toJs(facebook::jsi::Runtime& rt, const T& value, const std::shared_ptr<facebook::react::CallInvoker>& jsInvoker);
93119317
}
93129318

9319+
template <typename T>
9320+
struct facebook::react::NativeStatusBarManagerAndroidNativePlatformColorValueBridging {
9321+
public static T fromJs(facebook::jsi::Runtime& rt, const facebook::jsi::Object& value, const std::shared_ptr<facebook::react::CallInvoker>& jsInvoker);
9322+
public static T types;
9323+
public static facebook::jsi::Object toJs(facebook::jsi::Runtime& rt, const T& value, const std::shared_ptr<facebook::react::CallInvoker>& jsInvoker);
9324+
}
9325+
93139326
template <typename T>
93149327
struct facebook::react::RectangleCorners {
93159328
public T bottomLeft;

0 commit comments

Comments
 (0)