diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 0e01ff68d47..480748f43fc 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -2790,7 +2790,7 @@ public class com/facebook/react/fabric/mounting/SurfaceMountingManager { public fun setJSResponder (IIZ)V public fun stopSurface ()V public fun updateEventEmitter (ILcom/facebook/react/fabric/events/EventEmitterWrapper;)V - public fun updateLayout (IIIIIII)V + public fun updateLayout (IIIIIIII)V public fun updateOverflowInset (IIIII)V public fun updatePadding (IIIII)V public fun updateProps (ILcom/facebook/react/bridge/ReadableMap;)V @@ -5527,12 +5527,11 @@ public class com/facebook/react/uimanager/drawable/CSSBackgroundDrawable : andro public fun getComputedBorderRadius ()Lcom/facebook/react/uimanager/style/ComputedBorderRadius; public fun getDirectionAwareBorderInsets ()Landroid/graphics/RectF; public fun getFullBorderWidth ()F + public fun getLayoutDirection ()I public fun getOpacity ()I public fun getOutline (Landroid/graphics/Outline;)V - public fun getResolvedLayoutDirection ()I public fun hasRoundedBorders ()Z protected fun onBoundsChange (Landroid/graphics/Rect;)V - public fun onResolvedLayoutDirectionChanged (I)Z public fun paddingBoxPath ()Landroid/graphics/Path; public fun setAlpha (I)V public fun setBorderColor (IFF)V @@ -5542,9 +5541,9 @@ public class com/facebook/react/uimanager/drawable/CSSBackgroundDrawable : andro public fun setBorderWidth (IF)V public fun setColor (I)V public fun setColorFilter (Landroid/graphics/ColorFilter;)V + public fun setLayoutDirectionOverride (I)V public fun setRadius (F)V public fun setRadius (FI)V - public fun setResolvedLayoutDirection (I)Z } public abstract interface class com/facebook/react/uimanager/events/BatchEventDispatchedListener { @@ -6633,6 +6632,7 @@ public class com/facebook/react/views/scroll/OnScrollDispatchHelper { public class com/facebook/react/views/scroll/ReactHorizontalScrollContainerView : com/facebook/react/views/view/ReactViewGroup { public fun (Landroid/content/Context;)V + public fun getLayoutDirection ()I protected fun onLayout (ZIIII)V public fun setRemoveClippedSubviews (Z)V } @@ -7927,7 +7927,6 @@ public class com/facebook/react/views/view/ReactViewGroup : android/view/ViewGro public fun onInterceptTouchEvent (Landroid/view/MotionEvent;)Z protected fun onLayout (ZIIII)V protected fun onMeasure (II)V - public fun onRtlPropertiesChanged (I)V protected fun onSizeChanged (IIII)V public fun onTouchEvent (Landroid/view/MotionEvent;)Z public fun removeView (Landroid/view/View;)V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java index e1de337a0de..72b640e0bbb 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java @@ -938,7 +938,14 @@ public class SurfaceMountingManager { @UiThread public void updateLayout( - int reactTag, int parentTag, int x, int y, int width, int height, int displayType) { + int reactTag, + int parentTag, + int x, + int y, + int width, + int height, + int displayType, + int layoutDirection) { if (isStopped()) { return; } @@ -954,6 +961,13 @@ public class SurfaceMountingManager { throw new IllegalStateException("Unable to find View for tag: " + reactTag); } + if (ReactNativeFeatureFlags.setAndroidLayoutDirection()) { + viewToUpdate.setLayoutDirection( + layoutDirection == 1 + ? View.LAYOUT_DIRECTION_LTR + : layoutDirection == 2 ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_INHERIT); + } + viewToUpdate.measure( View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY)); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferBatchMountItem.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferBatchMountItem.java index 45621a90dad..c574a2724c5 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferBatchMountItem.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferBatchMountItem.java @@ -20,6 +20,7 @@ import com.facebook.react.bridge.ReadableMap; import com.facebook.react.fabric.events.EventEmitterWrapper; import com.facebook.react.fabric.mounting.MountingManager; import com.facebook.react.fabric.mounting.SurfaceMountingManager; +import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags; import com.facebook.react.uimanager.StateWrapper; import com.facebook.systrace.Systrace; @@ -150,9 +151,14 @@ final class IntBufferBatchMountItem implements BatchMountItem { int height = mIntBuffer[i++]; int displayType = mIntBuffer[i++]; - surfaceMountingManager.updateLayout( - reactTag, parentTag, x, y, width, height, displayType); - + if (ReactNativeFeatureFlags.setAndroidLayoutDirection()) { + int layoutDirection = mIntBuffer[i++]; + surfaceMountingManager.updateLayout( + reactTag, parentTag, x, y, width, height, displayType, layoutDirection); + } else { + surfaceMountingManager.updateLayout( + reactTag, parentTag, x, y, width, height, displayType, 0); + } } else if (type == INSTRUCTION_UPDATE_PADDING) { surfaceMountingManager.updatePadding( mIntBuffer[i++], mIntBuffer[i++], mIntBuffer[i++], mIntBuffer[i++], mIntBuffer[i++]); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt index 845e58a7ae6..6710de5fbf1 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<0ae7be647ca12c3efcc34f6098155550>> */ /** @@ -130,6 +130,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun preventDoubleTextMeasure(): Boolean = accessor.preventDoubleTextMeasure() + /** + * Propagate layout direction to Android views. + */ + @JvmStatic + public fun setAndroidLayoutDirection(): Boolean = accessor.setAndroidLayoutDirection() + /** * When enabled, it uses the modern fork of RuntimeScheduler that allows scheduling tasks with priorities from any thread. */ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt index 5dc81b6f875..49b093d4d2f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<5323fb8be9ec7ee6ac43d7f01bca020e>> */ /** @@ -37,6 +37,7 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso private var inspectorEnableModernCDPRegistryCache: Boolean? = null private var lazyAnimationCallbacksCache: Boolean? = null private var preventDoubleTextMeasureCache: Boolean? = null + private var setAndroidLayoutDirectionCache: Boolean? = null private var useModernRuntimeSchedulerCache: Boolean? = null private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null private var useStateAlignmentMechanismCache: Boolean? = null @@ -194,6 +195,15 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso return cached } + override fun setAndroidLayoutDirection(): Boolean { + var cached = setAndroidLayoutDirectionCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.setAndroidLayoutDirection() + setAndroidLayoutDirectionCache = cached + } + return cached + } + override fun useModernRuntimeScheduler(): Boolean { var cached = useModernRuntimeSchedulerCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt index b9295fc96c7..de3f8cb5818 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<77b8e93114ed0cc2b6bdd9ee46e162c7>> + * @generated SignedSource<> */ /** @@ -62,6 +62,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun preventDoubleTextMeasure(): Boolean + @DoNotStrip @JvmStatic public external fun setAndroidLayoutDirection(): Boolean + @DoNotStrip @JvmStatic public external fun useModernRuntimeScheduler(): Boolean @DoNotStrip @JvmStatic public external fun useNativeViewConfigsInBridgelessMode(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt index 2914764ebfe..149ecce3378 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<13a5d73dea53b8d4f16946cebc49e684>> + * @generated SignedSource<<4f50dab251c41380a14506975355e49d>> */ /** @@ -57,6 +57,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun preventDoubleTextMeasure(): Boolean = false + override fun setAndroidLayoutDirection(): Boolean = false + override fun useModernRuntimeScheduler(): Boolean = false override fun useNativeViewConfigsInBridgelessMode(): Boolean = false diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt index d2e26508e67..4ff04cdf7c1 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<67f1828f6a4cf9b2cf808be12d3fb06b>> + * @generated SignedSource<<00a695402781a9f3c45ba0594a785b57>> */ /** @@ -41,6 +41,7 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces private var inspectorEnableModernCDPRegistryCache: Boolean? = null private var lazyAnimationCallbacksCache: Boolean? = null private var preventDoubleTextMeasureCache: Boolean? = null + private var setAndroidLayoutDirectionCache: Boolean? = null private var useModernRuntimeSchedulerCache: Boolean? = null private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null private var useStateAlignmentMechanismCache: Boolean? = null @@ -215,6 +216,16 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun setAndroidLayoutDirection(): Boolean { + var cached = setAndroidLayoutDirectionCache + if (cached == null) { + cached = currentProvider.setAndroidLayoutDirection() + accessedFeatureFlags.add("setAndroidLayoutDirection") + setAndroidLayoutDirectionCache = cached + } + return cached + } + override fun useModernRuntimeScheduler(): Boolean { var cached = useModernRuntimeSchedulerCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt index e1f4174654a..3cd8ba0e743 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -57,6 +57,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun preventDoubleTextMeasure(): Boolean + @DoNotStrip public fun setAndroidLayoutDirection(): Boolean + @DoNotStrip public fun useModernRuntimeScheduler(): Boolean @DoNotStrip public fun useNativeViewConfigsInBridgelessMode(): Boolean 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 4e795bf6f23..39a486d26ea 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 @@ -7,6 +7,7 @@ package com.facebook.react.uimanager.drawable; +import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; @@ -119,7 +120,9 @@ public class CSSBackgroundDrawable extends Drawable { private BorderRadiusStyle mBorderRadius = new BorderRadiusStyle(); private ComputedBorderRadius mComputedBorderRadius = new ComputedBorderRadius(); private final Context mContext; - private int mLayoutDirection; + + // Should be removed after migrating to Android layout direction. + private int mLayoutDirectionOverride = -1; public CSSBackgroundDrawable(Context context) { mContext = context; @@ -163,6 +166,19 @@ public class CSSBackgroundDrawable extends Drawable { // do nothing } + @Deprecated + public void setLayoutDirectionOverride(int layoutDirection) { + if (mLayoutDirectionOverride != layoutDirection) { + mLayoutDirectionOverride = layoutDirection; + } + } + + @Override + @SuppressLint("WrongConstant") + public int getLayoutDirection() { + return mLayoutDirectionOverride == -1 ? super.getLayoutDirection() : mLayoutDirectionOverride; + } + @Override public int getOpacity() { return (Color.alpha(mColor) * mAlpha) >> 8; @@ -292,25 +308,6 @@ public class CSSBackgroundDrawable extends Drawable { invalidateSelf(); } - /** Similar to Drawable.getLayoutDirection, but available in APIs < 23. */ - public int getResolvedLayoutDirection() { - return mLayoutDirection; - } - - /** Similar to Drawable.setLayoutDirection, but available in APIs < 23. */ - public boolean setResolvedLayoutDirection(int layoutDirection) { - if (mLayoutDirection != layoutDirection) { - mLayoutDirection = layoutDirection; - return onResolvedLayoutDirectionChanged(layoutDirection); - } - return false; - } - - /** Similar to Drawable.onLayoutDirectionChanged, but available in APIs < 23. */ - public boolean onResolvedLayoutDirectionChanged(int layoutDirection) { - return false; - } - @VisibleForTesting public int getColor() { return mColor; @@ -392,7 +389,7 @@ public class CSSBackgroundDrawable extends Drawable { // Clip inner border canvas.clipPath(mInnerClipPathForBorderRadius, Region.Op.DIFFERENCE); - final boolean isRTL = getResolvedLayoutDirection() == View.LAYOUT_DIRECTION_RTL; + final boolean isRTL = getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; int colorStart = getBorderColor(Spacing.START); int colorEnd = getBorderColor(Spacing.END); @@ -591,7 +588,7 @@ public class CSSBackgroundDrawable extends Drawable { mComputedBorderRadius = mBorderRadius.resolve( - mLayoutDirection, + getLayoutDirection(), mContext, mOuterClipTempRectForBorderRadius.width(), mOuterClipTempRectForBorderRadius.height()); @@ -1080,7 +1077,7 @@ public class CSSBackgroundDrawable extends Drawable { colorTop = colorBlockStart; } - final boolean isRTL = getResolvedLayoutDirection() == View.LAYOUT_DIRECTION_RTL; + final boolean isRTL = getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; int colorStart = getBorderColor(Spacing.START); int colorEnd = getBorderColor(Spacing.END); @@ -1305,7 +1302,7 @@ public class CSSBackgroundDrawable extends Drawable { float borderRightWidth = getBorderWidthOrDefaultTo(borderWidth, Spacing.RIGHT); if (mBorderWidth != null) { - final boolean isRTL = getResolvedLayoutDirection() == View.LAYOUT_DIRECTION_RTL; + final boolean isRTL = getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; float borderStartWidth = mBorderWidth.getRaw(Spacing.START); float borderEndWidth = mBorderWidth.getRaw(Spacing.END); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerView.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerView.java index 3a60050526b..fbb10ecfc40 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerView.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerView.java @@ -10,6 +10,7 @@ package com.facebook.react.views.scroll; import android.content.Context; import androidx.core.view.ViewCompat; import com.facebook.infer.annotation.Nullsafe; +import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags; import com.facebook.react.modules.i18nmanager.I18nUtil; import com.facebook.react.views.view.ReactViewGroup; @@ -27,6 +28,14 @@ public class ReactHorizontalScrollContainerView extends ReactViewGroup { : ViewCompat.LAYOUT_DIRECTION_LTR; } + @Override + public int getLayoutDirection() { + if (ReactNativeFeatureFlags.setAndroidLayoutDirection()) { + return super.getLayoutDirection(); + } + return mLayoutDirection; + } + @Override public void setRemoveClippedSubviews(boolean removeClippedSubviews) { // Clipping doesn't work well for horizontal scroll views in RTL mode - in both @@ -34,7 +43,7 @@ public class ReactHorizontalScrollContainerView extends ReactViewGroup { // is TextInputs being blurred immediately after being focused. So, for now, // it's easier to just disable this for these specific RTL views. // TODO T86027499: support `setRemoveClippedSubviews` in RTL mode - if (mLayoutDirection == LAYOUT_DIRECTION_RTL) { + if (getLayoutDirection() == LAYOUT_DIRECTION_RTL) { super.setRemoveClippedSubviews(false); return; } @@ -44,7 +53,7 @@ public class ReactHorizontalScrollContainerView extends ReactViewGroup { @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - if (mLayoutDirection == LAYOUT_DIRECTION_RTL) { + if (getLayoutDirection() == LAYOUT_DIRECTION_RTL) { // When the layout direction is RTL, we expect Yoga to give us a layout // that extends off the screen to the left so we re-center it with left=0 int newLeft = 0; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java index 0c1ef425494..4ffe87f9d30 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java @@ -35,6 +35,7 @@ import com.facebook.infer.annotation.Assertions; import com.facebook.infer.annotation.Nullsafe; import com.facebook.react.common.ReactConstants; import com.facebook.react.common.build.ReactBuildConfig; +import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags; import com.facebook.react.modules.i18nmanager.I18nUtil; import com.facebook.react.uimanager.MeasureSpecAssertions; import com.facebook.react.uimanager.PointerEvents; @@ -1061,7 +1062,10 @@ public class ReactHorizontalScrollView extends HorizontalScrollView int firstOffset = 0; int lastOffset = maximumOffset; int width = getWidth() - ViewCompat.getPaddingStart(this) - ViewCompat.getPaddingEnd(this); - int layoutDirection = getReactScrollViewScrollState().getLayoutDirection(); + int layoutDirection = + ReactNativeFeatureFlags.setAndroidLayoutDirection() + ? getLayoutDirection() + : mReactScrollViewScrollState.getLayoutDirection(); // offsets are from the right edge in RTL layouts if (layoutDirection == LAYOUT_DIRECTION_RTL) { @@ -1385,7 +1389,11 @@ public class ReactHorizontalScrollView extends HorizontalScrollView // does not shift layout. If `maintainVisibleContentPosition` is enabled, we try to adjust // position so that the viewport keeps the same insets to previously visible views. TODO: MVCP // does not work in RTL. - if (mReactScrollViewScrollState.getLayoutDirection() == LAYOUT_DIRECTION_RTL) { + int layoutDirection = + ReactNativeFeatureFlags.setAndroidLayoutDirection() + ? v.getLayoutDirection() + : mReactScrollViewScrollState.getLayoutDirection(); + if (layoutDirection == LAYOUT_DIRECTION_RTL) { adjustPositionForContentChangeRTL(left, right, oldLeft, oldRight); } else if (mMaintainVisibleContentPositionHelper != null) { mMaintainVisibleContentPositionHelper.updateScrollPosition(); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java index ce066636ca8..3114e2cfdc1 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java @@ -32,6 +32,7 @@ import com.facebook.react.bridge.ReactNoCrashSoftException; import com.facebook.react.bridge.ReactSoftExceptionLogger; import com.facebook.react.bridge.UiThreadUtil; import com.facebook.react.common.annotations.VisibleForTesting; +import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags; import com.facebook.react.modules.i18nmanager.I18nUtil; import com.facebook.react.touch.OnInterceptTouchEventListener; import com.facebook.react.touch.ReactHitSlopView; @@ -129,7 +130,6 @@ public class ReactViewGroup extends ViewGroup private boolean mNeedsOffscreenAlphaCompositing; private @Nullable ViewGroupDrawingOrderHelper mDrawingOrderHelper; private @Nullable Path mPath; - private int mLayoutDirection; private float mBackfaceOpacity; private String mBackfaceVisibility; @@ -159,7 +159,6 @@ public class ReactViewGroup extends ViewGroup mNeedsOffscreenAlphaCompositing = false; mDrawingOrderHelper = null; mPath = null; - mLayoutDirection = 0; // set when background is created mBackfaceOpacity = 1.f; mBackfaceVisibility = "visible"; } @@ -199,13 +198,6 @@ public class ReactViewGroup extends ViewGroup // No-op since UIManagerModule handles actually laying out children. } - @Override - public void onRtlPropertiesChanged(int layoutDirection) { - if (mCSSBackgroundDrawable != null) { - mCSSBackgroundDrawable.setResolvedLayoutDirection(mLayoutDirection); - } - } - @Override @SuppressLint("MissingSuperCall") public void requestLayout() { @@ -806,10 +798,12 @@ public class ReactViewGroup extends ViewGroup new LayerDrawable(new Drawable[] {mCSSBackgroundDrawable, backgroundDrawable}); updateBackgroundDrawable(layerDrawable); } - - mLayoutDirection = - I18nUtil.getInstance().isRTL(getContext()) ? LAYOUT_DIRECTION_RTL : LAYOUT_DIRECTION_LTR; - mCSSBackgroundDrawable.setResolvedLayoutDirection(mLayoutDirection); + if (!ReactNativeFeatureFlags.setAndroidLayoutDirection()) { + mCSSBackgroundDrawable.setLayoutDirectionOverride( + I18nUtil.getInstance().isRTL(getContext()) + ? LAYOUT_DIRECTION_RTL + : LAYOUT_DIRECTION_LTR); + } } return mCSSBackgroundDrawable; } diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp index 61ec7ceaca4..ca193764065 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp @@ -63,7 +63,9 @@ static inline int getIntBufferSizeForType(CppMountItem::Type mountItemType) { case CppMountItem::Type::UpdatePadding: return 5; // tag, top, left, bottom, right case CppMountItem::Type::UpdateLayout: - return 7; // tag, parentTag, x, y, w, h, DisplayType + return ReactNativeFeatureFlags::setAndroidLayoutDirection() + ? 8 // tag, parentTag, x, y, w, h, DisplayType, LayoutDirection + : 7; // tag, parentTag, x, y, w, h, DisplayType case CppMountItem::Type::UpdateOverflowInset: return 5; // tag, left, top, right, bottom case CppMountItem::Undefined: @@ -496,7 +498,7 @@ void FabricMountingManager::executeMount( int intBufferPosition = 0; int objBufferPosition = 0; int prevMountItemType = -1; - jint temp[7]; + jint temp[8]; for (int i = 0; i < cppCommonMountItems.size(); i++) { const auto& mountItem = cppCommonMountItems[i]; const auto& mountItemType = mountItem.type; @@ -656,7 +658,7 @@ void FabricMountingManager::executeMount( intBufferPosition); for (const auto& mountItem : cppUpdateLayoutMountItems) { - auto layoutMetrics = mountItem.newChildShadowView.layoutMetrics; + const auto& layoutMetrics = mountItem.newChildShadowView.layoutMetrics; auto pointScaleFactor = layoutMetrics.pointScaleFactor; auto frame = layoutMetrics.frame; @@ -664,8 +666,8 @@ void FabricMountingManager::executeMount( int y = round(scale(frame.origin.y, pointScaleFactor)); int w = round(scale(frame.size.width, pointScaleFactor)); int h = round(scale(frame.size.height, pointScaleFactor)); - int displayType = - toInt(mountItem.newChildShadowView.layoutMetrics.displayType); + int displayType = toInt(layoutMetrics.displayType); + int layoutDirection = toInt(layoutMetrics.layoutDirection); temp[0] = mountItem.newChildShadowView.tag; temp[1] = mountItem.parentShadowView.tag; @@ -674,8 +676,15 @@ void FabricMountingManager::executeMount( temp[4] = w; temp[5] = h; temp[6] = displayType; - env->SetIntArrayRegion(intBufferArray, intBufferPosition, 7, temp); - intBufferPosition += 7; + + if (ReactNativeFeatureFlags::setAndroidLayoutDirection()) { + temp[7] = layoutDirection; + env->SetIntArrayRegion(intBufferArray, intBufferPosition, 8, temp); + intBufferPosition += 8; + } else { + env->SetIntArrayRegion(intBufferArray, intBufferPosition, 7, temp); + intBufferPosition += 7; + } } } if (!cppUpdateOverflowInsetMountItems.empty()) { diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp index be8c264daea..4bfccaff624 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<5d0f0b1953af3f0dd2ee66fed2b1115a>> */ /** @@ -141,6 +141,12 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } + bool setAndroidLayoutDirection() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("setAndroidLayoutDirection"); + return method(javaProvider_); + } + bool useModernRuntimeScheduler() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("useModernRuntimeScheduler"); @@ -248,6 +254,11 @@ bool JReactNativeFeatureFlagsCxxInterop::preventDoubleTextMeasure( return ReactNativeFeatureFlags::preventDoubleTextMeasure(); } +bool JReactNativeFeatureFlagsCxxInterop::setAndroidLayoutDirection( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::setAndroidLayoutDirection(); +} + bool JReactNativeFeatureFlagsCxxInterop::useModernRuntimeScheduler( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::useModernRuntimeScheduler(); @@ -331,6 +342,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "preventDoubleTextMeasure", JReactNativeFeatureFlagsCxxInterop::preventDoubleTextMeasure), + makeNativeMethod( + "setAndroidLayoutDirection", + JReactNativeFeatureFlagsCxxInterop::setAndroidLayoutDirection), makeNativeMethod( "useModernRuntimeScheduler", JReactNativeFeatureFlagsCxxInterop::useModernRuntimeScheduler), diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h index 778b3befef4..4b026033b0d 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -81,6 +81,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool preventDoubleTextMeasure( facebook::jni::alias_ref); + static bool setAndroidLayoutDirection( + facebook::jni::alias_ref); + static bool useModernRuntimeScheduler( facebook::jni::alias_ref); diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp index f14991eddd7..d7df428cd27 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<5001001b2979f9b759ddac1b035842bf>> + * @generated SignedSource<<71ea09d31186aea96ff207b1015f155e>> */ /** @@ -89,6 +89,10 @@ bool ReactNativeFeatureFlags::preventDoubleTextMeasure() { return getAccessor().preventDoubleTextMeasure(); } +bool ReactNativeFeatureFlags::setAndroidLayoutDirection() { + return getAccessor().setAndroidLayoutDirection(); +} + bool ReactNativeFeatureFlags::useModernRuntimeScheduler() { return getAccessor().useModernRuntimeScheduler(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index 061dced7211..eca725c01bc 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<4dd4bd2c61bff37de19a52b1bb60211c>> + * @generated SignedSource<> */ /** @@ -122,6 +122,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool preventDoubleTextMeasure(); + /** + * Propagate layout direction to Android views. + */ + RN_EXPORT static bool setAndroidLayoutDirection(); + /** * When enabled, it uses the modern fork of RuntimeScheduler that allows scheduling tasks with priorities from any thread. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index 21365b36ed0..6fabfbab220 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<7766e3504d137c8dee703a23d776689c>> + * @generated SignedSource<<2e874e6368f85709ecbb4c1e086ae7a9>> */ /** @@ -335,6 +335,24 @@ bool ReactNativeFeatureFlagsAccessor::preventDoubleTextMeasure() { return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::setAndroidLayoutDirection() { + auto flagValue = setAndroidLayoutDirection_.load(); + + if (!flagValue.has_value()) { + // This block is not exclusive but it is not necessary. + // If multiple threads try to initialize the feature flag, we would only + // be accessing the provider multiple times but the end state of this + // instance and the returned flag value would be the same. + + markFlagAsAccessed(17, "setAndroidLayoutDirection"); + + flagValue = currentProvider_->setAndroidLayoutDirection(); + setAndroidLayoutDirection_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::useModernRuntimeScheduler() { auto flagValue = useModernRuntimeScheduler_.load(); @@ -344,7 +362,7 @@ bool ReactNativeFeatureFlagsAccessor::useModernRuntimeScheduler() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(17, "useModernRuntimeScheduler"); + markFlagAsAccessed(18, "useModernRuntimeScheduler"); flagValue = currentProvider_->useModernRuntimeScheduler(); useModernRuntimeScheduler_ = flagValue; @@ -362,7 +380,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeViewConfigsInBridgelessMode() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(18, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(19, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -380,7 +398,7 @@ bool ReactNativeFeatureFlagsAccessor::useStateAlignmentMechanism() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(19, "useStateAlignmentMechanism"); + markFlagAsAccessed(20, "useStateAlignmentMechanism"); flagValue = currentProvider_->useStateAlignmentMechanism(); useStateAlignmentMechanism_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index 0483526befe..3c2daeb6ad5 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<00646bb38ef65efa782e5f601cd91716>> + * @generated SignedSource<<7d1c4c90d5e1feb0015376f20943ee51>> */ /** @@ -48,6 +48,7 @@ class ReactNativeFeatureFlagsAccessor { bool inspectorEnableModernCDPRegistry(); bool lazyAnimationCallbacks(); bool preventDoubleTextMeasure(); + bool setAndroidLayoutDirection(); bool useModernRuntimeScheduler(); bool useNativeViewConfigsInBridgelessMode(); bool useStateAlignmentMechanism(); @@ -61,7 +62,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 20> accessedFeatureFlags_; + std::array, 21> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> allowCollapsableChildren_; @@ -80,6 +81,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> inspectorEnableModernCDPRegistry_; std::atomic> lazyAnimationCallbacks_; std::atomic> preventDoubleTextMeasure_; + std::atomic> setAndroidLayoutDirection_; std::atomic> useModernRuntimeScheduler_; std::atomic> useNativeViewConfigsInBridgelessMode_; std::atomic> useStateAlignmentMechanism_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 7399078817e..c50025ebf06 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<2bfa4670757aa340c88ae8ff57270308>> */ /** @@ -95,6 +95,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool setAndroidLayoutDirection() override { + return false; + } + bool useModernRuntimeScheduler() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index 81fc8ce6c00..319de4e0794 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -42,6 +42,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool inspectorEnableModernCDPRegistry() = 0; virtual bool lazyAnimationCallbacks() = 0; virtual bool preventDoubleTextMeasure() = 0; + virtual bool setAndroidLayoutDirection() = 0; virtual bool useModernRuntimeScheduler() = 0; virtual bool useNativeViewConfigsInBridgelessMode() = 0; virtual bool useStateAlignmentMechanism() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index b8c2fe670ef..29091f3cbde 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<1fdca69483db9e0fc9f9ab7a2cd9ff85>> */ /** @@ -122,6 +122,11 @@ bool NativeReactNativeFeatureFlags::preventDoubleTextMeasure( return ReactNativeFeatureFlags::preventDoubleTextMeasure(); } +bool NativeReactNativeFeatureFlags::setAndroidLayoutDirection( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::setAndroidLayoutDirection(); +} + bool NativeReactNativeFeatureFlags::useModernRuntimeScheduler( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::useModernRuntimeScheduler(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index 696c5591ea8..815380f8988 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<07b3c6e705bdc70c7eba50d70b0dbf32>> + * @generated SignedSource<<9653b7699416f1702ba2f5e8b8f6da93>> */ /** @@ -69,6 +69,8 @@ class NativeReactNativeFeatureFlags bool preventDoubleTextMeasure(jsi::Runtime& runtime); + bool setAndroidLayoutDirection(jsi::Runtime& runtime); + bool useModernRuntimeScheduler(jsi::Runtime& runtime); bool useNativeViewConfigsInBridgelessMode(jsi::Runtime& runtime); diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index d124be2d97e..fbc772c54fe 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -118,6 +118,10 @@ const definitions: FeatureFlagDefinitions = { description: 'When enabled, ParagraphShadowNode will no longer call measure twice.', }, + setAndroidLayoutDirection: { + defaultValue: false, + description: 'Propagate layout direction to Android views.', + }, useModernRuntimeScheduler: { defaultValue: false, description: diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index 8c4fa4747c0..0378f10607e 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<7d51e120696413a287b048d6c4dd7b5c>> + * @generated SignedSource<<20c3c50d2124fbfc7bbe434c940ce3bf>> * @flow strict-local */ @@ -57,6 +57,7 @@ export type ReactNativeFeatureFlags = { inspectorEnableModernCDPRegistry: Getter, lazyAnimationCallbacks: Getter, preventDoubleTextMeasure: Getter, + setAndroidLayoutDirection: Getter, useModernRuntimeScheduler: Getter, useNativeViewConfigsInBridgelessMode: Getter, useStateAlignmentMechanism: Getter, @@ -170,6 +171,10 @@ export const lazyAnimationCallbacks: Getter = createNativeFlagGetter('l * When enabled, ParagraphShadowNode will no longer call measure twice. */ export const preventDoubleTextMeasure: Getter = createNativeFlagGetter('preventDoubleTextMeasure', false); +/** + * Propagate layout direction to Android views. + */ +export const setAndroidLayoutDirection: Getter = createNativeFlagGetter('setAndroidLayoutDirection', false); /** * When enabled, it uses the modern fork of RuntimeScheduler that allows scheduling tasks with priorities from any thread. */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index b4e60a304d5..f1b75954e54 100644 --- a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> * @flow strict-local */ @@ -40,6 +40,7 @@ export interface Spec extends TurboModule { +inspectorEnableModernCDPRegistry?: () => boolean; +lazyAnimationCallbacks?: () => boolean; +preventDoubleTextMeasure?: () => boolean; + +setAndroidLayoutDirection?: () => boolean; +useModernRuntimeScheduler?: () => boolean; +useNativeViewConfigsInBridgelessMode?: () => boolean; +useStateAlignmentMechanism?: () => boolean;