From 83c7643901dc75a3da3303fdcae0d809dc09eab7 Mon Sep 17 00:00:00 2001 From: Soe Lynn Date: Wed, 17 Apr 2024 09:31:51 -0700 Subject: [PATCH] Expose Gap Percentage to ReactNative (#44129) Summary: X-link: https://github.com/facebook/litho/pull/983 X-link: https://github.com/facebook/yoga/pull/1647 Expose the Gap Percent from Yoga to RN Layer Changelog: [Android][Breaking] Enable flex gap percentage value for RN. Differential Revision: D56160597 --- .../Libraries/StyleSheet/StyleSheetTypes.d.ts | 6 +- .../Libraries/StyleSheet/StyleSheetTypes.js | 6 +- .../__snapshots__/public-api-test.js.snap | 6 +- .../react-native/React/Views/RCTViewManager.m | 6 +- .../ReactAndroid/api/ReactAndroid.api | 12 +++- .../react/uimanager/LayoutShadowNode.java | 57 ++++++++++++++++--- .../react/uimanager/ReactShadowNode.java | 6 ++ .../react/uimanager/ReactShadowNodeImpl.java | 15 +++++ 8 files changed, 90 insertions(+), 24 deletions(-) diff --git a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts index f4a992563138..62c166db1b50 100644 --- a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts +++ b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts @@ -65,9 +65,9 @@ export interface FlexStyle { | 'row-reverse' | 'column-reverse' | undefined; - rowGap?: number | undefined; - gap?: number | undefined; - columnGap?: number | undefined; + rowGap?: number | string | undefined; + gap?: number | string | undefined; + columnGap?: number | string | undefined; flexGrow?: number | undefined; flexShrink?: number | undefined; flexWrap?: 'wrap' | 'nowrap' | 'wrap-reverse' | undefined; diff --git a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js index 59a7afc81d8c..f04a3643423b 100644 --- a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js +++ b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js @@ -644,9 +644,9 @@ type ____LayoutStyle_Internal = $ReadOnly<{ * between children may be larger than the gap value. * See https://developer.mozilla.org/en-US/docs/Web/CSS/gap for more details. */ - rowGap?: number, - columnGap?: number, - gap?: number, + rowGap?: number | string, + columnGap?: number | string, + gap?: number | string, }>; /** diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index 292fb1e85215..2894c7a2ff73 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -7584,9 +7584,9 @@ type ____LayoutStyle_Internal = $ReadOnly<{ aspectRatio?: number | string, zIndex?: number, direction?: \\"inherit\\" | \\"ltr\\" | \\"rtl\\", - rowGap?: number, - columnGap?: number, - gap?: number, + rowGap?: number | string, + columnGap?: number | string, + gap?: number | string, }>; export type ____ShadowStyle_InternalCore = $ReadOnly<{ shadowColor?: ____ColorValue_Internal, diff --git a/packages/react-native/React/Views/RCTViewManager.m b/packages/react-native/React/Views/RCTViewManager.m index 0a0126545bde..9e42eb3bdcd9 100644 --- a/packages/react-native/React/Views/RCTViewManager.m +++ b/packages/react-native/React/Views/RCTViewManager.m @@ -507,9 +507,9 @@ - (void)updateAccessibilityTraitsForRole:(RCTView *)view withDefaultView:(RCTVie RCT_EXPORT_SHADOW_PROPERTY(alignContent, YGAlign) RCT_EXPORT_SHADOW_PROPERTY(position, YGPositionType) RCT_EXPORT_SHADOW_PROPERTY(aspectRatio, float) -RCT_EXPORT_SHADOW_PROPERTY(rowGap, float) -RCT_EXPORT_SHADOW_PROPERTY(columnGap, float) -RCT_EXPORT_SHADOW_PROPERTY(gap, float) +RCT_EXPORT_SHADOW_PROPERTY(rowGap, YGValue) +RCT_EXPORT_SHADOW_PROPERTY(columnGap, YGValue) +RCT_EXPORT_SHADOW_PROPERTY(gap, YGValue) RCT_EXPORT_SHADOW_PROPERTY(overflow, YGOverflow) RCT_EXPORT_SHADOW_PROPERTY(display, YGDisplay) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 44ad742aa195..73a1b6e17cc1 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -4167,7 +4167,7 @@ public class com/facebook/react/uimanager/LayoutShadowNode : com/facebook/react/ public fun setAspectRatio (F)V public fun setBorderWidths (IF)V public fun setCollapsable (Z)V - public fun setColumnGap (F)V + public fun setColumnGap (Lcom/facebook/react/bridge/Dynamic;)V public fun setDisplay (Ljava/lang/String;)V public fun setFlex (F)V public fun setFlexBasis (Lcom/facebook/react/bridge/Dynamic;)V @@ -4175,7 +4175,7 @@ public class com/facebook/react/uimanager/LayoutShadowNode : com/facebook/react/ public fun setFlexGrow (F)V public fun setFlexShrink (F)V public fun setFlexWrap (Ljava/lang/String;)V - public fun setGap (F)V + public fun setGap (Lcom/facebook/react/bridge/Dynamic;)V public fun setHeight (Lcom/facebook/react/bridge/Dynamic;)V public fun setJustifyContent (Ljava/lang/String;)V public fun setMargins (ILcom/facebook/react/bridge/Dynamic;)V @@ -4187,7 +4187,7 @@ public class com/facebook/react/uimanager/LayoutShadowNode : com/facebook/react/ public fun setPaddings (ILcom/facebook/react/bridge/Dynamic;)V public fun setPosition (Ljava/lang/String;)V public fun setPositionValues (ILcom/facebook/react/bridge/Dynamic;)V - public fun setRowGap (F)V + public fun setRowGap (Lcom/facebook/react/bridge/Dynamic;)V public fun setShouldNotifyOnLayout (Z)V public fun setShouldNotifyPointerEnter (Z)V public fun setShouldNotifyPointerLeave (Z)V @@ -4620,6 +4620,7 @@ public abstract interface class com/facebook/react/uimanager/ReactShadowNode { public abstract fun setBaselineFunction (Lcom/facebook/yoga/YogaBaselineFunction;)V public abstract fun setBorder (IF)V public abstract fun setColumnGap (F)V + public abstract fun setColumnGapPercent (F)V public abstract fun setDefaultPadding (IF)V public abstract fun setDisplay (Lcom/facebook/yoga/YogaDisplay;)V public abstract fun setFlex (F)V @@ -4631,6 +4632,7 @@ public abstract interface class com/facebook/react/uimanager/ReactShadowNode { public abstract fun setFlexShrink (F)V public abstract fun setFlexWrap (Lcom/facebook/yoga/YogaWrap;)V public abstract fun setGap (F)V + public abstract fun setGapPercent (F)V public abstract fun setIsLayoutOnly (Z)V public abstract fun setJustifyContent (Lcom/facebook/yoga/YogaJustify;)V public abstract fun setLayoutDirection (Lcom/facebook/yoga/YogaDirection;)V @@ -4650,6 +4652,7 @@ public abstract interface class com/facebook/react/uimanager/ReactShadowNode { public abstract fun setReactTag (I)V public abstract fun setRootTag (I)V public abstract fun setRowGap (F)V + public abstract fun setRowGapPercent (F)V public abstract fun setShouldNotifyOnLayout (Z)V public abstract fun setStyleAspectRatio (F)V public abstract fun setStyleHeight (F)V @@ -4754,6 +4757,7 @@ public class com/facebook/react/uimanager/ReactShadowNodeImpl : com/facebook/rea public fun setBaselineFunction (Lcom/facebook/yoga/YogaBaselineFunction;)V public fun setBorder (IF)V public fun setColumnGap (F)V + public fun setColumnGapPercent (F)V public fun setDefaultPadding (IF)V public fun setDisplay (Lcom/facebook/yoga/YogaDisplay;)V public fun setFlex (F)V @@ -4765,6 +4769,7 @@ public class com/facebook/react/uimanager/ReactShadowNodeImpl : com/facebook/rea public fun setFlexShrink (F)V public fun setFlexWrap (Lcom/facebook/yoga/YogaWrap;)V public fun setGap (F)V + public fun setGapPercent (F)V public final fun setIsLayoutOnly (Z)V public fun setJustifyContent (Lcom/facebook/yoga/YogaJustify;)V public fun setLayoutDirection (Lcom/facebook/yoga/YogaDirection;)V @@ -4785,6 +4790,7 @@ public class com/facebook/react/uimanager/ReactShadowNodeImpl : com/facebook/rea public fun setReactTag (I)V public final fun setRootTag (I)V public fun setRowGap (F)V + public fun setRowGapPercent (F)V public fun setShouldNotifyOnLayout (Z)V public fun setStyleAspectRatio (F)V public fun setStyleHeight (F)V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/LayoutShadowNode.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/LayoutShadowNode.java index 8e6f7379f14c..53fcc782c205 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/LayoutShadowNode.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/LayoutShadowNode.java @@ -230,28 +230,67 @@ public void setFlexGrow(float flexGrow) { super.setFlexGrow(flexGrow); } - @ReactProp(name = ViewProps.ROW_GAP, defaultFloat = YogaConstants.UNDEFINED) - public void setRowGap(float rowGap) { + @ReactProp(name = ViewProps.ROW_GAP) + public void setRowGap(Dynamic rowGap) { if (isVirtual()) { return; } - super.setRowGap(PixelUtil.toPixelFromDIP(rowGap)); + + mTempYogaValue.setFromDynamic(rowGap); + switch (mTempYogaValue.unit) { + case AUTO: + case POINT: + case UNDEFINED: + setRowGap(mTempYogaValue.value); + break; + case PERCENT: + setRowGapPercent(mTempYogaValue.value); + break; + } + + rowGap.recycle(); } - @ReactProp(name = ViewProps.COLUMN_GAP, defaultFloat = YogaConstants.UNDEFINED) - public void setColumnGap(float columnGap) { + @ReactProp(name = ViewProps.COLUMN_GAP) + public void setColumnGap(Dynamic columnGap) { if (isVirtual()) { return; } - super.setColumnGap(PixelUtil.toPixelFromDIP(columnGap)); + + mTempYogaValue.setFromDynamic(columnGap); + switch (mTempYogaValue.unit) { + case AUTO: + case POINT: + case UNDEFINED: + setColumnGap(mTempYogaValue.value); + break; + case PERCENT: + setColumnGapPercent(mTempYogaValue.value); + break; + } + + columnGap.recycle(); } - @ReactProp(name = ViewProps.GAP, defaultFloat = YogaConstants.UNDEFINED) - public void setGap(float gap) { + @ReactProp(name = ViewProps.GAP) + public void setGap(Dynamic gap) { if (isVirtual()) { return; } - super.setGap(PixelUtil.toPixelFromDIP(gap)); + + mTempYogaValue.setFromDynamic(gap); + switch (mTempYogaValue.unit) { + case AUTO: + case POINT: + case UNDEFINED: + setGap(mTempYogaValue.value); + break; + case PERCENT: + setGapPercent(mTempYogaValue.value); + break; + } + + gap.recycle(); } @ReactProp(name = ViewProps.FLEX_SHRINK, defaultFloat = 0f) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java index f2c698c45a60..ef3464a2e2d7 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java @@ -318,10 +318,16 @@ public interface ReactShadowNode { void setRowGap(float rowGap); + void setRowGapPercent(float percent); + void setColumnGap(float columnGap); + void setColumnGapPercent(float percent); + void setGap(float gap); + void setGapPercent(float percent); + void setFlexShrink(float flexShrink); void setFlexBasis(float flexBasis); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNodeImpl.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNodeImpl.java index 2ac0e27b4d68..0009066a518e 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNodeImpl.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNodeImpl.java @@ -827,16 +827,31 @@ public void setRowGap(float rowGap) { mYogaNode.setGap(YogaGutter.ROW, rowGap); } + @Override + public void setRowGapPercent(float percent) { + mYogaNode.setGapPercent(YogaGutter.ROW, percent); + } + @Override public void setColumnGap(float columnGap) { mYogaNode.setGap(YogaGutter.COLUMN, columnGap); } + @Override + public void setColumnGapPercent(float percent) { + mYogaNode.setGapPercent(YogaGutter.COLUMN, percent); + } + @Override public void setGap(float gap) { mYogaNode.setGap(YogaGutter.ALL, gap); } + @Override + public void setGapPercent(float percent) { + mYogaNode.setGap(YogaGutter.ALL, percent); + } + @Override public void setFlexShrink(float flexShrink) { mYogaNode.setFlexShrink(flexShrink);