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";