diff --git a/packages/react-native/Libraries/Text/Text/RCTTextView.mm b/packages/react-native/Libraries/Text/Text/RCTTextView.mm index 47632aa885cdb3..280c39197a3636 100644 --- a/packages/react-native/Libraries/Text/Text/RCTTextView.mm +++ b/packages/react-native/Libraries/Text/Text/RCTTextView.mm @@ -11,6 +11,7 @@ #import #import +#import #import @@ -98,6 +99,42 @@ - (void)setTextStorage:(NSTextStorage *)textStorage [self setNeedsDisplay]; } +- (CGPoint)calculateDrawingPointWithTextStorage:(NSTextStorage *)textStorage + contentFrame:(CGRect)contentFrame { + if ([textStorage length] == 0) { + return contentFrame.origin; + } + + UIFont *font = [textStorage attribute:NSFontAttributeName atIndex:0 effectiveRange:NULL]; + if (!font) { + font = [UIFont systemFontOfSize:14]; + } + + NSParagraphStyle *paragraphStyle = [textStorage attribute:NSParagraphStyleAttributeName atIndex:0 effectiveRange:NULL]; + + CGFloat lineHeight = font.lineHeight; + if (paragraphStyle && paragraphStyle.minimumLineHeight > 0) { + lineHeight = paragraphStyle.minimumLineHeight; + } + + CGFloat ascent = font.ascender; + CGFloat descent = fabs(font.descender); + CGFloat textHeight = ascent + descent; + + CGFloat verticalOffset = 0; + // Adjust vertical offset to ensure text is vertically centered relative to the line height. + // Positive offset when text height exceeds line height, negative when line height exceeds text height. + if (textHeight > lineHeight) { + CGFloat difference = textHeight - lineHeight; + verticalOffset = difference / 2.0; + } else if (textHeight < lineHeight) { + CGFloat difference = lineHeight - textHeight; + verticalOffset = -(difference / 2.0); + } + + return CGPointMake(contentFrame.origin.x, contentFrame.origin.y + verticalOffset); +} + - (void)drawRect:(CGRect)rect { [super drawRect:rect]; @@ -118,8 +155,15 @@ - (void)drawRect:(CGRect)rect #endif NSRange glyphRange = [layoutManager glyphRangeForTextContainer:textContainer]; - [layoutManager drawBackgroundForGlyphRange:glyphRange atPoint:_contentFrame.origin]; - [layoutManager drawGlyphsForGlyphRange:glyphRange atPoint:_contentFrame.origin]; + + if (facebook::react::ReactNativeFeatureFlags::enableLineHeightCenteringOnIOS()) { + CGPoint drawingPoint = [self calculateDrawingPointWithTextStorage:_textStorage contentFrame:_contentFrame]; + [layoutManager drawBackgroundForGlyphRange:glyphRange atPoint:drawingPoint]; + [layoutManager drawGlyphsForGlyphRange:glyphRange atPoint:drawingPoint]; + } else { + [layoutManager drawBackgroundForGlyphRange:glyphRange atPoint:_contentFrame.origin]; + [layoutManager drawGlyphsForGlyphRange:glyphRange atPoint:_contentFrame.origin]; + } __block UIBezierPath *highlightPath = nil; NSRange characterRange = [layoutManager characterRangeForGlyphRange:glyphRange actualGlyphRange:NULL]; diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm index 3f87fcec845487..8f4cc3a8ad3dbc 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm @@ -9,6 +9,7 @@ #import "RCTParagraphComponentAccessibilityProvider.h" #import +#import #import #import #import @@ -326,6 +327,40 @@ @implementation RCTParagraphTextView { CAShapeLayer *_highlightLayer; } +- (CGRect)calculateCenteredFrameWithAttributedText:(NSAttributedString *)attributedText + frame:(CGRect)frame { + UIFont *font = [attributedText attribute:NSFontAttributeName atIndex:0 effectiveRange:NULL]; + if (!font) { + font = [UIFont systemFontOfSize:14]; + } + + NSParagraphStyle *paragraphStyle = [attributedText attribute:NSParagraphStyleAttributeName atIndex:0 effectiveRange:NULL]; + CGFloat lineHeight = font.lineHeight; + + if (paragraphStyle && paragraphStyle.minimumLineHeight > 0) { + lineHeight = paragraphStyle.minimumLineHeight; + } + + CGFloat ascent = font.ascender; + CGFloat descent = fabs(font.descender); + CGFloat textHeight = ascent + descent; + + CGFloat verticalOffset = 0; + // Adjust vertical offset to ensure text is vertically centered relative to the line height. + // Positive offset when text height exceeds line height, negative when line height exceeds text height. + if (textHeight > lineHeight) { + CGFloat difference = textHeight - lineHeight; + verticalOffset = difference / 2.0; + } else if (textHeight < lineHeight) { + CGFloat difference = lineHeight - textHeight; + verticalOffset = -(difference / 2.0); + } + + frame.origin.y += verticalOffset; + + return frame; +} + - (void)drawRect:(CGRect)rect { if (!_state) { @@ -343,6 +378,11 @@ - (void)drawRect:(CGRect)rect CGRect frame = RCTCGRectFromRect(_layoutMetrics.getContentFrame()); + if (ReactNativeFeatureFlags::enableLineHeightCenteringOnIOS()) { + NSAttributedString *attributedText = RCTNSAttributedStringFromAttributedString(_state->getData().attributedString); + frame = [self calculateCenteredFrameWithAttributedText:attributedText frame:frame]; + } + [nativeTextLayoutManager drawAttributedString:_state->getData().attributedString paragraphAttributes:_paragraphAttributes frame:frame 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 6da3f111828555..196ed33be3898c 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<<050d7e7fa1d91657a2a40cefada260d8>> */ /** @@ -58,12 +58,6 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun enableAlignItemsBaselineOnFabricIOS(): Boolean = accessor.enableAlignItemsBaselineOnFabricIOS() - /** - * When enabled, custom line height calculation will be centered from top to bottom. - */ - @JvmStatic - public fun enableAndroidLineHeightCentering(): Boolean = accessor.enableAndroidLineHeightCentering() - /** * Feature flag to enable the new bridgeless architecture. Note: Enabling this will force enable the following flags: `useTurboModules` & `enableFabricRenderer. */ @@ -136,6 +130,18 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun enableLayoutAnimationsOnIOS(): Boolean = accessor.enableLayoutAnimationsOnIOS() + /** + * When enabled, custom line height calculation will be centered from top to bottom. + */ + @JvmStatic + public fun enableLineHeightCenteringOnAndroid(): Boolean = accessor.enableLineHeightCenteringOnAndroid() + + /** + * When enabled, custom line height calculation will be centered from top to bottom. + */ + @JvmStatic + public fun enableLineHeightCenteringOnIOS(): Boolean = accessor.enableLineHeightCenteringOnIOS() + /** * Enables the reporting of long tasks through `PerformanceObserver`. Only works if the event loop is enabled. */ 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 682f303c8dcde3..e733f4c6c7a7cf 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<<46fc50f75cc9dfb2d9525862c0d81a13>> */ /** @@ -25,7 +25,6 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso private var batchRenderingUpdatesInEventLoopCache: Boolean? = null private var completeReactInstanceCreationOnBgThreadOnAndroidCache: Boolean? = null private var enableAlignItemsBaselineOnFabricIOSCache: Boolean? = null - private var enableAndroidLineHeightCenteringCache: Boolean? = null private var enableBridgelessArchitectureCache: Boolean? = null private var enableCleanTextInputYogaNodeCache: Boolean? = null private var enableDeletionOfUnmountedViewsCache: Boolean? = null @@ -38,6 +37,8 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso private var enableIOSViewClipToPaddingBoxCache: Boolean? = null private var enableLayoutAnimationsOnAndroidCache: Boolean? = null private var enableLayoutAnimationsOnIOSCache: Boolean? = null + private var enableLineHeightCenteringOnAndroidCache: Boolean? = null + private var enableLineHeightCenteringOnIOSCache: Boolean? = null private var enableLongTaskAPICache: Boolean? = null private var enableMicrotasksCache: Boolean? = null private var enablePreciseSchedulingForPremountItemsOnAndroidCache: Boolean? = null @@ -114,15 +115,6 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso return cached } - override fun enableAndroidLineHeightCentering(): Boolean { - var cached = enableAndroidLineHeightCenteringCache - if (cached == null) { - cached = ReactNativeFeatureFlagsCxxInterop.enableAndroidLineHeightCentering() - enableAndroidLineHeightCenteringCache = cached - } - return cached - } - override fun enableBridgelessArchitecture(): Boolean { var cached = enableBridgelessArchitectureCache if (cached == null) { @@ -231,6 +223,24 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso return cached } + override fun enableLineHeightCenteringOnAndroid(): Boolean { + var cached = enableLineHeightCenteringOnAndroidCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.enableLineHeightCenteringOnAndroid() + enableLineHeightCenteringOnAndroidCache = cached + } + return cached + } + + override fun enableLineHeightCenteringOnIOS(): Boolean { + var cached = enableLineHeightCenteringOnIOSCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.enableLineHeightCenteringOnIOS() + enableLineHeightCenteringOnIOSCache = cached + } + return cached + } + override fun enableLongTaskAPI(): Boolean { var cached = enableLongTaskAPICache 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 27d4feade5f15f..366bd09168ecdc 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<<2f1e29ca29c3679e5a87be1d0944efd9>> + * @generated SignedSource<> */ /** @@ -38,8 +38,6 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun enableAlignItemsBaselineOnFabricIOS(): Boolean - @DoNotStrip @JvmStatic public external fun enableAndroidLineHeightCentering(): Boolean - @DoNotStrip @JvmStatic public external fun enableBridgelessArchitecture(): Boolean @DoNotStrip @JvmStatic public external fun enableCleanTextInputYogaNode(): Boolean @@ -64,6 +62,10 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun enableLayoutAnimationsOnIOS(): Boolean + @DoNotStrip @JvmStatic public external fun enableLineHeightCenteringOnAndroid(): Boolean + + @DoNotStrip @JvmStatic public external fun enableLineHeightCenteringOnIOS(): Boolean + @DoNotStrip @JvmStatic public external fun enableLongTaskAPI(): Boolean @DoNotStrip @JvmStatic public external fun enableMicrotasks(): 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 c30d36d11f67e8..360e7d369bc0c1 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<> + * @generated SignedSource<> */ /** @@ -33,8 +33,6 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun enableAlignItemsBaselineOnFabricIOS(): Boolean = true - override fun enableAndroidLineHeightCentering(): Boolean = false - override fun enableBridgelessArchitecture(): Boolean = false override fun enableCleanTextInputYogaNode(): Boolean = false @@ -59,6 +57,10 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun enableLayoutAnimationsOnIOS(): Boolean = true + override fun enableLineHeightCenteringOnAndroid(): Boolean = false + + override fun enableLineHeightCenteringOnIOS(): Boolean = false + override fun enableLongTaskAPI(): Boolean = false override fun enableMicrotasks(): 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 c573dc34cdee55..1fc361c6238054 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<> + * @generated SignedSource<> */ /** @@ -29,7 +29,6 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces private var batchRenderingUpdatesInEventLoopCache: Boolean? = null private var completeReactInstanceCreationOnBgThreadOnAndroidCache: Boolean? = null private var enableAlignItemsBaselineOnFabricIOSCache: Boolean? = null - private var enableAndroidLineHeightCenteringCache: Boolean? = null private var enableBridgelessArchitectureCache: Boolean? = null private var enableCleanTextInputYogaNodeCache: Boolean? = null private var enableDeletionOfUnmountedViewsCache: Boolean? = null @@ -42,6 +41,8 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces private var enableIOSViewClipToPaddingBoxCache: Boolean? = null private var enableLayoutAnimationsOnAndroidCache: Boolean? = null private var enableLayoutAnimationsOnIOSCache: Boolean? = null + private var enableLineHeightCenteringOnAndroidCache: Boolean? = null + private var enableLineHeightCenteringOnIOSCache: Boolean? = null private var enableLongTaskAPICache: Boolean? = null private var enableMicrotasksCache: Boolean? = null private var enablePreciseSchedulingForPremountItemsOnAndroidCache: Boolean? = null @@ -123,16 +124,6 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces return cached } - override fun enableAndroidLineHeightCentering(): Boolean { - var cached = enableAndroidLineHeightCenteringCache - if (cached == null) { - cached = currentProvider.enableAndroidLineHeightCentering() - accessedFeatureFlags.add("enableAndroidLineHeightCentering") - enableAndroidLineHeightCenteringCache = cached - } - return cached - } - override fun enableBridgelessArchitecture(): Boolean { var cached = enableBridgelessArchitectureCache if (cached == null) { @@ -253,6 +244,26 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun enableLineHeightCenteringOnAndroid(): Boolean { + var cached = enableLineHeightCenteringOnAndroidCache + if (cached == null) { + cached = currentProvider.enableLineHeightCenteringOnAndroid() + accessedFeatureFlags.add("enableLineHeightCenteringOnAndroid") + enableLineHeightCenteringOnAndroidCache = cached + } + return cached + } + + override fun enableLineHeightCenteringOnIOS(): Boolean { + var cached = enableLineHeightCenteringOnIOSCache + if (cached == null) { + cached = currentProvider.enableLineHeightCenteringOnIOS() + accessedFeatureFlags.add("enableLineHeightCenteringOnIOS") + enableLineHeightCenteringOnIOSCache = cached + } + return cached + } + override fun enableLongTaskAPI(): Boolean { var cached = enableLongTaskAPICache 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 2ccc37065ce0f1..e1feb968995674 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<<7abedfd47601a9edd4e2982ea1450590>> + * @generated SignedSource<<3bc08e90a76c46d12a48d815e279a405>> */ /** @@ -33,8 +33,6 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun enableAlignItemsBaselineOnFabricIOS(): Boolean - @DoNotStrip public fun enableAndroidLineHeightCentering(): Boolean - @DoNotStrip public fun enableBridgelessArchitecture(): Boolean @DoNotStrip public fun enableCleanTextInputYogaNode(): Boolean @@ -59,6 +57,10 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun enableLayoutAnimationsOnIOS(): Boolean + @DoNotStrip public fun enableLineHeightCenteringOnAndroid(): Boolean + + @DoNotStrip public fun enableLineHeightCenteringOnIOS(): Boolean + @DoNotStrip public fun enableLongTaskAPI(): Boolean @DoNotStrip public fun enableMicrotasks(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/internal/span/CustomLineHeightSpan.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/internal/span/CustomLineHeightSpan.kt index e9aeb428645e28..ec89a95cc6622b 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/internal/span/CustomLineHeightSpan.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/internal/span/CustomLineHeightSpan.kt @@ -107,7 +107,7 @@ public class CustomLineHeightSpan(height: Float) : LineHeightSpan, ReactSpan { v: Int, fm: FontMetricsInt, ) { - if (ReactNativeFeatureFlags.enableAndroidLineHeightCentering()) chooseCenteredHeight(fm) + if (ReactNativeFeatureFlags.enableLineHeightCenteringOnAndroid()) chooseCenteredHeight(fm) else chooseOriginalHeight(fm) } } 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 aad5890f839a2f..58c46fd27c1a4b 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<<9f5e1568b62ca76e5771fade759d42e5>> + * @generated SignedSource<<72b89194c4713236e4607870e5c9eed8>> */ /** @@ -69,12 +69,6 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } - bool enableAndroidLineHeightCentering() override { - static const auto method = - getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableAndroidLineHeightCentering"); - return method(javaProvider_); - } - bool enableBridgelessArchitecture() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableBridgelessArchitecture"); @@ -147,6 +141,18 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } + bool enableLineHeightCenteringOnAndroid() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableLineHeightCenteringOnAndroid"); + return method(javaProvider_); + } + + bool enableLineHeightCenteringOnIOS() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableLineHeightCenteringOnIOS"); + return method(javaProvider_); + } + bool enableLongTaskAPI() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableLongTaskAPI"); @@ -356,11 +362,6 @@ bool JReactNativeFeatureFlagsCxxInterop::enableAlignItemsBaselineOnFabricIOS( return ReactNativeFeatureFlags::enableAlignItemsBaselineOnFabricIOS(); } -bool JReactNativeFeatureFlagsCxxInterop::enableAndroidLineHeightCentering( - facebook::jni::alias_ref /*unused*/) { - return ReactNativeFeatureFlags::enableAndroidLineHeightCentering(); -} - bool JReactNativeFeatureFlagsCxxInterop::enableBridgelessArchitecture( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::enableBridgelessArchitecture(); @@ -421,6 +422,16 @@ bool JReactNativeFeatureFlagsCxxInterop::enableLayoutAnimationsOnIOS( return ReactNativeFeatureFlags::enableLayoutAnimationsOnIOS(); } +bool JReactNativeFeatureFlagsCxxInterop::enableLineHeightCenteringOnAndroid( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::enableLineHeightCenteringOnAndroid(); +} + +bool JReactNativeFeatureFlagsCxxInterop::enableLineHeightCenteringOnIOS( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::enableLineHeightCenteringOnIOS(); +} + bool JReactNativeFeatureFlagsCxxInterop::enableLongTaskAPI( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::enableLongTaskAPI(); @@ -617,9 +628,6 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "enableAlignItemsBaselineOnFabricIOS", JReactNativeFeatureFlagsCxxInterop::enableAlignItemsBaselineOnFabricIOS), - makeNativeMethod( - "enableAndroidLineHeightCentering", - JReactNativeFeatureFlagsCxxInterop::enableAndroidLineHeightCentering), makeNativeMethod( "enableBridgelessArchitecture", JReactNativeFeatureFlagsCxxInterop::enableBridgelessArchitecture), @@ -656,6 +664,12 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "enableLayoutAnimationsOnIOS", JReactNativeFeatureFlagsCxxInterop::enableLayoutAnimationsOnIOS), + makeNativeMethod( + "enableLineHeightCenteringOnAndroid", + JReactNativeFeatureFlagsCxxInterop::enableLineHeightCenteringOnAndroid), + makeNativeMethod( + "enableLineHeightCenteringOnIOS", + JReactNativeFeatureFlagsCxxInterop::enableLineHeightCenteringOnIOS), makeNativeMethod( "enableLongTaskAPI", JReactNativeFeatureFlagsCxxInterop::enableLongTaskAPI), 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 9ac211e782d525..9fced004117a8f 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<<879ef38c2b34bc6cd15d6361abef1548>> + * @generated SignedSource<<1bbee06d60252787150cc5ac3b8edf52>> */ /** @@ -45,9 +45,6 @@ class JReactNativeFeatureFlagsCxxInterop static bool enableAlignItemsBaselineOnFabricIOS( facebook::jni::alias_ref); - static bool enableAndroidLineHeightCentering( - facebook::jni::alias_ref); - static bool enableBridgelessArchitecture( facebook::jni::alias_ref); @@ -84,6 +81,12 @@ class JReactNativeFeatureFlagsCxxInterop static bool enableLayoutAnimationsOnIOS( facebook::jni::alias_ref); + static bool enableLineHeightCenteringOnAndroid( + facebook::jni::alias_ref); + + static bool enableLineHeightCenteringOnIOS( + facebook::jni::alias_ref); + static bool enableLongTaskAPI( 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 c303c99c0ced38..7234e0782c17cf 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<<204e18de128eb47f29ef5383e592e181>> + * @generated SignedSource<> */ /** @@ -46,10 +46,6 @@ bool ReactNativeFeatureFlags::enableAlignItemsBaselineOnFabricIOS() { return getAccessor().enableAlignItemsBaselineOnFabricIOS(); } -bool ReactNativeFeatureFlags::enableAndroidLineHeightCentering() { - return getAccessor().enableAndroidLineHeightCentering(); -} - bool ReactNativeFeatureFlags::enableBridgelessArchitecture() { return getAccessor().enableBridgelessArchitecture(); } @@ -98,6 +94,14 @@ bool ReactNativeFeatureFlags::enableLayoutAnimationsOnIOS() { return getAccessor().enableLayoutAnimationsOnIOS(); } +bool ReactNativeFeatureFlags::enableLineHeightCenteringOnAndroid() { + return getAccessor().enableLineHeightCenteringOnAndroid(); +} + +bool ReactNativeFeatureFlags::enableLineHeightCenteringOnIOS() { + return getAccessor().enableLineHeightCenteringOnIOS(); +} + bool ReactNativeFeatureFlags::enableLongTaskAPI() { return getAccessor().enableLongTaskAPI(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index 877005a73c7bd9..8f6fed84601709 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<<9170ab789417914123e11ecb836aaa9a>> + * @generated SignedSource<<5c251b351228db851f19d3cfa027dca6>> */ /** @@ -64,11 +64,6 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool enableAlignItemsBaselineOnFabricIOS(); - /** - * When enabled, custom line height calculation will be centered from top to bottom. - */ - RN_EXPORT static bool enableAndroidLineHeightCentering(); - /** * Feature flag to enable the new bridgeless architecture. Note: Enabling this will force enable the following flags: `useTurboModules` & `enableFabricRenderer. */ @@ -129,6 +124,16 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool enableLayoutAnimationsOnIOS(); + /** + * When enabled, custom line height calculation will be centered from top to bottom. + */ + RN_EXPORT static bool enableLineHeightCenteringOnAndroid(); + + /** + * When enabled, custom line height calculation will be centered from top to bottom. + */ + RN_EXPORT static bool enableLineHeightCenteringOnIOS(); + /** * Enables the reporting of long tasks through `PerformanceObserver`. Only works if the event loop is enabled. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index d90b96250a262a..5fc8b74bddd2b8 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<> + * @generated SignedSource<<30a0366b8bc6acb6fcebda0b216eb39c>> */ /** @@ -119,24 +119,6 @@ bool ReactNativeFeatureFlagsAccessor::enableAlignItemsBaselineOnFabricIOS() { return flagValue.value(); } -bool ReactNativeFeatureFlagsAccessor::enableAndroidLineHeightCentering() { - auto flagValue = enableAndroidLineHeightCentering_.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(5, "enableAndroidLineHeightCentering"); - - flagValue = currentProvider_->enableAndroidLineHeightCentering(); - enableAndroidLineHeightCentering_ = flagValue; - } - - return flagValue.value(); -} - bool ReactNativeFeatureFlagsAccessor::enableBridgelessArchitecture() { auto flagValue = enableBridgelessArchitecture_.load(); @@ -146,7 +128,7 @@ bool ReactNativeFeatureFlagsAccessor::enableBridgelessArchitecture() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(6, "enableBridgelessArchitecture"); + markFlagAsAccessed(5, "enableBridgelessArchitecture"); flagValue = currentProvider_->enableBridgelessArchitecture(); enableBridgelessArchitecture_ = flagValue; @@ -164,7 +146,7 @@ bool ReactNativeFeatureFlagsAccessor::enableCleanTextInputYogaNode() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(7, "enableCleanTextInputYogaNode"); + markFlagAsAccessed(6, "enableCleanTextInputYogaNode"); flagValue = currentProvider_->enableCleanTextInputYogaNode(); enableCleanTextInputYogaNode_ = flagValue; @@ -182,7 +164,7 @@ bool ReactNativeFeatureFlagsAccessor::enableDeletionOfUnmountedViews() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(8, "enableDeletionOfUnmountedViews"); + markFlagAsAccessed(7, "enableDeletionOfUnmountedViews"); flagValue = currentProvider_->enableDeletionOfUnmountedViews(); enableDeletionOfUnmountedViews_ = flagValue; @@ -200,7 +182,7 @@ bool ReactNativeFeatureFlagsAccessor::enableEagerRootViewAttachment() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(9, "enableEagerRootViewAttachment"); + markFlagAsAccessed(8, "enableEagerRootViewAttachment"); flagValue = currentProvider_->enableEagerRootViewAttachment(); enableEagerRootViewAttachment_ = flagValue; @@ -218,7 +200,7 @@ bool ReactNativeFeatureFlagsAccessor::enableEventEmitterRetentionDuringGesturesO // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(10, "enableEventEmitterRetentionDuringGesturesOnAndroid"); + markFlagAsAccessed(9, "enableEventEmitterRetentionDuringGesturesOnAndroid"); flagValue = currentProvider_->enableEventEmitterRetentionDuringGesturesOnAndroid(); enableEventEmitterRetentionDuringGesturesOnAndroid_ = flagValue; @@ -236,7 +218,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricLogs() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(11, "enableFabricLogs"); + markFlagAsAccessed(10, "enableFabricLogs"); flagValue = currentProvider_->enableFabricLogs(); enableFabricLogs_ = flagValue; @@ -254,7 +236,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricRenderer() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(12, "enableFabricRenderer"); + markFlagAsAccessed(11, "enableFabricRenderer"); flagValue = currentProvider_->enableFabricRenderer(); enableFabricRenderer_ = flagValue; @@ -272,7 +254,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricRendererExclusively() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(13, "enableFabricRendererExclusively"); + markFlagAsAccessed(12, "enableFabricRendererExclusively"); flagValue = currentProvider_->enableFabricRendererExclusively(); enableFabricRendererExclusively_ = flagValue; @@ -290,7 +272,7 @@ bool ReactNativeFeatureFlagsAccessor::enableGranularShadowTreeStateReconciliatio // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(14, "enableGranularShadowTreeStateReconciliation"); + markFlagAsAccessed(13, "enableGranularShadowTreeStateReconciliation"); flagValue = currentProvider_->enableGranularShadowTreeStateReconciliation(); enableGranularShadowTreeStateReconciliation_ = flagValue; @@ -308,7 +290,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIOSViewClipToPaddingBox() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(15, "enableIOSViewClipToPaddingBox"); + markFlagAsAccessed(14, "enableIOSViewClipToPaddingBox"); flagValue = currentProvider_->enableIOSViewClipToPaddingBox(); enableIOSViewClipToPaddingBox_ = flagValue; @@ -326,7 +308,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(16, "enableLayoutAnimationsOnAndroid"); + markFlagAsAccessed(15, "enableLayoutAnimationsOnAndroid"); flagValue = currentProvider_->enableLayoutAnimationsOnAndroid(); enableLayoutAnimationsOnAndroid_ = flagValue; @@ -344,7 +326,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(17, "enableLayoutAnimationsOnIOS"); + markFlagAsAccessed(16, "enableLayoutAnimationsOnIOS"); flagValue = currentProvider_->enableLayoutAnimationsOnIOS(); enableLayoutAnimationsOnIOS_ = flagValue; @@ -353,6 +335,42 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnIOS() { return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::enableLineHeightCenteringOnAndroid() { + auto flagValue = enableLineHeightCenteringOnAndroid_.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, "enableLineHeightCenteringOnAndroid"); + + flagValue = currentProvider_->enableLineHeightCenteringOnAndroid(); + enableLineHeightCenteringOnAndroid_ = flagValue; + } + + return flagValue.value(); +} + +bool ReactNativeFeatureFlagsAccessor::enableLineHeightCenteringOnIOS() { + auto flagValue = enableLineHeightCenteringOnIOS_.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(18, "enableLineHeightCenteringOnIOS"); + + flagValue = currentProvider_->enableLineHeightCenteringOnIOS(); + enableLineHeightCenteringOnIOS_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::enableLongTaskAPI() { auto flagValue = enableLongTaskAPI_.load(); @@ -362,7 +380,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLongTaskAPI() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(18, "enableLongTaskAPI"); + markFlagAsAccessed(19, "enableLongTaskAPI"); flagValue = currentProvider_->enableLongTaskAPI(); enableLongTaskAPI_ = flagValue; @@ -380,7 +398,7 @@ bool ReactNativeFeatureFlagsAccessor::enableMicrotasks() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(19, "enableMicrotasks"); + markFlagAsAccessed(20, "enableMicrotasks"); flagValue = currentProvider_->enableMicrotasks(); enableMicrotasks_ = flagValue; @@ -398,7 +416,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePreciseSchedulingForPremountItemsOnA // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(20, "enablePreciseSchedulingForPremountItemsOnAndroid"); + markFlagAsAccessed(21, "enablePreciseSchedulingForPremountItemsOnAndroid"); flagValue = currentProvider_->enablePreciseSchedulingForPremountItemsOnAndroid(); enablePreciseSchedulingForPremountItemsOnAndroid_ = flagValue; @@ -416,7 +434,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePropsUpdateReconciliationAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(21, "enablePropsUpdateReconciliationAndroid"); + markFlagAsAccessed(22, "enablePropsUpdateReconciliationAndroid"); flagValue = currentProvider_->enablePropsUpdateReconciliationAndroid(); enablePropsUpdateReconciliationAndroid_ = flagValue; @@ -434,7 +452,7 @@ bool ReactNativeFeatureFlagsAccessor::enableReportEventPaintTime() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(22, "enableReportEventPaintTime"); + markFlagAsAccessed(23, "enableReportEventPaintTime"); flagValue = currentProvider_->enableReportEventPaintTime(); enableReportEventPaintTime_ = flagValue; @@ -452,7 +470,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSynchronousStateUpdates() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(23, "enableSynchronousStateUpdates"); + markFlagAsAccessed(24, "enableSynchronousStateUpdates"); flagValue = currentProvider_->enableSynchronousStateUpdates(); enableSynchronousStateUpdates_ = flagValue; @@ -470,7 +488,7 @@ bool ReactNativeFeatureFlagsAccessor::enableTextPreallocationOptimisation() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(24, "enableTextPreallocationOptimisation"); + markFlagAsAccessed(25, "enableTextPreallocationOptimisation"); flagValue = currentProvider_->enableTextPreallocationOptimisation(); enableTextPreallocationOptimisation_ = flagValue; @@ -488,7 +506,7 @@ bool ReactNativeFeatureFlagsAccessor::enableUIConsistency() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(25, "enableUIConsistency"); + markFlagAsAccessed(26, "enableUIConsistency"); flagValue = currentProvider_->enableUIConsistency(); enableUIConsistency_ = flagValue; @@ -506,7 +524,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecycling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(26, "enableViewRecycling"); + markFlagAsAccessed(27, "enableViewRecycling"); flagValue = currentProvider_->enableViewRecycling(); enableViewRecycling_ = flagValue; @@ -524,7 +542,7 @@ bool ReactNativeFeatureFlagsAccessor::excludeYogaFromRawProps() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(27, "excludeYogaFromRawProps"); + markFlagAsAccessed(28, "excludeYogaFromRawProps"); flagValue = currentProvider_->excludeYogaFromRawProps(); excludeYogaFromRawProps_ = flagValue; @@ -542,7 +560,7 @@ bool ReactNativeFeatureFlagsAccessor::fetchImagesInViewPreallocation() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(28, "fetchImagesInViewPreallocation"); + markFlagAsAccessed(29, "fetchImagesInViewPreallocation"); flagValue = currentProvider_->fetchImagesInViewPreallocation(); fetchImagesInViewPreallocation_ = flagValue; @@ -560,7 +578,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMappingOfEventPrioritiesBetweenFabricAn // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(29, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); + markFlagAsAccessed(30, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact(); fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue; @@ -578,7 +596,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMountingCoordinatorReportedPendingTrans // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(30, "fixMountingCoordinatorReportedPendingTransactionsOnAndroid"); + markFlagAsAccessed(31, "fixMountingCoordinatorReportedPendingTransactionsOnAndroid"); flagValue = currentProvider_->fixMountingCoordinatorReportedPendingTransactionsOnAndroid(); fixMountingCoordinatorReportedPendingTransactionsOnAndroid_ = flagValue; @@ -596,7 +614,7 @@ bool ReactNativeFeatureFlagsAccessor::forceBatchingMountItemsOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(31, "forceBatchingMountItemsOnAndroid"); + markFlagAsAccessed(32, "forceBatchingMountItemsOnAndroid"); flagValue = currentProvider_->forceBatchingMountItemsOnAndroid(); forceBatchingMountItemsOnAndroid_ = flagValue; @@ -614,7 +632,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledDebug() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(32, "fuseboxEnabledDebug"); + markFlagAsAccessed(33, "fuseboxEnabledDebug"); flagValue = currentProvider_->fuseboxEnabledDebug(); fuseboxEnabledDebug_ = flagValue; @@ -632,7 +650,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledRelease() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(33, "fuseboxEnabledRelease"); + markFlagAsAccessed(34, "fuseboxEnabledRelease"); flagValue = currentProvider_->fuseboxEnabledRelease(); fuseboxEnabledRelease_ = flagValue; @@ -650,7 +668,7 @@ bool ReactNativeFeatureFlagsAccessor::initEagerTurboModulesOnNativeModulesQueueA // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(34, "initEagerTurboModulesOnNativeModulesQueueAndroid"); + markFlagAsAccessed(35, "initEagerTurboModulesOnNativeModulesQueueAndroid"); flagValue = currentProvider_->initEagerTurboModulesOnNativeModulesQueueAndroid(); initEagerTurboModulesOnNativeModulesQueueAndroid_ = flagValue; @@ -668,7 +686,7 @@ bool ReactNativeFeatureFlagsAccessor::lazyAnimationCallbacks() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(35, "lazyAnimationCallbacks"); + markFlagAsAccessed(36, "lazyAnimationCallbacks"); flagValue = currentProvider_->lazyAnimationCallbacks(); lazyAnimationCallbacks_ = flagValue; @@ -686,7 +704,7 @@ bool ReactNativeFeatureFlagsAccessor::loadVectorDrawablesOnImages() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(36, "loadVectorDrawablesOnImages"); + markFlagAsAccessed(37, "loadVectorDrawablesOnImages"); flagValue = currentProvider_->loadVectorDrawablesOnImages(); loadVectorDrawablesOnImages_ = flagValue; @@ -704,7 +722,7 @@ bool ReactNativeFeatureFlagsAccessor::setAndroidLayoutDirection() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(37, "setAndroidLayoutDirection"); + markFlagAsAccessed(38, "setAndroidLayoutDirection"); flagValue = currentProvider_->setAndroidLayoutDirection(); setAndroidLayoutDirection_ = flagValue; @@ -722,7 +740,7 @@ bool ReactNativeFeatureFlagsAccessor::traceTurboModulePromiseRejectionsOnAndroid // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(38, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(39, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -740,7 +758,7 @@ bool ReactNativeFeatureFlagsAccessor::useFabricInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(39, "useFabricInterop"); + markFlagAsAccessed(40, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -758,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::useImmediateExecutorInAndroidBridgeless() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(40, "useImmediateExecutorInAndroidBridgeless"); + markFlagAsAccessed(41, "useImmediateExecutorInAndroidBridgeless"); flagValue = currentProvider_->useImmediateExecutorInAndroidBridgeless(); useImmediateExecutorInAndroidBridgeless_ = flagValue; @@ -776,7 +794,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(41, "useModernRuntimeScheduler"); + markFlagAsAccessed(42, "useModernRuntimeScheduler"); flagValue = currentProvider_->useModernRuntimeScheduler(); useModernRuntimeScheduler_ = flagValue; @@ -794,7 +812,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(42, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(43, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -812,7 +830,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimisedViewPreallocationOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(43, "useOptimisedViewPreallocationOnAndroid"); + markFlagAsAccessed(44, "useOptimisedViewPreallocationOnAndroid"); flagValue = currentProvider_->useOptimisedViewPreallocationOnAndroid(); useOptimisedViewPreallocationOnAndroid_ = flagValue; @@ -830,7 +848,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimizedEventBatchingOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(44, "useOptimizedEventBatchingOnAndroid"); + markFlagAsAccessed(45, "useOptimizedEventBatchingOnAndroid"); flagValue = currentProvider_->useOptimizedEventBatchingOnAndroid(); useOptimizedEventBatchingOnAndroid_ = flagValue; @@ -848,7 +866,7 @@ bool ReactNativeFeatureFlagsAccessor::useRuntimeShadowNodeReferenceUpdate() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(45, "useRuntimeShadowNodeReferenceUpdate"); + markFlagAsAccessed(46, "useRuntimeShadowNodeReferenceUpdate"); flagValue = currentProvider_->useRuntimeShadowNodeReferenceUpdate(); useRuntimeShadowNodeReferenceUpdate_ = flagValue; @@ -866,7 +884,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModuleInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(46, "useTurboModuleInterop"); + markFlagAsAccessed(47, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -884,7 +902,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModules() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(47, "useTurboModules"); + markFlagAsAccessed(48, "useTurboModules"); flagValue = currentProvider_->useTurboModules(); useTurboModules_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index a91cf698a9291d..c2dfb8bc410ef2 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<> + * @generated SignedSource<<8a51ea4d038abf17da8f113109d73989>> */ /** @@ -37,7 +37,6 @@ class ReactNativeFeatureFlagsAccessor { bool batchRenderingUpdatesInEventLoop(); bool completeReactInstanceCreationOnBgThreadOnAndroid(); bool enableAlignItemsBaselineOnFabricIOS(); - bool enableAndroidLineHeightCentering(); bool enableBridgelessArchitecture(); bool enableCleanTextInputYogaNode(); bool enableDeletionOfUnmountedViews(); @@ -50,6 +49,8 @@ class ReactNativeFeatureFlagsAccessor { bool enableIOSViewClipToPaddingBox(); bool enableLayoutAnimationsOnAndroid(); bool enableLayoutAnimationsOnIOS(); + bool enableLineHeightCenteringOnAndroid(); + bool enableLineHeightCenteringOnIOS(); bool enableLongTaskAPI(); bool enableMicrotasks(); bool enablePreciseSchedulingForPremountItemsOnAndroid(); @@ -91,14 +92,13 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 48> accessedFeatureFlags_; + std::array, 49> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> allowRecursiveCommitsWithSynchronousMountOnAndroid_; std::atomic> batchRenderingUpdatesInEventLoop_; std::atomic> completeReactInstanceCreationOnBgThreadOnAndroid_; std::atomic> enableAlignItemsBaselineOnFabricIOS_; - std::atomic> enableAndroidLineHeightCentering_; std::atomic> enableBridgelessArchitecture_; std::atomic> enableCleanTextInputYogaNode_; std::atomic> enableDeletionOfUnmountedViews_; @@ -111,6 +111,8 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> enableIOSViewClipToPaddingBox_; std::atomic> enableLayoutAnimationsOnAndroid_; std::atomic> enableLayoutAnimationsOnIOS_; + std::atomic> enableLineHeightCenteringOnAndroid_; + std::atomic> enableLineHeightCenteringOnIOS_; std::atomic> enableLongTaskAPI_; std::atomic> enableMicrotasks_; std::atomic> enablePreciseSchedulingForPremountItemsOnAndroid_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 5155dce2b4383a..7093f67313cff3 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<<079a09e6be3d2154e1cb65d58cfe792f>> + * @generated SignedSource<<01e5fa84a8416b540bec0797dcd40792>> */ /** @@ -47,10 +47,6 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return true; } - bool enableAndroidLineHeightCentering() override { - return false; - } - bool enableBridgelessArchitecture() override { return false; } @@ -99,6 +95,14 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return true; } + bool enableLineHeightCenteringOnAndroid() override { + return false; + } + + bool enableLineHeightCenteringOnIOS() override { + return false; + } + bool enableLongTaskAPI() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index 1f899448871802..607da928c657d3 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<<82b82bb4e685d432198b58803edadae4>> */ /** @@ -30,7 +30,6 @@ class ReactNativeFeatureFlagsProvider { virtual bool batchRenderingUpdatesInEventLoop() = 0; virtual bool completeReactInstanceCreationOnBgThreadOnAndroid() = 0; virtual bool enableAlignItemsBaselineOnFabricIOS() = 0; - virtual bool enableAndroidLineHeightCentering() = 0; virtual bool enableBridgelessArchitecture() = 0; virtual bool enableCleanTextInputYogaNode() = 0; virtual bool enableDeletionOfUnmountedViews() = 0; @@ -43,6 +42,8 @@ class ReactNativeFeatureFlagsProvider { virtual bool enableIOSViewClipToPaddingBox() = 0; virtual bool enableLayoutAnimationsOnAndroid() = 0; virtual bool enableLayoutAnimationsOnIOS() = 0; + virtual bool enableLineHeightCenteringOnAndroid() = 0; + virtual bool enableLineHeightCenteringOnIOS() = 0; virtual bool enableLongTaskAPI() = 0; virtual bool enableMicrotasks() = 0; virtual bool enablePreciseSchedulingForPremountItemsOnAndroid() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index 2e48f9cffabf38..026094a70e0c9c 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<<78ccaa6556b191a1e86aee8b74d8939f>> + * @generated SignedSource<<27fdafbfd349a23f7d608b447d1605ba>> */ /** @@ -62,11 +62,6 @@ bool NativeReactNativeFeatureFlags::enableAlignItemsBaselineOnFabricIOS( return ReactNativeFeatureFlags::enableAlignItemsBaselineOnFabricIOS(); } -bool NativeReactNativeFeatureFlags::enableAndroidLineHeightCentering( - jsi::Runtime& /*runtime*/) { - return ReactNativeFeatureFlags::enableAndroidLineHeightCentering(); -} - bool NativeReactNativeFeatureFlags::enableBridgelessArchitecture( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::enableBridgelessArchitecture(); @@ -127,6 +122,16 @@ bool NativeReactNativeFeatureFlags::enableLayoutAnimationsOnIOS( return ReactNativeFeatureFlags::enableLayoutAnimationsOnIOS(); } +bool NativeReactNativeFeatureFlags::enableLineHeightCenteringOnAndroid( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::enableLineHeightCenteringOnAndroid(); +} + +bool NativeReactNativeFeatureFlags::enableLineHeightCenteringOnIOS( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::enableLineHeightCenteringOnIOS(); +} + bool NativeReactNativeFeatureFlags::enableLongTaskAPI( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::enableLongTaskAPI(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index 53b51e736772b7..5918a8b5d7f90c 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<<7abbf20a370e97c2ef0e59bef4f6164a>> + * @generated SignedSource<<21cc50aeedbf6c396494a6129455f94e>> */ /** @@ -45,8 +45,6 @@ class NativeReactNativeFeatureFlags bool enableAlignItemsBaselineOnFabricIOS(jsi::Runtime& runtime); - bool enableAndroidLineHeightCentering(jsi::Runtime& runtime); - bool enableBridgelessArchitecture(jsi::Runtime& runtime); bool enableCleanTextInputYogaNode(jsi::Runtime& runtime); @@ -71,6 +69,10 @@ class NativeReactNativeFeatureFlags bool enableLayoutAnimationsOnIOS(jsi::Runtime& runtime); + bool enableLineHeightCenteringOnAndroid(jsi::Runtime& runtime); + + bool enableLineHeightCenteringOnIOS(jsi::Runtime& runtime); + bool enableLongTaskAPI(jsi::Runtime& runtime); bool enableMicrotasks(jsi::Runtime& runtime); diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index c3b8d503dfd929..0a7d9350df60b6 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -80,15 +80,6 @@ const definitions: FeatureFlagDefinitions = { purpose: 'experimentation', }, }, - enableAndroidLineHeightCentering: { - defaultValue: false, - metadata: { - dateAdded: '2024-09-11', - description: - 'When enabled, custom line height calculation will be centered from top to bottom.', - purpose: 'experimentation', - }, - }, enableBridgelessArchitecture: { defaultValue: false, metadata: { @@ -187,6 +178,24 @@ const definitions: FeatureFlagDefinitions = { purpose: 'release', }, }, + enableLineHeightCenteringOnAndroid: { + defaultValue: false, + metadata: { + dateAdded: '2024-09-11', + description: + 'When enabled, custom line height calculation will be centered from top to bottom.', + purpose: 'experimentation', + }, + }, + enableLineHeightCenteringOnIOS: { + defaultValue: false, + metadata: { + dateAdded: '2024-10-11', + description: + 'When enabled, custom line height calculation will be centered from top to bottom.', + purpose: 'experimentation', + }, + }, enableLongTaskAPI: { defaultValue: false, metadata: { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index bcd9820e354b84..1e848e164244bf 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<<0d6a473cc1c76dc73fe70eb557b6da60>> + * @generated SignedSource<> * @flow strict */ @@ -55,7 +55,6 @@ export type ReactNativeFeatureFlags = { batchRenderingUpdatesInEventLoop: Getter, completeReactInstanceCreationOnBgThreadOnAndroid: Getter, enableAlignItemsBaselineOnFabricIOS: Getter, - enableAndroidLineHeightCentering: Getter, enableBridgelessArchitecture: Getter, enableCleanTextInputYogaNode: Getter, enableDeletionOfUnmountedViews: Getter, @@ -68,6 +67,8 @@ export type ReactNativeFeatureFlags = { enableIOSViewClipToPaddingBox: Getter, enableLayoutAnimationsOnAndroid: Getter, enableLayoutAnimationsOnIOS: Getter, + enableLineHeightCenteringOnAndroid: Getter, + enableLineHeightCenteringOnIOS: Getter, enableLongTaskAPI: Getter, enableMicrotasks: Getter, enablePreciseSchedulingForPremountItemsOnAndroid: Getter, @@ -205,10 +206,6 @@ export const completeReactInstanceCreationOnBgThreadOnAndroid: Getter = * Kill-switch to turn off support for aling-items:baseline on Fabric iOS. */ export const enableAlignItemsBaselineOnFabricIOS: Getter = createNativeFlagGetter('enableAlignItemsBaselineOnFabricIOS', true); -/** - * When enabled, custom line height calculation will be centered from top to bottom. - */ -export const enableAndroidLineHeightCentering: Getter = createNativeFlagGetter('enableAndroidLineHeightCentering', false); /** * Feature flag to enable the new bridgeless architecture. Note: Enabling this will force enable the following flags: `useTurboModules` & `enableFabricRenderer. */ @@ -257,6 +254,14 @@ export const enableLayoutAnimationsOnAndroid: Getter = createNativeFlag * When enabled, LayoutAnimations API will animate state changes on iOS. */ export const enableLayoutAnimationsOnIOS: Getter = createNativeFlagGetter('enableLayoutAnimationsOnIOS', true); +/** + * When enabled, custom line height calculation will be centered from top to bottom. + */ +export const enableLineHeightCenteringOnAndroid: Getter = createNativeFlagGetter('enableLineHeightCenteringOnAndroid', false); +/** + * When enabled, custom line height calculation will be centered from top to bottom. + */ +export const enableLineHeightCenteringOnIOS: Getter = createNativeFlagGetter('enableLineHeightCenteringOnIOS', false); /** * Enables the reporting of long tasks through `PerformanceObserver`. Only works if the event loop is enabled. */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index e2bb20b3ef210a..18e22913d091b7 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<<9f1fdcadab63bdd81d7992329113e90b>> * @flow strict */ @@ -28,7 +28,6 @@ export interface Spec extends TurboModule { +batchRenderingUpdatesInEventLoop?: () => boolean; +completeReactInstanceCreationOnBgThreadOnAndroid?: () => boolean; +enableAlignItemsBaselineOnFabricIOS?: () => boolean; - +enableAndroidLineHeightCentering?: () => boolean; +enableBridgelessArchitecture?: () => boolean; +enableCleanTextInputYogaNode?: () => boolean; +enableDeletionOfUnmountedViews?: () => boolean; @@ -41,6 +40,8 @@ export interface Spec extends TurboModule { +enableIOSViewClipToPaddingBox?: () => boolean; +enableLayoutAnimationsOnAndroid?: () => boolean; +enableLayoutAnimationsOnIOS?: () => boolean; + +enableLineHeightCenteringOnAndroid?: () => boolean; + +enableLineHeightCenteringOnIOS?: () => boolean; +enableLongTaskAPI?: () => boolean; +enableMicrotasks?: () => boolean; +enablePreciseSchedulingForPremountItemsOnAndroid?: () => boolean; diff --git a/packages/rn-tester/Podfile b/packages/rn-tester/Podfile index 7e723ec52341e6..9b692c4bd5b16f 100644 --- a/packages/rn-tester/Podfile +++ b/packages/rn-tester/Podfile @@ -54,6 +54,7 @@ def pods(target_name, options = {}) # Additional Pods which aren't included in the default Podfile pod 'React-RCTPushNotification', :path => "#{@prefix_path}/Libraries/PushNotificationIOS" + pod 'React-featureflags', :path => "#{@prefix_path}/ReactCommon/react/featureflags" # Additional Pods which are classed as unstable # RNTester native modules and components