diff --git a/Libraries/StyleSheet/StyleSheetTypes.js b/Libraries/StyleSheet/StyleSheetTypes.js index b2d596a14df668..d92728984483dd 100644 --- a/Libraries/StyleSheet/StyleSheetTypes.js +++ b/Libraries/StyleSheet/StyleSheetTypes.js @@ -522,8 +522,9 @@ type ____TransformStyle_Internal = $ReadOnly<{| * Because they are dynamically generated, they may cause performance regressions. Static * shadow image asset may be a better way to go for optimal performance. * - * These properties are iOS only - for similar functionality on Android, use the [`elevation` - * property](docs/viewstyleproptypes.html#elevation). + * Shadow-related properties are not fully supported on Android. + * To add a drop shadow to a view use the [`elevation` property](docs/viewstyleproptypes.html#elevation) (Android 5.0+). + * To customize the color use the [`shadowColor` property](docs/shadow-props.html#shadowColor) (Android 9.0+). */ export type ____ShadowStyle_Internal = $ReadOnly<{| /** diff --git a/RNTester/js/examples/BoxShadow/BoxShadowExample.js b/RNTester/js/examples/BoxShadow/BoxShadowExample.js index 5801cf3f5ad4ae..429fb0873c504c 100644 --- a/RNTester/js/examples/BoxShadow/BoxShadowExample.js +++ b/RNTester/js/examples/BoxShadow/BoxShadowExample.js @@ -46,6 +46,29 @@ const styles = StyleSheet.create({ margin: 8, backgroundColor: 'red', }, + + elevation1: { + elevation: 1, + }, + elevation2: { + elevation: 3, + }, + elevation3: { + elevation: 10, + }, + shadowColor1: { + shadowColor: 'red', + }, + shadowColor2: { + shadowColor: 'blue', + }, + shadowColor3: { + shadowColor: '#00FF0080', + }, + border: { + borderWidth: 5, + borderColor: '#EEE', + }, }); exports.title = 'Box Shadow'; @@ -97,4 +120,75 @@ exports.examples = [ ); }, }, + + { + title: 'Basic elevation', + description: 'elevation: 1, 3, 6', + platform: 'android', + render() { + return ( + + + + + + ); + }, + }, + { + title: 'Fractional elevation', + description: 'elevation: 0.1, 0.5, 1.5', + platform: 'android', + render() { + return ( + + + + + + ); + }, + }, + { + title: 'Colored shadow', + description: "shadowColor: 'red', 'blue', '#00FF0080'", + platform: 'android', + render() { + return ( + + + + + + ); + }, + }, + { + title: 'Shaped shadow', + description: 'borderRadius: 50', + platform: 'android', + render() { + return ( + + + + + + ); + }, + }, + { + title: 'Borders', + description: 'borderWidth: 5', + platform: 'android', + render() { + return ( + + + + + + ); + }, + }, ]; diff --git a/RNTester/js/utils/RNTesterList.android.js b/RNTester/js/utils/RNTesterList.android.js index 66962af515439d..0e01adf9f0cb94 100644 --- a/RNTester/js/utils/RNTesterList.android.js +++ b/RNTester/js/utils/RNTesterList.android.js @@ -144,6 +144,10 @@ const APIExamples: Array = [ key: 'BorderExample', module: require('../examples/Border/BorderExample'), }, + { + key: 'BoxShadowExample', + module: require('../examples/BoxShadow/BoxShadowExample'), + }, { key: 'ClipboardExample', module: require('../examples/Clipboard/ClipboardExample'), diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java index ef39975d4936ba..2028bdb6082536 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java @@ -95,6 +95,15 @@ public void setElevation(@NonNull T view, float elevation) { ViewCompat.setElevation(view, PixelUtil.toPixelFromDIP(elevation)); } + @Override + @ReactProp(name = ViewProps.SHADOW_COLOR, defaultInt = Color.BLACK, customType = "Color") + public void setShadowColor(@NonNull T view, int shadowColor) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + view.setOutlineAmbientShadowColor(shadowColor); + view.setOutlineSpotShadowColor(shadowColor); + } + } + @Override @ReactProp(name = ViewProps.Z_INDEX) public void setZIndex(@NonNull T view, float zIndex) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerAdapter.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerAdapter.java index 6af559a15c90f2..c0e21dece66f2a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerAdapter.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerAdapter.java @@ -54,6 +54,9 @@ public void setBorderTopRightRadius(@NonNull T view, float borderRadius) {} @Override public void setElevation(@NonNull T view, float elevation) {} + @Override + public void setShadowColor(@NonNull T view, int shadowColor) {} + @Override public void setImportantForAccessibility( @NonNull T view, @Nullable String importantForAccessibility) {} diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerDelegate.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerDelegate.java index f430398bacf208..1598b578877b2f 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerDelegate.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerDelegate.java @@ -74,6 +74,10 @@ public void setProperty(T view, String propName, @Nullable Object value) { case ViewProps.ELEVATION: mViewManager.setElevation(view, value == null ? 0.0f : ((Double) value).floatValue()); break; + case ViewProps.SHADOW_COLOR: + mViewManager.setShadowColor( + view, value == null ? 0 : ColorPropConverter.getColor(value, view.getContext())); + break; case ViewProps.IMPORTANT_FOR_ACCESSIBILITY: mViewManager.setImportantForAccessibility(view, (String) value); break; diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerInterface.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerInterface.java index fb194e213699f2..5423eeedd91a71 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerInterface.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerInterface.java @@ -43,6 +43,8 @@ public interface BaseViewManagerInterface { void setElevation(T view, float elevation); + void setShadowColor(T view, int shadowColor); + void setImportantForAccessibility(T view, @Nullable String importantForAccessibility); void setNativeId(T view, @Nullable String nativeId); diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewProps.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewProps.java index fcb4d2bb4f15cc..ac780e8bb4f91b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewProps.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewProps.java @@ -140,6 +140,7 @@ public class ViewProps { public static final String TRANSFORM = "transform"; public static final String ELEVATION = "elevation"; + public static final String SHADOW_COLOR = "shadowColor"; public static final String Z_INDEX = "zIndex"; public static final String RENDER_TO_HARDWARE_TEXTURE = "renderToHardwareTextureAndroid"; public static final String ACCESSIBILITY_LABEL = "accessibilityLabel";