diff --git a/packages/react-native/Package.swift b/packages/react-native/Package.swift index bf6f3e98149ab6..3e1ee334e772ff 100644 --- a/packages/react-native/Package.swift +++ b/packages/react-native/Package.swift @@ -68,6 +68,17 @@ let reactOSCompat = RNTarget( path: "ReactCommon/oscompat" ) +let rctSwiftUI = RNTarget( + name: .rctSwiftUI, + path: "ReactApple/RCTSwiftUI" +) + +let rctSwiftUIWrapper = RNTarget( + name: .rctSwiftUIWrapper, + path: "ReactApple/RCTSwiftUIWrapper", + dependencies: [.rctSwiftUI] +) + // React-rendererconsistency.podspec let reactRendererConsistency = RNTarget( name: .reactRendererConsistency, @@ -417,7 +428,7 @@ let reactFabric = RNTarget( let reactRCTFabric = RNTarget( name: .reactRCTFabric, path: "React/Fabric", - dependencies: [.reactNativeDependencies, .reactCore, .reactRCTImage, .yoga, .reactRCTText, .jsi, .reactFabricComponents, .reactGraphics, .reactImageManager, .reactDebug, .reactUtils, .reactPerformanceTimeline, .reactRendererDebug, .reactRendererConsistency, .reactRuntimeScheduler, .reactRCTAnimation, .reactJsInspector, .reactJsInspectorNetwork, .reactJsInspectorTracing, .reactFabric, .reactFabricImage] + dependencies: [.reactNativeDependencies, .reactCore, .reactRCTImage, .yoga, .reactRCTText, .jsi, .reactFabricComponents, .reactGraphics, .reactImageManager, .reactDebug, .reactUtils, .reactPerformanceTimeline, .reactRendererDebug, .reactRendererConsistency, .reactRuntimeScheduler, .reactRCTAnimation, .reactJsInspector, .reactJsInspectorNetwork, .reactJsInspectorTracing, .reactFabric, .reactFabricImage, .rctSwiftUIWrapper] ) /// React-FabricComponents.podspec @@ -556,6 +567,8 @@ let targets = [ reactCore, reactCoreRCTWebsocket, reactFabric, + rctSwiftUI, + rctSwiftUIWrapper, reactRCTFabric, reactFabricComponents, reactFabricImage, @@ -703,6 +716,9 @@ extension String { static let logger = "React-logger" static let mapbuffer = "React-Mapbuffer" + static let rctSwiftUI = "RCTSwiftUI" + static let rctSwiftUIWrapper = "RCTSwiftUIWrapper" + static let rctDeprecation = "RCT-Deprecation" static let yoga = "Yoga" static let reactUtils = "React-utils" 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 ad9c47d161e97b..f1cd27faec1e3c 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm @@ -19,6 +19,7 @@ #import #import #import +#import #import #import #import @@ -50,6 +51,7 @@ @implementation RCTViewComponentView { UIView *_containerView; BOOL _useCustomContainerView; NSMutableSet *_accessibilityOrderNativeIDs; + RCTSwiftUIContainerViewWrapper* _swiftUIWrapper; } #ifdef RCT_DYNAMIC_FRAMEWORKS @@ -576,6 +578,10 @@ - (void)updateLayoutMetrics:(const LayoutMetrics &)layoutMetrics auto newTransform = _props->resolveTransform(layoutMetrics); self.layer.transform = RCTCATransform3DFromTransformMatrix(newTransform); } + + if (_swiftUIWrapper) { + [_swiftUIWrapper updateLayoutWithBounds:self.bounds]; + } } - (BOOL)isJSResponder @@ -793,44 +799,96 @@ - (BOOL)styleWouldClipOverflowInk ((!_props->boxShadow.empty() || (clipToPaddingBox && nonZeroBorderWidth)) || _props->outlineWidth != 0); } +// The view that is used as the receiver for all styling (borders, background, +// etc.). Most of the time, this is just `self`. When a view has a filter like +// `blur` applied, we need to wrap it in a SwiftUI view to render the effect. +// In this case, `effectiveContentView` will be the content view inside the +// SwiftUI wrapper. +- (UIView *)effectiveContentView +{ + if (!ReactNativeFeatureFlags::enableSwiftUIBasedFilters()) { + return self; + } + + UIView *effectiveContentView = self; + + if (self.styleNeedsSwiftUIContainer) { + if (!_swiftUIWrapper) { + _swiftUIWrapper = [RCTSwiftUIContainerViewWrapper new]; + UIView *swiftUIContentView = [[UIView alloc] init]; + for (UIView *subview in self.subviews) { + [swiftUIContentView addSubview:subview]; + } + swiftUIContentView.clipsToBounds = self.clipsToBounds; + self.clipsToBounds = NO; + swiftUIContentView.layer.mask = self.layer.mask; + self.layer.mask = nil; + [_swiftUIWrapper updateContentView:swiftUIContentView]; + [_swiftUIWrapper updateLayoutWithBounds:self.bounds]; + [self addSubview:_swiftUIWrapper.hostingView]; + + [self transferVisualPropertiesFromView:self toView:swiftUIContentView]; + } + + effectiveContentView = _swiftUIWrapper.contentView; + } else { + if (_swiftUIWrapper) { + UIView *swiftUIContentView = _swiftUIWrapper.contentView; + for (UIView *subview in swiftUIContentView.subviews) { + [self addSubview:subview]; + } + self.clipsToBounds = swiftUIContentView.clipsToBounds; + self.layer.mask = swiftUIContentView.layer.mask; + + [self transferVisualPropertiesFromView:swiftUIContentView toView:self]; + + [_swiftUIWrapper.hostingView removeFromSuperview]; + _swiftUIWrapper = nil; + } + } + + return effectiveContentView; +} + // This UIView is the UIView that holds all subviews. It is sometimes not self // because we want to render "overflow ink" that extends beyond the bounds of // the view and is not affected by clipping. - (UIView *)currentContainerView { + UIView* effectiveContentView = self.effectiveContentView; + if (_useCustomContainerView) { if (!_containerView) { _containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)]; - for (UIView *subview in self.subviews) { + for (UIView *subview in effectiveContentView.subviews) { [_containerView addSubview:subview]; } - _containerView.clipsToBounds = self.clipsToBounds; - self.clipsToBounds = NO; - _containerView.layer.mask = self.layer.mask; - self.layer.mask = nil; - [self addSubview:_containerView]; + _containerView.clipsToBounds = effectiveContentView.clipsToBounds; + effectiveContentView.clipsToBounds = NO; + _containerView.layer.mask = effectiveContentView.layer.mask; + effectiveContentView.layer.mask = nil; + [effectiveContentView addSubview:_containerView]; } - return _containerView; + effectiveContentView = _containerView; } else { if (_containerView) { for (UIView *subview in _containerView.subviews) { - [self addSubview:subview]; + [effectiveContentView addSubview:subview]; } - self.clipsToBounds = _containerView.clipsToBounds; - self.layer.mask = _containerView.layer.mask; + effectiveContentView.clipsToBounds = _containerView.clipsToBounds; + effectiveContentView.layer.mask = _containerView.layer.mask; [_containerView removeFromSuperview]; _containerView = nil; } - - return self; } + return effectiveContentView; } - (void)invalidateLayer { - CALayer *layer = self.layer; - + CALayer *layer = self.effectiveContentView.layer; + if (CGSizeEqualToSize(layer.bounds.size, CGSizeZero)) { return; } @@ -910,7 +968,7 @@ - (void)invalidateLayer if (!_backgroundColorLayer) { _backgroundColorLayer = [CALayer layer]; _backgroundColorLayer.zPosition = BACKGROUND_COLOR_ZPOSITION; - [self.layer addSublayer:_backgroundColorLayer]; + [layer addSublayer:_backgroundColorLayer]; } [self shapeLayerToMatchView:_backgroundColorLayer borderMetrics:borderMetrics]; _backgroundColorLayer.backgroundColor = backgroundColor.CGColor; @@ -986,31 +1044,43 @@ - (void)invalidateLayer // filter [_filterLayer removeFromSuperlayer]; _filterLayer = nil; + if (_swiftUIWrapper) { + [_swiftUIWrapper updateBlurRadius:@(0)]; + } self.layer.opacity = (float)_props->opacity; if (!_props->filter.empty()) { float multiplicativeBrightness = 1; + bool hasBrightnessFilter = false; for (const auto &primitive : _props->filter) { if (std::holds_alternative(primitive.parameters)) { if (primitive.type == FilterType::Brightness) { multiplicativeBrightness *= std::get(primitive.parameters); + hasBrightnessFilter = true; } else if (primitive.type == FilterType::Opacity) { self.layer.opacity *= std::get(primitive.parameters); + } else if (primitive.type == FilterType::Blur) { + if (_swiftUIWrapper) { + Float blurRadius = std::get(primitive.parameters); + [_swiftUIWrapper updateBlurRadius:@(blurRadius)]; + } } } } - - _filterLayer = [CALayer layer]; - [self shapeLayerToMatchView:_filterLayer borderMetrics:borderMetrics]; - _filterLayer.compositingFilter = @"multiplyBlendMode"; - _filterLayer.backgroundColor = [UIColor colorWithRed:multiplicativeBrightness - green:multiplicativeBrightness - blue:multiplicativeBrightness - alpha:self.layer.opacity] - .CGColor; - // So that this layer is always above any potential sublayers this view may - // add - _filterLayer.zPosition = CGFLOAT_MAX; - [self.layer addSublayer:_filterLayer]; + + if (hasBrightnessFilter) { + _filterLayer = [CALayer layer]; + [self shapeLayerToMatchView:_filterLayer borderMetrics:borderMetrics]; + _filterLayer.compositingFilter = @"multiplyBlendMode"; + _filterLayer.backgroundColor = [UIColor colorWithRed:multiplicativeBrightness + green:multiplicativeBrightness + blue:multiplicativeBrightness + alpha:self.layer.opacity] + .CGColor; + // So that this layer is always above any potential sublayers this view may + // add + _filterLayer.zPosition = CGFLOAT_MAX; + [layer addSublayer:_filterLayer]; + } } // background image @@ -1025,7 +1095,7 @@ - (void)invalidateLayer [self shapeLayerToMatchView:backgroundImageLayer borderMetrics:borderMetrics]; backgroundImageLayer.masksToBounds = YES; backgroundImageLayer.zPosition = BACKGROUND_COLOR_ZPOSITION; - [self.layer addSublayer:backgroundImageLayer]; + [layer addSublayer:backgroundImageLayer]; [_backgroundImageLayers addObject:backgroundImageLayer]; } else if (std::holds_alternative(backgroundImage)) { const auto &radialGradient = std::get(backgroundImage); @@ -1034,7 +1104,7 @@ - (void)invalidateLayer [self shapeLayerToMatchView:backgroundImageLayer borderMetrics:borderMetrics]; backgroundImageLayer.masksToBounds = YES; backgroundImageLayer.zPosition = BACKGROUND_COLOR_ZPOSITION; - [self.layer addSublayer:backgroundImageLayer]; + [layer addSublayer:backgroundImageLayer]; [_backgroundImageLayers addObject:backgroundImageLayer]; } } @@ -1056,7 +1126,7 @@ - (void)invalidateLayer RCTUIEdgeInsetsFromEdgeInsets(borderMetrics.borderWidths), self.layer.bounds.size); shadowLayer.zPosition = _borderLayer.zPosition; - [self.layer addSublayer:shadowLayer]; + [layer addSublayer:shadowLayer]; [_boxShadowLayers addObject:shadowLayer]; } } @@ -1410,6 +1480,63 @@ - (NSString *)componentViewName_DO_NOT_USE_THIS_IS_BROKEN return RCTNSStringFromString([[self class] componentDescriptorProvider].name); } +- (BOOL) styleNeedsSwiftUIContainer { + for (const auto &primitive : _props->filter) { + if (primitive.type == FilterType::Blur) { + return YES; + } + } + return NO; +} + +- (void)transferVisualPropertiesFromView:(UIView *)sourceView toView:(UIView *)destinationView +{ + // shadow + destinationView.layer.shadowColor = sourceView.layer.shadowColor; + sourceView.layer.shadowColor = nil; + destinationView.layer.shadowOffset = sourceView.layer.shadowOffset; + sourceView.layer.shadowOffset = CGSizeZero; + destinationView.layer.shadowOpacity = sourceView.layer.shadowOpacity; + sourceView.layer.shadowOpacity = 0; + destinationView.layer.shadowRadius = sourceView.layer.shadowRadius; + sourceView.layer.shadowRadius = 0; + + // background + destinationView.layer.backgroundColor = sourceView.layer.backgroundColor; + sourceView.layer.backgroundColor = nil; + if (_backgroundColorLayer) { + [destinationView.layer addSublayer:_backgroundColorLayer]; + } + + // border + destinationView.layer.borderColor = sourceView.layer.borderColor; + sourceView.layer.borderColor = nil; + destinationView.layer.borderWidth = sourceView.layer.borderWidth; + sourceView.layer.borderWidth = 0; + + // corner + destinationView.layer.cornerRadius = sourceView.layer.cornerRadius; + sourceView.layer.cornerRadius = 0; + destinationView.layer.cornerCurve = sourceView.layer.cornerCurve; + + // custom layers + if (_borderLayer) { + [destinationView.layer addSublayer:_borderLayer]; + } + if (_outlineLayer) { + [destinationView.layer addSublayer:_outlineLayer]; + } + if (_filterLayer) { + [destinationView.layer addSublayer:_filterLayer]; + } + for (CALayer *layer in _backgroundImageLayers) { + [destinationView.layer addSublayer:layer]; + } + for (CALayer *layer in _boxShadowLayers) { + [destinationView.layer addSublayer:layer]; + } +} + @end #ifdef __cplusplus 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 1c944cfdb449d5..49acdd06ce5175 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<<2294f3350aca0f19862f8cfdbe9479b6>> + * @generated SignedSource<<8c98913f6aa27523fcef5b4e86aee818>> */ /** @@ -252,6 +252,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun enableResourceTimingAPI(): Boolean = accessor.enableResourceTimingAPI() + /** + * When enabled, it will use SwiftUI for filter effects like blur on iOS. + */ + @JvmStatic + public fun enableSwiftUIBasedFilters(): Boolean = accessor.enableSwiftUIBasedFilters() + /** * Enables View Culling: as soon as a view goes off screen, it can be reused anywhere in the UI and pieced together with other items to create new UI elements. */ 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 86efa711dbee61..d7e8dace4e0c9f 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<<9f50b2fc5f4aad27e6cd8ecbde3d791a>> + * @generated SignedSource<> */ /** @@ -57,6 +57,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces private var enablePreparedTextLayoutCache: Boolean? = null private var enablePropsUpdateReconciliationAndroidCache: Boolean? = null private var enableResourceTimingAPICache: Boolean? = null + private var enableSwiftUIBasedFiltersCache: Boolean? = null private var enableViewCullingCache: Boolean? = null private var enableViewRecyclingCache: Boolean? = null private var enableViewRecyclingForTextCache: Boolean? = null @@ -422,6 +423,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun enableSwiftUIBasedFilters(): Boolean { + var cached = enableSwiftUIBasedFiltersCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.enableSwiftUIBasedFilters() + enableSwiftUIBasedFiltersCache = cached + } + return cached + } + override fun enableViewCulling(): Boolean { var cached = enableViewCullingCache 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 78807ec46d74e0..751c0ba3aab8bd 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<<27b8c102b60eadcf284fd3c156a037aa>> + * @generated SignedSource<<317ca8ad274f90a55b6260ef1cfdc5c4>> */ /** @@ -102,6 +102,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun enableResourceTimingAPI(): Boolean + @DoNotStrip @JvmStatic public external fun enableSwiftUIBasedFilters(): Boolean + @DoNotStrip @JvmStatic public external fun enableViewCulling(): Boolean @DoNotStrip @JvmStatic public external fun enableViewRecycling(): 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 d0a00d655c3407..f38e2404c047fe 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<<9583365cd9d7786ee9be03ff34b0766f>> + * @generated SignedSource<<3ffcb64bc57de018a8377b8871edc97c>> */ /** @@ -97,6 +97,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun enableResourceTimingAPI(): Boolean = false + override fun enableSwiftUIBasedFilters(): Boolean = false + override fun enableViewCulling(): Boolean = false override fun enableViewRecycling(): 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 5db38a867a2355..39ec8940d81425 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<<8bcbcc20f92faf4c50c093fac701dfa2>> + * @generated SignedSource<<12c44c119f6898b82d70dd3885d2f8fc>> */ /** @@ -61,6 +61,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc private var enablePreparedTextLayoutCache: Boolean? = null private var enablePropsUpdateReconciliationAndroidCache: Boolean? = null private var enableResourceTimingAPICache: Boolean? = null + private var enableSwiftUIBasedFiltersCache: Boolean? = null private var enableViewCullingCache: Boolean? = null private var enableViewRecyclingCache: Boolean? = null private var enableViewRecyclingForTextCache: Boolean? = null @@ -463,6 +464,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc return cached } + override fun enableSwiftUIBasedFilters(): Boolean { + var cached = enableSwiftUIBasedFiltersCache + if (cached == null) { + cached = currentProvider.enableSwiftUIBasedFilters() + accessedFeatureFlags.add("enableSwiftUIBasedFilters") + enableSwiftUIBasedFiltersCache = cached + } + return cached + } + override fun enableViewCulling(): Boolean { var cached = enableViewCullingCache 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 6bdae86b22bf2d..becbab38a97d13 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<<8a2403250a16c2b2b573fc05db6e4768>> + * @generated SignedSource<<9486ceb9a821413d42e5291316a6674b>> */ /** @@ -97,6 +97,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun enableResourceTimingAPI(): Boolean + @DoNotStrip public fun enableSwiftUIBasedFilters(): Boolean + @DoNotStrip public fun enableViewCulling(): Boolean @DoNotStrip public fun enableViewRecycling(): 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 a9a3cdc5bb68fa..738556ac385da9 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<<72694e8b935e15e4b826a0174fd0c23f>> + * @generated SignedSource<<9c637b9804b154a19f3bdabff3062333>> */ /** @@ -261,6 +261,12 @@ class ReactNativeFeatureFlagsJavaProvider return method(javaProvider_); } + bool enableSwiftUIBasedFilters() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableSwiftUIBasedFilters"); + return method(javaProvider_); + } + bool enableViewCulling() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableViewCulling"); @@ -636,6 +642,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableResourceTimingAPI( return ReactNativeFeatureFlags::enableResourceTimingAPI(); } +bool JReactNativeFeatureFlagsCxxInterop::enableSwiftUIBasedFilters( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::enableSwiftUIBasedFilters(); +} + bool JReactNativeFeatureFlagsCxxInterop::enableViewCulling( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::enableViewCulling(); @@ -933,6 +944,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "enableResourceTimingAPI", JReactNativeFeatureFlagsCxxInterop::enableResourceTimingAPI), + makeNativeMethod( + "enableSwiftUIBasedFilters", + JReactNativeFeatureFlagsCxxInterop::enableSwiftUIBasedFilters), makeNativeMethod( "enableViewCulling", JReactNativeFeatureFlagsCxxInterop::enableViewCulling), 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 95ead5f18e1fb7..fe00b00f2f51ea 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<<90f0583b9d527a1291431a8318f10356>> + * @generated SignedSource<> */ /** @@ -141,6 +141,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool enableResourceTimingAPI( facebook::jni::alias_ref); + static bool enableSwiftUIBasedFilters( + facebook::jni::alias_ref); + static bool enableViewCulling( facebook::jni::alias_ref); diff --git a/packages/react-native/ReactApple/RCTSwiftUI/RCTSwiftUI.podspec b/packages/react-native/ReactApple/RCTSwiftUI/RCTSwiftUI.podspec new file mode 100644 index 00000000000000..aae005f716fefe --- /dev/null +++ b/packages/react-native/ReactApple/RCTSwiftUI/RCTSwiftUI.podspec @@ -0,0 +1,38 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +require "json" + +package = JSON.parse(File.read(File.join(__dir__, "..", "..", "package.json"))) +version = package['version'] + +source = { :git => 'https://github.com/facebook/react-native.git' } +if version == '1000.0.0' + # This is an unpublished version, use the latest commit hash of the react-native repo, which we're presumably in. + source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1") +else + source[:tag] = "v#{version}" +end + +Pod::Spec.new do |s| + s.name = "RCTSwiftUI" + s.version = version + s.summary = "Swift utilities for React Native." + s.homepage = "https://reactnative.dev/" + s.license = package["license"] + s.author = "Meta Platforms, Inc. and its affiliates" + s.platforms = min_supported_versions + s.source = source + s.source_files = "*.{h,m,swift}" + s.public_header_files = "*.h" + s.module_name = "RCTSwiftUI" + s.header_dir = "RCTSwiftUI" + + # Swift-specific configuration + s.pod_target_xcconfig = { + "SWIFT_VERSION" => "5.0", + } + +end diff --git a/packages/react-native/ReactApple/RCTSwiftUI/RCTSwiftUIContainerView.swift b/packages/react-native/ReactApple/RCTSwiftUI/RCTSwiftUIContainerView.swift new file mode 100644 index 00000000000000..651097685f7330 --- /dev/null +++ b/packages/react-native/ReactApple/RCTSwiftUI/RCTSwiftUIContainerView.swift @@ -0,0 +1,76 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import SwiftUI +import UIKit + +@MainActor @objc public class RCTSwiftUIContainerView: NSObject { + private var containerViewModel = ContainerViewModel() + private var hostingController: UIHostingController? + + @objc public override init() { + super.init(); + hostingController = UIHostingController(rootView: SwiftUIContainerView(viewModel: containerViewModel)) + guard let view = hostingController?.view else { + return + } + view.backgroundColor = .clear; + } + + @objc public func updateContentView(_ view: UIView) { + containerViewModel.contentView = view + } + + @objc public func hostingView() -> UIView? { + return hostingController?.view; + } + + @objc public func contentView() -> UIView? { + return containerViewModel.contentView + } + + @objc public func updateBlurRadius(_ radius: NSNumber) { + let blurRadius = CGFloat(radius.floatValue) + containerViewModel.blurRadius = blurRadius + } + + @objc public func updateLayout(withBounds bounds: CGRect) { + hostingController?.view.frame = bounds + containerViewModel.contentView?.frame = bounds + } + + @objc public func resetStyles() { + containerViewModel.blurRadius = 0 + } +} + +class ContainerViewModel: ObservableObject { + @Published var blurRadius: CGFloat = 0 + @Published var contentView: UIView? +} + +struct SwiftUIContainerView: View { + @ObservedObject var viewModel: ContainerViewModel + + var body: some View { + if let contentView = viewModel.contentView { + UIViewWrapper(view: contentView) + .blur(radius: viewModel.blurRadius) + } + } +} + +struct UIViewWrapper: UIViewRepresentable { + let view: UIView + + func makeUIView(context: Context) -> UIView { + return view + } + + func updateUIView(_ uiView: UIView, context: Context) { + } +} diff --git a/packages/react-native/ReactApple/RCTSwiftUIWrapper/RCTSwiftUIContainerViewWrapper.h b/packages/react-native/ReactApple/RCTSwiftUIWrapper/RCTSwiftUIContainerViewWrapper.h new file mode 100644 index 00000000000000..37d00a65f594b1 --- /dev/null +++ b/packages/react-native/ReactApple/RCTSwiftUIWrapper/RCTSwiftUIContainerViewWrapper.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface RCTSwiftUIContainerViewWrapper : NSObject + +- (UIView *)contentView; +- (void)updateBlurRadius:(NSNumber *)radius; +- (void)updateContentView:(UIView *)view; +- (UIView *)hostingView; +- (void)resetStyles; +- (void)updateLayoutWithBounds:(CGRect)bounds; + +@end + +NS_ASSUME_NONNULL_END diff --git a/packages/react-native/ReactApple/RCTSwiftUIWrapper/RCTSwiftUIContainerViewWrapper.m b/packages/react-native/ReactApple/RCTSwiftUIWrapper/RCTSwiftUIContainerViewWrapper.m new file mode 100644 index 00000000000000..5feeab32718e5e --- /dev/null +++ b/packages/react-native/ReactApple/RCTSwiftUIWrapper/RCTSwiftUIContainerViewWrapper.m @@ -0,0 +1,49 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import "RCTSwiftUIContainerViewWrapper.h" + +@import RCTSwiftUI; + +@interface RCTSwiftUIContainerViewWrapper () +@property (nonatomic, strong) RCTSwiftUIContainerView *swiftContainerView; +@end + +@implementation RCTSwiftUIContainerViewWrapper + +- (instancetype)init { + if (self = [super init]) { + _swiftContainerView = [RCTSwiftUIContainerView new]; + } + return self; +} + +- (UIView *)contentView { + return [self.swiftContainerView contentView]; +} + +- (UIView *)hostingView { + return [self.swiftContainerView hostingView]; +} + +- (void)resetStyles { + [self.swiftContainerView resetStyles]; +} + +- (void)updateContentView:(UIView *)view { + return [self.swiftContainerView updateContentView:view]; +} + +- (void)updateBlurRadius:(NSNumber *)radius { + [self.swiftContainerView updateBlurRadius:radius]; +} + +- (void)updateLayoutWithBounds:(CGRect)bounds { + [self.swiftContainerView updateLayoutWithBounds:bounds]; +} + +@end diff --git a/packages/react-native/ReactApple/RCTSwiftUIWrapper/RCTSwiftUIWrapper.podspec b/packages/react-native/ReactApple/RCTSwiftUIWrapper/RCTSwiftUIWrapper.podspec new file mode 100644 index 00000000000000..93bc0e91bb8512 --- /dev/null +++ b/packages/react-native/ReactApple/RCTSwiftUIWrapper/RCTSwiftUIWrapper.podspec @@ -0,0 +1,38 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +require "json" + +package = JSON.parse(File.read(File.join(__dir__, "..", "..", "package.json"))) +version = package['version'] + +source = { :git => 'https://github.com/facebook/react-native.git' } +if version == '1000.0.0' + # This is an unpublished version, use the latest commit hash of the react-native repo, which we're presumably in. + source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1") +else + source[:tag] = "v#{version}" +end + +Pod::Spec.new do |s| + s.name = "RCTSwiftUIWrapper" + s.version = version + s.summary = "Swift utilities for React Native." + s.homepage = "https://reactnative.dev/" + s.license = package["license"] + s.author = "Meta Platforms, Inc. and its affiliates" + s.platforms = min_supported_versions + s.source = source + s.source_files = "*.{h,m}" + s.public_header_files = "*.h" + s.module_name = "RCTSwiftUIWrapper" + s.header_dir = "RCTSwiftUIWrapper" + s.dependency "RCTSwiftUI" + + s.pod_target_xcconfig = { + "SWIFT_VERSION" => "5.0", + } + +end diff --git a/packages/react-native/ReactCommon/React-Fabric.podspec b/packages/react-native/ReactCommon/React-Fabric.podspec index f5966f9aa13b12..c6b51c2d7beba8 100644 --- a/packages/react-native/ReactCommon/React-Fabric.podspec +++ b/packages/react-native/ReactCommon/React-Fabric.podspec @@ -48,6 +48,7 @@ Pod::Spec.new do |s| s.dependency "React-featureflags" s.dependency "React-runtimescheduler" s.dependency "React-cxxreact" + s.dependency "RCTSwiftUIWrapper" add_dependency(s, "React-runtimeexecutor", :additional_framework_paths => ["platform/ios"]) add_dependency(s, "React-rendererdebug") diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp index abbbbada0d54ca..7fd9ed81dbfe45 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<<6ff8aafa0de2f6c5cf8b42e0d43302e9>> + * @generated SignedSource<> */ /** @@ -174,6 +174,10 @@ bool ReactNativeFeatureFlags::enableResourceTimingAPI() { return getAccessor().enableResourceTimingAPI(); } +bool ReactNativeFeatureFlags::enableSwiftUIBasedFilters() { + return getAccessor().enableSwiftUIBasedFilters(); +} + bool ReactNativeFeatureFlags::enableViewCulling() { return getAccessor().enableViewCulling(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index b2fd0f4d5d915b..7a368d862d07c1 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<> + * @generated SignedSource<> */ /** @@ -224,6 +224,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool enableResourceTimingAPI(); + /** + * When enabled, it will use SwiftUI for filter effects like blur on iOS. + */ + RN_EXPORT static bool enableSwiftUIBasedFilters(); + /** * Enables View Culling: as soon as a view goes off screen, it can be reused anywhere in the UI and pieced together with other items to create new UI elements. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index d8dc0377858e88..401c074280a008 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<<1affcd93b19e37b0c2777263bac0fa07>> + * @generated SignedSource<<590f97d6e525740dba57d7c25e500992>> */ /** @@ -695,6 +695,24 @@ bool ReactNativeFeatureFlagsAccessor::enableResourceTimingAPI() { return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::enableSwiftUIBasedFilters() { + auto flagValue = enableSwiftUIBasedFilters_.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(37, "enableSwiftUIBasedFilters"); + + flagValue = currentProvider_->enableSwiftUIBasedFilters(); + enableSwiftUIBasedFilters_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::enableViewCulling() { auto flagValue = enableViewCulling_.load(); @@ -704,7 +722,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewCulling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(37, "enableViewCulling"); + markFlagAsAccessed(38, "enableViewCulling"); flagValue = currentProvider_->enableViewCulling(); enableViewCulling_ = flagValue; @@ -722,7 +740,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(38, "enableViewRecycling"); + markFlagAsAccessed(39, "enableViewRecycling"); flagValue = currentProvider_->enableViewRecycling(); enableViewRecycling_ = flagValue; @@ -740,7 +758,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForText() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(39, "enableViewRecyclingForText"); + markFlagAsAccessed(40, "enableViewRecyclingForText"); flagValue = currentProvider_->enableViewRecyclingForText(); enableViewRecyclingForText_ = flagValue; @@ -758,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForView() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(40, "enableViewRecyclingForView"); + markFlagAsAccessed(41, "enableViewRecyclingForView"); flagValue = currentProvider_->enableViewRecyclingForView(); enableViewRecyclingForView_ = flagValue; @@ -776,7 +794,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewDebugFeatures() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(41, "enableVirtualViewDebugFeatures"); + markFlagAsAccessed(42, "enableVirtualViewDebugFeatures"); flagValue = currentProvider_->enableVirtualViewDebugFeatures(); enableVirtualViewDebugFeatures_ = flagValue; @@ -794,7 +812,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewRenderState() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(42, "enableVirtualViewRenderState"); + markFlagAsAccessed(43, "enableVirtualViewRenderState"); flagValue = currentProvider_->enableVirtualViewRenderState(); enableVirtualViewRenderState_ = flagValue; @@ -812,7 +830,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewWindowFocusDetection() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(43, "enableVirtualViewWindowFocusDetection"); + markFlagAsAccessed(44, "enableVirtualViewWindowFocusDetection"); flagValue = currentProvider_->enableVirtualViewWindowFocusDetection(); enableVirtualViewWindowFocusDetection_ = flagValue; @@ -830,7 +848,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(44, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); + markFlagAsAccessed(45, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact(); fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue; @@ -848,7 +866,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(45, "fuseboxEnabledRelease"); + markFlagAsAccessed(46, "fuseboxEnabledRelease"); flagValue = currentProvider_->fuseboxEnabledRelease(); fuseboxEnabledRelease_ = flagValue; @@ -866,7 +884,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxNetworkInspectionEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(46, "fuseboxNetworkInspectionEnabled"); + markFlagAsAccessed(47, "fuseboxNetworkInspectionEnabled"); flagValue = currentProvider_->fuseboxNetworkInspectionEnabled(); fuseboxNetworkInspectionEnabled_ = flagValue; @@ -884,7 +902,7 @@ bool ReactNativeFeatureFlagsAccessor::hideOffscreenVirtualViewsOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(47, "hideOffscreenVirtualViewsOnIOS"); + markFlagAsAccessed(48, "hideOffscreenVirtualViewsOnIOS"); flagValue = currentProvider_->hideOffscreenVirtualViewsOnIOS(); hideOffscreenVirtualViewsOnIOS_ = flagValue; @@ -902,7 +920,7 @@ bool ReactNativeFeatureFlagsAccessor::perfMonitorV2Enabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(48, "perfMonitorV2Enabled"); + markFlagAsAccessed(49, "perfMonitorV2Enabled"); flagValue = currentProvider_->perfMonitorV2Enabled(); perfMonitorV2Enabled_ = flagValue; @@ -920,7 +938,7 @@ double ReactNativeFeatureFlagsAccessor::preparedTextCacheSize() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(49, "preparedTextCacheSize"); + markFlagAsAccessed(50, "preparedTextCacheSize"); flagValue = currentProvider_->preparedTextCacheSize(); preparedTextCacheSize_ = flagValue; @@ -938,7 +956,7 @@ bool ReactNativeFeatureFlagsAccessor::preventShadowTreeCommitExhaustion() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(50, "preventShadowTreeCommitExhaustion"); + markFlagAsAccessed(51, "preventShadowTreeCommitExhaustion"); flagValue = currentProvider_->preventShadowTreeCommitExhaustion(); preventShadowTreeCommitExhaustion_ = flagValue; @@ -956,7 +974,7 @@ bool ReactNativeFeatureFlagsAccessor::releaseImageDataWhenConsumed() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(51, "releaseImageDataWhenConsumed"); + markFlagAsAccessed(52, "releaseImageDataWhenConsumed"); flagValue = currentProvider_->releaseImageDataWhenConsumed(); releaseImageDataWhenConsumed_ = flagValue; @@ -974,7 +992,7 @@ bool ReactNativeFeatureFlagsAccessor::shouldPressibilityUseW3CPointerEventsForHo // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(52, "shouldPressibilityUseW3CPointerEventsForHover"); + markFlagAsAccessed(53, "shouldPressibilityUseW3CPointerEventsForHover"); flagValue = currentProvider_->shouldPressibilityUseW3CPointerEventsForHover(); shouldPressibilityUseW3CPointerEventsForHover_ = flagValue; @@ -992,7 +1010,7 @@ bool ReactNativeFeatureFlagsAccessor::skipActivityIdentityAssertionOnHostPause() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(53, "skipActivityIdentityAssertionOnHostPause"); + markFlagAsAccessed(54, "skipActivityIdentityAssertionOnHostPause"); flagValue = currentProvider_->skipActivityIdentityAssertionOnHostPause(); skipActivityIdentityAssertionOnHostPause_ = flagValue; @@ -1010,7 +1028,7 @@ bool ReactNativeFeatureFlagsAccessor::sweepActiveTouchOnChildNativeGesturesAndro // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(54, "sweepActiveTouchOnChildNativeGesturesAndroid"); + markFlagAsAccessed(55, "sweepActiveTouchOnChildNativeGesturesAndroid"); flagValue = currentProvider_->sweepActiveTouchOnChildNativeGesturesAndroid(); sweepActiveTouchOnChildNativeGesturesAndroid_ = flagValue; @@ -1028,7 +1046,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(55, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(56, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -1046,7 +1064,7 @@ bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommit( // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(56, "updateRuntimeShadowNodeReferencesOnCommit"); + markFlagAsAccessed(57, "updateRuntimeShadowNodeReferencesOnCommit"); flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommit(); updateRuntimeShadowNodeReferencesOnCommit_ = flagValue; @@ -1064,7 +1082,7 @@ bool ReactNativeFeatureFlagsAccessor::useAlwaysAvailableJSErrorHandling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(57, "useAlwaysAvailableJSErrorHandling"); + markFlagAsAccessed(58, "useAlwaysAvailableJSErrorHandling"); flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling(); useAlwaysAvailableJSErrorHandling_ = flagValue; @@ -1082,7 +1100,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(58, "useFabricInterop"); + markFlagAsAccessed(59, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -1100,7 +1118,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeEqualsInNativeReadableArrayAndroi // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(59, "useNativeEqualsInNativeReadableArrayAndroid"); + markFlagAsAccessed(60, "useNativeEqualsInNativeReadableArrayAndroid"); flagValue = currentProvider_->useNativeEqualsInNativeReadableArrayAndroid(); useNativeEqualsInNativeReadableArrayAndroid_ = flagValue; @@ -1118,7 +1136,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeTransformHelperAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(60, "useNativeTransformHelperAndroid"); + markFlagAsAccessed(61, "useNativeTransformHelperAndroid"); flagValue = currentProvider_->useNativeTransformHelperAndroid(); useNativeTransformHelperAndroid_ = flagValue; @@ -1136,7 +1154,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(61, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(62, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -1154,7 +1172,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(62, "useOptimizedEventBatchingOnAndroid"); + markFlagAsAccessed(63, "useOptimizedEventBatchingOnAndroid"); flagValue = currentProvider_->useOptimizedEventBatchingOnAndroid(); useOptimizedEventBatchingOnAndroid_ = flagValue; @@ -1172,7 +1190,7 @@ bool ReactNativeFeatureFlagsAccessor::useRawPropsJsiValue() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(63, "useRawPropsJsiValue"); + markFlagAsAccessed(64, "useRawPropsJsiValue"); flagValue = currentProvider_->useRawPropsJsiValue(); useRawPropsJsiValue_ = flagValue; @@ -1190,7 +1208,7 @@ bool ReactNativeFeatureFlagsAccessor::useShadowNodeStateOnClone() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(64, "useShadowNodeStateOnClone"); + markFlagAsAccessed(65, "useShadowNodeStateOnClone"); flagValue = currentProvider_->useShadowNodeStateOnClone(); useShadowNodeStateOnClone_ = flagValue; @@ -1208,7 +1226,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(65, "useTurboModuleInterop"); + markFlagAsAccessed(66, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -1226,7 +1244,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(66, "useTurboModules"); + markFlagAsAccessed(67, "useTurboModules"); flagValue = currentProvider_->useTurboModules(); useTurboModules_ = flagValue; @@ -1244,7 +1262,7 @@ double ReactNativeFeatureFlagsAccessor::virtualViewPrerenderRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(67, "virtualViewPrerenderRatio"); + markFlagAsAccessed(68, "virtualViewPrerenderRatio"); flagValue = currentProvider_->virtualViewPrerenderRatio(); virtualViewPrerenderRatio_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index ee48c0e3204010..8550cccd49f8b2 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<<0475f8a956182c197023fce2e38a6820>> */ /** @@ -69,6 +69,7 @@ class ReactNativeFeatureFlagsAccessor { bool enablePreparedTextLayout(); bool enablePropsUpdateReconciliationAndroid(); bool enableResourceTimingAPI(); + bool enableSwiftUIBasedFilters(); bool enableViewCulling(); bool enableViewRecycling(); bool enableViewRecyclingForText(); @@ -111,7 +112,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 68> accessedFeatureFlags_; + std::array, 69> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> cdpInteractionMetricsEnabled_; @@ -150,6 +151,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> enablePreparedTextLayout_; std::atomic> enablePropsUpdateReconciliationAndroid_; std::atomic> enableResourceTimingAPI_; + std::atomic> enableSwiftUIBasedFilters_; std::atomic> enableViewCulling_; std::atomic> enableViewRecycling_; std::atomic> enableViewRecyclingForText_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 5dae3f5f9e8e91..7b44800f1a6170 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<<9cadc9005e270e9a3faaf75cbbcdb1d4>> */ /** @@ -175,6 +175,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool enableSwiftUIBasedFilters() override { + return false; + } + bool enableViewCulling() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h index 135e3278fbef06..f05c98eeb4609b 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.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<<757089d037ab0f7c6cda11b079dafa2c>> + * @generated SignedSource<<49925440c97d02cffe248072a14370b6>> */ /** @@ -378,6 +378,15 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef return ReactNativeFeatureFlagsDefaults::enableResourceTimingAPI(); } + bool enableSwiftUIBasedFilters() override { + auto value = values_["enableSwiftUIBasedFilters"]; + if (!value.isNull()) { + return value.getBool(); + } + + return ReactNativeFeatureFlagsDefaults::enableSwiftUIBasedFilters(); + } + bool enableViewCulling() override { auto value = values_["enableViewCulling"]; if (!value.isNull()) { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index 9aa389ae11fdc1..a01b3b67843361 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<<33c7ddecd2532875e5144039927daa07>> + * @generated SignedSource<<3c905e4c98ee169a3f73ce7748885080>> */ /** @@ -62,6 +62,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool enablePreparedTextLayout() = 0; virtual bool enablePropsUpdateReconciliationAndroid() = 0; virtual bool enableResourceTimingAPI() = 0; + virtual bool enableSwiftUIBasedFilters() = 0; virtual bool enableViewCulling() = 0; virtual bool enableViewRecycling() = 0; virtual bool enableViewRecyclingForText() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index bf7582dfdc74c7..77d7affd3dfff2 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<<07c2f85e56246236c44e30e936cb9a40>> + * @generated SignedSource<> */ /** @@ -229,6 +229,11 @@ bool NativeReactNativeFeatureFlags::enableResourceTimingAPI( return ReactNativeFeatureFlags::enableResourceTimingAPI(); } +bool NativeReactNativeFeatureFlags::enableSwiftUIBasedFilters( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::enableSwiftUIBasedFilters(); +} + bool NativeReactNativeFeatureFlags::enableViewCulling( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::enableViewCulling(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index 179c27cee848b5..8e5b75bf8646ae 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<<57b7676134d7d0782f576b852c71aa1f>> + * @generated SignedSource<> */ /** @@ -110,6 +110,8 @@ class NativeReactNativeFeatureFlags bool enableResourceTimingAPI(jsi::Runtime& runtime); + bool enableSwiftUIBasedFilters(jsi::Runtime& runtime); + bool enableViewCulling(jsi::Runtime& runtime); bool enableViewRecycling(jsi::Runtime& runtime); diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index bfac428c842fcd..d72f47e4c5ba4c 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -440,6 +440,17 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'none', }, + enableSwiftUIBasedFilters: { + defaultValue: false, + metadata: { + dateAdded: '2025-07-30', + description: + 'When enabled, it will use SwiftUI for filter effects like blur on iOS.', + expectedReleaseValue: true, + purpose: 'experimentation', + }, + ossReleaseStage: 'none', + }, enableViewCulling: { defaultValue: false, metadata: { diff --git a/packages/react-native/scripts/react_native_pods.rb b/packages/react-native/scripts/react_native_pods.rb index 0cbcb39e385453..bcbe46f2104d21 100644 --- a/packages/react-native/scripts/react_native_pods.rb +++ b/packages/react-native/scripts/react_native_pods.rb @@ -148,6 +148,8 @@ def use_react_native! ( pod 'RCTDeprecation', :path => "#{prefix}/ReactApple/Libraries/RCTFoundation/RCTDeprecation" pod 'React-RCTFBReactNativeSpec', :path => "#{prefix}/React" pod 'React-jsi', :path => "#{prefix}/ReactCommon/jsi" + pod 'RCTSwiftUI', :path => "#{prefix}/ReactApple/RCTSwiftUI" + pod 'RCTSwiftUIWrapper', :path => "#{prefix}/ReactApple/RCTSwiftUIWrapper" if hermes_enabled setup_hermes!(:react_native_path => prefix) diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index c8d9bb946ab86c..c70af8129cd96b 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<<24a5d3213cbc7cd101d34e059ba5c8c4>> + * @generated SignedSource<<7a99ee2b4eae123000834a55c6f3251e>> * @flow strict * @noformat */ @@ -83,6 +83,7 @@ export type ReactNativeFeatureFlags = $ReadOnly<{ enablePreparedTextLayout: Getter, enablePropsUpdateReconciliationAndroid: Getter, enableResourceTimingAPI: Getter, + enableSwiftUIBasedFilters: Getter, enableViewCulling: Getter, enableViewRecycling: Getter, enableViewRecyclingForText: Getter, @@ -323,6 +324,10 @@ export const enablePropsUpdateReconciliationAndroid: Getter = createNat * Enables the reporting of network resource timings through `PerformanceObserver`. */ export const enableResourceTimingAPI: Getter = createNativeFlagGetter('enableResourceTimingAPI', false); +/** + * When enabled, it will use SwiftUI for filter effects like blur on iOS. + */ +export const enableSwiftUIBasedFilters: Getter = createNativeFlagGetter('enableSwiftUIBasedFilters', false); /** * Enables View Culling: as soon as a view goes off screen, it can be reused anywhere in the UI and pieced together with other items to create new UI elements. */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index c1a41088665e4e..e340b66d89596b 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<<4bd1c1bd236e9afa5b010f58683d5e67>> + * @generated SignedSource<> * @flow strict * @noformat */ @@ -62,6 +62,7 @@ export interface Spec extends TurboModule { +enablePreparedTextLayout?: () => boolean; +enablePropsUpdateReconciliationAndroid?: () => boolean; +enableResourceTimingAPI?: () => boolean; + +enableSwiftUIBasedFilters?: () => boolean; +enableViewCulling?: () => boolean; +enableViewRecycling?: () => boolean; +enableViewRecyclingForText?: () => boolean; diff --git a/packages/rn-tester/Podfile.lock b/packages/rn-tester/Podfile.lock index d059054edf4520..5addd20bc01b9f 100644 --- a/packages/rn-tester/Podfile.lock +++ b/packages/rn-tester/Podfile.lock @@ -94,6 +94,9 @@ PODS: - glog - RCTDeprecation (1000.0.0) - RCTRequired (1000.0.0) + - RCTSwiftUI (1000.0.0) + - RCTSwiftUIWrapper (1000.0.0): + - RCTSwiftUI - RCTTypeSafety (1000.0.0): - FBLazyVector (= 1000.0.0) - RCTRequired (= 1000.0.0) @@ -576,6 +579,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTRequired + - RCTSwiftUIWrapper - RCTTypeSafety - React-Core - React-cxxreact @@ -618,6 +622,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTRequired + - RCTSwiftUIWrapper - RCTTypeSafety - React-Core - React-cxxreact @@ -643,6 +648,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTRequired + - RCTSwiftUIWrapper - RCTTypeSafety - React-Core - React-cxxreact @@ -668,6 +674,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTRequired + - RCTSwiftUIWrapper - RCTTypeSafety - React-Core - React-cxxreact @@ -693,6 +700,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTRequired + - RCTSwiftUIWrapper - RCTTypeSafety - React-Core - React-cxxreact @@ -718,6 +726,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTRequired + - RCTSwiftUIWrapper - RCTTypeSafety - React-Core - React-cxxreact @@ -743,6 +752,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTRequired + - RCTSwiftUIWrapper - RCTTypeSafety - React-Core - React-cxxreact @@ -772,6 +782,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTRequired + - RCTSwiftUIWrapper - RCTTypeSafety - React-Core - React-cxxreact @@ -797,6 +808,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTRequired + - RCTSwiftUIWrapper - RCTTypeSafety - React-Core - React-cxxreact @@ -822,6 +834,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTRequired + - RCTSwiftUIWrapper - RCTTypeSafety - React-Core - React-cxxreact @@ -847,6 +860,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTRequired + - RCTSwiftUIWrapper - RCTTypeSafety - React-Core - React-cxxreact @@ -874,6 +888,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTRequired + - RCTSwiftUIWrapper - RCTTypeSafety - React-Core - React-cxxreact @@ -899,6 +914,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTRequired + - RCTSwiftUIWrapper - RCTTypeSafety - React-Core - React-cxxreact @@ -924,6 +940,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTRequired + - RCTSwiftUIWrapper - RCTTypeSafety - React-Core - React-cxxreact @@ -949,6 +966,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTRequired + - RCTSwiftUIWrapper - RCTTypeSafety - React-Core - React-cxxreact @@ -974,6 +992,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTRequired + - RCTSwiftUIWrapper - RCTTypeSafety - React-Core - React-cxxreact @@ -999,6 +1018,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTRequired + - RCTSwiftUIWrapper - RCTTypeSafety - React-Core - React-cxxreact @@ -1024,6 +1044,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTRequired + - RCTSwiftUIWrapper - RCTTypeSafety - React-Core - React-cxxreact @@ -1050,6 +1071,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTRequired + - RCTSwiftUIWrapper - RCTTypeSafety - React-Core - React-cxxreact @@ -1075,6 +1097,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTRequired + - RCTSwiftUIWrapper - RCTTypeSafety - React-Core - React-cxxreact @@ -1103,6 +1126,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTRequired + - RCTSwiftUIWrapper - RCTTypeSafety - React-Core - React-cxxreact @@ -1128,6 +1152,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTRequired + - RCTSwiftUIWrapper - RCTTypeSafety - React-Core - React-cxxreact @@ -1153,6 +1178,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTRequired + - RCTSwiftUIWrapper - RCTTypeSafety - React-Core - React-cxxreact @@ -1180,6 +1206,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTRequired + - RCTSwiftUIWrapper - RCTTypeSafety - React-Core - React-cxxreact @@ -2436,6 +2463,8 @@ DEPENDENCIES: - RCT-Folly (from `../react-native/third-party-podspecs/RCT-Folly.podspec`) - RCTDeprecation (from `../react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation`) - RCTRequired (from `../react-native/Libraries/Required`) + - RCTSwiftUI (from `../react-native/ReactApple/RCTSwiftUI`) + - RCTSwiftUIWrapper (from `../react-native/ReactApple/RCTSwiftUIWrapper`) - RCTTypeSafety (from `../react-native/Libraries/TypeSafety`) - React (from `../react-native/`) - React-callinvoker (from `../react-native/ReactCommon/callinvoker`) @@ -2536,6 +2565,10 @@ EXTERNAL SOURCES: :path: "../react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation" RCTRequired: :path: "../react-native/Libraries/Required" + RCTSwiftUI: + :path: "../react-native/ReactApple/RCTSwiftUI" + RCTSwiftUIWrapper: + :path: "../react-native/ReactApple/RCTSwiftUIWrapper" RCTTypeSafety: :path: "../react-native/Libraries/TypeSafety" React: diff --git a/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj b/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj index 4ceae9d500a18a..7394678f293afb 100644 --- a/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj +++ b/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj @@ -10,15 +10,15 @@ 0EA618032BE537D3001875EF /* RNTesterBundle.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 0EA618022BE537D3001875EF /* RNTesterBundle.bundle */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 2DDEF0101F84BF7B00DBDF73 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2DDEF00F1F84BF7B00DBDF73 /* Images.xcassets */; }; - 3584606AB7F8ADF7A07A3E14 /* libPods-RNTesterIntegrationTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DF9F45393190A3F008764D08 /* libPods-RNTesterIntegrationTests.a */; }; 383889DA23A7398900D06C3E /* RCTConvert_UIColorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 383889D923A7398900D06C3E /* RCTConvert_UIColorTests.m */; }; 3D2AFAF51D646CF80089D1A3 /* legacy_image@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 3D2AFAF41D646CF80089D1A3 /* legacy_image@2x.png */; }; + 3F4D148C63BBF774A25488A6 /* libPods-RNTesterIntegrationTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 93A243F0D4D5C54911E811C4 /* libPods-RNTesterIntegrationTests.a */; }; + 46C0FD761B0B9B1E8662B759 /* libPods-RNTesterUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B312B0EEE90BA411618B015 /* libPods-RNTesterUnitTests.a */; }; 5C60EB1C226440DB0018C04F /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C60EB1B226440DB0018C04F /* AppDelegate.mm */; }; 8145AE06241172D900A3F8DA /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8145AE05241172D900A3F8DA /* LaunchScreen.storyboard */; }; 832F45BB2A8A6E1F0097B4E6 /* SwiftTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 832F45BA2A8A6E1F0097B4E6 /* SwiftTest.swift */; }; - A36E4394472D388C2F6BBABA /* libPods-RNTester.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 48A747D61749335D863001E9 /* libPods-RNTester.a */; }; A975CA6C2C05EADF0043F72A /* RCTNetworkTaskTests.m in Sources */ = {isa = PBXBuildFile; fileRef = A975CA6B2C05EADE0043F72A /* RCTNetworkTaskTests.m */; }; - BF2C34488C1E5FF62D331DD4 /* libPods-RNTesterUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E89C730A8F64BC35672D4D81 /* libPods-RNTesterUnitTests.a */; }; + C175B6D9ED9336FB66637943 /* libPods-RNTester.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C706D402EE4AF9BE838CBA9 /* libPods-RNTester.a */; }; CD10C7A5290BD4EB0033E1ED /* RCTEventEmitterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CD10C7A4290BD4EB0033E1ED /* RCTEventEmitterTests.m */; }; E62F11832A5C6580000BF1C8 /* FlexibleSizeExampleView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 27F441E81BEBE5030039B79C /* FlexibleSizeExampleView.mm */; }; E62F11842A5C6584000BF1C8 /* UpdatePropertiesExampleView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 272E6B3C1BEA849E001FCF37 /* UpdatePropertiesExampleView.mm */; }; @@ -84,27 +84,28 @@ 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = RNTester/AppDelegate.h; sourceTree = ""; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = RNTester/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = RNTester/main.m; sourceTree = ""; }; + 20B55D3C33B683598D2A4424 /* Pods-RNTesterIntegrationTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterIntegrationTests.debug.xcconfig"; path = "Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests.debug.xcconfig"; sourceTree = ""; }; 272E6B3B1BEA849E001FCF37 /* UpdatePropertiesExampleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UpdatePropertiesExampleView.h; path = RNTester/NativeExampleViews/UpdatePropertiesExampleView.h; sourceTree = ""; }; 272E6B3C1BEA849E001FCF37 /* UpdatePropertiesExampleView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = UpdatePropertiesExampleView.mm; path = RNTester/NativeExampleViews/UpdatePropertiesExampleView.mm; sourceTree = ""; }; - 2734C5E31C1D7A09BF872585 /* Pods-RNTester.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTester.debug.xcconfig"; path = "Target Support Files/Pods-RNTester/Pods-RNTester.debug.xcconfig"; sourceTree = ""; }; 27F441E81BEBE5030039B79C /* FlexibleSizeExampleView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = FlexibleSizeExampleView.mm; path = RNTester/NativeExampleViews/FlexibleSizeExampleView.mm; sourceTree = ""; }; 27F441EA1BEBE5030039B79C /* FlexibleSizeExampleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FlexibleSizeExampleView.h; path = RNTester/NativeExampleViews/FlexibleSizeExampleView.h; sourceTree = ""; }; + 2B312B0EEE90BA411618B015 /* libPods-RNTesterUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 2DDEF00F1F84BF7B00DBDF73 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = RNTester/Images.xcassets; sourceTree = ""; }; - 359825B9A5AE4A3F4AA612DD /* Pods-RNTesterUnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterUnitTests.debug.xcconfig"; path = "Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests.debug.xcconfig"; sourceTree = ""; }; 383889D923A7398900D06C3E /* RCTConvert_UIColorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTConvert_UIColorTests.m; sourceTree = ""; }; 3D2AFAF41D646CF80089D1A3 /* legacy_image@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "legacy_image@2x.png"; path = "RNTester/legacy_image@2x.png"; sourceTree = ""; }; - 48A747D61749335D863001E9 /* libPods-RNTester.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTester.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 3FF60722627F93D8F62FA1E3 /* Pods-RNTesterUnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterUnitTests.release.xcconfig"; path = "Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests.release.xcconfig"; sourceTree = ""; }; + 4C706D402EE4AF9BE838CBA9 /* libPods-RNTester.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTester.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 51BC9297B6C3163C14532020 /* Pods-RNTester.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTester.release.xcconfig"; path = "Target Support Files/Pods-RNTester/Pods-RNTester.release.xcconfig"; sourceTree = ""; }; 5C60EB1B226440DB0018C04F /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = RNTester/AppDelegate.mm; sourceTree = ""; }; - 66C3087F2D5BF762FE9E6422 /* Pods-RNTesterIntegrationTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterIntegrationTests.debug.xcconfig"; path = "Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests.debug.xcconfig"; sourceTree = ""; }; - 7CDA7A212644C6BB8C0D00D8 /* Pods-RNTesterIntegrationTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterIntegrationTests.release.xcconfig"; path = "Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests.release.xcconfig"; sourceTree = ""; }; 8145AE05241172D900A3F8DA /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = RNTester/LaunchScreen.storyboard; sourceTree = ""; }; 832F45BA2A8A6E1F0097B4E6 /* SwiftTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SwiftTest.swift; path = RNTester/SwiftTest.swift; sourceTree = ""; }; - 8BFB9C61D7BDE894E24BF24F /* Pods-RNTesterUnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterUnitTests.release.xcconfig"; path = "Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests.release.xcconfig"; sourceTree = ""; }; - 9B8542B8C590B51BD0588751 /* Pods-RNTester.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTester.release.xcconfig"; path = "Target Support Files/Pods-RNTester/Pods-RNTester.release.xcconfig"; sourceTree = ""; }; + 93A243F0D4D5C54911E811C4 /* libPods-RNTesterIntegrationTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterIntegrationTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; A975CA6B2C05EADE0043F72A /* RCTNetworkTaskTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCTNetworkTaskTests.m; sourceTree = ""; }; AC474BFB29BBD4A1002BDAED /* RNTester.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; name = RNTester.xctestplan; path = RNTester/RNTester.xctestplan; sourceTree = ""; }; + B0E70A8A05E03E868F8703FE /* Pods-RNTesterIntegrationTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterIntegrationTests.release.xcconfig"; path = "Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests.release.xcconfig"; sourceTree = ""; }; + CA59C9994B1822826D8983F0 /* Pods-RNTester.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTester.debug.xcconfig"; path = "Target Support Files/Pods-RNTester/Pods-RNTester.debug.xcconfig"; sourceTree = ""; }; CD10C7A4290BD4EB0033E1ED /* RCTEventEmitterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTEventEmitterTests.m; sourceTree = ""; }; - DF9F45393190A3F008764D08 /* libPods-RNTesterIntegrationTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterIntegrationTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + D134EB89DD98253FCF879A47 /* Pods-RNTesterUnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterUnitTests.debug.xcconfig"; path = "Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests.debug.xcconfig"; sourceTree = ""; }; E771AEEA22B44E3100EA1189 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = RNTester/Info.plist; sourceTree = ""; }; E7C1241922BEC44B00DA25C0 /* RNTesterIntegrationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNTesterIntegrationTests.m; sourceTree = ""; }; E7DB209F22B2BA84005AC45F /* RNTesterUnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RNTesterUnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -166,7 +167,6 @@ E7DB215E22B2F3EC005AC45F /* RCTLoggingTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTLoggingTests.m; sourceTree = ""; }; E7DB215F22B2F3EC005AC45F /* RCTUIManagerScenarioTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTUIManagerScenarioTests.m; sourceTree = ""; }; E7DB218B22B41FCD005AC45F /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = XCTest.framework; sourceTree = DEVELOPER_DIR; }; - E89C730A8F64BC35672D4D81 /* libPods-RNTesterUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; F0D621C22BBB9E38005960AC /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; /* End PBXFileReference section */ @@ -175,7 +175,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - A36E4394472D388C2F6BBABA /* libPods-RNTester.a in Frameworks */, + C175B6D9ED9336FB66637943 /* libPods-RNTester.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -184,7 +184,7 @@ buildActionMask = 2147483647; files = ( E7DB213122B2C649005AC45F /* JavaScriptCore.framework in Frameworks */, - BF2C34488C1E5FF62D331DD4 /* libPods-RNTesterUnitTests.a in Frameworks */, + 46C0FD761B0B9B1E8662B759 /* libPods-RNTesterUnitTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -194,7 +194,7 @@ files = ( E7DB218C22B41FCD005AC45F /* XCTest.framework in Frameworks */, E7DB216722B2F69F005AC45F /* JavaScriptCore.framework in Frameworks */, - 3584606AB7F8ADF7A07A3E14 /* libPods-RNTesterIntegrationTests.a in Frameworks */, + 3F4D148C63BBF774A25488A6 /* libPods-RNTesterIntegrationTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -265,9 +265,9 @@ E7DB211822B2BD53005AC45F /* libReact-RCTText.a */, E7DB211A22B2BD53005AC45F /* libReact-RCTVibration.a */, E7DB212222B2BD53005AC45F /* libyoga.a */, - 48A747D61749335D863001E9 /* libPods-RNTester.a */, - DF9F45393190A3F008764D08 /* libPods-RNTesterIntegrationTests.a */, - E89C730A8F64BC35672D4D81 /* libPods-RNTesterUnitTests.a */, + 4C706D402EE4AF9BE838CBA9 /* libPods-RNTester.a */, + 93A243F0D4D5C54911E811C4 /* libPods-RNTesterIntegrationTests.a */, + 2B312B0EEE90BA411618B015 /* libPods-RNTesterUnitTests.a */, ); name = Frameworks; sourceTree = ""; @@ -308,12 +308,12 @@ E23BD6487B06BD71F1A86914 /* Pods */ = { isa = PBXGroup; children = ( - 2734C5E31C1D7A09BF872585 /* Pods-RNTester.debug.xcconfig */, - 9B8542B8C590B51BD0588751 /* Pods-RNTester.release.xcconfig */, - 66C3087F2D5BF762FE9E6422 /* Pods-RNTesterIntegrationTests.debug.xcconfig */, - 7CDA7A212644C6BB8C0D00D8 /* Pods-RNTesterIntegrationTests.release.xcconfig */, - 359825B9A5AE4A3F4AA612DD /* Pods-RNTesterUnitTests.debug.xcconfig */, - 8BFB9C61D7BDE894E24BF24F /* Pods-RNTesterUnitTests.release.xcconfig */, + CA59C9994B1822826D8983F0 /* Pods-RNTester.debug.xcconfig */, + 51BC9297B6C3163C14532020 /* Pods-RNTester.release.xcconfig */, + 20B55D3C33B683598D2A4424 /* Pods-RNTesterIntegrationTests.debug.xcconfig */, + B0E70A8A05E03E868F8703FE /* Pods-RNTesterIntegrationTests.release.xcconfig */, + D134EB89DD98253FCF879A47 /* Pods-RNTesterUnitTests.debug.xcconfig */, + 3FF60722627F93D8F62FA1E3 /* Pods-RNTesterUnitTests.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -378,14 +378,14 @@ isa = PBXNativeTarget; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "RNTester" */; buildPhases = ( - ABDE2A52ACD1B95E14790B5E /* [CP] Check Pods Manifest.lock */, + F28F13DD10D40D98C0BB7BE8 /* [CP] Check Pods Manifest.lock */, 13B07F871A680F5B00A75B9A /* Sources */, 13B07F8C1A680F5B00A75B9A /* Frameworks */, 13B07F8E1A680F5B00A75B9A /* Resources */, 68CD48B71D2BCB2C007E06A9 /* Build JS Bundle */, 79E8BE2B119D4C5CCD2F04B3 /* [RN] Copy Hermes Framework */, - 02B6FEF7E86B613B42F31284 /* [CP] Embed Pods Frameworks */, - 5625E703156DD564DE9175B0 /* [CP] Copy Pods Resources */, + 17FE348EDF12252D972FFC2F /* [CP] Embed Pods Frameworks */, + DFEE284B22AD5E88BBF1026A /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -400,12 +400,12 @@ isa = PBXNativeTarget; buildConfigurationList = E7DB20A622B2BA84005AC45F /* Build configuration list for PBXNativeTarget "RNTesterUnitTests" */; buildPhases = ( - 4F76596957F7356516B534CE /* [CP] Check Pods Manifest.lock */, + B8A88048D4E22316B9E74600 /* [CP] Check Pods Manifest.lock */, E7DB209B22B2BA84005AC45F /* Sources */, E7DB209C22B2BA84005AC45F /* Frameworks */, E7DB209D22B2BA84005AC45F /* Resources */, - A904658C20543C2EDC217D15 /* [CP] Embed Pods Frameworks */, - 01934C30687B8C926E4F59CD /* [CP] Copy Pods Resources */, + FD96BE05C0CECDF7D53C7CC9 /* [CP] Embed Pods Frameworks */, + 5ECFFC3767E171859C7610A6 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -421,12 +421,12 @@ isa = PBXNativeTarget; buildConfigurationList = E7DB215A22B2F332005AC45F /* Build configuration list for PBXNativeTarget "RNTesterIntegrationTests" */; buildPhases = ( - B7EB74515CDE78D98087DD53 /* [CP] Check Pods Manifest.lock */, + 2978D2EE0533828E5DB62B8F /* [CP] Check Pods Manifest.lock */, E7DB214F22B2F332005AC45F /* Sources */, E7DB215022B2F332005AC45F /* Frameworks */, E7DB215122B2F332005AC45F /* Resources */, - 4F27ACC9DB890B37D6C267F1 /* [CP] Embed Pods Frameworks */, - E446637427ECD101CAACE52B /* [CP] Copy Pods Resources */, + A27E74B2EEF82EC119BCB5A2 /* [CP] Embed Pods Frameworks */, + 48BF6B9FD13CB20F2C71C2A2 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -510,24 +510,7 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 01934C30687B8C926E4F59CD /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-resources-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-resources-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - 02B6FEF7E86B613B42F31284 /* [CP] Embed Pods Frameworks */ = { + 17FE348EDF12252D972FFC2F /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -544,60 +527,60 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - 4F27ACC9DB890B37D6C267F1 /* [CP] Embed Pods Frameworks */ = { + 2978D2EE0533828E5DB62B8F /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Embed Pods Frameworks"; + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RNTesterIntegrationTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-frameworks.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 4F76596957F7356516B534CE /* [CP] Check Pods Manifest.lock */ = { + 48BF6B9FD13CB20F2C71C2A2 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-resources-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; + name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RNTesterUnitTests-checkManifestLockResult.txt", + "${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; - 5625E703156DD564DE9175B0 /* [CP] Copy Pods Resources */ = { + 5ECFFC3767E171859C7610A6 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-resources-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-resources-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-resources-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; 68CD48B71D2BCB2C007E06A9 /* Build JS Bundle */ = { @@ -634,24 +617,24 @@ shellPath = /bin/sh; shellScript = ". ../react-native/sdks/hermes-engine/utils/copy-hermes-xcode.sh\n"; }; - A904658C20543C2EDC217D15 /* [CP] Embed Pods Frameworks */ = { + A27E74B2EEF82EC119BCB5A2 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - ABDE2A52ACD1B95E14790B5E /* [CP] Check Pods Manifest.lock */ = { + B8A88048D4E22316B9E74600 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -666,14 +649,31 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RNTester-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-RNTesterUnitTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - B7EB74515CDE78D98087DD53 /* [CP] Check Pods Manifest.lock */ = { + DFEE284B22AD5E88BBF1026A /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + F28F13DD10D40D98C0BB7BE8 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -688,28 +688,28 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RNTesterIntegrationTests-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-RNTester-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - E446637427ECD101CAACE52B /* [CP] Copy Pods Resources */ = { + FD96BE05C0CECDF7D53C7CC9 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-resources-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Copy Pods Resources"; + name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-resources-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -794,7 +794,7 @@ /* Begin XCBuildConfiguration section */ 13B07F941A680F5B00A75B9A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 2734C5E31C1D7A09BF872585 /* Pods-RNTester.debug.xcconfig */; + baseConfigurationReference = CA59C9994B1822826D8983F0 /* Pods-RNTester.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; @@ -832,7 +832,7 @@ }; 13B07F951A680F5B00A75B9A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9B8542B8C590B51BD0588751 /* Pods-RNTester.release.xcconfig */; + baseConfigurationReference = 51BC9297B6C3163C14532020 /* Pods-RNTester.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; @@ -1063,7 +1063,7 @@ }; E7DB20A722B2BA84005AC45F /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 359825B9A5AE4A3F4AA612DD /* Pods-RNTesterUnitTests.debug.xcconfig */; + baseConfigurationReference = D134EB89DD98253FCF879A47 /* Pods-RNTesterUnitTests.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_ANALYZER_NONNULL = YES; @@ -1101,7 +1101,7 @@ }; E7DB20A822B2BA84005AC45F /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 8BFB9C61D7BDE894E24BF24F /* Pods-RNTesterUnitTests.release.xcconfig */; + baseConfigurationReference = 3FF60722627F93D8F62FA1E3 /* Pods-RNTesterUnitTests.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_ANALYZER_NONNULL = YES; @@ -1139,7 +1139,7 @@ }; E7DB215B22B2F332005AC45F /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 66C3087F2D5BF762FE9E6422 /* Pods-RNTesterIntegrationTests.debug.xcconfig */; + baseConfigurationReference = 20B55D3C33B683598D2A4424 /* Pods-RNTesterIntegrationTests.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -1178,7 +1178,7 @@ }; E7DB215C22B2F332005AC45F /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7CDA7A212644C6BB8C0D00D8 /* Pods-RNTesterIntegrationTests.release.xcconfig */; + baseConfigurationReference = B0E70A8A05E03E868F8703FE /* Pods-RNTesterIntegrationTests.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; diff --git a/packages/rn-tester/js/examples/Filter/FilterExample.js b/packages/rn-tester/js/examples/Filter/FilterExample.js index 987e1da56232be..842085967df43e 100644 --- a/packages/rn-tester/js/examples/Filter/FilterExample.js +++ b/packages/rn-tester/js/examples/Filter/FilterExample.js @@ -15,7 +15,7 @@ import type {ViewStyleProp} from 'react-native/Libraries/StyleSheet/StyleSheet'; import React from 'react'; import {useState} from 'react'; -import {Image, StyleSheet, Text, View} from 'react-native'; +import {Animated, Button, Image, StyleSheet, Text, View} from 'react-native'; const alphaHotdog = require('../../assets/alpha-hotdog.png'); const hotdog = require('../../assets/hotdog.jpg'); @@ -67,6 +67,14 @@ function StaticViewAndImageWithState(props: Props): React.Node { } const styles = StyleSheet.create({ + blurWithShadow: { + filter: [{blur: 10}], + boxShadow: '0 0 10px 10px black', + overflow: 'hidden', + backgroundColor: 'pink', + height: 100, + width: 100, + }, commonView: { width: 150, height: 150, @@ -189,7 +197,6 @@ exports.examples = [ title: 'Blur', description: 'blur(10)', name: 'blur', - platform: 'android', render(): React.Node { return (