diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm index 99104f0ec8fc..eeee2ed1a725 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm @@ -11,9 +11,11 @@ #import #import #import +#import #import #import #import +#import #import #import @@ -63,7 +65,15 @@ - (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared & // `tintColor` if (oldImageProps.tintColor != newImageProps.tintColor) { - _imageView.tintColor = RCTUIColorFromSharedColor(newImageProps.tintColor); + if (ReactNativeFeatureFlags::enableImageTransparentTintColor()) { + if (newImageProps.tintColor.has_value()) { + _imageView.tintColor = RCTUIColorFromSharedColor(newImageProps.tintColor.value()); + } else { + _imageView.tintColor = nil; + } + } else { + _imageView.tintColor = RCTUIColorFromSharedColor(newImageProps.tintColor.value_or(SharedColor{})); + } } [super updateProps:props oldProps:oldProps]; diff --git a/packages/react-native/ReactCommon/react/renderer/components/image/ImageProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/image/ImageProps.cpp index 3645736ea94f..25570ca1ea51 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/image/ImageProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/image/ImageProps.cpp @@ -5,10 +5,12 @@ * LICENSE file in the root directory of this source tree. */ +#include #include #include #include #include +#include namespace facebook::react { @@ -199,8 +201,24 @@ folly::dynamic ImageProps::getDiffProps(const Props* prevProps) const { result["capInsets"] = convertEdgeInsets(capInsets); } - if (tintColor != oldProps->tintColor) { - result["tintColor"] = *tintColor; + if (ReactNativeFeatureFlags::enableImageTransparentTintColor()) { + // New: emit any defined tint (including transparent); emit null to clear on + // unset. + if (tintColor != oldProps->tintColor) { + if (tintColor.has_value()) { + result["tintColor"] = *tintColor.value(); + } else { + result["tintColor"] = folly::dynamic(nullptr); + } + } + } else { + // pre-`std::optional` behavior + SharedColor tintColorValue = tintColor.value_or(SharedColor{}); + SharedColor prevTintColorValue = + oldProps->tintColor.value_or(SharedColor{}); + if (tintColorValue != prevTintColorValue) { + result["tintColor"] = *tintColorValue; + } } if (internal_analyticTag != oldProps->internal_analyticTag) { diff --git a/packages/react-native/ReactCommon/react/renderer/components/image/ImageProps.h b/packages/react-native/ReactCommon/react/renderer/components/image/ImageProps.h index f38fdb179e8b..e53e1995d38c 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/image/ImageProps.h +++ b/packages/react-native/ReactCommon/react/renderer/components/image/ImageProps.h @@ -31,7 +31,7 @@ class ImageProps final : public ViewProps { ImageResizeMode resizeMode{ImageResizeMode::Stretch}; Float blurRadius{}; EdgeInsets capInsets{}; - SharedColor tintColor{}; + std::optional tintColor{}; std::string internal_analyticTag{}; std::string resizeMethod{"auto"}; Float resizeMultiplier{1.f}; diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageRequestParams.h b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageRequestParams.h index e960e01b5b5c..d28bf2b3a63f 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageRequestParams.h +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageRequestParams.h @@ -26,7 +26,7 @@ class ImageRequestParams { Float resizeMultiplier, bool shouldNotifyLoadEvents, SharedColor overlayColor, - SharedColor tintColor, + std::optional tintColor, Float fadeDuration, bool progressiveRenderingEnabled, ImageSource loadingIndicatorSource, @@ -55,7 +55,7 @@ class ImageRequestParams { Float resizeMultiplier{}; bool shouldNotifyLoadEvents{}; SharedColor overlayColor{}; - SharedColor tintColor{}; + std::optional tintColor{}; Float fadeDuration{}; bool progressiveRenderingEnabled{}; ImageSource loadingIndicatorSource{}; diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/conversions.h b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/conversions.h index bf4ca03661d7..f68374914a9d 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/conversions.h +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/conversions.h @@ -7,6 +7,7 @@ #pragma once +#include #include #include #include @@ -75,8 +76,16 @@ inline void serializeImageRequestParams(MapBufferBuilder &builder, const ImageRe if (isColorMeaningful(imageRequestParams.overlayColor)) { builder.putInt(IS_KEY_OVERLAY_COLOR, toAndroidRepr(imageRequestParams.overlayColor)); } - if (isColorMeaningful(imageRequestParams.tintColor)) { - builder.putInt(IS_KEY_TINT_COLOR, toAndroidRepr(imageRequestParams.tintColor)); + if (ReactNativeFeatureFlags::enableImageTransparentTintColor()) { + if (imageRequestParams.tintColor.has_value()) { + builder.putInt(IS_KEY_TINT_COLOR, toAndroidRepr(imageRequestParams.tintColor.value())); + } + } else { + // pre-`std::optional` behavior + SharedColor tintColor = imageRequestParams.tintColor.value_or(SharedColor{}); + if (isColorMeaningful(tintColor)) { + builder.putInt(IS_KEY_TINT_COLOR, toAndroidRepr(tintColor)); + } } builder.putInt(IS_KEY_FADE_DURATION, static_cast(imageRequestParams.fadeDuration)); builder.putBool(IS_KEY_PROGRESSIVE_RENDERING_ENABLED, imageRequestParams.progressiveRenderingEnabled); diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api index 5caa29627d62..dff12a0398b3 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api @@ -2594,7 +2594,7 @@ class facebook::react::ImageProps : public facebook::react::HostPlatformViewProp public facebook::react::ImageSource loadingIndicatorSource; public facebook::react::ImageSources sources; public facebook::react::SharedColor overlayColor; - public facebook::react::SharedColor tintColor; + public std::optional tintColor; public std::string resizeMethod; public virtual facebook::react::ComponentName getDiffPropsImplementationTarget() const override; public virtual folly::dynamic getDiffProps(const facebook::react::Props* prevProps) const override; @@ -2616,7 +2616,7 @@ class facebook::react::ImageRequest { class facebook::react::ImageRequestParams { public ImageRequestParams() = default; - public ImageRequestParams(facebook::react::Float blurRadius, facebook::react::ImageSource defaultSource, facebook::react::ImageResizeMode resizeMode, std::string resizeMethod, facebook::react::Float resizeMultiplier, bool shouldNotifyLoadEvents, facebook::react::SharedColor overlayColor, facebook::react::SharedColor tintColor, facebook::react::Float fadeDuration, bool progressiveRenderingEnabled, facebook::react::ImageSource loadingIndicatorSource, std::string analyticTag, facebook::react::Size size); + public ImageRequestParams(facebook::react::Float blurRadius, facebook::react::ImageSource defaultSource, facebook::react::ImageResizeMode resizeMode, std::string resizeMethod, facebook::react::Float resizeMultiplier, bool shouldNotifyLoadEvents, facebook::react::SharedColor overlayColor, std::optional tintColor, facebook::react::Float fadeDuration, bool progressiveRenderingEnabled, facebook::react::ImageSource loadingIndicatorSource, std::string analyticTag, facebook::react::Size size); public bool operator==(const facebook::react::ImageRequestParams& rhs) const = default; public bool progressiveRenderingEnabled; public bool shouldNotifyLoadEvents; @@ -2627,8 +2627,8 @@ class facebook::react::ImageRequestParams { public facebook::react::ImageSource defaultSource; public facebook::react::ImageSource loadingIndicatorSource; public facebook::react::SharedColor overlayColor; - public facebook::react::SharedColor tintColor; public facebook::react::Size size; + public std::optional tintColor; public std::string analyticTag; public std::string resizeMethod; } diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api index 957dedf6aba8..bae821b61ec2 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api @@ -2576,7 +2576,7 @@ class facebook::react::ImageProps : public facebook::react::HostPlatformViewProp public facebook::react::ImageSource loadingIndicatorSource; public facebook::react::ImageSources sources; public facebook::react::SharedColor overlayColor; - public facebook::react::SharedColor tintColor; + public std::optional tintColor; public std::string resizeMethod; public virtual facebook::react::ComponentName getDiffPropsImplementationTarget() const override; public virtual folly::dynamic getDiffProps(const facebook::react::Props* prevProps) const override; @@ -2598,7 +2598,7 @@ class facebook::react::ImageRequest { class facebook::react::ImageRequestParams { public ImageRequestParams() = default; - public ImageRequestParams(facebook::react::Float blurRadius, facebook::react::ImageSource defaultSource, facebook::react::ImageResizeMode resizeMode, std::string resizeMethod, facebook::react::Float resizeMultiplier, bool shouldNotifyLoadEvents, facebook::react::SharedColor overlayColor, facebook::react::SharedColor tintColor, facebook::react::Float fadeDuration, bool progressiveRenderingEnabled, facebook::react::ImageSource loadingIndicatorSource, std::string analyticTag, facebook::react::Size size); + public ImageRequestParams(facebook::react::Float blurRadius, facebook::react::ImageSource defaultSource, facebook::react::ImageResizeMode resizeMode, std::string resizeMethod, facebook::react::Float resizeMultiplier, bool shouldNotifyLoadEvents, facebook::react::SharedColor overlayColor, std::optional tintColor, facebook::react::Float fadeDuration, bool progressiveRenderingEnabled, facebook::react::ImageSource loadingIndicatorSource, std::string analyticTag, facebook::react::Size size); public bool operator==(const facebook::react::ImageRequestParams& rhs) const = default; public bool progressiveRenderingEnabled; public bool shouldNotifyLoadEvents; @@ -2609,8 +2609,8 @@ class facebook::react::ImageRequestParams { public facebook::react::ImageSource defaultSource; public facebook::react::ImageSource loadingIndicatorSource; public facebook::react::SharedColor overlayColor; - public facebook::react::SharedColor tintColor; public facebook::react::Size size; + public std::optional tintColor; public std::string analyticTag; public std::string resizeMethod; } diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api index 016bc534b9f6..beb96517ca4e 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api @@ -2591,7 +2591,7 @@ class facebook::react::ImageProps : public facebook::react::HostPlatformViewProp public facebook::react::ImageSource loadingIndicatorSource; public facebook::react::ImageSources sources; public facebook::react::SharedColor overlayColor; - public facebook::react::SharedColor tintColor; + public std::optional tintColor; public std::string resizeMethod; public virtual facebook::react::ComponentName getDiffPropsImplementationTarget() const override; public virtual folly::dynamic getDiffProps(const facebook::react::Props* prevProps) const override; @@ -2613,7 +2613,7 @@ class facebook::react::ImageRequest { class facebook::react::ImageRequestParams { public ImageRequestParams() = default; - public ImageRequestParams(facebook::react::Float blurRadius, facebook::react::ImageSource defaultSource, facebook::react::ImageResizeMode resizeMode, std::string resizeMethod, facebook::react::Float resizeMultiplier, bool shouldNotifyLoadEvents, facebook::react::SharedColor overlayColor, facebook::react::SharedColor tintColor, facebook::react::Float fadeDuration, bool progressiveRenderingEnabled, facebook::react::ImageSource loadingIndicatorSource, std::string analyticTag, facebook::react::Size size); + public ImageRequestParams(facebook::react::Float blurRadius, facebook::react::ImageSource defaultSource, facebook::react::ImageResizeMode resizeMode, std::string resizeMethod, facebook::react::Float resizeMultiplier, bool shouldNotifyLoadEvents, facebook::react::SharedColor overlayColor, std::optional tintColor, facebook::react::Float fadeDuration, bool progressiveRenderingEnabled, facebook::react::ImageSource loadingIndicatorSource, std::string analyticTag, facebook::react::Size size); public bool operator==(const facebook::react::ImageRequestParams& rhs) const = default; public bool progressiveRenderingEnabled; public bool shouldNotifyLoadEvents; @@ -2624,8 +2624,8 @@ class facebook::react::ImageRequestParams { public facebook::react::ImageSource defaultSource; public facebook::react::ImageSource loadingIndicatorSource; public facebook::react::SharedColor overlayColor; - public facebook::react::SharedColor tintColor; public facebook::react::Size size; + public std::optional tintColor; public std::string analyticTag; public std::string resizeMethod; } diff --git a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api index 32fdfd48d335..c27595d7f77a 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api @@ -5008,7 +5008,7 @@ class facebook::react::ImageProps : public facebook::react::HostPlatformViewProp public facebook::react::ImageSource loadingIndicatorSource; public facebook::react::ImageSources sources; public facebook::react::SharedColor overlayColor; - public facebook::react::SharedColor tintColor; + public std::optional tintColor; public std::string resizeMethod; public void setProp(const facebook::react::PropsParserContext& context, facebook::react::RawPropsPropNameHash hash, const char* propName, const facebook::react::RawValue& value); } diff --git a/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api index bee7a8777e7b..c8a738e9069d 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api @@ -4979,7 +4979,7 @@ class facebook::react::ImageProps : public facebook::react::HostPlatformViewProp public facebook::react::ImageSource loadingIndicatorSource; public facebook::react::ImageSources sources; public facebook::react::SharedColor overlayColor; - public facebook::react::SharedColor tintColor; + public std::optional tintColor; public std::string resizeMethod; public void setProp(const facebook::react::PropsParserContext& context, facebook::react::RawPropsPropNameHash hash, const char* propName, const facebook::react::RawValue& value); } diff --git a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api index 01edab95afd9..3d09b6d29173 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api @@ -5005,7 +5005,7 @@ class facebook::react::ImageProps : public facebook::react::HostPlatformViewProp public facebook::react::ImageSource loadingIndicatorSource; public facebook::react::ImageSources sources; public facebook::react::SharedColor overlayColor; - public facebook::react::SharedColor tintColor; + public std::optional tintColor; public std::string resizeMethod; public void setProp(const facebook::react::PropsParserContext& context, facebook::react::RawPropsPropNameHash hash, const char* propName, const facebook::react::RawValue& value); } diff --git a/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api index e33b73a68d4b..0c7d0a5b8a1c 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api @@ -1729,7 +1729,7 @@ class facebook::react::ImageProps : public facebook::react::HostPlatformViewProp public facebook::react::ImageSource loadingIndicatorSource; public facebook::react::ImageSources sources; public facebook::react::SharedColor overlayColor; - public facebook::react::SharedColor tintColor; + public std::optional tintColor; public std::string resizeMethod; public void setProp(const facebook::react::PropsParserContext& context, facebook::react::RawPropsPropNameHash hash, const char* propName, const facebook::react::RawValue& value); } diff --git a/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api index 7dcd0bb477e2..4b6b80e8c2b8 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api @@ -1712,7 +1712,7 @@ class facebook::react::ImageProps : public facebook::react::HostPlatformViewProp public facebook::react::ImageSource loadingIndicatorSource; public facebook::react::ImageSources sources; public facebook::react::SharedColor overlayColor; - public facebook::react::SharedColor tintColor; + public std::optional tintColor; public std::string resizeMethod; public void setProp(const facebook::react::PropsParserContext& context, facebook::react::RawPropsPropNameHash hash, const char* propName, const facebook::react::RawValue& value); } diff --git a/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api index f6ba681cc2a7..a0e1c10862b6 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api @@ -1726,7 +1726,7 @@ class facebook::react::ImageProps : public facebook::react::HostPlatformViewProp public facebook::react::ImageSource loadingIndicatorSource; public facebook::react::ImageSources sources; public facebook::react::SharedColor overlayColor; - public facebook::react::SharedColor tintColor; + public std::optional tintColor; public std::string resizeMethod; public void setProp(const facebook::react::PropsParserContext& context, facebook::react::RawPropsPropNameHash hash, const char* propName, const facebook::react::RawValue& value); }