react-native-screens 4.12.0 → 4.13.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 (235) hide show
  1. package/RNScreens.podspec +29 -2
  2. package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +4 -0
  3. package/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.kt +9 -1
  4. package/android/src/main/java/com/swmansion/rnscreens/ScreenFragmentWrapper.kt +0 -1
  5. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +4 -4
  6. package/android/src/main/java/com/swmansion/rnscreens/ScreensModule.kt +1 -1
  7. package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/DimmingView.kt +4 -4
  8. package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/DimmingViewManager.kt +8 -2
  9. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenAnimationDelegate.kt +1 -2
  10. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenEventEmitter.kt +16 -13
  11. package/android/src/main/java/com/swmansion/rnscreens/gamma/common/BaseEventEmitter.kt +22 -0
  12. package/android/src/main/java/com/swmansion/rnscreens/gamma/common/FragmentProviding.kt +11 -0
  13. package/android/src/main/java/com/swmansion/rnscreens/gamma/common/NamingAwareEventType.kt +13 -0
  14. package/android/src/main/java/com/swmansion/rnscreens/gamma/helpers/EventHelpers.kt +6 -0
  15. package/android/src/main/java/com/swmansion/rnscreens/gamma/helpers/FragmentManagerHelper.kt +76 -0
  16. package/android/src/main/java/com/swmansion/rnscreens/gamma/helpers/SystemDrawable.kt +33 -0
  17. package/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/TabScreen.kt +101 -0
  18. package/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/TabScreenDelegate.kt +17 -0
  19. package/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/TabScreenEventEmitter.kt +46 -0
  20. package/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/TabScreenFragment.kt +37 -0
  21. package/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/TabScreenViewManager.kt +178 -0
  22. package/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/TabsHost.kt +433 -0
  23. package/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/TabsHostEventEmitter.kt +14 -0
  24. package/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/TabsHostViewManager.kt +177 -0
  25. package/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/event/TabScreenDidAppearEvent.kt +30 -0
  26. package/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/event/TabScreenDidDisappearEvent.kt +30 -0
  27. package/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/event/TabScreenWillAppearEvent.kt +30 -0
  28. package/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/event/TabScreenWillDisappearEvent.kt +30 -0
  29. package/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/event/TabsHostNativeFocusChangeEvent.kt +36 -0
  30. package/android/src/main/java/com/swmansion/rnscreens/stack/views/ChildDrawingOrderStrategyImpl.kt +0 -1
  31. package/android/src/main/java/com/swmansion/rnscreens/transition/ExternalBoundaryValuesEvaluator.kt +9 -2
  32. package/android/src/main/java/com/swmansion/rnscreens/utils/FragmentTransactionKt.kt +4 -1
  33. package/android/src/main/jni/rnscreens.h +1 -0
  34. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSBottomTabsManagerDelegate.java +76 -0
  35. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSBottomTabsManagerInterface.java +33 -0
  36. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSBottomTabsScreenManagerDelegate.java +97 -0
  37. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSBottomTabsScreenManagerInterface.java +40 -0
  38. package/android/src/paper/java/com/swmansion/rnscreens/FabricEnabledHeaderConfigViewGroup.kt +2 -2
  39. package/android/src/versioned/backgroundcolor/76/ViewBackgroundUtils.kt +0 -1
  40. package/android/src/versioned/backgroundcolor/latest/ViewBackgroundUtils.kt +0 -3
  41. package/android/src/versioned/pointerevents/77/com/swmansion/rnscreens/PointerEventsBoxNoneImpl.kt +1 -1
  42. package/android/src/versioned/pointerevents/latest/com/swmansion/rnscreens/PointerEventsBoxNoneImpl.kt +1 -1
  43. package/common/cpp/react/renderer/components/rnscreens/RNSBottomTabsComponentDescriptor.h +31 -0
  44. package/common/cpp/react/renderer/components/rnscreens/RNSBottomTabsShadowNode.cpp +20 -0
  45. package/common/cpp/react/renderer/components/rnscreens/RNSBottomTabsShadowNode.h +32 -0
  46. package/common/cpp/react/renderer/components/rnscreens/RNSBottomTabsState.cpp +22 -0
  47. package/common/cpp/react/renderer/components/rnscreens/RNSBottomTabsState.h +44 -0
  48. package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.cpp +8 -0
  49. package/common/cpp/react/renderer/components/rnscreens/RNSSplitViewScreenComponentDescriptor.h +40 -0
  50. package/common/cpp/react/renderer/components/rnscreens/RNSSplitViewScreenShadowNode.cpp +13 -0
  51. package/common/cpp/react/renderer/components/rnscreens/RNSSplitViewScreenShadowNode.h +36 -0
  52. package/common/cpp/react/renderer/components/rnscreens/RNSSplitViewScreenState.h +32 -0
  53. package/cpp/RNScreensTurboModule.h +5 -0
  54. package/ios/RNSEnums.h +6 -0
  55. package/ios/RNSScreen.h +2 -1
  56. package/ios/RNSScreen.mm +48 -1
  57. package/ios/RNSScreenContainer.mm +6 -0
  58. package/ios/RNSScreenStack.h +3 -1
  59. package/ios/RNSScreenStack.mm +39 -2
  60. package/ios/RNSScreenStackHeaderConfig.mm +1 -1
  61. package/ios/RNSScrollViewBehaviorOverriding.h +24 -0
  62. package/ios/RNSScrollViewFinder.h +13 -0
  63. package/ios/RNSScrollViewFinder.mm +22 -0
  64. package/ios/RNSScrollViewHelper.h +10 -0
  65. package/ios/RNSScrollViewHelper.mm +15 -0
  66. package/ios/RNScreens-Bridging-Header.h +4 -0
  67. package/ios/UIScrollView+RNScreens.h +14 -0
  68. package/ios/UIScrollView+RNScreens.mm +15 -0
  69. package/ios/bottom-tabs/RCTConvert+RNSBottomTabs.h +18 -0
  70. package/ios/bottom-tabs/RCTConvert+RNSBottomTabs.mm +25 -0
  71. package/ios/bottom-tabs/RNSBottomTabsHostComponentView.h +80 -0
  72. package/ios/bottom-tabs/RNSBottomTabsHostComponentView.mm +486 -0
  73. package/ios/bottom-tabs/RNSBottomTabsHostComponentViewManager.h +11 -0
  74. package/ios/bottom-tabs/RNSBottomTabsHostComponentViewManager.mm +48 -0
  75. package/ios/bottom-tabs/RNSBottomTabsHostEventEmitter.h +53 -0
  76. package/ios/bottom-tabs/RNSBottomTabsHostEventEmitter.mm +57 -0
  77. package/ios/bottom-tabs/RNSBottomTabsScreenComponentView.h +95 -0
  78. package/ios/bottom-tabs/RNSBottomTabsScreenComponentView.mm +492 -0
  79. package/ios/bottom-tabs/RNSBottomTabsScreenComponentViewManager.h +9 -0
  80. package/ios/bottom-tabs/RNSBottomTabsScreenComponentViewManager.mm +55 -0
  81. package/ios/bottom-tabs/RNSBottomTabsScreenEventEmitter.h +53 -0
  82. package/ios/bottom-tabs/RNSBottomTabsScreenEventEmitter.mm +106 -0
  83. package/ios/bottom-tabs/RNSBottomTabsSpecialEffectsSupporting.h +17 -0
  84. package/ios/bottom-tabs/RNSTabBarAppearanceCoordinator.h +34 -0
  85. package/ios/bottom-tabs/RNSTabBarAppearanceCoordinator.mm +243 -0
  86. package/ios/bottom-tabs/RNSTabBarAppearanceProvider.h +23 -0
  87. package/ios/bottom-tabs/RNSTabBarController.h +132 -0
  88. package/ios/bottom-tabs/RNSTabBarController.mm +206 -0
  89. package/ios/bottom-tabs/RNSTabBarControllerDelegate.h +9 -0
  90. package/ios/bottom-tabs/RNSTabBarControllerDelegate.mm +63 -0
  91. package/ios/bottom-tabs/RNSTabsScreenViewController.h +42 -0
  92. package/ios/bottom-tabs/RNSTabsScreenViewController.mm +105 -0
  93. package/ios/bottom-tabs/extensions/RNSBottomTabsHostComponentView+RNSImageLoader.h +21 -0
  94. package/ios/bottom-tabs/extensions/RNSBottomTabsHostComponentView+RNSImageLoader.mm +22 -0
  95. package/ios/bridging/RNSReactBaseView.h +31 -0
  96. package/ios/bridging/RNSReactBaseView.mm +5 -0
  97. package/ios/bridging/Swift-Bridging.h +7 -0
  98. package/ios/conversion/RNSConversions-BottomTabs.mm +216 -0
  99. package/ios/conversion/RNSConversions-SplitView.mm +63 -0
  100. package/ios/conversion/RNSConversions.h +53 -0
  101. package/ios/gamma/ReactMountingTransactionObserving.swift +7 -0
  102. package/ios/gamma/split-view/RNSSplitViewHostComponentView.h +29 -0
  103. package/ios/gamma/split-view/RNSSplitViewHostComponentView.mm +209 -0
  104. package/ios/gamma/split-view/RNSSplitViewHostComponentViewManager.h +11 -0
  105. package/ios/gamma/split-view/RNSSplitViewHostComponentViewManager.mm +7 -0
  106. package/ios/gamma/split-view/RNSSplitViewHostController.swift +98 -0
  107. package/ios/gamma/split-view/RNSSplitViewNavigationController.swift +31 -0
  108. package/ios/gamma/split-view/RNSSplitViewScreenComponentView.h +24 -0
  109. package/ios/gamma/split-view/RNSSplitViewScreenComponentView.mm +106 -0
  110. package/ios/gamma/split-view/RNSSplitViewScreenComponentViewManager.h +11 -0
  111. package/ios/gamma/split-view/RNSSplitViewScreenComponentViewManager.mm +7 -0
  112. package/ios/gamma/split-view/RNSSplitViewScreenController.swift +86 -0
  113. package/ios/gamma/split-view/RNSSplitViewScreenShadowStateProxy.h +35 -0
  114. package/ios/gamma/split-view/RNSSplitViewScreenShadowStateProxy.mm +56 -0
  115. package/ios/gamma/stack/RNSScreenStackHostComponentView.h +16 -0
  116. package/ios/gamma/stack/RNSScreenStackHostComponentView.mm +143 -0
  117. package/ios/gamma/stack/RNSScreenStackHostComponentViewManager.h +11 -0
  118. package/ios/gamma/stack/RNSScreenStackHostComponentViewManager.mm +7 -0
  119. package/ios/gamma/stack/RNSStackController.swift +65 -0
  120. package/ios/gamma/stack/RNSStackScreenComponentEventEmitter.h +37 -0
  121. package/ios/gamma/stack/RNSStackScreenComponentEventEmitter.mm +60 -0
  122. package/ios/gamma/stack/RNSStackScreenComponentView.h +36 -0
  123. package/ios/gamma/stack/RNSStackScreenComponentView.mm +124 -0
  124. package/ios/gamma/stack/RNSStackScreenComponentViewManager.h +11 -0
  125. package/ios/gamma/stack/RNSStackScreenComponentViewManager.mm +7 -0
  126. package/ios/gamma/stack/RNSStackScreenController.swift +56 -0
  127. package/ios/utils/NSString+RNSUtility.h +17 -0
  128. package/ios/utils/NSString+RNSUtility.mm +37 -0
  129. package/lib/commonjs/components/BottomTabs.js +54 -0
  130. package/lib/commonjs/components/BottomTabs.js.map +1 -0
  131. package/lib/commonjs/components/BottomTabsScreen.js +149 -0
  132. package/lib/commonjs/components/BottomTabsScreen.js.map +1 -0
  133. package/lib/commonjs/components/gamma/ScreenStackHost.js +27 -0
  134. package/lib/commonjs/components/gamma/ScreenStackHost.js.map +1 -0
  135. package/lib/commonjs/components/gamma/SplitViewHost.js +57 -0
  136. package/lib/commonjs/components/gamma/SplitViewHost.js.map +1 -0
  137. package/lib/commonjs/components/gamma/SplitViewScreen.js +22 -0
  138. package/lib/commonjs/components/gamma/SplitViewScreen.js.map +1 -0
  139. package/lib/commonjs/components/gamma/StackScreen.js +51 -0
  140. package/lib/commonjs/components/gamma/StackScreen.js.map +1 -0
  141. package/lib/commonjs/fabric/BottomTabsNativeComponent.js +19 -0
  142. package/lib/commonjs/fabric/BottomTabsNativeComponent.js.map +1 -0
  143. package/lib/commonjs/fabric/BottomTabsScreenNativeComponent.js +14 -0
  144. package/lib/commonjs/fabric/BottomTabsScreenNativeComponent.js.map +1 -0
  145. package/lib/commonjs/fabric/gamma/ScreenStackHostNativeComponent.js +11 -0
  146. package/lib/commonjs/fabric/gamma/ScreenStackHostNativeComponent.js.map +1 -0
  147. package/lib/commonjs/fabric/gamma/SplitViewHostNativeComponent.js +11 -0
  148. package/lib/commonjs/fabric/gamma/SplitViewHostNativeComponent.js.map +1 -0
  149. package/lib/commonjs/fabric/gamma/SplitViewScreenNativeComponent.js +13 -0
  150. package/lib/commonjs/fabric/gamma/SplitViewScreenNativeComponent.js.map +1 -0
  151. package/lib/commonjs/fabric/gamma/StackScreenNativeComponent.js +12 -0
  152. package/lib/commonjs/fabric/gamma/StackScreenNativeComponent.js.map +1 -0
  153. package/lib/commonjs/flags.js +70 -0
  154. package/lib/commonjs/flags.js.map +1 -0
  155. package/lib/commonjs/index.js +66 -3
  156. package/lib/commonjs/index.js.map +1 -1
  157. package/lib/commonjs/utils.js +0 -28
  158. package/lib/commonjs/utils.js.map +1 -1
  159. package/lib/module/components/BottomTabs.js +48 -0
  160. package/lib/module/components/BottomTabs.js.map +1 -0
  161. package/lib/module/components/BottomTabsScreen.js +144 -0
  162. package/lib/module/components/BottomTabsScreen.js.map +1 -0
  163. package/lib/module/components/gamma/ScreenStackHost.js +20 -0
  164. package/lib/module/components/gamma/ScreenStackHost.js.map +1 -0
  165. package/lib/module/components/gamma/SplitViewHost.js +50 -0
  166. package/lib/module/components/gamma/SplitViewHost.js.map +1 -0
  167. package/lib/module/components/gamma/SplitViewScreen.js +15 -0
  168. package/lib/module/components/gamma/SplitViewScreen.js.map +1 -0
  169. package/lib/module/components/gamma/StackScreen.js +44 -0
  170. package/lib/module/components/gamma/StackScreen.js.map +1 -0
  171. package/lib/module/fabric/BottomTabsNativeComponent.js +15 -0
  172. package/lib/module/fabric/BottomTabsNativeComponent.js.map +1 -0
  173. package/lib/module/fabric/BottomTabsScreenNativeComponent.js +12 -0
  174. package/lib/module/fabric/BottomTabsScreenNativeComponent.js.map +1 -0
  175. package/lib/module/fabric/gamma/ScreenStackHostNativeComponent.js +5 -0
  176. package/lib/module/fabric/gamma/ScreenStackHostNativeComponent.js.map +1 -0
  177. package/lib/module/fabric/gamma/SplitViewHostNativeComponent.js +5 -0
  178. package/lib/module/fabric/gamma/SplitViewHostNativeComponent.js.map +1 -0
  179. package/lib/module/fabric/gamma/SplitViewScreenNativeComponent.js +7 -0
  180. package/lib/module/fabric/gamma/SplitViewScreenNativeComponent.js.map +1 -0
  181. package/lib/module/fabric/gamma/StackScreenNativeComponent.js +8 -0
  182. package/lib/module/fabric/gamma/StackScreenNativeComponent.js.map +1 -0
  183. package/lib/module/flags.js +64 -0
  184. package/lib/module/flags.js.map +1 -0
  185. package/lib/module/index.js +16 -1
  186. package/lib/module/index.js.map +1 -1
  187. package/lib/module/utils.js +0 -27
  188. package/lib/module/utils.js.map +1 -1
  189. package/lib/typescript/components/BottomTabs.d.ts +30 -0
  190. package/lib/typescript/components/BottomTabs.d.ts.map +1 -0
  191. package/lib/typescript/components/BottomTabsScreen.d.ts +56 -0
  192. package/lib/typescript/components/BottomTabsScreen.d.ts.map +1 -0
  193. package/lib/typescript/components/gamma/ScreenStackHost.d.ts +13 -0
  194. package/lib/typescript/components/gamma/ScreenStackHost.d.ts.map +1 -0
  195. package/lib/typescript/components/gamma/SplitViewHost.d.ts +13 -0
  196. package/lib/typescript/components/gamma/SplitViewHost.d.ts.map +1 -0
  197. package/lib/typescript/components/gamma/SplitViewScreen.d.ts +13 -0
  198. package/lib/typescript/components/gamma/SplitViewScreen.d.ts.map +1 -0
  199. package/lib/typescript/components/gamma/StackScreen.d.ts +21 -0
  200. package/lib/typescript/components/gamma/StackScreen.d.ts.map +1 -0
  201. package/lib/typescript/fabric/BottomTabsNativeComponent.d.ts +31 -0
  202. package/lib/typescript/fabric/BottomTabsNativeComponent.d.ts.map +1 -0
  203. package/lib/typescript/fabric/BottomTabsScreenNativeComponent.d.ts +51 -0
  204. package/lib/typescript/fabric/BottomTabsScreenNativeComponent.d.ts.map +1 -0
  205. package/lib/typescript/fabric/gamma/ScreenStackHostNativeComponent.d.ts +7 -0
  206. package/lib/typescript/fabric/gamma/ScreenStackHostNativeComponent.d.ts.map +1 -0
  207. package/lib/typescript/fabric/gamma/SplitViewHostNativeComponent.d.ts +16 -0
  208. package/lib/typescript/fabric/gamma/SplitViewHostNativeComponent.d.ts.map +1 -0
  209. package/lib/typescript/fabric/gamma/SplitViewScreenNativeComponent.d.ts +7 -0
  210. package/lib/typescript/fabric/gamma/SplitViewScreenNativeComponent.d.ts.map +1 -0
  211. package/lib/typescript/fabric/gamma/StackScreenNativeComponent.d.ts +15 -0
  212. package/lib/typescript/fabric/gamma/StackScreenNativeComponent.d.ts.map +1 -0
  213. package/lib/typescript/flags.d.ts +45 -0
  214. package/lib/typescript/flags.d.ts.map +1 -0
  215. package/lib/typescript/index.d.ts +14 -1
  216. package/lib/typescript/index.d.ts.map +1 -1
  217. package/lib/typescript/utils.d.ts +0 -26
  218. package/lib/typescript/utils.d.ts.map +1 -1
  219. package/package.json +34 -6
  220. package/react-native.config.js +2 -1
  221. package/src/components/BottomTabs.tsx +115 -0
  222. package/src/components/BottomTabsScreen.tsx +291 -0
  223. package/src/components/gamma/ScreenStackHost.tsx +32 -0
  224. package/src/components/gamma/SplitViewHost.tsx +84 -0
  225. package/src/components/gamma/SplitViewScreen.tsx +26 -0
  226. package/src/components/gamma/StackScreen.tsx +64 -0
  227. package/src/fabric/BottomTabsNativeComponent.ts +82 -0
  228. package/src/fabric/BottomTabsScreenNativeComponent.ts +107 -0
  229. package/src/fabric/gamma/ScreenStackHostNativeComponent.ts +8 -0
  230. package/src/fabric/gamma/SplitViewHostNativeComponent.ts +39 -0
  231. package/src/fabric/gamma/SplitViewScreenNativeComponent.ts +10 -0
  232. package/src/fabric/gamma/StackScreenNativeComponent.ts +25 -0
  233. package/src/flags.ts +72 -0
  234. package/src/index.tsx +18 -1
  235. package/src/utils.ts +0 -28
@@ -0,0 +1,31 @@
1
+ import Foundation
2
+ import UIKit
3
+
4
+ protocol RNSSplitViewNavigationControllerViewFrameObserver: AnyObject {
5
+ func splitViewNavCtrlViewDidChangeFrameOrigin(
6
+ _ splitViewNavCtrl: RNSSplitViewNavigationController)
7
+ }
8
+
9
+ @objc
10
+ public class RNSSplitViewNavigationController: UINavigationController {
11
+ private var viewFrameObservation: NSKeyValueObservation?
12
+ weak var viewFrameOriginChangeObserver: RNSSplitViewNavigationControllerViewFrameObserver?
13
+
14
+ override public func viewDidLoad() {
15
+ super.viewDidLoad()
16
+
17
+ viewFrameObservation?.invalidate()
18
+ viewFrameObservation = self.view.observe(\.frame, options: [.old, .new]) {
19
+ [weak self] (view, change) in
20
+ guard let oldFrame = change.oldValue, let newFrame = change.newValue else { return }
21
+
22
+ if oldFrame.origin != newFrame.origin {
23
+ self?.onViewOriginChange()
24
+ }
25
+ }
26
+ }
27
+
28
+ private func onViewOriginChange() {
29
+ viewFrameOriginChangeObserver?.splitViewNavCtrlViewDidChangeFrameOrigin(self)
30
+ }
31
+ }
@@ -0,0 +1,24 @@
1
+ #import "RNSReactBaseView.h"
2
+ #import "RNSSplitViewScreenShadowStateProxy.h"
3
+
4
+ NS_ASSUME_NONNULL_BEGIN
5
+
6
+ @class RNSSplitViewHostComponentView;
7
+ @class RNSSplitViewScreenController;
8
+
9
+ @interface RNSSplitViewScreenComponentView : RNSReactBaseView
10
+
11
+ @property (nonatomic, strong, readonly, nonnull) RNSSplitViewScreenController *controller;
12
+ @property (nonatomic, weak, readwrite, nullable) RNSSplitViewHostComponentView *splitViewHost;
13
+
14
+ @end
15
+
16
+ #pragma mark - ShadowTreeState
17
+
18
+ @interface RNSSplitViewScreenComponentView ()
19
+
20
+ - (nonnull RNSSplitViewScreenShadowStateProxy *)shadowStateProxy;
21
+
22
+ @end
23
+
24
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,106 @@
1
+ #import "RNSSplitViewScreenComponentView.h"
2
+ #import <React/RCTAssert.h>
3
+ #import <React/RCTSurfaceTouchHandler.h>
4
+ #import <rnscreens/RNSSplitViewScreenComponentDescriptor.h>
5
+
6
+ #import "Swift-Bridging.h"
7
+
8
+ namespace react = facebook::react;
9
+
10
+ @implementation RNSSplitViewScreenComponentView {
11
+ RNSSplitViewScreenController *_Nullable _controller;
12
+ RNSSplitViewScreenShadowStateProxy *_Nonnull _shadowStateProxy;
13
+ RCTSurfaceTouchHandler *_Nullable _touchHandler;
14
+ }
15
+
16
+ - (RNSSplitViewScreenController *)controller
17
+ {
18
+ RCTAssert(
19
+ _controller != nil,
20
+ @"[RNScreens] Attempt to access RNSSplitViewScreenController before RNSSplitViewScreenComponentView was initialized. (for: %@)",
21
+ self);
22
+ return _controller;
23
+ }
24
+
25
+ - (instancetype)initWithFrame:(CGRect)frame
26
+ {
27
+ if (self = [super initWithFrame:frame]) {
28
+ [self initState];
29
+ }
30
+
31
+ return self;
32
+ }
33
+
34
+ - (void)initState
35
+ {
36
+ [self setupController];
37
+
38
+ _shadowStateProxy = [RNSSplitViewScreenShadowStateProxy new];
39
+ }
40
+
41
+ - (void)setupController
42
+ {
43
+ _controller = [[RNSSplitViewScreenController alloc] initWithSplitViewScreenComponentView:self];
44
+ _controller.view = self;
45
+ }
46
+
47
+ - (void)didMoveToWindow
48
+ {
49
+ // Starting from iOS 26, a new column type called 'inspector' was introduced.
50
+ // This column can be displayed as a modal, independent of the React Native view hierarchy.
51
+ // In contrast, prior to iOS 26, all SplitView columns were placed under RCTSurface,
52
+ // meaning that touches were handler by RN handlers.
53
+ if (@available(iOS 26.0, *)) {
54
+ // If the current controller’s splitViewController is of type RNSSplitViewHostController,
55
+ // we know that we're still inside the RN hierarchy,
56
+ // so there's no need to enforce additional touch event support.
57
+ if ([_controller isInSplitViewHostSubtree]) {
58
+ return;
59
+ }
60
+
61
+ if (self.window != nil) {
62
+ if (_touchHandler == nil) {
63
+ _touchHandler = [RCTSurfaceTouchHandler new];
64
+ }
65
+ [_touchHandler attachToView:self];
66
+ } else {
67
+ [_touchHandler detachFromView:self];
68
+ }
69
+ }
70
+ }
71
+
72
+ #pragma mark - ShadowTreeState
73
+
74
+ - (nonnull RNSSplitViewScreenShadowStateProxy *)shadowStateProxy
75
+ {
76
+ RCTAssert(_shadowStateProxy != nil, @"[RNScreens] Attempt to access uninitialized _shadowStateProxy");
77
+ return _shadowStateProxy;
78
+ }
79
+
80
+ #pragma mark - RCTViewComponentViewProtocol
81
+
82
+ + (react::ComponentDescriptorProvider)componentDescriptorProvider
83
+ {
84
+ return react::concreteComponentDescriptorProvider<react::RNSSplitViewScreenComponentDescriptor>();
85
+ }
86
+
87
+ + (BOOL)shouldBeRecycled
88
+ {
89
+ // There won't be tens of instances of this component usually & it's easier for now.
90
+ // We could consider enabling it someday though.
91
+ return NO;
92
+ }
93
+
94
+ - (void)updateState:(react::State::Shared const &)state oldState:(react::State::Shared const &)oldState
95
+ {
96
+ [super updateState:state oldState:oldState];
97
+
98
+ [_shadowStateProxy updateState:state oldState:oldState];
99
+ }
100
+
101
+ @end
102
+
103
+ Class<RCTComponentViewProtocol> RNSSplitViewScreenCls(void)
104
+ {
105
+ return RNSSplitViewScreenComponentView.class;
106
+ }
@@ -0,0 +1,11 @@
1
+ #pragma once
2
+
3
+ #import <React/RCTViewManager.h>
4
+
5
+ NS_ASSUME_NONNULL_BEGIN
6
+
7
+ @interface RNSSplitViewScreenComponentViewManager : RCTViewManager
8
+
9
+ @end
10
+
11
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,7 @@
1
+ #import "RNSSplitViewScreenComponentViewManager.h"
2
+
3
+ @implementation RNSSplitViewScreenComponentViewManager
4
+
5
+ RCT_EXPORT_MODULE(RNSSplitViewScreenComponentViewManager)
6
+
7
+ @end
@@ -0,0 +1,86 @@
1
+ import Foundation
2
+ import UIKit
3
+
4
+ @objc
5
+ public class RNSSplitViewScreenController: UIViewController {
6
+ let splitViewScreenComponentView: RNSSplitViewScreenComponentView
7
+
8
+ private var shadowStateProxy: RNSSplitViewScreenShadowStateProxy {
9
+ return splitViewScreenComponentView.shadowStateProxy()
10
+ }
11
+
12
+ @objc public required init(splitViewScreenComponentView: RNSSplitViewScreenComponentView) {
13
+ self.splitViewScreenComponentView = splitViewScreenComponentView
14
+ super.init(nibName: nil, bundle: nil)
15
+ }
16
+
17
+ required init?(coder aDecoder: NSCoder) {
18
+ return nil
19
+ }
20
+
21
+ func findSplitViewHostController() -> RNSSplitViewHostController? {
22
+ if let splitViewHostController = self.splitViewController as? RNSSplitViewHostController {
23
+ return splitViewHostController
24
+ }
25
+
26
+ if let splitViewHost = self.splitViewScreenComponentView.splitViewHost {
27
+ return splitViewHost.splitViewHostController
28
+ }
29
+
30
+ return nil
31
+ }
32
+
33
+ /// Checks whether `self` is attached under a parent split view controller
34
+ /// that is presented by SplitViewHost. This might not be the case, for example,
35
+ /// when `self` is presented as a modal.
36
+ @objc
37
+ public func isInSplitViewHostSubtree() -> Bool {
38
+ return self.splitViewController is RNSSplitViewHostController
39
+ }
40
+
41
+ // MARK: Signals
42
+
43
+ @objc
44
+ public func setNeedsLifecycleStateUpdate() {
45
+ findSplitViewHostController()?.setNeedsUpdateOfChildViewControllers()
46
+ }
47
+
48
+ // MARK: Layout
49
+
50
+ @objc
51
+ public override func viewDidLayoutSubviews() {
52
+ super.viewDidLayoutSubviews()
53
+ if #available(iOS 26.0, *) {
54
+ // For modals, which are presented outside the SplitViewHost subtree (and RN hierarchy),
55
+ // we're attaching our touch handler adn we don't need to apply any offset corrections,
56
+ // because it's positioned relatively to our RNSSplitViewScreenComponentView
57
+ if isInSplitViewHostSubtree() {
58
+ let ancestorView = findSplitViewHostController()?.view
59
+
60
+ assert(
61
+ ancestorView != nil,
62
+ "[RNScreens] Expected to find RNSSplitViewHost component for RNSSplitViewScreen component"
63
+ )
64
+
65
+ shadowStateProxy.updateShadowState(
66
+ ofComponent: splitViewScreenComponentView,
67
+ inContextOfAncestorView: ancestorView!
68
+ )
69
+ } else {
70
+ shadowStateProxy.updateShadowState(
71
+ ofComponent: splitViewScreenComponentView
72
+ )
73
+ }
74
+ }
75
+
76
+ // TODO: to be removed - only for testing purposes for inspector column
77
+ // if #available(iOS 26.0, *) {
78
+ // findSplitViewHostController()?.show(.inspector)
79
+ // }
80
+ }
81
+
82
+ func columnPositioningDidChangeIn(splitViewController: UISplitViewController) {
83
+ shadowStateProxy.updateShadowState(
84
+ ofComponent: splitViewScreenComponentView, inContextOfAncestorView: splitViewController.view)
85
+ }
86
+ }
@@ -0,0 +1,35 @@
1
+ #import <Foundation/Foundation.h>
2
+
3
+ #if defined(__cplusplus)
4
+ #import <react/renderer/core/State.h>
5
+
6
+ namespace react = facebook::react;
7
+ #endif // __cplusplus
8
+
9
+ NS_ASSUME_NONNULL_BEGIN
10
+
11
+ @class RNSSplitViewScreenComponentView;
12
+
13
+ @interface RNSSplitViewScreenShadowStateProxy : NSObject
14
+
15
+ - (void)updateShadowStateOfComponent:(RNSSplitViewScreenComponentView *)screenComponentView;
16
+
17
+ - (void)updateShadowStateOfComponent:(RNSSplitViewScreenComponentView *)screenComponentView
18
+ inContextOfAncestorView:(UIView *_Nullable)ancestorView;
19
+
20
+ - (void)updateShadowStateWithFrame:(CGRect)frame;
21
+
22
+ @end
23
+
24
+ #pragma mark - Hidden from Swift
25
+
26
+ #if defined(__cplusplus)
27
+
28
+ @interface RNSSplitViewScreenShadowStateProxy ()
29
+
30
+ - (void)updateState:(react::State::Shared const &)state oldState:(react::State::Shared const &)oldState;
31
+
32
+ @end
33
+
34
+ #endif // __cplusplus
35
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,56 @@
1
+ #import "RNSSplitViewScreenShadowStateProxy.h"
2
+
3
+ #import <React/RCTConversions.h>
4
+ #import <rnscreens/RNSSplitViewScreenShadowNode.h>
5
+ #import "RNSSplitViewScreenComponentView.h"
6
+
7
+ namespace react = facebook::react;
8
+
9
+ @implementation RNSSplitViewScreenShadowStateProxy {
10
+ react::RNSSplitViewScreenShadowNode::ConcreteState::Shared _state;
11
+ CGRect _lastScheduledFrame;
12
+ }
13
+
14
+ - (instancetype)init
15
+ {
16
+ if (self = [super init]) {
17
+ _lastScheduledFrame = CGRectNull;
18
+ }
19
+
20
+ return self;
21
+ }
22
+
23
+ - (void)updateShadowStateOfComponent:(RNSSplitViewScreenComponentView *)screenComponentView
24
+ {
25
+ [self updateShadowStateOfComponent:screenComponentView inContextOfAncestorView:nil];
26
+ }
27
+
28
+ - (void)updateShadowStateOfComponent:(RNSSplitViewScreenComponentView *)screenComponentView
29
+ inContextOfAncestorView:(UIView *_Nullable)ancestorView
30
+ {
31
+ CGRect frame = screenComponentView.frame;
32
+ if (ancestorView != nil) {
33
+ frame = [screenComponentView convertRect:frame toView:ancestorView];
34
+ }
35
+ [self updateShadowStateWithFrame:frame];
36
+ }
37
+
38
+ - (void)updateShadowStateWithFrame:(CGRect)frame
39
+ {
40
+ if (_state == nullptr) {
41
+ return;
42
+ }
43
+
44
+ if (!CGRectEqualToRect(frame, _lastScheduledFrame)) {
45
+ auto newState = react::RNSSplitViewScreenState{RCTSizeFromCGSize(frame.size), RCTPointFromCGPoint(frame.origin)};
46
+ _state->updateState(std::move(newState));
47
+ _lastScheduledFrame = frame;
48
+ }
49
+ }
50
+
51
+ - (void)updateState:(react::State::Shared const &)state oldState:(react::State::Shared const &)oldState
52
+ {
53
+ _state = std::static_pointer_cast<const react::RNSSplitViewScreenShadowNode::ConcreteState>(state);
54
+ }
55
+
56
+ @end
@@ -0,0 +1,16 @@
1
+ #import "RNSReactBaseView.h"
2
+ #import "RNSStackScreenComponentView.h"
3
+
4
+ @class RNSStackController;
5
+
6
+ NS_ASSUME_NONNULL_BEGIN
7
+
8
+ @interface RNSScreenStackHostComponentView : RNSReactBaseView
9
+
10
+ @property (nonatomic, nonnull, strong, readonly) RNSStackController *stackController;
11
+
12
+ - (nonnull NSMutableArray<RNSStackScreenComponentView *> *)reactSubviews;
13
+
14
+ @end
15
+
16
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,143 @@
1
+ #import "RNSScreenStackHostComponentView.h"
2
+
3
+ #import <React/RCTConversions.h>
4
+ #import <React/RCTMountingTransactionObserving.h>
5
+ #import <React/UIView+React.h>
6
+ #import <react/renderer/components/rnscreens/ComponentDescriptors.h>
7
+ #import <react/renderer/components/rnscreens/EventEmitters.h>
8
+ #import <react/renderer/components/rnscreens/Props.h>
9
+ #import <react/renderer/components/rnscreens/RCTComponentViewHelpers.h>
10
+ #import "RNSDefines.h"
11
+
12
+ #import "Swift-Bridging.h"
13
+
14
+ namespace react = facebook::react;
15
+
16
+ @interface RNSScreenStackHostComponentView () <RCTMountingTransactionObserving>
17
+ @end
18
+
19
+ @implementation RNSScreenStackHostComponentView {
20
+ RNSStackController *_Nonnull _controller;
21
+ NSMutableArray<RNSStackScreenComponentView *> *_Nonnull _reactSubviews;
22
+
23
+ bool _hasModifiedReactSubviewsInCurrentTransaction;
24
+ }
25
+
26
+ - (instancetype)initWithFrame:(CGRect)frame
27
+ {
28
+ if (self = [super initWithFrame:frame]) {
29
+ [self initState];
30
+ }
31
+ return self;
32
+ }
33
+
34
+ - (void)initState
35
+ {
36
+ _controller = [[RNSStackController alloc] initWithStackHostComponentView:self];
37
+ _hasModifiedReactSubviewsInCurrentTransaction = false;
38
+ _reactSubviews = [NSMutableArray new];
39
+ }
40
+
41
+ - (void)didMoveToWindow
42
+ {
43
+ RCTAssert(_controller != nil, @"[RNScreens] Controller must not be nil while attaching to window");
44
+
45
+ [self reactAddControllerToClosestParent:_controller];
46
+ }
47
+
48
+ - (void)reactAddControllerToClosestParent:(UIViewController *)controller
49
+ {
50
+ if (!controller.parentViewController) {
51
+ UIView *parentView = (UIView *)self.reactSuperview;
52
+ while (parentView) {
53
+ if (parentView.reactViewController) {
54
+ [parentView.reactViewController addChildViewController:controller];
55
+ [self addSubview:controller.view];
56
+ [controller didMoveToParentViewController:parentView.reactViewController];
57
+ break;
58
+ }
59
+ parentView = (UIView *)parentView.reactSuperview;
60
+ }
61
+ return;
62
+ }
63
+ }
64
+
65
+ RNS_IGNORE_SUPER_CALL_BEGIN
66
+ - (nonnull NSMutableArray<RNSStackScreenComponentView *> *)reactSubviews
67
+ {
68
+ return _reactSubviews;
69
+ }
70
+ RNS_IGNORE_SUPER_CALL_END
71
+
72
+ - (nonnull RNSStackController *)stackController
73
+ {
74
+ RCTAssert(_controller != nil, @"[RNScreens] Controller must not be nil");
75
+ return _controller;
76
+ }
77
+
78
+ #pragma mark - RCTViewComponentViewProtocol
79
+
80
+ - (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
81
+ {
82
+ RCTAssert(
83
+ [childComponentView isKindOfClass:RNSStackScreenComponentView.class],
84
+ @"[RNScreens] Attempt to mount child of unsupported type: %@, expected %@",
85
+ childComponentView.class,
86
+ RNSStackScreenComponentView.class);
87
+
88
+ auto *childScreen = static_cast<RNSStackScreenComponentView *>(childComponentView);
89
+ childScreen.stackHost = self;
90
+ [_reactSubviews insertObject:childScreen atIndex:index];
91
+ _hasModifiedReactSubviewsInCurrentTransaction = true;
92
+ }
93
+
94
+ - (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
95
+ {
96
+ RCTAssert(
97
+ [childComponentView isKindOfClass:RNSStackScreenComponentView.class],
98
+ @"[RNScreens] Attempt to unmount child of unsupported type: %@, expected %@",
99
+ childComponentView.class,
100
+ RNSStackScreenComponentView.class);
101
+
102
+ auto *childScreen = static_cast<RNSStackScreenComponentView *>(childComponentView);
103
+ [_reactSubviews removeObject:childScreen];
104
+ childScreen.stackHost = nil;
105
+ _hasModifiedReactSubviewsInCurrentTransaction = true;
106
+ }
107
+
108
+ + (react::ComponentDescriptorProvider)componentDescriptorProvider
109
+ {
110
+ return react::concreteComponentDescriptorProvider<react::RNSScreenStackHostComponentDescriptor>();
111
+ }
112
+
113
+ + (BOOL)shouldBeRecycled
114
+ {
115
+ // There won't be tens of instances of this component usually & it's easier for now.
116
+ // We could consider enabling it someday though.
117
+ return NO;
118
+ }
119
+
120
+ #pragma mark - RCTMountingTransactionObserving
121
+
122
+ - (void)mountingTransactionWillMount:(const facebook::react::MountingTransaction &)transaction
123
+ withSurfaceTelemetry:(const facebook::react::SurfaceTelemetry &)surfaceTelemetry
124
+ {
125
+ _hasModifiedReactSubviewsInCurrentTransaction = false;
126
+ [_controller reactMountingTransactionWillMount];
127
+ }
128
+
129
+ - (void)mountingTransactionDidMount:(const facebook::react::MountingTransaction &)transaction
130
+ withSurfaceTelemetry:(const facebook::react::SurfaceTelemetry &)surfaceTelemetry
131
+ {
132
+ if (_hasModifiedReactSubviewsInCurrentTransaction) {
133
+ [_controller setNeedsUpdateOfChildViewControllers];
134
+ }
135
+ [_controller reactMountingTransactionDidMount];
136
+ }
137
+
138
+ @end
139
+
140
+ Class<RCTComponentViewProtocol> RNSScreenStackHostCls(void)
141
+ {
142
+ return RNSScreenStackHostComponentView.class;
143
+ }
@@ -0,0 +1,11 @@
1
+ #pragma once
2
+
3
+ #import <React/RCTViewManager.h>
4
+
5
+ NS_ASSUME_NONNULL_BEGIN
6
+
7
+ @interface RNSScreenStackHostComponentViewManager : RCTViewManager
8
+
9
+ @end
10
+
11
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,7 @@
1
+ #import "RNSScreenStackHostComponentViewManager.h"
2
+
3
+ @implementation RNSScreenStackHostComponentViewManager
4
+
5
+ RCT_EXPORT_MODULE(RNSScreenStackHostViewManager)
6
+
7
+ @end
@@ -0,0 +1,65 @@
1
+ import Foundation
2
+ import UIKit
3
+
4
+ @objc
5
+ public class RNSStackController: UINavigationController, ReactMountingTransactionObserving {
6
+ private var needsChildViewControllersUpdate = false
7
+ private let screenStackHostComponentView: RNSScreenStackHostComponentView
8
+
9
+ @objc public required init(stackHostComponentView: RNSScreenStackHostComponentView) {
10
+ self.screenStackHostComponentView = stackHostComponentView
11
+ super.init(nibName: nil, bundle: nil)
12
+ }
13
+
14
+ required init?(coder aDecoder: NSCoder) {
15
+ return nil
16
+ }
17
+
18
+ // MARK: Signals
19
+
20
+ @objc
21
+ public func setNeedsUpdateOfChildViewControllers() {
22
+ needsChildViewControllersUpdate = true
23
+ }
24
+
25
+ // MARK: Updating
26
+
27
+ @objc
28
+ public func updateChildViewControllersIfNeeded() {
29
+ if needsChildViewControllersUpdate {
30
+ updateChildViewControllers()
31
+ }
32
+ }
33
+
34
+ @objc
35
+ public func updateChildViewControllers() {
36
+ precondition(
37
+ needsChildViewControllersUpdate,
38
+ "[RNScreens] Child view controller must be invalidated when update is forced!")
39
+
40
+ let activeControllers = sourceAllViewControllers()
41
+ .filter { screenCtrl in screenCtrl.screenStackComponentView.maxLifecycleState == .attached }
42
+
43
+ setViewControllers(activeControllers, animated: true)
44
+
45
+ needsChildViewControllersUpdate = false
46
+ }
47
+
48
+ private func sourceAllViewControllers() -> [RNSStackScreenController] {
49
+ let screenStackComponents =
50
+ screenStackHostComponentView.reactSubviews() as! [RNSStackScreenComponentView]
51
+ return screenStackComponents.lazy.map(\.controller)
52
+ }
53
+
54
+ // MARK: ReactMountingTransactionObserving
55
+
56
+ @objc
57
+ public func reactMountingTransactionWillMount() {
58
+ // noop
59
+ }
60
+
61
+ @objc
62
+ public func reactMountingTransactionDidMount() {
63
+ updateChildViewControllersIfNeeded()
64
+ }
65
+ }
@@ -0,0 +1,37 @@
1
+ #import <Foundation/Foundation.h>
2
+
3
+ // Hide C++ symbols from C compiler used when building Swift module
4
+ #if defined(__cplusplus)
5
+ #import <react/renderer/components/rnscreens/EventEmitters.h>
6
+
7
+ namespace react = facebook::react;
8
+ #endif // __cplusplus
9
+
10
+ NS_ASSUME_NONNULL_BEGIN
11
+
12
+ /**
13
+ * These methods can be called to send an appropriate event to ElementTree.
14
+ * Returned value denotes whether the event has been successfully dispatched to React event pipeline.
15
+ * The returned value of `true` does not mean, that the event has been successfully delivered.
16
+ */
17
+ @interface RNSStackScreenComponentEventEmitter : NSObject
18
+
19
+ - (BOOL)emitOnWillAppear;
20
+ - (BOOL)emitOnDidAppear;
21
+ - (BOOL)emitOnWillDisappear;
22
+ - (BOOL)emitOnDidDisappear;
23
+
24
+ @end
25
+
26
+ #pragma mark - Hidden from Swift
27
+
28
+ #if defined(__cplusplus)
29
+
30
+ @interface RNSStackScreenComponentEventEmitter ()
31
+
32
+ - (void)updateEventEmitter:(const std::shared_ptr<const react::RNSStackScreenEventEmitter> &)emitter;
33
+
34
+ @end
35
+
36
+ #endif // __cplusplus
37
+ NS_ASSUME_NONNULL_END