Enable box shadows for Image (#45693)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45693

This wires box shadow application for `ReactImageViewManager` to `BackgroundStyleApplicator` for setting shadows. This same logic will get copy-pasted to other view managers later up the stack (including Vito images, ScrollViews, etc, then eventually View), until we are able to consolidate to BaseViewManager.

Changelog: [Internal]

Reviewed By: rshest

Differential Revision: D60266016

fbshipit-source-id: eaa842f539ee1654ab719c7d341b4b748db7a15c
This commit is contained in:
Nick Gerleman
2024-07-29 20:02:55 -07:00
committed by Facebook GitHub Bot
parent 496e77b85c
commit 1c1c8335db
6 changed files with 34 additions and 0 deletions
@@ -113,6 +113,9 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig =
borderBottomRightRadius: true,
borderTopRightRadius: true,
loadingIndicatorSrc: true,
experimental_boxShadow: {
process: require('../StyleSheet/processBoxShadow').default,
},
},
}
: {
@@ -10,6 +10,8 @@
'use strict';
import processBoxShadow from '../StyleSheet/processBoxShadow';
const ReactNativeStyleAttributes = require('../Components/View/ReactNativeStyleAttributes');
const resolveAssetSource = require('../Image/resolveAssetSource');
const processColor = require('../StyleSheet/processColor').default;
@@ -193,6 +195,8 @@ function getProcessorForType(typeName: string): ?(nextProp: any) => any {
return processFilter;
case 'ImageSource':
return resolveAssetSource;
case 'BoxShadow':
return processBoxShadow;
}
return null;
}
@@ -4008,6 +4008,7 @@ public final class com/facebook/react/uimanager/BackgroundStyleApplicator {
public static final fun setBorderRadius (Landroid/view/View;Lcom/facebook/react/uimanager/style/BorderRadiusProp;Lcom/facebook/react/uimanager/LengthPercentage;)V
public static final fun setBorderStyle (Landroid/view/View;Lcom/facebook/react/uimanager/style/BorderStyle;)V
public static final fun setBorderWidth (Landroid/view/View;Lcom/facebook/react/uimanager/style/LogicalEdge;Ljava/lang/Float;)V
public static final fun setBoxShadow (Landroid/view/View;Lcom/facebook/react/bridge/ReadableArray;)V
public static final fun setBoxShadow (Landroid/view/View;Ljava/util/List;)V
}
@@ -5440,6 +5441,7 @@ public final class com/facebook/react/uimanager/ViewProps {
public static final field BORDER_WIDTH Ljava/lang/String;
public static final field BOTTOM Ljava/lang/String;
public static final field BOX_NONE Ljava/lang/String;
public static final field BOX_SHADOW Ljava/lang/String;
public static final field COLLAPSABLE Ljava/lang/String;
public static final field COLLAPSABLE_CHILDREN Ljava/lang/String;
public static final field COLOR Ljava/lang/String;
@@ -6515,6 +6517,7 @@ public final class com/facebook/react/views/image/ReactImageManager : com/facebo
public final fun setBorderColor (Lcom/facebook/react/views/image/ReactImageView;Ljava/lang/Integer;)V
public final fun setBorderRadius (Lcom/facebook/react/views/image/ReactImageView;IF)V
public final fun setBorderWidth (Lcom/facebook/react/views/image/ReactImageView;F)V
public final fun setBoxShadow (Lcom/facebook/react/views/image/ReactImageView;Lcom/facebook/react/bridge/ReadableArray;)V
public final fun setDefaultSource (Lcom/facebook/react/views/image/ReactImageView;Ljava/lang/String;)V
public final fun setFadeDuration (Lcom/facebook/react/views/image/ReactImageView;I)V
public final fun setHeaders (Lcom/facebook/react/views/image/ReactImageView;Lcom/facebook/react/bridge/ReadableMap;)V
@@ -10,9 +10,12 @@ package com.facebook.react.uimanager
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Rect
import android.os.Build
import android.view.View
import androidx.annotation.ColorInt
import androidx.annotation.RequiresApi
import com.facebook.common.logging.FLog
import com.facebook.react.bridge.ReadableArray
import com.facebook.react.common.annotations.UnstableReactNativeAPI
import com.facebook.react.uimanager.drawable.CSSBackgroundDrawable
import com.facebook.react.uimanager.drawable.CompositeBackgroundDrawable
@@ -121,6 +124,19 @@ public object BackgroundStyleApplicator {
view.background = ensureCompositeBackgroundDrawable(view).withNewShadows(shadowDrawables)
}
@JvmStatic
public fun setBoxShadow(view: View, shadows: ReadableArray): Unit {
if (Build.VERSION.SDK_INT < 31) {
FLog.w("BackgroundStyleApplicator", "\"boxShadow\" requires Android 12 or later")
} else {
val shadowStyles = mutableListOf<BoxShadow>()
for (i in 0..<shadows.size()) {
shadowStyles.add(checkNotNull(BoxShadow.parse(shadows.getMap(i))))
}
BackgroundStyleApplicator.setBoxShadow(view, shadowStyles)
}
}
@JvmStatic
public fun clipToPaddingBox(view: View, canvas: Canvas): Unit {
// The canvas may be scrolled, so we need to offset
@@ -135,6 +135,7 @@ public object ViewProps {
public const val BORDER_START_COLOR: String = "borderStartColor"
public const val BORDER_END_COLOR: String = "borderEndColor"
public const val ON_LAYOUT: String = "onLayout"
public const val BOX_SHADOW: String = "experimental_boxShadow"
public const val FILTER: String = "experimental_filter"
public const val MIX_BLEND_MODE: String = "experimental_mixBlendMode"
public const val TRANSFORM: String = "transform"
@@ -261,6 +261,13 @@ public constructor(
}
}
@ReactProp(name = ViewProps.BOX_SHADOW, customType = "BoxShadow")
public fun setBoxShadow(view: ReactImageView, shadows: ReadableArray): Unit {
if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) {
BackgroundStyleApplicator.setBoxShadow(view, shadows)
}
}
public override fun setBackgroundColor(
view: ReactImageView,
@ColorInt backgroundColor: Int