react-native-screens 3.35.0-rc.1 → 3.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. package/README.md +1 -1
  2. package/android/CMakeLists.txt +28 -19
  3. package/android/build.gradle +18 -2
  4. package/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +4 -3
  5. package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +18 -34
  6. package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +9 -3
  7. package/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt +2 -1
  8. package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +1 -1
  9. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderHeightChangeEvent.kt +3 -3
  10. package/android/src/main/java/com/swmansion/rnscreens/ext/ViewExt.kt +56 -0
  11. package/android/src/main/jni/CMakeLists.txt +28 -19
  12. package/android/src/main/res/base/anim/rns_ios_from_left_background_close.xml +5 -0
  13. package/android/src/main/res/base/anim/{rns_slide_out_to_left_ios.xml → rns_ios_from_left_background_open.xml} +1 -1
  14. package/android/src/main/res/base/anim/rns_ios_from_left_foreground_close.xml +6 -0
  15. package/android/src/main/res/base/anim/rns_ios_from_left_foreground_open.xml +6 -0
  16. package/android/src/main/res/base/anim/rns_ios_from_right_background_open.xml +5 -0
  17. package/android/src/paper/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +1 -1
  18. package/common/cpp/react/renderer/components/rnscreens/RNSScreenComponentDescriptor.h +5 -99
  19. package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.cpp +101 -0
  20. package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.h +2 -0
  21. package/ios/RNSConvert.h +13 -4
  22. package/ios/RNSConvert.mm +54 -29
  23. package/ios/RNSEnums.h +46 -0
  24. package/ios/RNSFullWindowOverlay.mm +6 -0
  25. package/ios/RNSModalScreen.mm +7 -0
  26. package/ios/RNSScreen.h +14 -0
  27. package/ios/RNSScreen.mm +22 -4
  28. package/ios/RNSScreenContainer.mm +6 -0
  29. package/ios/RNSScreenNavigationContainer.mm +7 -0
  30. package/ios/RNSScreenStack.mm +53 -7
  31. package/ios/RNSScreenStackHeaderConfig.h +1 -1
  32. package/ios/RNSScreenStackHeaderConfig.mm +54 -29
  33. package/ios/RNSScreenStackHeaderSubview.mm +30 -3
  34. package/ios/RNSSearchBar.mm +7 -0
  35. package/lib/commonjs/TransitionProgressContext.js +1 -0
  36. package/lib/commonjs/TransitionProgressContext.js.map +1 -1
  37. package/lib/commonjs/components/FullWindowOverlay.js +8 -5
  38. package/lib/commonjs/components/FullWindowOverlay.js.map +1 -1
  39. package/lib/commonjs/components/Screen.js +9 -0
  40. package/lib/commonjs/components/Screen.js.map +1 -1
  41. package/lib/commonjs/components/Screen.web.js +2 -0
  42. package/lib/commonjs/components/Screen.web.js.map +1 -1
  43. package/lib/commonjs/components/ScreenContainer.js +1 -0
  44. package/lib/commonjs/components/ScreenContainer.js.map +1 -1
  45. package/lib/commonjs/components/ScreenStack.js +1 -0
  46. package/lib/commonjs/components/ScreenStack.js.map +1 -1
  47. package/lib/commonjs/components/ScreenStackHeaderConfig.js +1 -0
  48. package/lib/commonjs/components/ScreenStackHeaderConfig.js.map +1 -1
  49. package/lib/commonjs/components/SearchBar.js +1 -0
  50. package/lib/commonjs/components/SearchBar.js.map +1 -1
  51. package/lib/commonjs/core.js +1 -0
  52. package/lib/commonjs/core.js.map +1 -1
  53. package/lib/commonjs/fabric/FullWindowOverlayNativeComponent.js +1 -0
  54. package/lib/commonjs/fabric/FullWindowOverlayNativeComponent.js.map +1 -1
  55. package/lib/commonjs/fabric/ModalScreenNativeComponent.js +1 -0
  56. package/lib/commonjs/fabric/ModalScreenNativeComponent.js.map +1 -1
  57. package/lib/commonjs/fabric/NativeScreensModule.js +2 -1
  58. package/lib/commonjs/fabric/NativeScreensModule.js.map +1 -1
  59. package/lib/commonjs/fabric/ScreenContainerNativeComponent.js +1 -0
  60. package/lib/commonjs/fabric/ScreenContainerNativeComponent.js.map +1 -1
  61. package/lib/commonjs/fabric/ScreenNativeComponent.js +1 -0
  62. package/lib/commonjs/fabric/ScreenNativeComponent.js.map +1 -1
  63. package/lib/commonjs/fabric/ScreenNavigationContainerNativeComponent.js +1 -0
  64. package/lib/commonjs/fabric/ScreenNavigationContainerNativeComponent.js.map +1 -1
  65. package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js +1 -0
  66. package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
  67. package/lib/commonjs/fabric/ScreenStackHeaderSubviewNativeComponent.js +1 -0
  68. package/lib/commonjs/fabric/ScreenStackHeaderSubviewNativeComponent.js.map +1 -1
  69. package/lib/commonjs/fabric/ScreenStackNativeComponent.js +1 -0
  70. package/lib/commonjs/fabric/ScreenStackNativeComponent.js.map +1 -1
  71. package/lib/commonjs/fabric/SearchBarNativeComponent.js +2 -2
  72. package/lib/commonjs/fabric/SearchBarNativeComponent.js.map +1 -1
  73. package/lib/commonjs/native-stack/contexts/GHContext.js +1 -0
  74. package/lib/commonjs/native-stack/contexts/GHContext.js.map +1 -1
  75. package/lib/module/TransitionProgressContext.js +2 -0
  76. package/lib/module/TransitionProgressContext.js.map +1 -1
  77. package/lib/module/components/FullWindowOverlay.js +9 -6
  78. package/lib/module/components/FullWindowOverlay.js.map +1 -1
  79. package/lib/module/components/Screen.js +10 -0
  80. package/lib/module/components/Screen.js.map +1 -1
  81. package/lib/module/components/Screen.web.js +3 -0
  82. package/lib/module/components/Screen.web.js.map +1 -1
  83. package/lib/module/components/ScreenContainer.js +2 -0
  84. package/lib/module/components/ScreenContainer.js.map +1 -1
  85. package/lib/module/components/ScreenStack.js +2 -0
  86. package/lib/module/components/ScreenStack.js.map +1 -1
  87. package/lib/module/components/ScreenStackHeaderConfig.js +2 -0
  88. package/lib/module/components/ScreenStackHeaderConfig.js.map +1 -1
  89. package/lib/module/components/SearchBar.js +2 -0
  90. package/lib/module/components/SearchBar.js.map +1 -1
  91. package/lib/module/core.js +2 -0
  92. package/lib/module/core.js.map +1 -1
  93. package/lib/module/fabric/FullWindowOverlayNativeComponent.js +2 -0
  94. package/lib/module/fabric/FullWindowOverlayNativeComponent.js.map +1 -1
  95. package/lib/module/fabric/ModalScreenNativeComponent.js +2 -0
  96. package/lib/module/fabric/ModalScreenNativeComponent.js.map +1 -1
  97. package/lib/module/fabric/NativeScreensModule.js +2 -1
  98. package/lib/module/fabric/NativeScreensModule.js.map +1 -1
  99. package/lib/module/fabric/ScreenContainerNativeComponent.js +2 -0
  100. package/lib/module/fabric/ScreenContainerNativeComponent.js.map +1 -1
  101. package/lib/module/fabric/ScreenNativeComponent.js +2 -0
  102. package/lib/module/fabric/ScreenNativeComponent.js.map +1 -1
  103. package/lib/module/fabric/ScreenNavigationContainerNativeComponent.js +2 -0
  104. package/lib/module/fabric/ScreenNavigationContainerNativeComponent.js.map +1 -1
  105. package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js +2 -0
  106. package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
  107. package/lib/module/fabric/ScreenStackHeaderSubviewNativeComponent.js +2 -0
  108. package/lib/module/fabric/ScreenStackHeaderSubviewNativeComponent.js.map +1 -1
  109. package/lib/module/fabric/ScreenStackNativeComponent.js +2 -0
  110. package/lib/module/fabric/ScreenStackNativeComponent.js.map +1 -1
  111. package/lib/module/fabric/SearchBarNativeComponent.js +2 -0
  112. package/lib/module/fabric/SearchBarNativeComponent.js.map +1 -1
  113. package/lib/module/native-stack/contexts/GHContext.js +2 -0
  114. package/lib/module/native-stack/contexts/GHContext.js.map +1 -1
  115. package/lib/typescript/TransitionProgressContext.d.ts.map +1 -1
  116. package/lib/typescript/components/FullWindowOverlay.d.ts.map +1 -1
  117. package/lib/typescript/components/Screen.d.ts.map +1 -1
  118. package/lib/typescript/components/Screen.web.d.ts.map +1 -1
  119. package/lib/typescript/components/ScreenContainer.d.ts.map +1 -1
  120. package/lib/typescript/components/ScreenStack.d.ts.map +1 -1
  121. package/lib/typescript/components/ScreenStackHeaderConfig.d.ts.map +1 -1
  122. package/lib/typescript/components/SearchBar.d.ts.map +1 -1
  123. package/lib/typescript/core.d.ts.map +1 -1
  124. package/lib/typescript/fabric/FullWindowOverlayNativeComponent.d.ts.map +1 -1
  125. package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts.map +1 -1
  126. package/lib/typescript/fabric/NativeScreensModule.d.ts.map +1 -1
  127. package/lib/typescript/fabric/ScreenContainerNativeComponent.d.ts.map +1 -1
  128. package/lib/typescript/fabric/ScreenNativeComponent.d.ts +1 -1
  129. package/lib/typescript/fabric/ScreenNativeComponent.d.ts.map +1 -1
  130. package/lib/typescript/fabric/ScreenNavigationContainerNativeComponent.d.ts.map +1 -1
  131. package/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts +2 -2
  132. package/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts.map +1 -1
  133. package/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts.map +1 -1
  134. package/lib/typescript/fabric/ScreenStackNativeComponent.d.ts.map +1 -1
  135. package/lib/typescript/fabric/SearchBarNativeComponent.d.ts.map +1 -1
  136. package/lib/typescript/native-stack/contexts/GHContext.d.ts.map +1 -1
  137. package/lib/typescript/native-stack/types.d.ts +3 -1
  138. package/lib/typescript/native-stack/types.d.ts.map +1 -1
  139. package/lib/typescript/types.d.ts +5 -3
  140. package/lib/typescript/types.d.ts.map +1 -1
  141. package/native-stack/README.md +3 -1
  142. package/package.json +1 -1
  143. package/src/TransitionProgressContext.tsx +2 -0
  144. package/src/components/FullWindowOverlay.tsx +10 -2
  145. package/src/components/Screen.tsx +8 -0
  146. package/src/components/Screen.web.tsx +3 -0
  147. package/src/components/ScreenContainer.tsx +2 -0
  148. package/src/components/ScreenStack.tsx +2 -0
  149. package/src/components/ScreenStackHeaderConfig.tsx +2 -0
  150. package/src/components/SearchBar.tsx +2 -0
  151. package/src/core.ts +2 -0
  152. package/src/fabric/FullWindowOverlayNativeComponent.ts +2 -0
  153. package/src/fabric/ModalScreenNativeComponent.ts +2 -0
  154. package/src/fabric/NativeScreensModule.ts +2 -0
  155. package/src/fabric/ScreenContainerNativeComponent.ts +2 -0
  156. package/src/fabric/ScreenNativeComponent.ts +5 -1
  157. package/src/fabric/ScreenNavigationContainerNativeComponent.ts +2 -0
  158. package/src/fabric/ScreenStackHeaderConfigNativeComponent.ts +4 -1
  159. package/src/fabric/ScreenStackHeaderSubviewNativeComponent.ts +2 -0
  160. package/src/fabric/ScreenStackNativeComponent.ts +2 -0
  161. package/src/fabric/SearchBarNativeComponent.ts +2 -0
  162. package/src/native-stack/contexts/GHContext.tsx +2 -0
  163. package/src/native-stack/types.tsx +3 -1
  164. package/src/types.tsx +7 -2
  165. package/windows/RNScreens/Screen.h +3 -1
  166. /package/android/src/main/res/base/anim/{rns_slide_in_from_left_ios.xml → rns_ios_from_right_background_close.xml} +0 -0
  167. /package/android/src/main/res/base/anim/{rns_slide_out_to_right_ios.xml → rns_ios_from_right_foreground_close.xml} +0 -0
  168. /package/android/src/main/res/base/anim/{rns_slide_in_from_right_ios.xml → rns_ios_from_right_foreground_open.xml} +0 -0
@@ -15,6 +15,107 @@ Point RNSScreenShadowNode::getContentOriginOffset(
15
15
  return {contentOffset.x, contentOffset.y};
16
16
  }
17
17
 
18
+ std::optional<std::reference_wrapper<const ShadowNode::Shared>>
19
+ findHeaderConfigChild(const YogaLayoutableShadowNode &screenShadowNode) {
20
+ for (const ShadowNode::Shared &child : screenShadowNode.getChildren()) {
21
+ if (std::strcmp(child->getComponentName(), "RNSScreenStackHeaderConfig") ==
22
+ 0) {
23
+ return {std::cref(child)};
24
+ }
25
+ }
26
+ return {};
27
+ }
28
+
29
+ static constexpr const char *kScreenDummyLayoutHelperClass =
30
+ "com/swmansion/rnscreens/utils/ScreenDummyLayoutHelper";
31
+
32
+ #ifdef ANDROID
33
+ std::optional<float> findHeaderHeight(
34
+ const int fontSize,
35
+ const bool isTitleEmpty) {
36
+ JNIEnv *env = facebook::jni::Environment::current();
37
+
38
+ if (env == nullptr) {
39
+ LOG(ERROR) << "[RNScreens] Failed to retrieve env\n";
40
+ return {};
41
+ }
42
+
43
+ jclass layoutHelperClass = env->FindClass(kScreenDummyLayoutHelperClass);
44
+
45
+ if (layoutHelperClass == nullptr) {
46
+ LOG(ERROR) << "[RNScreens] Failed to find class with id "
47
+ << kScreenDummyLayoutHelperClass;
48
+ return {};
49
+ }
50
+
51
+ jmethodID computeDummyLayoutID =
52
+ env->GetMethodID(layoutHelperClass, "computeDummyLayout", "(IZ)F");
53
+
54
+ if (computeDummyLayoutID == nullptr) {
55
+ LOG(ERROR) << "[RNScreens] Failed to retrieve computeDummyLayout method ID";
56
+ return {};
57
+ }
58
+
59
+ jmethodID getInstanceMethodID = env->GetStaticMethodID(
60
+ layoutHelperClass,
61
+ "getInstance",
62
+ "()Lcom/swmansion/rnscreens/utils/ScreenDummyLayoutHelper;");
63
+
64
+ if (getInstanceMethodID == nullptr) {
65
+ LOG(ERROR) << "[RNScreens] Failed to retrieve getInstanceMethodID";
66
+ return {};
67
+ }
68
+
69
+ jobject packageInstance =
70
+ env->CallStaticObjectMethod(layoutHelperClass, getInstanceMethodID);
71
+
72
+ if (packageInstance == nullptr) {
73
+ LOG(ERROR)
74
+ << "[RNScreens] Failed to retrieve packageInstance or the package instance was null on JVM side";
75
+ return {};
76
+ }
77
+
78
+ jfloat headerHeight = env->CallFloatMethod(
79
+ packageInstance, computeDummyLayoutID, fontSize, isTitleEmpty);
80
+
81
+ return {headerHeight};
82
+ }
83
+ #endif // ANDROID
84
+
85
+ void RNSScreenShadowNode::appendChild(const ShadowNode::Shared &child) {
86
+ YogaLayoutableShadowNode::appendChild(child);
87
+ #ifdef ANDROID
88
+ const auto &stateData = getStateData();
89
+ if (stateData.frameSize.width == 0 || stateData.frameSize.height == 0) {
90
+ // This code path should be executed only on the very first (few)
91
+ // layout(s), when we haven't received state update from JVM side yet.
92
+ auto headerConfigChildOpt = findHeaderConfigChild(*this);
93
+ auto &screenShadowNode = static_cast<RNSScreenShadowNode &>(*this);
94
+
95
+ // During creation of the shadow node children are not attached yet.
96
+ // We also do not want to set any padding in case.
97
+ if (headerConfigChildOpt) {
98
+ const auto &headerConfigChild = headerConfigChildOpt->get();
99
+ const auto &headerProps =
100
+ *std::static_pointer_cast<const RNSScreenStackHeaderConfigProps>(
101
+ headerConfigChild->getProps());
102
+
103
+ const auto headerHeight = headerProps.hidden
104
+ ? 0.f
105
+ : findHeaderHeight(
106
+ headerProps.titleFontSize, headerProps.title.empty())
107
+ .value_or(0.f);
108
+
109
+ screenShadowNode.setPadding({0, 0, 0, headerHeight});
110
+ screenShadowNode.setHeaderHeight(headerHeight);
111
+ screenShadowNode.getFrameCorrectionModes().set(FrameCorrectionModes::Mode(
112
+ FrameCorrectionModes::Mode::FrameHeightCorrection |
113
+ FrameCorrectionModes::Mode::FrameOriginCorrection));
114
+ }
115
+ }
116
+ #endif // ANDROID
117
+ }
118
+
18
119
  void RNSScreenShadowNode::layout(facebook::react::LayoutContext layoutContext) {
19
120
  YogaLayoutableShadowNode::layout(layoutContext);
20
121
 
@@ -28,6 +28,8 @@ class JSI_EXPORT RNSScreenShadowNode final : public ConcreteViewShadowNode<
28
28
 
29
29
  Point getContentOriginOffset(bool includeTransform) const override;
30
30
 
31
+ void appendChild(const ShadowNode::Shared &child) override;
32
+
31
33
  void layout(LayoutContext layoutContext) override;
32
34
 
33
35
  #pragma mark - Custom interface
package/ios/RNSConvert.h CHANGED
@@ -1,12 +1,17 @@
1
- #ifdef RCT_NEW_ARCH_ENABLED
2
1
  #import <UIKit/UIKit.h>
2
+ #ifdef RCT_NEW_ARCH_ENABLED
3
3
  #import <react/renderer/components/rnscreens/Props.h>
4
+ #endif // RCT_NEW_ARCH_ENABLED
4
5
  #import "RNSEnums.h"
5
6
 
7
+ #ifdef RCT_NEW_ARCH_ENABLED
6
8
  namespace react = facebook::react;
9
+ #endif // RCT_NEW_ARCH_ENABLED
7
10
 
8
11
  @interface RNSConvert : NSObject
9
12
 
13
+ #ifdef RCT_NEW_ARCH_ENABLED
14
+
10
15
  + (UISemanticContentAttribute)UISemanticContentAttributeFromCppEquivalent:
11
16
  (react::RNSScreenStackHeaderConfigDirection)direction;
12
17
 
@@ -40,8 +45,12 @@ namespace react = facebook::react;
40
45
 
41
46
  + (RNSSearchBarPlacement)RNSScreenSearchBarPlacementFromCppEquivalent:(react::RNSSearchBarPlacement)placement;
42
47
 
43
- + (UIBlurEffectStyle)UIBlurEffectStyleFromCppEquivalent:(react::RNSScreenStackHeaderConfigBlurEffect)blurEffect;
44
-
45
- @end
48
+ + (RNSBlurEffectStyle)RNSBlurEffectStyleFromCppEquivalent:(react::RNSScreenStackHeaderConfigBlurEffect)blurEffect;
46
49
 
47
50
  #endif // RCT_NEW_ARCH_ENABLED
51
+
52
+ /// This method fails (by assertion) when `blurEffect == RNSBlurEffectStyleNone` which has no counter part in the UIKit
53
+ /// type.
54
+ + (UIBlurEffectStyle)tryConvertRNSBlurEffectStyleToUIBlurEffectStyle:(RNSBlurEffectStyle)blurEffect;
55
+
56
+ @end
package/ios/RNSConvert.mm CHANGED
@@ -1,8 +1,12 @@
1
1
  #import "RNSConvert.h"
2
2
 
3
- #ifdef RCT_NEW_ARCH_ENABLED
3
+ #ifndef RCT_NEW_ARCH_ENABLED
4
+ #import <react/RCTAssert.h>
5
+ #endif // !RCT_NEW_ARCH_ENABLED
6
+
4
7
  @implementation RNSConvert
5
8
 
9
+ #ifdef RCT_NEW_ARCH_ENABLED
6
10
  + (UISemanticContentAttribute)UISemanticContentAttributeFromCppEquivalent:
7
11
  (react::RNSScreenStackHeaderConfigDirection)direction
8
12
  {
@@ -51,12 +55,15 @@
51
55
  + (RNSScreenStackAnimation)RNSScreenStackAnimationFromCppEquivalent:(react::RNSScreenStackAnimation)stackAnimation
52
56
  {
53
57
  switch (stackAnimation) {
54
- // these three are intentionally grouped
58
+ // these four are intentionally grouped
55
59
  case react::RNSScreenStackAnimation::Slide_from_right:
56
60
  case react::RNSScreenStackAnimation::Ios:
61
+ case react::RNSScreenStackAnimation::Ios_from_right:
57
62
  case react::RNSScreenStackAnimation::Default:
58
63
  return RNSScreenStackAnimationDefault;
64
+ // these two are intentionally grouped
59
65
  case react::RNSScreenStackAnimation::Slide_from_left:
66
+ case react::RNSScreenStackAnimation::Ios_from_left:
60
67
  return RNSScreenStackAnimationSlideFromLeft;
61
68
  case react::RNSScreenStackAnimation::Flip:
62
69
  return RNSScreenStackAnimationFlip;
@@ -177,71 +184,89 @@
177
184
  }
178
185
  }
179
186
 
180
- + (UIBlurEffectStyle)UIBlurEffectStyleFromCppEquivalent:(react::RNSScreenStackHeaderConfigBlurEffect)blurEffect
187
+ + (RNSBlurEffectStyle)RNSBlurEffectStyleFromCppEquivalent:(react::RNSScreenStackHeaderConfigBlurEffect)blurEffect
181
188
  {
182
189
  #if !TARGET_OS_TV && defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \
183
190
  __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
184
191
  if (@available(iOS 13.0, *)) {
185
192
  switch (blurEffect) {
193
+ case react::RNSScreenStackHeaderConfigBlurEffect::None:
194
+ return RNSBlurEffectStyleNone;
186
195
  case react::RNSScreenStackHeaderConfigBlurEffect::ExtraLight:
187
- return UIBlurEffectStyleExtraLight;
196
+ return RNSBlurEffectStyleExtraLight;
188
197
  case react::RNSScreenStackHeaderConfigBlurEffect::Light:
189
- return UIBlurEffectStyleLight;
198
+ return RNSBlurEffectStyleLight;
190
199
  case react::RNSScreenStackHeaderConfigBlurEffect::Dark:
191
- return UIBlurEffectStyleDark;
200
+ return RNSBlurEffectStyleDark;
192
201
  case react::RNSScreenStackHeaderConfigBlurEffect::Regular:
193
- return UIBlurEffectStyleRegular;
202
+ return RNSBlurEffectStyleRegular;
194
203
  case react::RNSScreenStackHeaderConfigBlurEffect::Prominent:
195
- return UIBlurEffectStyleProminent;
204
+ return RNSBlurEffectStyleProminent;
196
205
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemUltraThinMaterial:
197
- return UIBlurEffectStyleSystemUltraThinMaterial;
206
+ return RNSBlurEffectStyleSystemUltraThinMaterial;
198
207
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemThinMaterial:
199
- return UIBlurEffectStyleSystemThinMaterial;
208
+ return RNSBlurEffectStyleSystemThinMaterial;
200
209
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemMaterial:
201
- return UIBlurEffectStyleSystemMaterial;
210
+ return RNSBlurEffectStyleSystemMaterial;
202
211
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemThickMaterial:
203
- return UIBlurEffectStyleSystemThickMaterial;
212
+ return RNSBlurEffectStyleSystemThickMaterial;
204
213
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemChromeMaterial:
205
- return UIBlurEffectStyleSystemChromeMaterial;
214
+ return RNSBlurEffectStyleSystemChromeMaterial;
206
215
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemUltraThinMaterialLight:
207
- return UIBlurEffectStyleSystemUltraThinMaterialLight;
216
+ return RNSBlurEffectStyleSystemUltraThinMaterialLight;
208
217
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemThinMaterialLight:
209
- return UIBlurEffectStyleSystemThinMaterialLight;
218
+ return RNSBlurEffectStyleSystemThinMaterialLight;
210
219
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemMaterialLight:
211
- return UIBlurEffectStyleSystemMaterialLight;
220
+ return RNSBlurEffectStyleSystemMaterialLight;
212
221
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemThickMaterialLight:
213
- return UIBlurEffectStyleSystemThickMaterialLight;
222
+ return RNSBlurEffectStyleSystemThickMaterialLight;
214
223
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemChromeMaterialLight:
215
- return UIBlurEffectStyleSystemChromeMaterialLight;
224
+ return RNSBlurEffectStyleSystemChromeMaterialLight;
216
225
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemUltraThinMaterialDark:
217
- return UIBlurEffectStyleSystemUltraThinMaterialDark;
226
+ return RNSBlurEffectStyleSystemUltraThinMaterialDark;
218
227
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemThinMaterialDark:
219
- return UIBlurEffectStyleSystemThinMaterialDark;
228
+ return RNSBlurEffectStyleSystemThinMaterialDark;
220
229
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemMaterialDark:
221
- return UIBlurEffectStyleSystemMaterialDark;
230
+ return RNSBlurEffectStyleSystemMaterialDark;
222
231
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemThickMaterialDark:
223
- return UIBlurEffectStyleSystemThickMaterialDark;
232
+ return RNSBlurEffectStyleSystemThickMaterialDark;
224
233
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemChromeMaterialDark:
225
- return UIBlurEffectStyleSystemChromeMaterialDark;
234
+ return RNSBlurEffectStyleSystemChromeMaterialDark;
226
235
  }
227
236
  }
228
237
  #endif
229
238
 
230
239
  switch (blurEffect) {
240
+ case react::RNSScreenStackHeaderConfigBlurEffect::None:
241
+ return RNSBlurEffectStyleNone;
231
242
  case react::RNSScreenStackHeaderConfigBlurEffect::Light:
232
- return UIBlurEffectStyleLight;
243
+ return RNSBlurEffectStyleLight;
233
244
  case react::RNSScreenStackHeaderConfigBlurEffect::Dark:
234
- return UIBlurEffectStyleDark;
245
+ return RNSBlurEffectStyleDark;
235
246
  case react::RNSScreenStackHeaderConfigBlurEffect::Regular:
236
- return UIBlurEffectStyleRegular;
247
+ return RNSBlurEffectStyleRegular;
237
248
  case react::RNSScreenStackHeaderConfigBlurEffect::Prominent:
238
- return UIBlurEffectStyleProminent;
249
+ return RNSBlurEffectStyleProminent;
239
250
  case react::RNSScreenStackHeaderConfigBlurEffect::ExtraLight:
240
251
  default:
241
- return UIBlurEffectStyleExtraLight;
252
+ return RNSBlurEffectStyleNone;
242
253
  }
243
254
  }
244
255
 
245
- @end
256
+ #endif // RCT_NEW_ARCH_ENABLED
246
257
 
258
+ + (UIBlurEffectStyle)tryConvertRNSBlurEffectStyleToUIBlurEffectStyle:(RNSBlurEffectStyle)blurEffect
259
+ {
260
+ #ifdef RCT_NEW_ARCH_ENABLED
261
+ react_native_assert(blurEffect != RNSBlurEffectStyleNone);
262
+ #else
263
+ RCTAssert(
264
+ blurEffect != RNSBlurEffectStyleNone, @"RNSBlurEffectStyleNone variant is not convertible to UIBlurEffectStyle");
247
265
  #endif // RCT_NEW_ARCH_ENABLED
266
+
267
+ // Cast safety: RNSBlurEffectStyle is defined in such way that its values map 1:1 with
268
+ // UIBlurEffectStyle, except RNSBlurEffectStyleNone which is excluded above.
269
+ return (UIBlurEffectStyle)blurEffect;
270
+ }
271
+
272
+ @end
package/ios/RNSEnums.h CHANGED
@@ -70,3 +70,49 @@ typedef NS_ENUM(NSInteger, RNSSearchBarPlacement) {
70
70
  RNSSearchBarPlacementInline,
71
71
  RNSSearchBarPlacementStacked,
72
72
  };
73
+
74
+ // Redefinition of UIBlurEffectStyle. We need to represent additional case of `None`.
75
+ typedef NS_ENUM(NSInteger, RNSBlurEffectStyle) {
76
+ /// No blur effect should be visible
77
+ RNSBlurEffectStyleNone = -1,
78
+ RNSBlurEffectStyleExtraLight = UIBlurEffectStyleExtraLight,
79
+ RNSBlurEffectStyleLight = UIBlurEffectStyleLight,
80
+ RNSBlurEffectStyleDark = UIBlurEffectStyleDark,
81
+ // TODO: Add support for this variant on tvOS
82
+ // RNSBlurEffectStyleExtraDark = UIBlurEffectStyleExtraDark API_AVAILABLE(tvos(10.0)) API_UNAVAILABLE(ios)
83
+ // API_UNAVAILABLE(watchos),
84
+ RNSBlurEffectStyleRegular API_AVAILABLE(ios(10.0)) API_UNAVAILABLE(watchos) = UIBlurEffectStyleRegular,
85
+ RNSBlurEffectStyleProminent API_AVAILABLE(ios(10.0)) API_UNAVAILABLE(watchos) = UIBlurEffectStyleProminent,
86
+ RNSBlurEffectStyleSystemUltraThinMaterial API_AVAILABLE(ios(13.0))
87
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemUltraThinMaterial,
88
+ RNSBlurEffectStyleSystemThinMaterial API_AVAILABLE(ios(13.0))
89
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemThinMaterial,
90
+ RNSBlurEffectStyleSystemMaterial API_AVAILABLE(ios(13.0))
91
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemMaterial,
92
+ RNSBlurEffectStyleSystemThickMaterial API_AVAILABLE(ios(13.0))
93
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemThickMaterial,
94
+ RNSBlurEffectStyleSystemChromeMaterial API_AVAILABLE(ios(13.0))
95
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemChromeMaterial,
96
+ RNSBlurEffectStyleSystemUltraThinMaterialLight API_AVAILABLE(ios(13.0))
97
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemUltraThinMaterialLight,
98
+ RNSBlurEffectStyleSystemThinMaterialLight API_AVAILABLE(ios(13.0))
99
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemThinMaterialLight,
100
+ RNSBlurEffectStyleSystemMaterialLight API_AVAILABLE(ios(13.0))
101
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemMaterialLight,
102
+ RNSBlurEffectStyleSystemThickMaterialLight API_AVAILABLE(ios(13.0))
103
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemThickMaterialLight,
104
+ RNSBlurEffectStyleSystemChromeMaterialLight API_AVAILABLE(ios(13.0))
105
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemChromeMaterialLight,
106
+
107
+ RNSBlurEffectStyleSystemUltraThinMaterialDark API_AVAILABLE(ios(13.0))
108
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemUltraThinMaterialDark,
109
+ RNSBlurEffectStyleSystemThinMaterialDark API_AVAILABLE(ios(13.0))
110
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemThinMaterialDark,
111
+ RNSBlurEffectStyleSystemMaterialDark API_AVAILABLE(ios(13.0))
112
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemMaterialDark,
113
+ RNSBlurEffectStyleSystemThickMaterialDark API_AVAILABLE(ios(13.0))
114
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemThickMaterialDark,
115
+ RNSBlurEffectStyleSystemChromeMaterialDark API_AVAILABLE(ios(13.0))
116
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemChromeMaterialDark
117
+
118
+ } API_AVAILABLE(ios(8.0)) API_UNAVAILABLE(watchos);
@@ -15,6 +15,12 @@
15
15
 
16
16
  @implementation RNSFullWindowOverlayContainer
17
17
 
18
+ // Needed because of this: https://github.com/facebook/react-native/pull/37274
19
+ + (void)load
20
+ {
21
+ [super load];
22
+ }
23
+
18
24
  - (instancetype)initWithFrame:(CGRect)frame
19
25
  {
20
26
  if (self = [super initWithFrame:frame]) {
@@ -30,6 +30,13 @@
30
30
  }
31
31
 
32
32
  #ifdef RCT_NEW_ARCH_ENABLED
33
+
34
+ // Needed because of this: https://github.com/facebook/react-native/pull/37274
35
+ + (void)load
36
+ {
37
+ [super load];
38
+ }
39
+
33
40
  + (react::ComponentDescriptorProvider)componentDescriptorProvider
34
41
  {
35
42
  return react::concreteComponentDescriptorProvider<react::RNSModalScreenComponentDescriptor>();
package/ios/RNSScreen.h CHANGED
@@ -99,6 +99,8 @@ namespace react = facebook::react;
99
99
  @property (nonatomic) react::LayoutMetrics newLayoutMetrics;
100
100
  @property (weak, nonatomic) RNSScreenStackHeaderConfig *config;
101
101
  @property (nonatomic, readonly) BOOL hasHeaderConfig;
102
+ @property (nonatomic, readonly, getter=isMarkedForUnmountInCurrentTransaction)
103
+ BOOL markedForUnmountInCurrentTransaction;
102
104
  #else
103
105
  @property (nonatomic, copy) RCTDirectEventBlock onAppear;
104
106
  @property (nonatomic, copy) RCTDirectEventBlock onDisappear;
@@ -122,6 +124,10 @@ namespace react = facebook::react;
122
124
  - (void)updateBounds;
123
125
  - (void)notifyDismissedWithCount:(int)dismissCount;
124
126
  - (instancetype)initWithFrame:(CGRect)frame;
127
+ /// Tell `Screen` that it will be unmounted in next transaction.
128
+ /// The component needs this so that we can later decide whether to
129
+ /// replace it with snapshot or not.
130
+ - (void)willBeUnmountedInUpcomingTransaction;
125
131
  #else
126
132
  - (instancetype)initWithBridge:(RCTBridge *)bridge;
127
133
  #endif // RCT_NEW_ARCH_ENABLED
@@ -131,6 +137,14 @@ namespace react = facebook::react;
131
137
  - (BOOL)isModal;
132
138
  - (BOOL)isPresentedAsNativeModal;
133
139
 
140
+ /**
141
+ * Tell `Screen` component that it has been removed from react state and can safely cleanup
142
+ * any retained resources.
143
+ *
144
+ * Note, that on old architecture this method might be called by RN via `RCTInvalidating` protocol.
145
+ */
146
+ - (void)invalidate;
147
+
134
148
  /// Looks for header configuration in instance's `reactSubviews` and returns it. If not present returns `nil`.
135
149
  - (RNSScreenStackHeaderConfig *_Nullable)findHeaderConfig;
136
150
 
package/ios/RNSScreen.mm CHANGED
@@ -53,6 +53,13 @@ namespace react = facebook::react;
53
53
  }
54
54
 
55
55
  #ifdef RCT_NEW_ARCH_ENABLED
56
+
57
+ // Needed because of this: https://github.com/facebook/react-native/pull/37274
58
+ + (void)load
59
+ {
60
+ [super load];
61
+ }
62
+
56
63
  - (instancetype)initWithFrame:(CGRect)frame
57
64
  {
58
65
  if (self = [super initWithFrame:frame]) {
@@ -91,6 +98,9 @@ namespace react = facebook::react;
91
98
  #if !TARGET_OS_TV
92
99
  _sheetExpandsWhenScrolledToEdge = YES;
93
100
  #endif // !TARGET_OS_TV
101
+ #ifdef RCT_NEW_ARCH_ENABLED
102
+ _markedForUnmountInCurrentTransaction = NO;
103
+ #endif // RCT_NEW_ARCH_ENABLED
94
104
  }
95
105
 
96
106
  - (UIViewController *)reactViewController
@@ -607,6 +617,11 @@ namespace react = facebook::react;
607
617
  self.controller.modalPresentationStyle == UIModalPresentationOverCurrentContext;
608
618
  }
609
619
 
620
+ - (void)invalidate
621
+ {
622
+ _controller = nil;
623
+ }
624
+
610
625
  #if !TARGET_OS_TV && !TARGET_OS_VISION
611
626
  /**
612
627
  * Updates settings for sheet presentation controller.
@@ -677,6 +692,11 @@ namespace react = facebook::react;
677
692
  return _config != nil;
678
693
  }
679
694
 
695
+ - (void)willBeUnmountedInUpcomingTransaction
696
+ {
697
+ _markedForUnmountInCurrentTransaction = YES;
698
+ }
699
+
680
700
  + (react::ComponentDescriptorProvider)componentDescriptorProvider
681
701
  {
682
702
  return react::concreteComponentDescriptorProvider<react::RNSScreenComponentDescriptor>();
@@ -852,10 +872,6 @@ namespace react = facebook::react;
852
872
  // subviews
853
873
  }
854
874
 
855
- - (void)invalidate
856
- {
857
- _controller = nil;
858
- }
859
875
  #endif
860
876
 
861
877
  @end
@@ -1550,6 +1566,8 @@ RCT_ENUM_CONVERTER(
1550
1566
  @"slide_from_right" : @(RNSScreenStackAnimationDefault),
1551
1567
  @"slide_from_left" : @(RNSScreenStackAnimationSlideFromLeft),
1552
1568
  @"ios" : @(RNSScreenStackAnimationDefault),
1569
+ @"ios_from_right" : @(RNSScreenStackAnimationDefault),
1570
+ @"ios_from_left" : @(RNSScreenStackAnimationSlideFromLeft),
1553
1571
  }),
1554
1572
  RNSScreenStackAnimationDefault,
1555
1573
  integerValue)
@@ -251,6 +251,12 @@ namespace react = facebook::react;
251
251
  #pragma mark-- Fabric specific
252
252
  #ifdef RCT_NEW_ARCH_ENABLED
253
253
 
254
+ // Needed because of this: https://github.com/facebook/react-native/pull/37274
255
+ + (void)load
256
+ {
257
+ [super load];
258
+ }
259
+
254
260
  - (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
255
261
  {
256
262
  if (![childComponentView isKindOfClass:[RNSScreenView class]]) {
@@ -43,6 +43,13 @@ namespace react = facebook::react;
43
43
  {
44
44
  return react::concreteComponentDescriptorProvider<react::RNSScreenNavigationContainerComponentDescriptor>();
45
45
  }
46
+
47
+ // Needed because of this: https://github.com/facebook/react-native/pull/37274
48
+ + (void)load
49
+ {
50
+ [super load];
51
+ }
52
+
46
53
  #endif
47
54
 
48
55
  @end
@@ -120,9 +120,23 @@ namespace react = facebook::react;
120
120
  UIPercentDrivenInteractiveTransition *_interactionController;
121
121
  __weak RNSScreenStackManager *_manager;
122
122
  BOOL _updateScheduled;
123
+ #ifdef RCT_NEW_ARCH_ENABLED
124
+ /// Screens that are subject of `ShadowViewMutation::Type::Delete` mutation
125
+ /// in current transaction. This vector should be populated when we receive notification via
126
+ /// `RCTMountingObserving` protocol, that a transaction will be performed, and should
127
+ /// be cleaned up when we're notified that the transaction has been completed.
128
+ std::vector<__strong RNSScreenView *> _toBeDeletedScreens;
129
+ #endif // RCT_NEW_ARCH_ENABLED
123
130
  }
124
131
 
125
132
  #ifdef RCT_NEW_ARCH_ENABLED
133
+
134
+ // Needed because of this: https://github.com/facebook/react-native/pull/37274
135
+ + (void)load
136
+ {
137
+ [super load];
138
+ }
139
+
126
140
  - (instancetype)initWithFrame:(CGRect)frame
127
141
  {
128
142
  if (self = [super initWithFrame:frame]) {
@@ -506,13 +520,6 @@ namespace react = facebook::react;
506
520
  [changeRootController dismissViewControllerAnimated:shouldAnimate completion:finish];
507
521
  return;
508
522
  }
509
-
510
- UIViewController *lastModalVc = [self lastFromPresentedViewControllerChainStartingFrom:firstModalToBeDismissed];
511
-
512
- if (lastModalVc != firstModalToBeDismissed) {
513
- [lastModalVc dismissViewControllerAnimated:shouldAnimate completion:finish];
514
- return;
515
- }
516
523
  }
517
524
 
518
525
  // changeRootController does not have presentedViewController but it does not mean that no modals are in presentation;
@@ -1118,6 +1125,16 @@ namespace react = facebook::react;
1118
1125
  // `- [RNSScreenStackView mountingTransactionDidMount: withSurfaceTelemetry:]`
1119
1126
  }
1120
1127
 
1128
+ - (nullable RNSScreenView *)childScreenForTag:(react::Tag)tag
1129
+ {
1130
+ for (RNSScreenView *child in _reactSubviews) {
1131
+ if (child.tag == tag) {
1132
+ return child;
1133
+ }
1134
+ }
1135
+ return nil;
1136
+ }
1137
+
1121
1138
  - (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
1122
1139
  {
1123
1140
  RNSScreenView *screenChildComponent = (RNSScreenView *)childComponentView;
@@ -1151,6 +1168,20 @@ namespace react = facebook::react;
1151
1168
  [screenChildComponent removeFromSuperview];
1152
1169
  }
1153
1170
 
1171
+ - (void)mountingTransactionWillMount:(const facebook::react::MountingTransaction &)transaction
1172
+ withSurfaceTelemetry:(const facebook::react::SurfaceTelemetry &)surfaceTelemetry
1173
+ {
1174
+ for (const auto &mutation : transaction.getMutations()) {
1175
+ if (mutation.type == react::ShadowViewMutation::Delete) {
1176
+ RNSScreenView *_Nullable toBeRemovedChild = [self childScreenForTag:mutation.oldChildShadowView.tag];
1177
+ if (toBeRemovedChild != nil) {
1178
+ [toBeRemovedChild willBeUnmountedInUpcomingTransaction];
1179
+ _toBeDeletedScreens.push_back(toBeRemovedChild);
1180
+ }
1181
+ }
1182
+ }
1183
+ }
1184
+
1154
1185
  - (void)mountingTransactionDidMount:(const facebook::react::MountingTransaction &)transaction
1155
1186
  withSurfaceTelemetry:(const facebook::react::SurfaceTelemetry &)surfaceTelemetry
1156
1187
  {
@@ -1167,6 +1198,21 @@ namespace react = facebook::react;
1167
1198
  break;
1168
1199
  }
1169
1200
  }
1201
+
1202
+ if (!self->_toBeDeletedScreens.empty()) {
1203
+ __weak RNSScreenStackView *weakSelf = self;
1204
+ // We want to run after container updates are performed (transitions etc.)
1205
+ dispatch_async(dispatch_get_main_queue(), ^{
1206
+ RNSScreenStackView *_Nullable strongSelf = weakSelf;
1207
+ if (strongSelf == nil) {
1208
+ return;
1209
+ }
1210
+ for (RNSScreenView *screenRef : strongSelf->_toBeDeletedScreens) {
1211
+ [screenRef invalidate];
1212
+ }
1213
+ strongSelf->_toBeDeletedScreens.clear();
1214
+ });
1215
+ }
1170
1216
  }
1171
1217
 
1172
1218
  - (void)prepareForRecycle
@@ -55,7 +55,7 @@
55
55
  @property (nonatomic) BOOL backButtonInCustomView;
56
56
  @property (nonatomic) UISemanticContentAttribute direction;
57
57
  @property (nonatomic) UINavigationItemBackButtonDisplayMode backButtonDisplayMode;
58
- @property (nonatomic) UIBlurEffectStyle blurEffect;
58
+ @property (nonatomic) RNSBlurEffectStyle blurEffect;
59
59
 
60
60
  + (void)willShowViewController:(UIViewController *)vc
61
61
  animated:(BOOL)animated