From 3a8c0eb85850287fa9a845ab1bf77ad038939ac0 Mon Sep 17 00:00:00 2001 From: Joe Vilches Date: Thu, 29 Aug 2024 12:56:26 -0700 Subject: [PATCH] Decouple clipping logic from border drawing (#46191) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/46191 Borders should not have to deal with clipping logic, that is fairly independent. Changelog: [Internal] Reviewed By: lenaic Differential Revision: D61418470 --- .../View/RCTViewComponentView.mm | 105 +++++++++++------- .../featureflags/ReactNativeFeatureFlags.kt | 8 +- .../ReactNativeFeatureFlagsCxxAccessor.kt | 12 +- .../ReactNativeFeatureFlagsCxxInterop.kt | 4 +- .../ReactNativeFeatureFlagsDefaults.kt | 4 +- .../ReactNativeFeatureFlagsLocalAccessor.kt | 13 ++- .../ReactNativeFeatureFlagsProvider.kt | 4 +- .../JReactNativeFeatureFlagsCxxInterop.cpp | 16 ++- .../JReactNativeFeatureFlagsCxxInterop.h | 5 +- .../featureflags/ReactNativeFeatureFlags.cpp | 6 +- .../featureflags/ReactNativeFeatureFlags.h | 7 +- .../ReactNativeFeatureFlagsAccessor.cpp | 84 ++++++++------ .../ReactNativeFeatureFlagsAccessor.h | 6 +- .../ReactNativeFeatureFlagsDefaults.h | 6 +- .../ReactNativeFeatureFlagsProvider.h | 3 +- .../NativeReactNativeFeatureFlags.cpp | 7 +- .../NativeReactNativeFeatureFlags.h | 4 +- .../ReactNativeFeatureFlags.config.js | 4 + .../featureflags/ReactNativeFeatureFlags.js | 7 +- .../specs/NativeReactNativeFeatureFlags.js | 3 +- 20 files changed, 217 insertions(+), 91 deletions(-) diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm index 1d9570cd764d06..bcebeda597d8de 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm @@ -16,6 +16,7 @@ #import #import #import +#import #import #import #import @@ -308,7 +309,7 @@ - (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared & // `overflow` if (oldViewProps.getClipsContentToBounds() != newViewProps.getClipsContentToBounds()) { - self.clipsToBounds = newViewProps.getClipsContentToBounds(); + self.currentContainerView.clipsToBounds = newViewProps.getClipsContentToBounds(); needsInvalidateLayer = YES; } @@ -577,7 +578,6 @@ - (void)prepareForRecycle _eventEmitter.reset(); _isJSResponder = NO; _removeClippedSubviews = NO; - _useCustomContainerView = NO; _reactSubviews = [NSMutableArray new]; } @@ -605,7 +605,7 @@ - (UIView *)betterHitTest:(CGPoint)point withEvent:(UIEvent *)event BOOL isPointInside = [self pointInside:point withEvent:event]; - BOOL clipsToBounds = self.clipsToBounds; + BOOL clipsToBounds = self.currentContainerView.clipsToBounds; clipsToBounds = clipsToBounds || _layoutMetrics.overflowInset == EdgeInsets{}; @@ -696,7 +696,8 @@ - (BOOL)styleWouldClipOverflowInk { const auto borderMetrics = _props->resolveBorderMetrics(_layoutMetrics); BOOL nonZeroBorderWidth = !(borderMetrics.borderWidths.isUniform() && borderMetrics.borderWidths.left == 0); - return _props->getClipsContentToBounds() && (!_props->boxShadow.empty() || nonZeroBorderWidth); + BOOL clipToPaddingBox = ReactNativeFeatureFlags::enableIOSViewClipToPaddingBox(); + return _props->getClipsContentToBounds() && (!_props->boxShadow.empty() || (clipToPaddingBox && nonZeroBorderWidth)); } // This UIView is the UIView that holds all subviews. It is sometimes not self @@ -710,6 +711,10 @@ - (UIView *)currentContainerView for (UIView *subview in self.subviews) { [_containerView addSubview:subview]; } + _containerView.clipsToBounds = self.clipsToBounds; + self.clipsToBounds = NO; + _containerView.layer.mask = self.layer.mask; + self.layer.mask = nil; [self addSubview:_containerView]; } @@ -719,6 +724,8 @@ - (UIView *)currentContainerView for (UIView *subview in _containerView.subviews) { [self addSubview:subview]; } + self.clipsToBounds = _containerView.clipsToBounds; + self.layer.mask = _containerView.layer.mask; [_containerView removeFromSuperview]; _containerView = nil; } @@ -788,7 +795,7 @@ - (void)invalidateLayer // iOS draws borders in front of the content whereas CSS draws them behind // the content. For this reason, only use iOS border drawing when clipping // or when the border is hidden. - borderMetrics.borderWidths.left == 0 || self.clipsToBounds || + borderMetrics.borderWidths.left == 0 || self.currentContainerView.clipsToBounds || (colorComponentsFromColor(borderMetrics.borderColors.left).alpha == 0 && (*borderMetrics.borderColors.left).getUIColor() != nullptr)); @@ -813,17 +820,25 @@ - (void)invalidateLayer [self.layer addSublayer:_backgroundColorLayer]; } - CAShapeLayer *maskLayer = [self - createMaskLayer:self.bounds - cornerInsets:RCTGetCornerInsets(RCTCornerRadiiFromBorderRadii(borderMetrics.borderRadii), UIEdgeInsetsZero)]; _backgroundColorLayer.backgroundColor = backgroundColor; - _backgroundColorLayer.mask = maskLayer; + if (borderMetrics.borderRadii.isUniform()) { + _backgroundColorLayer.mask = nil; + _backgroundColorLayer.cornerRadius = borderMetrics.borderRadii.topLeft.horizontal; + _backgroundColorLayer.cornerCurve = CornerCurveFromBorderCurve(borderMetrics.borderCurves.topLeft); + } else { + CAShapeLayer *maskLayer = + [self createMaskLayer:self.bounds + cornerInsets:RCTGetCornerInsets( + RCTCornerRadiiFromBorderRadii(borderMetrics.borderRadii), UIEdgeInsetsZero)]; + _backgroundColorLayer.mask = maskLayer; + _backgroundColorLayer.cornerRadius = 0; + } } - // Stage 2. Border Rendering + // borders if (useCoreAnimationBorderRendering) { - layer.mask = nil; [_borderLayer removeFromSuperlayer]; + _borderLayer = nil; layer.borderWidth = (CGFloat)borderMetrics.borderWidths.left; CGColorRef borderColor = RCTCreateCGColorRefFromSharedColor(borderMetrics.borderColors.left); @@ -880,37 +895,9 @@ - (void)invalidateLayer // If mutations are applied inside of Animation block, it may cause _borderLayer to be animated. // To stop that, imperatively remove all animations from _borderLayer. [_borderLayer removeAllAnimations]; - - // Stage 2.5. Custom Clipping Mask - CAShapeLayer *maskLayer = nil; - CGFloat cornerRadius = 0; - if (self.clipsToBounds) { - if (borderMetrics.borderRadii.isUniform()) { - // In this case we can simply use `cornerRadius` exclusively. - cornerRadius = borderMetrics.borderRadii.topLeft.horizontal; - } else { - RCTCornerInsets cornerInsets = - RCTGetCornerInsets(RCTCornerRadiiFromBorderRadii(borderMetrics.borderRadii), UIEdgeInsetsZero); - maskLayer = [self createMaskLayer:self.bounds cornerInsets:cornerInsets]; - } - } - - layer.cornerRadius = cornerRadius; - layer.mask = maskLayer; - - for (UIView *subview in self.currentContainerView.subviews) { - if ([subview isKindOfClass:[UIImageView class]]) { - RCTCornerInsets cornerInsets = RCTGetCornerInsets( - RCTCornerRadiiFromBorderRadii(borderMetrics.borderRadii), - RCTUIEdgeInsetsFromEdgeInsets(borderMetrics.borderWidths)); - - // If the subview is an image view, we have to apply the mask directly to the image view's layer, - // otherwise the image might overflow with the border radius. - subview.layer.mask = [self createMaskLayer:subview.bounds cornerInsets:cornerInsets]; - } - } } + // filter [_filterLayer removeFromSuperlayer]; _filterLayer = nil; self.layer.opacity = (float)_props->opacity; @@ -947,6 +934,7 @@ - (void)invalidateLayer [self.layer addSublayer:_filterLayer]; } + // background image [self clearExistingGradientLayers]; if (!_props->backgroundImage.empty()) { for (const auto &gradient : _props->backgroundImage) { @@ -994,6 +982,7 @@ - (void)invalidateLayer } } + // box shadow [_boxShadowLayer removeFromSuperlayer]; _boxShadowLayer = nil; if (!_props->boxShadow.empty()) { @@ -1010,6 +999,42 @@ - (void)invalidateLayer _boxShadowLayer.contents = (id)boxShadowImage.CGImage; } + + // clipping + if (self.currentContainerView.clipsToBounds) { + BOOL clipToPaddingBox = ReactNativeFeatureFlags::enableIOSViewClipToPaddingBox(); + if (clipToPaddingBox) { + CALayer *maskLayer = [self createMaskLayer:RCTCGRectFromRect(_layoutMetrics.getPaddingFrame()) + cornerInsets:RCTGetCornerInsets( + RCTCornerRadiiFromBorderRadii(borderMetrics.borderRadii), + RCTUIEdgeInsetsFromEdgeInsets(borderMetrics.borderWidths))]; + self.currentContainerView.layer.mask = maskLayer; + } else { + if (borderMetrics.borderRadii.isUniform()) { + self.currentContainerView.layer.cornerRadius = borderMetrics.borderRadii.topLeft.horizontal; + } else { + CALayer *maskLayer = + [self createMaskLayer:self.bounds + cornerInsets:RCTGetCornerInsets( + RCTCornerRadiiFromBorderRadii(borderMetrics.borderRadii), UIEdgeInsetsZero)]; + self.currentContainerView.layer.mask = maskLayer; + } + + for (UIView *subview in self.currentContainerView.subviews) { + if ([subview isKindOfClass:[UIImageView class]]) { + RCTCornerInsets cornerInsets = RCTGetCornerInsets( + RCTCornerRadiiFromBorderRadii(borderMetrics.borderRadii), + RCTUIEdgeInsetsFromEdgeInsets(borderMetrics.borderWidths)); + + // If the subview is an image view, we have to apply the mask directly to the image view's layer, + // otherwise the image might overflow with the border radius. + subview.layer.mask = [self createMaskLayer:subview.bounds cornerInsets:cornerInsets]; + } + } + } + } else { + self.currentContainerView.layer.mask = nil; + } } - (CAShapeLayer *)createMaskLayer:(CGRect)bounds cornerInsets:(RCTCornerInsets)cornerInsets 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 c9e5e731a7b8b1..640274dcad085d 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<<8fa471e86dbaac07b3bee229de063392>> */ /** @@ -112,6 +112,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun enableGranularShadowTreeStateReconciliation(): Boolean = accessor.enableGranularShadowTreeStateReconciliation() + /** + * iOS Views will clip to their padding box vs border box + */ + @JvmStatic + public fun enableIOSViewClipToPaddingBox(): Boolean = accessor.enableIOSViewClipToPaddingBox() + /** * When enabled, LayoutAnimations API will animate state changes on iOS. */ 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 e00a8b171176fa..e95997c6515235 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<<9ed448a2c92f8494ac23b6d8e69e220d>> */ /** @@ -34,6 +34,7 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso private var enableFabricLogsCache: Boolean? = null private var enableFabricRendererExclusivelyCache: Boolean? = null private var enableGranularShadowTreeStateReconciliationCache: Boolean? = null + private var enableIOSViewClipToPaddingBoxCache: Boolean? = null private var enableLayoutAnimationsOnIOSCache: Boolean? = null private var enableLongTaskAPICache: Boolean? = null private var enableMicrotasksCache: Boolean? = null @@ -193,6 +194,15 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso return cached } + override fun enableIOSViewClipToPaddingBox(): Boolean { + var cached = enableIOSViewClipToPaddingBoxCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.enableIOSViewClipToPaddingBox() + enableIOSViewClipToPaddingBoxCache = cached + } + return cached + } + override fun enableLayoutAnimationsOnIOS(): Boolean { var cached = enableLayoutAnimationsOnIOSCache 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 d221e1420b827e..26e7206750ffa3 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<<580db8acae42a65aeb678d2d6ef4630c>> + * @generated SignedSource<> */ /** @@ -56,6 +56,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun enableGranularShadowTreeStateReconciliation(): Boolean + @DoNotStrip @JvmStatic public external fun enableIOSViewClipToPaddingBox(): Boolean + @DoNotStrip @JvmStatic public external fun enableLayoutAnimationsOnIOS(): Boolean @DoNotStrip @JvmStatic public external fun enableLongTaskAPI(): 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 f537181cd6546c..0dfd2393ecabeb 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<<00aae631e9d9b146fae9be838e04e165>> + * @generated SignedSource<<22f05fff5c867324d44729c5bf02dddb>> */ /** @@ -51,6 +51,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun enableGranularShadowTreeStateReconciliation(): Boolean = false + override fun enableIOSViewClipToPaddingBox(): Boolean = false + override fun enableLayoutAnimationsOnIOS(): Boolean = true override fun enableLongTaskAPI(): 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 4f41507f1b1103..0def0294db9bb2 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<> */ /** @@ -38,6 +38,7 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces private var enableFabricLogsCache: Boolean? = null private var enableFabricRendererExclusivelyCache: Boolean? = null private var enableGranularShadowTreeStateReconciliationCache: Boolean? = null + private var enableIOSViewClipToPaddingBoxCache: Boolean? = null private var enableLayoutAnimationsOnIOSCache: Boolean? = null private var enableLongTaskAPICache: Boolean? = null private var enableMicrotasksCache: Boolean? = null @@ -211,6 +212,16 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun enableIOSViewClipToPaddingBox(): Boolean { + var cached = enableIOSViewClipToPaddingBoxCache + if (cached == null) { + cached = currentProvider.enableIOSViewClipToPaddingBox() + accessedFeatureFlags.add("enableIOSViewClipToPaddingBox") + enableIOSViewClipToPaddingBoxCache = cached + } + return cached + } + override fun enableLayoutAnimationsOnIOS(): Boolean { var cached = enableLayoutAnimationsOnIOSCache 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 2226963318ce94..f7816779917842 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<<2c8c28515aa6929b975ef7193c8bf72e>> + * @generated SignedSource<<46e8ddef352182c1c6a9669caa7d5111>> */ /** @@ -51,6 +51,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun enableGranularShadowTreeStateReconciliation(): Boolean + @DoNotStrip public fun enableIOSViewClipToPaddingBox(): Boolean + @DoNotStrip public fun enableLayoutAnimationsOnIOS(): Boolean @DoNotStrip public fun enableLongTaskAPI(): Boolean 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 aff927743127e4..05ea8405b32477 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<<35f5003b77104e68e32741e4626e2ba6>> + * @generated SignedSource<<07d3bcf171990d2976f611a82d8fcd32>> */ /** @@ -123,6 +123,12 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } + bool enableIOSViewClipToPaddingBox() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableIOSViewClipToPaddingBox"); + return method(javaProvider_); + } + bool enableLayoutAnimationsOnIOS() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableLayoutAnimationsOnIOS"); @@ -389,6 +395,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableGranularShadowTreeStateReconcilia return ReactNativeFeatureFlags::enableGranularShadowTreeStateReconciliation(); } +bool JReactNativeFeatureFlagsCxxInterop::enableIOSViewClipToPaddingBox( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::enableIOSViewClipToPaddingBox(); +} + bool JReactNativeFeatureFlagsCxxInterop::enableLayoutAnimationsOnIOS( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::enableLayoutAnimationsOnIOS(); @@ -608,6 +619,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "enableGranularShadowTreeStateReconciliation", JReactNativeFeatureFlagsCxxInterop::enableGranularShadowTreeStateReconciliation), + makeNativeMethod( + "enableIOSViewClipToPaddingBox", + JReactNativeFeatureFlagsCxxInterop::enableIOSViewClipToPaddingBox), makeNativeMethod( "enableLayoutAnimationsOnIOS", JReactNativeFeatureFlagsCxxInterop::enableLayoutAnimationsOnIOS), 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 760d549343c2c9..d96398bfc3cf38 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<<2c2a6ebec94e8a30f112694c08f3166d>> */ /** @@ -72,6 +72,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool enableGranularShadowTreeStateReconciliation( facebook::jni::alias_ref); + static bool enableIOSViewClipToPaddingBox( + facebook::jni::alias_ref); + static bool enableLayoutAnimationsOnIOS( 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 a336b0da56a8e5..338a6ac52344d4 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<> + * @generated SignedSource<<89f23392636714a1c7cb285913230fac>> */ /** @@ -77,6 +77,10 @@ bool ReactNativeFeatureFlags::enableGranularShadowTreeStateReconciliation() { return getAccessor().enableGranularShadowTreeStateReconciliation(); } +bool ReactNativeFeatureFlags::enableIOSViewClipToPaddingBox() { + return getAccessor().enableIOSViewClipToPaddingBox(); +} + bool ReactNativeFeatureFlags::enableLayoutAnimationsOnIOS() { return getAccessor().enableLayoutAnimationsOnIOS(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index 63271e91427bb5..c3b824b43803d2 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<<748622d87b1051bbb1cd79fb479ab0e2>> + * @generated SignedSource<<3765fa5d78a5240a4326ec401cce9f22>> */ /** @@ -107,6 +107,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool enableGranularShadowTreeStateReconciliation(); + /** + * iOS Views will clip to their padding box vs border box + */ + RN_EXPORT static bool enableIOSViewClipToPaddingBox(); + /** * When enabled, LayoutAnimations API will animate state changes on iOS. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index 312b2e36eb03a6..0b46e2a639e067 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<<90f05e6a6a414704176234724ca1fc04>> + * @generated SignedSource<> */ /** @@ -281,6 +281,24 @@ bool ReactNativeFeatureFlagsAccessor::enableGranularShadowTreeStateReconciliatio return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::enableIOSViewClipToPaddingBox() { + auto flagValue = enableIOSViewClipToPaddingBox_.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(14, "enableIOSViewClipToPaddingBox"); + + flagValue = currentProvider_->enableIOSViewClipToPaddingBox(); + enableIOSViewClipToPaddingBox_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnIOS() { auto flagValue = enableLayoutAnimationsOnIOS_.load(); @@ -290,7 +308,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(14, "enableLayoutAnimationsOnIOS"); + markFlagAsAccessed(15, "enableLayoutAnimationsOnIOS"); flagValue = currentProvider_->enableLayoutAnimationsOnIOS(); enableLayoutAnimationsOnIOS_ = flagValue; @@ -308,7 +326,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(15, "enableLongTaskAPI"); + markFlagAsAccessed(16, "enableLongTaskAPI"); flagValue = currentProvider_->enableLongTaskAPI(); enableLongTaskAPI_ = flagValue; @@ -326,7 +344,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(16, "enableMicrotasks"); + markFlagAsAccessed(17, "enableMicrotasks"); flagValue = currentProvider_->enableMicrotasks(); enableMicrotasks_ = flagValue; @@ -344,7 +362,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(17, "enablePropsUpdateReconciliationAndroid"); + markFlagAsAccessed(18, "enablePropsUpdateReconciliationAndroid"); flagValue = currentProvider_->enablePropsUpdateReconciliationAndroid(); enablePropsUpdateReconciliationAndroid_ = flagValue; @@ -362,7 +380,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(18, "enableReportEventPaintTime"); + markFlagAsAccessed(19, "enableReportEventPaintTime"); flagValue = currentProvider_->enableReportEventPaintTime(); enableReportEventPaintTime_ = flagValue; @@ -380,7 +398,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(19, "enableSynchronousStateUpdates"); + markFlagAsAccessed(20, "enableSynchronousStateUpdates"); flagValue = currentProvider_->enableSynchronousStateUpdates(); enableSynchronousStateUpdates_ = flagValue; @@ -398,7 +416,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(20, "enableUIConsistency"); + markFlagAsAccessed(21, "enableUIConsistency"); flagValue = currentProvider_->enableUIConsistency(); enableUIConsistency_ = flagValue; @@ -416,7 +434,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(21, "enableViewRecycling"); + markFlagAsAccessed(22, "enableViewRecycling"); flagValue = currentProvider_->enableViewRecycling(); enableViewRecycling_ = flagValue; @@ -434,7 +452,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(22, "excludeYogaFromRawProps"); + markFlagAsAccessed(23, "excludeYogaFromRawProps"); flagValue = currentProvider_->excludeYogaFromRawProps(); excludeYogaFromRawProps_ = flagValue; @@ -452,7 +470,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(23, "fetchImagesInViewPreallocation"); + markFlagAsAccessed(24, "fetchImagesInViewPreallocation"); flagValue = currentProvider_->fetchImagesInViewPreallocation(); fetchImagesInViewPreallocation_ = flagValue; @@ -470,7 +488,7 @@ bool ReactNativeFeatureFlagsAccessor::fixIncorrectScrollViewStateUpdateOnAndroid // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(24, "fixIncorrectScrollViewStateUpdateOnAndroid"); + markFlagAsAccessed(25, "fixIncorrectScrollViewStateUpdateOnAndroid"); flagValue = currentProvider_->fixIncorrectScrollViewStateUpdateOnAndroid(); fixIncorrectScrollViewStateUpdateOnAndroid_ = flagValue; @@ -488,7 +506,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(25, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); + markFlagAsAccessed(26, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact(); fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue; @@ -506,7 +524,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMissedFabricStateUpdatesOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(26, "fixMissedFabricStateUpdatesOnAndroid"); + markFlagAsAccessed(27, "fixMissedFabricStateUpdatesOnAndroid"); flagValue = currentProvider_->fixMissedFabricStateUpdatesOnAndroid(); fixMissedFabricStateUpdatesOnAndroid_ = flagValue; @@ -524,7 +542,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(27, "fixMountingCoordinatorReportedPendingTransactionsOnAndroid"); + markFlagAsAccessed(28, "fixMountingCoordinatorReportedPendingTransactionsOnAndroid"); flagValue = currentProvider_->fixMountingCoordinatorReportedPendingTransactionsOnAndroid(); fixMountingCoordinatorReportedPendingTransactionsOnAndroid_ = flagValue; @@ -542,7 +560,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(28, "forceBatchingMountItemsOnAndroid"); + markFlagAsAccessed(29, "forceBatchingMountItemsOnAndroid"); flagValue = currentProvider_->forceBatchingMountItemsOnAndroid(); forceBatchingMountItemsOnAndroid_ = flagValue; @@ -560,7 +578,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(29, "fuseboxEnabledDebug"); + markFlagAsAccessed(30, "fuseboxEnabledDebug"); flagValue = currentProvider_->fuseboxEnabledDebug(); fuseboxEnabledDebug_ = flagValue; @@ -578,7 +596,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(30, "fuseboxEnabledRelease"); + markFlagAsAccessed(31, "fuseboxEnabledRelease"); flagValue = currentProvider_->fuseboxEnabledRelease(); fuseboxEnabledRelease_ = flagValue; @@ -596,7 +614,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(31, "initEagerTurboModulesOnNativeModulesQueueAndroid"); + markFlagAsAccessed(32, "initEagerTurboModulesOnNativeModulesQueueAndroid"); flagValue = currentProvider_->initEagerTurboModulesOnNativeModulesQueueAndroid(); initEagerTurboModulesOnNativeModulesQueueAndroid_ = flagValue; @@ -614,7 +632,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(32, "lazyAnimationCallbacks"); + markFlagAsAccessed(33, "lazyAnimationCallbacks"); flagValue = currentProvider_->lazyAnimationCallbacks(); lazyAnimationCallbacks_ = flagValue; @@ -632,7 +650,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(33, "loadVectorDrawablesOnImages"); + markFlagAsAccessed(34, "loadVectorDrawablesOnImages"); flagValue = currentProvider_->loadVectorDrawablesOnImages(); loadVectorDrawablesOnImages_ = flagValue; @@ -650,7 +668,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(34, "setAndroidLayoutDirection"); + markFlagAsAccessed(35, "setAndroidLayoutDirection"); flagValue = currentProvider_->setAndroidLayoutDirection(); setAndroidLayoutDirection_ = flagValue; @@ -668,7 +686,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(35, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(36, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -686,7 +704,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(36, "useFabricInterop"); + markFlagAsAccessed(37, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -704,7 +722,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(37, "useImmediateExecutorInAndroidBridgeless"); + markFlagAsAccessed(38, "useImmediateExecutorInAndroidBridgeless"); flagValue = currentProvider_->useImmediateExecutorInAndroidBridgeless(); useImmediateExecutorInAndroidBridgeless_ = flagValue; @@ -722,7 +740,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(38, "useModernRuntimeScheduler"); + markFlagAsAccessed(39, "useModernRuntimeScheduler"); flagValue = currentProvider_->useModernRuntimeScheduler(); useModernRuntimeScheduler_ = flagValue; @@ -740,7 +758,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(39, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(40, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -758,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::useNewReactImageViewBackgroundDrawing() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(40, "useNewReactImageViewBackgroundDrawing"); + markFlagAsAccessed(41, "useNewReactImageViewBackgroundDrawing"); flagValue = currentProvider_->useNewReactImageViewBackgroundDrawing(); useNewReactImageViewBackgroundDrawing_ = flagValue; @@ -776,7 +794,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(41, "useOptimisedViewPreallocationOnAndroid"); + markFlagAsAccessed(42, "useOptimisedViewPreallocationOnAndroid"); flagValue = currentProvider_->useOptimisedViewPreallocationOnAndroid(); useOptimisedViewPreallocationOnAndroid_ = flagValue; @@ -794,7 +812,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(42, "useRuntimeShadowNodeReferenceUpdate"); + markFlagAsAccessed(43, "useRuntimeShadowNodeReferenceUpdate"); flagValue = currentProvider_->useRuntimeShadowNodeReferenceUpdate(); useRuntimeShadowNodeReferenceUpdate_ = flagValue; @@ -812,7 +830,7 @@ bool ReactNativeFeatureFlagsAccessor::useRuntimeShadowNodeReferenceUpdateOnLayou // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(43, "useRuntimeShadowNodeReferenceUpdateOnLayout"); + markFlagAsAccessed(44, "useRuntimeShadowNodeReferenceUpdateOnLayout"); flagValue = currentProvider_->useRuntimeShadowNodeReferenceUpdateOnLayout(); useRuntimeShadowNodeReferenceUpdateOnLayout_ = flagValue; @@ -830,7 +848,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(44, "useStateAlignmentMechanism"); + markFlagAsAccessed(45, "useStateAlignmentMechanism"); flagValue = currentProvider_->useStateAlignmentMechanism(); useStateAlignmentMechanism_ = flagValue; @@ -848,7 +866,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(45, "useTurboModuleInterop"); + markFlagAsAccessed(46, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index 45b9d9bbc04b8c..1dd9fbb3273b5d 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<<2a71493572a1a2c8115f2561c8b1937d>> */ /** @@ -45,6 +45,7 @@ class ReactNativeFeatureFlagsAccessor { bool enableFabricLogs(); bool enableFabricRendererExclusively(); bool enableGranularShadowTreeStateReconciliation(); + bool enableIOSViewClipToPaddingBox(); bool enableLayoutAnimationsOnIOS(); bool enableLongTaskAPI(); bool enableMicrotasks(); @@ -87,7 +88,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 46> accessedFeatureFlags_; + std::array, 47> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> allowRecursiveCommitsWithSynchronousMountOnAndroid_; @@ -103,6 +104,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> enableFabricLogs_; std::atomic> enableFabricRendererExclusively_; std::atomic> enableGranularShadowTreeStateReconciliation_; + std::atomic> enableIOSViewClipToPaddingBox_; std::atomic> enableLayoutAnimationsOnIOS_; std::atomic> enableLongTaskAPI_; std::atomic> enableMicrotasks_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 90513ef6228796..eafa80524c2347 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<<2a6da297297ebd942e5842fd25666a5f>> */ /** @@ -83,6 +83,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool enableIOSViewClipToPaddingBox() override { + return false; + } + bool enableLayoutAnimationsOnIOS() override { return true; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index 8bf060efdcc50b..df49ba187bcf4c 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<<6bfd567b419f4dbb1a72470265fae271>> + * @generated SignedSource<<2a6b9519588ad43e54a794d4e56b6abe>> */ /** @@ -39,6 +39,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool enableFabricLogs() = 0; virtual bool enableFabricRendererExclusively() = 0; virtual bool enableGranularShadowTreeStateReconciliation() = 0; + virtual bool enableIOSViewClipToPaddingBox() = 0; virtual bool enableLayoutAnimationsOnIOS() = 0; virtual bool enableLongTaskAPI() = 0; virtual bool enableMicrotasks() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index f33a4a9be696ab..b3a9749657d7a4 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<<903710df33dd5666f8f2ddce79f66660>> + * @generated SignedSource<> */ /** @@ -107,6 +107,11 @@ bool NativeReactNativeFeatureFlags::enableGranularShadowTreeStateReconciliation( return ReactNativeFeatureFlags::enableGranularShadowTreeStateReconciliation(); } +bool NativeReactNativeFeatureFlags::enableIOSViewClipToPaddingBox( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::enableIOSViewClipToPaddingBox(); +} + bool NativeReactNativeFeatureFlags::enableLayoutAnimationsOnIOS( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::enableLayoutAnimationsOnIOS(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index 166b4071f13575..da3dbf9b219f66 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<<6d1f1233f646704d1403f984dabbb2e4>> + * @generated SignedSource<> */ /** @@ -63,6 +63,8 @@ class NativeReactNativeFeatureFlags bool enableGranularShadowTreeStateReconciliation(jsi::Runtime& runtime); + bool enableIOSViewClipToPaddingBox(jsi::Runtime& runtime); + bool enableLayoutAnimationsOnIOS(jsi::Runtime& runtime); bool enableLongTaskAPI(jsi::Runtime& runtime); diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 09b3f412d4a085..420a5f278aaafe 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -101,6 +101,10 @@ const definitions: FeatureFlagDefinitions = { description: 'When enabled, the renderer would only fail commits when they propagate state and the last commit that updated state changed before committing.', }, + enableIOSViewClipToPaddingBox: { + defaultValue: false, + description: 'iOS Views will clip to their padding box vs border box', + }, enableLayoutAnimationsOnIOS: { defaultValue: true, description: diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index b6e642d9b100fa..fab3eda1c2c89f 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<> + * @generated SignedSource<<60e0ce2ac07d65d757c1cf92c04d1a2a>> * @flow strict-local */ @@ -60,6 +60,7 @@ export type ReactNativeFeatureFlags = { enableFabricLogs: Getter, enableFabricRendererExclusively: Getter, enableGranularShadowTreeStateReconciliation: Getter, + enableIOSViewClipToPaddingBox: Getter, enableLayoutAnimationsOnIOS: Getter, enableLongTaskAPI: Getter, enableMicrotasks: Getter, @@ -220,6 +221,10 @@ export const enableFabricRendererExclusively: Getter = createNativeFlag * When enabled, the renderer would only fail commits when they propagate state and the last commit that updated state changed before committing. */ export const enableGranularShadowTreeStateReconciliation: Getter = createNativeFlagGetter('enableGranularShadowTreeStateReconciliation', false); +/** + * iOS Views will clip to their padding box vs border box + */ +export const enableIOSViewClipToPaddingBox: Getter = createNativeFlagGetter('enableIOSViewClipToPaddingBox', false); /** * When enabled, LayoutAnimations API will animate state changes on iOS. */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index 98c7d4b774b6c5..a67456f029ccfa 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<<0f11ba941f22bed8f3b43d1332dc4557>> + * @generated SignedSource<<29bbca2e83e9d92c4aac66c5bb46a47d>> * @flow strict-local */ @@ -37,6 +37,7 @@ export interface Spec extends TurboModule { +enableFabricLogs?: () => boolean; +enableFabricRendererExclusively?: () => boolean; +enableGranularShadowTreeStateReconciliation?: () => boolean; + +enableIOSViewClipToPaddingBox?: () => boolean; +enableLayoutAnimationsOnIOS?: () => boolean; +enableLongTaskAPI?: () => boolean; +enableMicrotasks?: () => boolean;