diff --git a/packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponent.js b/packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponent.js index aa4f79b921d..8af9904c233 100644 --- a/packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponent.js +++ b/packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponent.js @@ -46,6 +46,9 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig = }, decelerationRate: true, enableSyncOnScroll: true, // Fabric only. + experimental_boxShadow: { + process: require('../../StyleSheet/processBoxShadow').default, + }, disableIntervalMomentum: true, maintainVisibleContentPosition: true, pagingEnabled: true, diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 380e888c35b..d8a150dcec5 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -7190,11 +7190,14 @@ public class com/facebook/react/views/scroll/ReactScrollViewManager : com/facebo public synthetic fun scrollTo (Ljava/lang/Object;Lcom/facebook/react/views/scroll/ReactScrollViewCommandHelper$ScrollToCommandData;)V public fun scrollToEnd (Lcom/facebook/react/views/scroll/ReactScrollView;Lcom/facebook/react/views/scroll/ReactScrollViewCommandHelper$ScrollToEndCommandData;)V public synthetic fun scrollToEnd (Ljava/lang/Object;Lcom/facebook/react/views/scroll/ReactScrollViewCommandHelper$ScrollToEndCommandData;)V + public synthetic fun setBackgroundColor (Landroid/view/View;I)V + public fun setBackgroundColor (Lcom/facebook/react/views/scroll/ReactScrollView;I)V public fun setBorderColor (Lcom/facebook/react/views/scroll/ReactScrollView;ILjava/lang/Integer;)V public fun setBorderRadius (Lcom/facebook/react/views/scroll/ReactScrollView;IF)V public fun setBorderStyle (Lcom/facebook/react/views/scroll/ReactScrollView;Ljava/lang/String;)V public fun setBorderWidth (Lcom/facebook/react/views/scroll/ReactScrollView;IF)V public fun setBottomFillColor (Lcom/facebook/react/views/scroll/ReactScrollView;I)V + public fun setBoxShadow (Lcom/facebook/react/views/scroll/ReactScrollView;Lcom/facebook/react/bridge/ReadableArray;)V public fun setContentOffset (Lcom/facebook/react/views/scroll/ReactScrollView;Lcom/facebook/react/bridge/ReadableMap;)V public fun setDecelerationRate (Lcom/facebook/react/views/scroll/ReactScrollView;F)V public fun setDisableIntervalMomentum (Lcom/facebook/react/views/scroll/ReactScrollView;Z)V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java index ca3c4b88043..bca1e6a4907 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java @@ -39,6 +39,8 @@ import com.facebook.react.animated.NativeAnimatedModule; import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.common.ReactConstants; +import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags; +import com.facebook.react.uimanager.BackgroundStyleApplicator; import com.facebook.react.uimanager.MeasureSpecAssertions; import com.facebook.react.uimanager.PixelUtil; import com.facebook.react.uimanager.PointerEvents; @@ -48,6 +50,7 @@ import com.facebook.react.uimanager.ReactOverflowViewWithInset; import com.facebook.react.uimanager.StateWrapper; import com.facebook.react.uimanager.ViewProps; import com.facebook.react.uimanager.events.NativeGestureUtil; +import com.facebook.react.uimanager.style.Overflow; import com.facebook.react.views.scroll.ReactScrollViewHelper.HasFlingAnimator; import com.facebook.react.views.scroll.ReactScrollViewHelper.HasScrollEventThrottle; import com.facebook.react.views.scroll.ReactScrollViewHelper.HasScrollState; @@ -90,7 +93,7 @@ public class ReactScrollView extends ScrollView private boolean mActivelyScrolling; private @Nullable Rect mClippingRect; - private @Nullable String mOverflow = ViewProps.HIDDEN; + private Overflow mOverflow = Overflow.SCROLL; private boolean mDragging; private boolean mPagingEnabled = false; private @Nullable Runnable mPostTouchRunnable; @@ -262,7 +265,7 @@ public class ReactScrollView extends ScrollView } public void setOverflow(@Nullable String overflow) { - mOverflow = overflow; + mOverflow = overflow == null ? Overflow.SCROLL : Overflow.fromString(overflow); mReactBackgroundManager.setOverflow(overflow == null ? ViewProps.SCROLL : overflow); } @@ -282,7 +285,16 @@ public class ReactScrollView extends ScrollView @Override public @Nullable String getOverflow() { - return mOverflow; + switch (mOverflow) { + case HIDDEN: + return "hidden"; + case SCROLL: + return "scroll"; + case VISIBLE: + return "visible"; + } + + return null; } @Override @@ -648,7 +660,13 @@ public class ReactScrollView extends ScrollView @Override public void onDraw(Canvas canvas) { - mReactBackgroundManager.maybeClipToPaddingBox(canvas); + if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) { + if (mOverflow != Overflow.VISIBLE) { + BackgroundStyleApplicator.clipToPaddingBox(this, canvas); + } + } else { + mReactBackgroundManager.maybeClipToPaddingBox(canvas); + } super.onDraw(canvas); } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java index 84bbd6907fd..aff035e2b45 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java @@ -9,6 +9,7 @@ package com.facebook.react.views.scroll; import android.graphics.Color; import android.view.View; +import androidx.annotation.ColorInt; import androidx.annotation.Nullable; import androidx.core.view.ViewCompat; import com.facebook.infer.annotation.Nullsafe; @@ -16,7 +17,11 @@ import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.RetryableMountingLayerException; import com.facebook.react.common.MapBuilder; +import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags; import com.facebook.react.module.annotations.ReactModule; +import com.facebook.react.uimanager.BackgroundStyleApplicator; +import com.facebook.react.uimanager.LengthPercentage; +import com.facebook.react.uimanager.LengthPercentageType; import com.facebook.react.uimanager.PixelUtil; import com.facebook.react.uimanager.PointerEvents; import com.facebook.react.uimanager.ReactClippingViewGroupHelper; @@ -28,6 +33,9 @@ import com.facebook.react.uimanager.ViewGroupManager; import com.facebook.react.uimanager.ViewProps; import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.annotations.ReactPropGroup; +import com.facebook.react.uimanager.style.BorderRadiusProp; +import com.facebook.react.uimanager.style.BorderStyle; +import com.facebook.react.uimanager.style.LogicalEdge; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -237,20 +245,37 @@ public class ReactScrollViewManager extends ViewGroupManager }, defaultFloat = Float.NaN) public void setBorderRadius(ReactScrollView view, int index, float borderRadius) { - if (!Float.isNaN(borderRadius)) { - borderRadius = PixelUtil.toPixelFromDIP(borderRadius); - } - - if (index == 0) { - view.setBorderRadius(borderRadius); + if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) { + @Nullable + LengthPercentage radius = + Float.isNaN(borderRadius) + ? null + : new LengthPercentage( + PixelUtil.toPixelFromDIP(borderRadius), LengthPercentageType.POINT); + BackgroundStyleApplicator.setBorderRadius(view, BorderRadiusProp.values()[index], radius); } else { - view.setBorderRadius(borderRadius, index - 1); + if (!Float.isNaN(borderRadius)) { + borderRadius = PixelUtil.toPixelFromDIP(borderRadius); + } + + if (index == 0) { + view.setBorderRadius(borderRadius); + } else { + view.setBorderRadius(borderRadius, index - 1); + } } } @ReactProp(name = "borderStyle") public void setBorderStyle(ReactScrollView view, @Nullable String borderStyle) { - view.setBorderStyle(borderStyle); + if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) { + @Nullable + BorderStyle parsedBorderStyle = + borderStyle == null ? null : BorderStyle.fromString(borderStyle); + BackgroundStyleApplicator.setBorderStyle(view, parsedBorderStyle); + } else { + view.setBorderStyle(borderStyle); + } } @ReactPropGroup( @@ -263,10 +288,15 @@ public class ReactScrollViewManager extends ViewGroupManager }, defaultFloat = Float.NaN) public void setBorderWidth(ReactScrollView view, int index, float width) { - if (!Float.isNaN(width)) { - width = PixelUtil.toPixelFromDIP(width); + if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) { + BackgroundStyleApplicator.setBorderWidth(view, LogicalEdge.values()[index], width); + } else { + if (!Float.isNaN(width)) { + width = PixelUtil.toPixelFromDIP(width); + } + + view.setBorderWidth(SPACING_TYPES[index], width); } - view.setBorderWidth(SPACING_TYPES[index], width); } @ReactPropGroup( @@ -279,7 +309,11 @@ public class ReactScrollViewManager extends ViewGroupManager }, customType = "Color") public void setBorderColor(ReactScrollView view, int index, @Nullable Integer color) { - view.setBorderColor(SPACING_TYPES[index], color); + if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) { + BackgroundStyleApplicator.setBorderColor(view, LogicalEdge.ALL, color); + } else { + view.setBorderColor(SPACING_TYPES[index], color); + } } @ReactProp(name = "overflow") @@ -339,6 +373,22 @@ public class ReactScrollViewManager extends ViewGroupManager } } + @ReactProp(name = ViewProps.BOX_SHADOW, customType = "BoxShadow") + public void setBoxShadow(ReactScrollView view, ReadableArray shadows) { + if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) { + BackgroundStyleApplicator.setBoxShadow(view, shadows); + } + } + + @Override + public void setBackgroundColor(ReactScrollView view, @ColorInt int backgroundColor) { + if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) { + BackgroundStyleApplicator.setBackgroundColor(view, backgroundColor); + } else { + super.setBackgroundColor(view, backgroundColor); + } + } + @Override public @Nullable Object updateState( ReactScrollView view, ReactStylesDiffMap props, StateWrapper stateWrapper) {