Skip to content

Commit dfed2d9

Browse files
authored
Fix shadowColor and outline prop defaults in BaseViewManagerDelegate
## Summary: `BaseViewManagerDelegate` resets three props to values that don't match the `@ReactProp` defaults in `BaseViewManager` when they're removed: | Prop | `BaseViewManager` default | `BaseViewManagerDelegate` | | --- | --- | --- | | `shadowColor` | `Color.BLACK` | `0` | | `outlineOffset` | `0f` | `YogaConstants.UNDEFINED` | | `outlineWidth` | `0f` | `YogaConstants.UNDEFINED` | This affects every component whose view manager uses a codegen delegate (e.g. `Switch`, `Modal`, `RefreshControl`, and third-party Fabric components), but not `View`. Removing `shadowColor` from a view with `elevation` makes the shadow disappear instead of going back to black, and removing `outlineOffset` makes the outline disappear instead of drawing it with no offset. This makes the delegate use the same defaults as `BaseViewManager`. ## Changelog: [ANDROID] [FIXED] - Fix `shadowColor`, `outlineOffset` and `outlineWidth` not resetting to their defaults on components with a codegen view manager delegate ## Test Plan: Added `setShadowColorResetsToBlack`, `setOutlineOffsetResetsToZero` and `setOutlineWidthResetsToZero` to `BaseViewManagerDelegateTest`. They pass with this change and fail without it (`0` instead of `-16777216`, `NaNf` instead of `0.0f`). ``` ./gradlew :packages:react-native:ReactAndroid:testDebugUnitTest --tests "com.facebook.react.uimanager.BaseViewManagerDelegateTest" ``` Also checked in RNTester on an OPPO K12x 5G (CPH2667, Android 16) with a `View` and a `Switch` side by side, each with `elevation` + `shadowColor: 'red'` and `outlineWidth` + `outlineOffset: 8`, then removing `shadowColor` and `outlineOffset`: - Before: `View` resets correctly; on `Switch` the shadow and the outline both disappear. - After: `Switch` matches `View` (black shadow, outline with no offset). | Before | After | | --- | --- | | <img width="360" alt="Before" src="https://github.com/user-attachments/assets/94029d71-1786-45b1-bbcf-616aafcdd5ac" /> | <img width="360" alt="After" src="https://github.com/user-attachments/assets/014a6285-6dc4-44f4-94e7-cb9a9a54b285" /> | 🤖 Generated with [Claude Code](https://claude.com/claude-code) Differential Revision: D127789219 Pull Request resolved: #59423
1 parent 3cee68f commit dfed2d9

2 files changed

Lines changed: 29 additions & 9 deletions

File tree

‎packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerDelegate.kt‎

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
package com.facebook.react.uimanager
99

10+
import android.graphics.Color
1011
import android.view.View
1112
import com.facebook.react.bridge.ColorPropConverter
1213
import com.facebook.react.bridge.Dynamic
@@ -89,7 +90,10 @@ public abstract class BaseViewManagerDelegate<
8990
ViewProps.MIX_BLEND_MODE -> mViewManager.setMixBlendMode(view, value as String?)
9091

9192
ViewProps.SHADOW_COLOR ->
92-
mViewManager.setShadowColor(view, ColorPropConverter.getColor(value, view.context, 0))
93+
mViewManager.setShadowColor(
94+
view,
95+
ColorPropConverter.getColor(value, view.context, Color.BLACK),
96+
)
9397

9498
ViewProps.IMPORTANT_FOR_ACCESSIBILITY ->
9599
mViewManager.setImportantForAccessibility(view, value as String?)
@@ -113,18 +117,12 @@ public abstract class BaseViewManagerDelegate<
113117
)
114118

115119
ViewProps.OUTLINE_OFFSET ->
116-
mViewManager.setOutlineOffset(
117-
view,
118-
(value as Double?)?.toFloat() ?: YogaConstants.UNDEFINED,
119-
)
120+
mViewManager.setOutlineOffset(view, (value as Double?)?.toFloat() ?: 0.0f)
120121

121122
ViewProps.OUTLINE_STYLE -> mViewManager.setOutlineStyle(view, value as String?)
122123

123124
ViewProps.OUTLINE_WIDTH ->
124-
mViewManager.setOutlineWidth(
125-
view,
126-
(value as Double?)?.toFloat() ?: YogaConstants.UNDEFINED,
127-
)
125+
mViewManager.setOutlineWidth(view, (value as Double?)?.toFloat() ?: 0.0f)
128126

129127
ViewProps.RENDER_TO_HARDWARE_TEXTURE ->
130128
mViewManager.setRenderToHardwareTexture(view, value as Boolean? ?: false)

‎packages/react-native/ReactAndroid/src/test/java/com/facebook/react/uimanager/BaseViewManagerDelegateTest.java‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import static org.mockito.Mockito.mock;
1111
import static org.mockito.Mockito.verify;
1212

13+
import android.graphics.Color;
1314
import com.facebook.react.bridge.ReactApplicationContext;
1415
import com.facebook.react.bridge.ReactTestHelper;
1516
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags;
@@ -63,4 +64,25 @@ public void setOutlineColorPreservesNull() {
6364

6465
verify(viewManager).setOutlineColor(view, null);
6566
}
67+
68+
@Test
69+
public void setShadowColorResetsToBlack() {
70+
delegate.setProperty(view, ViewProps.SHADOW_COLOR, null);
71+
72+
verify(viewManager).setShadowColor(view, Color.BLACK);
73+
}
74+
75+
@Test
76+
public void setOutlineOffsetResetsToZero() {
77+
delegate.setProperty(view, ViewProps.OUTLINE_OFFSET, null);
78+
79+
verify(viewManager).setOutlineOffset(view, 0f);
80+
}
81+
82+
@Test
83+
public void setOutlineWidthResetsToZero() {
84+
delegate.setProperty(view, ViewProps.OUTLINE_WIDTH, null);
85+
86+
verify(viewManager).setOutlineWidth(view, 0f);
87+
}
6688
}

0 commit comments

Comments
 (0)