From da7c4aebe1c1a7ba11fac89b6512a76e230ccfb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Guzm=C3=A1n?= Date: Thu, 24 Oct 2024 23:39:48 +0200 Subject: [PATCH 1/6] feat(view): border style none wip --- .../uimanager/BackgroundStyleApplicator.kt | 9 +++++++++ .../uimanager/drawable/BorderDrawable.kt | 20 +++++++++++++++++++ .../drawable/CSSBackgroundDrawable.java | 20 +++++++++++++++++++ .../react/uimanager/style/BorderStyle.kt | 5 +++++ .../react/views/view/ReactViewManager.kt | 1 + .../rn-tester/js/examples/View/ViewExample.js | 18 +++++++++++++++++ 6 files changed, 73 insertions(+) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BackgroundStyleApplicator.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BackgroundStyleApplicator.kt index a4cd613b6dbd98..493269dc961a53 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BackgroundStyleApplicator.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BackgroundStyleApplicator.kt @@ -17,6 +17,7 @@ import android.os.Build import android.view.View import android.widget.ImageView import androidx.annotation.ColorInt +import com.facebook.common.logging.FLog import com.facebook.react.bridge.ReadableArray import com.facebook.react.common.annotations.UnstableReactNativeAPI import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags @@ -118,6 +119,8 @@ public object BackgroundStyleApplicator { @JvmStatic public fun getBorderWidth(view: View, edge: LogicalEdge): Float? { + FLog.w("ReactNative", "getBorderWidth") + return if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) { val width = getBorder(view)?.borderWidth?.getRaw(edge.toSpacingType()) if (width == null || width.isNaN()) null else width.pxToDp() @@ -203,9 +206,13 @@ public object BackgroundStyleApplicator { @JvmStatic public fun setBorderStyle(view: View, borderStyle: BorderStyle?): Unit { + FLog.w("ReactNative", "setBorderStyle in BackgroundStyleApplicator $borderStyle") + if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) { + FLog.w("ReactNative", "enableNewBackgroundAndBorderDrawables enabled") ensureBorderDrawable(view).borderStyle = borderStyle } else { + FLog.w("ReactNative", "enableNewBackgroundAndBorderDrawables disabled") ensureCSSBackground(view).borderStyle = borderStyle } } @@ -474,6 +481,8 @@ public object BackgroundStyleApplicator { view.background = compositeBackgroundDrawable.withNewBorder(border) } + FLog.w("ReactNative", "ensureBorderDrawable $border") + return border } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BorderDrawable.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BorderDrawable.kt index a6c331df7d3380..e34526ebd20ef3 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BorderDrawable.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BorderDrawable.kt @@ -22,6 +22,7 @@ import android.graphics.RectF import android.graphics.Region import android.graphics.drawable.Drawable import android.os.Build +import com.facebook.common.logging.FLog import com.facebook.react.uimanager.FloatUtil.floatsEqual import com.facebook.react.uimanager.LengthPercentage import com.facebook.react.uimanager.PixelUtil @@ -209,6 +210,8 @@ internal class BorderDrawable( } fun setBorderStyle(style: String?) { + FLog.w("ReactNative", "setBorderStyle") + val borderStyle = if (style == null) null else BorderStyle.valueOf(style.uppercase()) this.borderStyle = borderStyle needUpdatePath = true @@ -233,6 +236,8 @@ internal class BorderDrawable( } private fun drawRectangularBorders(canvas: Canvas) { + FLog.w("ReactNative", "drawRectangularBorders") + val borderWidth = computeBorderInsets() val borderLeft = borderWidth.left.roundToInt() val borderTop = borderWidth.top.roundToInt() @@ -547,6 +552,10 @@ internal class BorderDrawable( /** For rounded borders we use default "borderWidth" property. */ private fun getFullBorderWidth(): Float { + if (this.borderStyle == BorderStyle.NONE) { + return 0f + } + val borderWidth = this.borderWidth?.getRaw(Spacing.ALL) ?: Float.NaN return if (!borderWidth.isNaN()) borderWidth else 0f } @@ -570,6 +579,7 @@ internal class BorderDrawable( private fun getPathEffect(style: BorderStyle, borderWidth: Float): PathEffect? { return when (style) { + BorderStyle.NONE, BorderStyle.SOLID -> null BorderStyle.DASHED -> DashPathEffect( @@ -650,12 +660,22 @@ internal class BorderDrawable( } private fun updatePath() { + FLog.w("ReactNative", "Updating Path with border style: $borderStyle") + if (!needUpdatePath) { return } needUpdatePath = false + FLog.w("ReactNative", "Updating Path with border style: $borderStyle") + + // if borderStyle is none, we don't need to draw anything + if (this.borderStyle == BorderStyle.NONE) { + FLog.w("ReactNative", "Skipping drawing border as borderStyle is none") + return + } + // Path innerClipPathForBorderRadius = innerClipPathForBorderRadius ?: Path() outerClipPathForBorderRadius = outerClipPathForBorderRadius ?: Path() diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CSSBackgroundDrawable.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CSSBackgroundDrawable.java index 506b9c89304209..2b2386dea4187e 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CSSBackgroundDrawable.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CSSBackgroundDrawable.java @@ -14,6 +14,7 @@ import android.graphics.ColorFilter; import android.graphics.ComposeShader; import android.graphics.DashPathEffect; +import com.facebook.common.logging.FLog; import android.graphics.Outline; import android.graphics.Paint; import android.graphics.Path; @@ -75,6 +76,9 @@ public class CSSBackgroundDrawable extends Drawable { private static @Nullable PathEffect getPathEffect(BorderStyle style, float borderWidth) { switch (style) { + case NONE: + return null; + case SOLID: return null; @@ -625,6 +629,12 @@ private void updatePath() { final RectF borderWidth = getDirectionAwareBorderInsets(); + FLog.w( + "ReactNative", + "updatePathForBorderRadius: borderWidth: %s, borderRadius: %s", + borderWidth, + mBorderRadius); + int colorLeft = getBorderColor(Spacing.LEFT); int colorTop = getBorderColor(Spacing.TOP); int colorRight = getBorderColor(Spacing.RIGHT); @@ -1044,6 +1054,15 @@ private static void getEllipseIntersectionWithLine( } public float getBorderWidthOrDefaultTo(final float defaultValue, final int spacingType) { + @Nullable BorderStyle borderStyle = getBorderStyle(); + + FLog.w("ReactNative", "getBorderWidthOrDefaultTo called in CSSBackgroundDrawable with " + borderStyle); + + // THIS IS WORKING NOW!! We gotta clean up non needed places and duplicate the logic in the other drawables + if (borderStyle == BorderStyle.NONE) { + return defaultValue; + } + @Nullable Float width = getBorderWidth(spacingType); if (width == null) { return defaultValue; @@ -1068,6 +1087,7 @@ public float getBorderWidthOrDefaultTo(final float defaultValue, final int spaci /** Set type of border */ private void updatePathEffect() { + FLog.w("ReactNative", "updatePathEffect called in CSSBackgroundDrawable with " + mBorderStyle); // Used for rounded border and rounded background PathEffect mPathEffectForBorderStyle = mBorderStyle != null ? getPathEffect(mBorderStyle, getFullBorderWidth()) : null; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderStyle.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderStyle.kt index c23030b3fc9000..81955e98385add 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderStyle.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderStyle.kt @@ -7,7 +7,10 @@ package com.facebook.react.uimanager.style +import com.facebook.common.logging.FLog; + public enum class BorderStyle { + NONE, SOLID, DASHED, DOTTED; @@ -15,7 +18,9 @@ public enum class BorderStyle { public companion object { @JvmStatic public fun fromString(borderStyle: String): BorderStyle? { + FLog.w("ReactNative", "parsing border style: $borderStyle") return when (borderStyle.lowercase()) { + "none" -> NONE "solid" -> SOLID "dashed" -> DASHED "dotted" -> DOTTED diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.kt index 9c87b54b06c579..35af3086484628 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.kt @@ -172,6 +172,7 @@ public open class ReactViewManager : ReactClippingViewManager() @ReactProp(name = "borderStyle") public open fun setBorderStyle(view: ReactViewGroup, borderStyle: String?) { + FLog.w("ReactNative", "parsing border style in ReactViewManager: $borderStyle") val parsedBorderStyle = if (borderStyle == null) null else BorderStyle.fromString(borderStyle) BackgroundStyleApplicator.setBorderStyle(view, parsedBorderStyle) } diff --git a/packages/rn-tester/js/examples/View/ViewExample.js b/packages/rn-tester/js/examples/View/ViewExample.js index f25662a3f402a9..7a1732aa91adb5 100644 --- a/packages/rn-tester/js/examples/View/ViewExample.js +++ b/packages/rn-tester/js/examples/View/ViewExample.js @@ -62,6 +62,24 @@ class ViewBorderStyleExample extends React.Component< Dotted border style + + + None border style + + ); From 7f3ab9b931f5293e438fdbf832931a72b0bb5a7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Guzm=C3=A1n?= Date: Fri, 25 Oct 2024 22:13:35 +0200 Subject: [PATCH 2/6] feat(border): making border style none work in css background drawable --- .../uimanager/drawable/BorderDrawable.kt | 26 ++++------- .../drawable/CSSBackgroundDrawable.java | 23 +++------- .../react/uimanager/style/BorderStyle.kt | 3 -- .../rn-tester/js/examples/View/ViewExample.js | 46 +++++++++++-------- 4 files changed, 42 insertions(+), 56 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BorderDrawable.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BorderDrawable.kt index e34526ebd20ef3..9bbe7af392ab01 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BorderDrawable.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BorderDrawable.kt @@ -168,6 +168,14 @@ internal class BorderDrawable( } override fun draw(canvas: Canvas) { + FLog.w("ReactNative", "draw called") + + if (this.borderStyle == BorderStyle.NONE) { + FLog.w("ReactNative", "draw called with BorderStyle.NONE") + + return + } + updatePathEffect() computedBorderColors = borderColors?.resolve(layoutDirection, context) ?: computedBorderColors if (borderRadius?.hasRoundedBorders() == true) { @@ -210,8 +218,6 @@ internal class BorderDrawable( } fun setBorderStyle(style: String?) { - FLog.w("ReactNative", "setBorderStyle") - val borderStyle = if (style == null) null else BorderStyle.valueOf(style.uppercase()) this.borderStyle = borderStyle needUpdatePath = true @@ -236,8 +242,6 @@ internal class BorderDrawable( } private fun drawRectangularBorders(canvas: Canvas) { - FLog.w("ReactNative", "drawRectangularBorders") - val borderWidth = computeBorderInsets() val borderLeft = borderWidth.left.roundToInt() val borderTop = borderWidth.top.roundToInt() @@ -552,10 +556,6 @@ internal class BorderDrawable( /** For rounded borders we use default "borderWidth" property. */ private fun getFullBorderWidth(): Float { - if (this.borderStyle == BorderStyle.NONE) { - return 0f - } - val borderWidth = this.borderWidth?.getRaw(Spacing.ALL) ?: Float.NaN return if (!borderWidth.isNaN()) borderWidth else 0f } @@ -660,22 +660,12 @@ internal class BorderDrawable( } private fun updatePath() { - FLog.w("ReactNative", "Updating Path with border style: $borderStyle") - if (!needUpdatePath) { return } needUpdatePath = false - FLog.w("ReactNative", "Updating Path with border style: $borderStyle") - - // if borderStyle is none, we don't need to draw anything - if (this.borderStyle == BorderStyle.NONE) { - FLog.w("ReactNative", "Skipping drawing border as borderStyle is none") - return - } - // Path innerClipPathForBorderRadius = innerClipPathForBorderRadius ?: Path() outerClipPathForBorderRadius = outerClipPathForBorderRadius ?: Path() diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CSSBackgroundDrawable.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CSSBackgroundDrawable.java index 2b2386dea4187e..fbf0f39ef94a2e 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CSSBackgroundDrawable.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CSSBackgroundDrawable.java @@ -14,7 +14,6 @@ import android.graphics.ColorFilter; import android.graphics.ComposeShader; import android.graphics.DashPathEffect; -import com.facebook.common.logging.FLog; import android.graphics.Outline; import android.graphics.Paint; import android.graphics.Path; @@ -629,12 +628,6 @@ private void updatePath() { final RectF borderWidth = getDirectionAwareBorderInsets(); - FLog.w( - "ReactNative", - "updatePathForBorderRadius: borderWidth: %s, borderRadius: %s", - borderWidth, - mBorderRadius); - int colorLeft = getBorderColor(Spacing.LEFT); int colorTop = getBorderColor(Spacing.TOP); int colorRight = getBorderColor(Spacing.RIGHT); @@ -1054,15 +1047,6 @@ private static void getEllipseIntersectionWithLine( } public float getBorderWidthOrDefaultTo(final float defaultValue, final int spacingType) { - @Nullable BorderStyle borderStyle = getBorderStyle(); - - FLog.w("ReactNative", "getBorderWidthOrDefaultTo called in CSSBackgroundDrawable with " + borderStyle); - - // THIS IS WORKING NOW!! We gotta clean up non needed places and duplicate the logic in the other drawables - if (borderStyle == BorderStyle.NONE) { - return defaultValue; - } - @Nullable Float width = getBorderWidth(spacingType); if (width == null) { return defaultValue; @@ -1087,7 +1071,6 @@ public float getBorderWidthOrDefaultTo(final float defaultValue, final int spaci /** Set type of border */ private void updatePathEffect() { - FLog.w("ReactNative", "updatePathEffect called in CSSBackgroundDrawable with " + mBorderStyle); // Used for rounded border and rounded background PathEffect mPathEffectForBorderStyle = mBorderStyle != null ? getPathEffect(mBorderStyle, getFullBorderWidth()) : null; @@ -1405,6 +1388,12 @@ public int getBorderColor(int position) { } public RectF getDirectionAwareBorderInsets() { + @Nullable BorderStyle borderStyle = getBorderStyle(); + + if (borderStyle == BorderStyle.NONE) { + return new RectF(0, 0, 0, 0); + } + final float borderWidth = getBorderWidthOrDefaultTo(0, Spacing.ALL); final float borderTopWidth = getBorderWidthOrDefaultTo(borderWidth, Spacing.TOP); final float borderBottomWidth = getBorderWidthOrDefaultTo(borderWidth, Spacing.BOTTOM); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderStyle.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderStyle.kt index 81955e98385add..cc86bcb89ca2e4 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderStyle.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderStyle.kt @@ -7,8 +7,6 @@ package com.facebook.react.uimanager.style -import com.facebook.common.logging.FLog; - public enum class BorderStyle { NONE, SOLID, @@ -18,7 +16,6 @@ public enum class BorderStyle { public companion object { @JvmStatic public fun fromString(borderStyle: String): BorderStyle? { - FLog.w("ReactNative", "parsing border style: $borderStyle") return when (borderStyle.lowercase()) { "none" -> NONE "solid" -> SOLID diff --git a/packages/rn-tester/js/examples/View/ViewExample.js b/packages/rn-tester/js/examples/View/ViewExample.js index 7a1732aa91adb5..ffb93325cd263f 100644 --- a/packages/rn-tester/js/examples/View/ViewExample.js +++ b/packages/rn-tester/js/examples/View/ViewExample.js @@ -51,6 +51,7 @@ class ViewBorderStyleExample extends React.Component< borderWidth: 1, borderRadius: 5, padding: 5, + backgroundColor: 'red', }, this.state.showBorder ? { @@ -62,24 +63,33 @@ class ViewBorderStyleExample extends React.Component< Dotted border style - - - None border style - - + {Platform.OS === 'android' ? ( + + + None border style + + + ) : null} ); From 87f08315c5aa11c0833a310ea34c4b4134fdaad5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Guzm=C3=A1n?= Date: Fri, 25 Oct 2024 22:30:39 +0200 Subject: [PATCH 3/6] refactor(border): cleaning up logs and reverting extra example styles --- .../react/uimanager/BackgroundStyleApplicator.kt | 9 --------- .../facebook/react/uimanager/drawable/BorderDrawable.kt | 5 ----- .../react/uimanager/drawable/CSSBackgroundDrawable.java | 2 -- .../com/facebook/react/uimanager/style/BorderStyle.kt | 2 +- .../com/facebook/react/views/view/ReactViewManager.kt | 1 - packages/rn-tester/js/examples/View/ViewExample.js | 9 +-------- 6 files changed, 2 insertions(+), 26 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BackgroundStyleApplicator.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BackgroundStyleApplicator.kt index 493269dc961a53..a4cd613b6dbd98 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BackgroundStyleApplicator.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BackgroundStyleApplicator.kt @@ -17,7 +17,6 @@ import android.os.Build import android.view.View import android.widget.ImageView import androidx.annotation.ColorInt -import com.facebook.common.logging.FLog import com.facebook.react.bridge.ReadableArray import com.facebook.react.common.annotations.UnstableReactNativeAPI import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags @@ -119,8 +118,6 @@ public object BackgroundStyleApplicator { @JvmStatic public fun getBorderWidth(view: View, edge: LogicalEdge): Float? { - FLog.w("ReactNative", "getBorderWidth") - return if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) { val width = getBorder(view)?.borderWidth?.getRaw(edge.toSpacingType()) if (width == null || width.isNaN()) null else width.pxToDp() @@ -206,13 +203,9 @@ public object BackgroundStyleApplicator { @JvmStatic public fun setBorderStyle(view: View, borderStyle: BorderStyle?): Unit { - FLog.w("ReactNative", "setBorderStyle in BackgroundStyleApplicator $borderStyle") - if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) { - FLog.w("ReactNative", "enableNewBackgroundAndBorderDrawables enabled") ensureBorderDrawable(view).borderStyle = borderStyle } else { - FLog.w("ReactNative", "enableNewBackgroundAndBorderDrawables disabled") ensureCSSBackground(view).borderStyle = borderStyle } } @@ -481,8 +474,6 @@ public object BackgroundStyleApplicator { view.background = compositeBackgroundDrawable.withNewBorder(border) } - FLog.w("ReactNative", "ensureBorderDrawable $border") - return border } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BorderDrawable.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BorderDrawable.kt index 9bbe7af392ab01..b1e6471da282c0 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BorderDrawable.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BorderDrawable.kt @@ -22,7 +22,6 @@ import android.graphics.RectF import android.graphics.Region import android.graphics.drawable.Drawable import android.os.Build -import com.facebook.common.logging.FLog import com.facebook.react.uimanager.FloatUtil.floatsEqual import com.facebook.react.uimanager.LengthPercentage import com.facebook.react.uimanager.PixelUtil @@ -168,11 +167,7 @@ internal class BorderDrawable( } override fun draw(canvas: Canvas) { - FLog.w("ReactNative", "draw called") - if (this.borderStyle == BorderStyle.NONE) { - FLog.w("ReactNative", "draw called with BorderStyle.NONE") - return } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CSSBackgroundDrawable.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CSSBackgroundDrawable.java index fbf0f39ef94a2e..7f6838e769a063 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CSSBackgroundDrawable.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CSSBackgroundDrawable.java @@ -76,8 +76,6 @@ public class CSSBackgroundDrawable extends Drawable { private static @Nullable PathEffect getPathEffect(BorderStyle style, float borderWidth) { switch (style) { case NONE: - return null; - case SOLID: return null; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderStyle.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderStyle.kt index cc86bcb89ca2e4..0fad52eec50ef9 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderStyle.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderStyle.kt @@ -17,7 +17,7 @@ public enum class BorderStyle { @JvmStatic public fun fromString(borderStyle: String): BorderStyle? { return when (borderStyle.lowercase()) { - "none" -> NONE + "none" -> NONE "solid" -> SOLID "dashed" -> DASHED "dotted" -> DOTTED diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.kt index 35af3086484628..9c87b54b06c579 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.kt @@ -172,7 +172,6 @@ public open class ReactViewManager : ReactClippingViewManager() @ReactProp(name = "borderStyle") public open fun setBorderStyle(view: ReactViewGroup, borderStyle: String?) { - FLog.w("ReactNative", "parsing border style in ReactViewManager: $borderStyle") val parsedBorderStyle = if (borderStyle == null) null else BorderStyle.fromString(borderStyle) BackgroundStyleApplicator.setBorderStyle(view, parsedBorderStyle) } diff --git a/packages/rn-tester/js/examples/View/ViewExample.js b/packages/rn-tester/js/examples/View/ViewExample.js index ffb93325cd263f..b448475210cfe0 100644 --- a/packages/rn-tester/js/examples/View/ViewExample.js +++ b/packages/rn-tester/js/examples/View/ViewExample.js @@ -51,7 +51,6 @@ class ViewBorderStyleExample extends React.Component< borderWidth: 1, borderRadius: 5, padding: 5, - backgroundColor: 'red', }, this.state.showBorder ? { @@ -72,7 +71,6 @@ class ViewBorderStyleExample extends React.Component< borderWidth: 1, borderRadius: 5, padding: 5, - backgroundColor: 'red', }, this.state.showBorder ? { @@ -80,12 +78,7 @@ class ViewBorderStyleExample extends React.Component< } : null, ]}> - + None border style From d5e1ffc4dd21854496c4ca7d1d4783332a4c0f17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Guzm=C3=A1n?= Date: Sat, 26 Oct 2024 00:03:43 +0200 Subject: [PATCH 4/6] feat(text): adding new border style example --- .../js/examples/Text/TextExample.android.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/packages/rn-tester/js/examples/Text/TextExample.android.js b/packages/rn-tester/js/examples/Text/TextExample.android.js index 6daf107f26373d..d89275f24b84e5 100644 --- a/packages/rn-tester/js/examples/Text/TextExample.android.js +++ b/packages/rn-tester/js/examples/Text/TextExample.android.js @@ -16,6 +16,8 @@ import TextLegend from '../../components/TextLegend'; import TextAdjustsDynamicLayoutExample from './TextAdjustsDynamicLayoutExample'; import TextInlineViewsExample from './TextInlineViewsExample'; +import Platform from 'react-native/Libraries/Utilities/Platform.android'; + const TextInlineView = require('../../components/TextInlineView'); const React = require('react'); const { @@ -1092,6 +1094,23 @@ const examples = [ }}> Text with background AND borderWidth + {Platform.OS === 'android' ? ( + + Text with borderWidth, borderRadius but borderStyle set to "none" + + ) : null} ); }, From 3b125c63bd51ecaed673917697aa4b5f6bb78713 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Guzm=C3=A1n?= Date: Mon, 28 Oct 2024 23:33:11 +0100 Subject: [PATCH 5/6] feat(styles): setting border style in yoga and applying logic to for --- .../components/view/YogaStylableProps.cpp | 7 ++++ .../renderer/components/view/conversions.h | 37 ++++++++++++++++ .../renderer/components/view/primitives.h | 2 +- .../ReactCommon/yoga/yoga/YGEnums.cpp | 14 +++++++ .../ReactCommon/yoga/yoga/YGEnums.h | 7 ++++ .../ReactCommon/yoga/yoga/enums/BorderStyle.h | 42 +++++++++++++++++++ .../ReactCommon/yoga/yoga/style/Style.h | 13 ++++++ .../rn-tester/js/examples/View/ViewExample.js | 6 +-- 8 files changed, 124 insertions(+), 4 deletions(-) create mode 100644 packages/react-native/ReactCommon/yoga/yoga/enums/BorderStyle.h diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp index 4f36bf6bb813e1..cc33c46b8a39e2 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp @@ -540,6 +540,13 @@ YogaStylableProps::YogaStylableProps( sourceProps.yogaStyle.boxSizing(), yogaStyle.boxSizing())); + yogaStyle.setBorderStyle(convertRawProp( + context, + rawProps, + "borderStyle", + sourceProps.yogaStyle.borderStyle(), + yogaStyle.borderStyle())); + convertRawPropAliases(context, sourceProps, rawProps); }; diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h b/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h index 58e04bba088aae..bfeec481af7137 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h +++ b/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h @@ -446,6 +446,35 @@ inline void fromRawValue( LOG(ERROR) << "Could not parse yoga::Display: " << stringValue; } +inline void fromRawValue( + const PropsParserContext& context, + const RawValue& value, + yoga::BorderStyle& result) { + result = yoga::BorderStyle::Solid; + react_native_expect(value.hasType()); + if (!value.hasType()) { + return; + } + auto stringValue = (std::string)value; + if (stringValue == "none") { + result = yoga::BorderStyle::None; + return; + } + if (stringValue == "solid") { + result = yoga::BorderStyle::Solid; + return; + } + if (stringValue == "dotted") { + result = yoga::BorderStyle::Dotted; + return; + } + if (stringValue == "dashed") { + result = yoga::BorderStyle::Dashed; + return; + } + LOG(ERROR) << "Could not parse yoga::BorderStyle: " << stringValue; +} + inline void fromRawValue( const PropsParserContext& context, const RawValue& value, @@ -775,6 +804,10 @@ inline void fromRawValue( return; } auto stringValue = (std::string)value; + if (stringValue == "none") { + result = BorderStyle::None; + return; + } if (stringValue == "solid") { result = BorderStyle::Solid; return; @@ -1369,6 +1402,10 @@ inline std::string toString(const yoga::Display& value) { return YGDisplayToString(yoga::unscopedEnum(value)); } +inline std::string toString(const yoga::BorderStyle& value) { + return YGBorderStyleToString(yoga::unscopedEnum(value)); +} + inline std::string toString(const yoga::Style::Length& length) { switch (length.unit()) { case yoga::Unit::Undefined: diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/primitives.h b/packages/react-native/ReactCommon/react/renderer/components/view/primitives.h index feb396a0535584..a61c056b917f68 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/primitives.h +++ b/packages/react-native/ReactCommon/react/renderer/components/view/primitives.h @@ -90,7 +90,7 @@ enum class BackfaceVisibility : uint8_t { Auto, Visible, Hidden }; enum class BorderCurve : uint8_t { Circular, Continuous }; -enum class BorderStyle : uint8_t { Solid, Dotted, Dashed }; +enum class BorderStyle : uint8_t { None, Solid, Dotted, Dashed }; enum class OutlineStyle : uint8_t { Solid, Dotted, Dashed }; diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp index cddd5d5849ff83..2322b3798abb2f 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp @@ -260,3 +260,17 @@ const char* YGWrapToString(const YGWrap value) { } return "unknown"; } + +const char* YGBorderStyleToString(const YGBorderStyle value) { + switch (value) { + case YGBorderStyleNone: + return "none"; + case YGBorderStyleSolid: + return "solid"; + case YGBorderStyleDotted: + return "dotted"; + case YGBorderStyleDashed: + return "dashed"; + } + return "unknown"; +} diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h index 27f0426f450ec4..a500bf45a3929a 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h +++ b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h @@ -139,4 +139,11 @@ YG_ENUM_DECL( YGWrapWrap, YGWrapWrapReverse) +YG_ENUM_DECL( + YGBorderStyle, + YGBorderStyleNone, + YGBorderStyleSolid, + YGBorderStyleDotted, + YGBorderStyleDashed) + YG_EXTERN_C_END diff --git a/packages/react-native/ReactCommon/yoga/yoga/enums/BorderStyle.h b/packages/react-native/ReactCommon/yoga/yoga/enums/BorderStyle.h new file mode 100644 index 00000000000000..3b2fec387e6df1 --- /dev/null +++ b/packages/react-native/ReactCommon/yoga/yoga/enums/BorderStyle.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// @generated by enums.py +// clang-format off +#pragma once + +#include +#include +#include + +namespace facebook::yoga { + +enum class BorderStyle : uint8_t { + None = YGBorderStyleNone, + Solid = YGBorderStyleSolid, + Dotted = YGBorderStyleDotted, + Dashed = YGBorderStyleDashed, +}; + +template <> +constexpr int32_t ordinalCount() { + return 4; +} + +constexpr BorderStyle scopedEnum(YGBorderStyle unscoped) { + return static_cast(unscoped); +} + +constexpr YGBorderStyle unscopedEnum(BorderStyle scoped) { + return static_cast(scoped); +} + +inline const char* toString(BorderStyle e) { + return YGBorderStyleToString(unscopedEnum(e)); +} + +} // namespace facebook::yoga diff --git a/packages/react-native/ReactCommon/yoga/yoga/style/Style.h b/packages/react-native/ReactCommon/yoga/yoga/style/Style.h index 73203e6cca3c7c..2c96bd69a23c28 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/style/Style.h +++ b/packages/react-native/ReactCommon/yoga/yoga/style/Style.h @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -250,6 +251,13 @@ class YG_EXPORT Style { boxSizing_ = value; } + BorderStyle borderStyle() const { + return borderStyle_; + } + void setBorderStyle(BorderStyle value) { + borderStyle_ = value; + } + bool horizontalInsetsDefined() const { return position_[yoga::to_underlying(Edge::Left)].isDefined() || position_[yoga::to_underlying(Edge::Right)].isDefined() || @@ -707,6 +715,10 @@ class YG_EXPORT Style { } Style::Length computeBorder(PhysicalEdge edge, Direction direction) const { + if (borderStyle_ == BorderStyle::None) { + return Style::Length{}; + } + switch (edge) { case PhysicalEdge::Left: return computeLeftEdge(border_, direction); @@ -734,6 +746,7 @@ class YG_EXPORT Style { Overflow overflow_ : bitCount() = Overflow::Visible; Display display_ : bitCount() = Display::Flex; BoxSizing boxSizing_ : bitCount() = BoxSizing::BorderBox; + BorderStyle borderStyle_ : bitCount() = BorderStyle::Solid; StyleValueHandle flex_{}; StyleValueHandle flexGrow_{}; diff --git a/packages/rn-tester/js/examples/View/ViewExample.js b/packages/rn-tester/js/examples/View/ViewExample.js index b448475210cfe0..44dcea8e263300 100644 --- a/packages/rn-tester/js/examples/View/ViewExample.js +++ b/packages/rn-tester/js/examples/View/ViewExample.js @@ -31,7 +31,7 @@ class ViewBorderStyleExample extends React.Component< Date: Mon, 28 Oct 2024 23:54:56 +0100 Subject: [PATCH 6/6] fix(ios): adding missing border style in ios enum --- .../Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm index 8b4b87996862e2..c8db4e550b40cd 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm @@ -731,6 +731,8 @@ static CALayerCornerCurve CornerCurveFromBorderCurve(BorderCurve borderCurve) static RCTBorderStyle RCTBorderStyleFromBorderStyle(BorderStyle borderStyle) { switch (borderStyle) { + case BorderStyle::None: + return RCTBorderStyleUnset; case BorderStyle::Solid: return RCTBorderStyleSolid; case BorderStyle::Dotted: