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,291 @@
1
+ 'use client';
2
+
3
+ import React from 'react';
4
+ import BottomTabsScreenNativeComponent, {
5
+ BlurEffect,
6
+ type IconType,
7
+ type NativeProps,
8
+ } from '../fabric/BottomTabsScreenNativeComponent';
9
+ import {
10
+ type ColorValue,
11
+ type ImageSourcePropType,
12
+ type NativeSyntheticEvent,
13
+ StyleSheet,
14
+ TextStyle,
15
+ type ViewProps,
16
+ findNodeHandle,
17
+ } from 'react-native';
18
+ import { Freeze } from 'react-freeze';
19
+ import { freezeEnabled } from '../core';
20
+ import { featureFlags } from '../flags';
21
+
22
+ export type EmptyObject = Record<string, never>;
23
+ export type BottomTabsScreenEventHandler<T> = (
24
+ event: NativeSyntheticEvent<T>,
25
+ ) => void;
26
+
27
+ // iOS-specific: SFSymbol usage
28
+ export interface SFIcon {
29
+ sfSymbolName: string;
30
+ }
31
+
32
+ export interface ImageIcon {
33
+ imageSource: ImageSourcePropType;
34
+ }
35
+
36
+ // iOS-specific: image as a template usage
37
+ export interface TemplateIcon {
38
+ templateSource: ImageSourcePropType;
39
+ }
40
+
41
+ // iOS-specific: SFSymbol, image as a template usage
42
+ export type Icon = SFIcon | ImageIcon | TemplateIcon;
43
+
44
+ export interface BottomTabsScreenProps {
45
+ children?: ViewProps['children'];
46
+ placeholder?: React.ReactNode | undefined;
47
+
48
+ // Control
49
+
50
+ // Works only in 'controlled' mode. Otherwise this prop indicates only initally selected tab.
51
+ isFocused?: boolean;
52
+ tabKey: string;
53
+
54
+ // Tab Bar Appearance
55
+ // tabBarAppearance?: TabBarAppearance; // Does not work due to codegen issue.
56
+ tabBarBackgroundColor?: ColorValue;
57
+ tabBarBlurEffect?: BlurEffect; // defaults to 'none'
58
+
59
+ tabBarItemTitleFontFamily?: TextStyle['fontFamily'];
60
+ tabBarItemTitleFontSize?: TextStyle['fontSize'];
61
+ tabBarItemTitleFontWeight?: TextStyle['fontWeight'];
62
+ tabBarItemTitleFontStyle?: TextStyle['fontStyle'];
63
+ tabBarItemTitleFontColor?: TextStyle['color'];
64
+ tabBarItemTitlePositionAdjustment?: {
65
+ horizontal?: number;
66
+ vertical?: number;
67
+ };
68
+
69
+ tabBarItemIconColor?: ColorValue;
70
+
71
+ tabBarItemBadgeBackgroundColor?: ColorValue;
72
+
73
+ // General
74
+ title?: string;
75
+
76
+ // Android specific
77
+ iconResourceName?: string;
78
+
79
+ icon?: Icon;
80
+ selectedIcon?: Icon;
81
+
82
+ badgeValue?: string;
83
+
84
+ specialEffects?: {
85
+ repeatedTabSelection?: {
86
+ popToRoot?: boolean;
87
+ scrollToTop?: boolean;
88
+ };
89
+ };
90
+
91
+ overrideScrollViewContentInsetAdjustmentBehavior?: boolean; // defaults to true
92
+
93
+ // Events
94
+ onWillAppear?: BottomTabsScreenEventHandler<EmptyObject>;
95
+ onDidAppear?: BottomTabsScreenEventHandler<EmptyObject>;
96
+ onWillDisappear?: BottomTabsScreenEventHandler<EmptyObject>;
97
+ onDidDisappear?: BottomTabsScreenEventHandler<EmptyObject>;
98
+ }
99
+
100
+ /**
101
+ * EXPERIMENTAL API, MIGHT CHANGE W/O ANY NOTICE
102
+ */
103
+ function BottomTabsScreen(props: BottomTabsScreenProps) {
104
+ const componentNodeRef = React.useRef<React.Component<NativeProps>>(null);
105
+ const componentNodeHandle = React.useRef<number>(-1);
106
+
107
+ React.useEffect(() => {
108
+ if (componentNodeRef.current != null) {
109
+ componentNodeHandle.current =
110
+ findNodeHandle(componentNodeRef.current) ?? -1;
111
+ } else {
112
+ componentNodeHandle.current = -1;
113
+ }
114
+ }, []);
115
+
116
+ const [nativeViewIsVisible, setNativeViewIsVisible] = React.useState(false);
117
+
118
+ const {
119
+ onWillAppear,
120
+ onDidAppear,
121
+ onWillDisappear,
122
+ onDidDisappear,
123
+ isFocused = false,
124
+ icon,
125
+ selectedIcon,
126
+ ...rest
127
+ } = props;
128
+
129
+ let shouldFreeze = freezeEnabled();
130
+
131
+ if (featureFlags.experiment.controlledBottomTabs) {
132
+ // If the tabs are JS controlled, we want to freeze only when given view is not focused && it is not currently visible
133
+ shouldFreeze = shouldFreeze && !nativeViewIsVisible && !isFocused;
134
+ } else {
135
+ shouldFreeze = shouldFreeze && !nativeViewIsVisible;
136
+ }
137
+
138
+ const onWillAppearCallback = React.useCallback(
139
+ (event: NativeSyntheticEvent<EmptyObject>) => {
140
+ console.log(
141
+ `TabsScreen [${componentNodeHandle.current}] onWillAppear received`,
142
+ );
143
+ setNativeViewIsVisible(true);
144
+ onWillAppear?.(event);
145
+ },
146
+ [onWillAppear],
147
+ );
148
+
149
+ const onDidAppearCallback = React.useCallback(
150
+ (event: NativeSyntheticEvent<EmptyObject>) => {
151
+ console.log(
152
+ `TabsScreen [${componentNodeHandle.current}] onDidAppear received`,
153
+ );
154
+ onDidAppear?.(event);
155
+ },
156
+ [onDidAppear],
157
+ );
158
+
159
+ const onWillDisappearCallback = React.useCallback(
160
+ (event: NativeSyntheticEvent<EmptyObject>) => {
161
+ console.log(
162
+ `TabsScreen [${componentNodeHandle.current}] onWillDisappear received`,
163
+ );
164
+ onWillDisappear?.(event);
165
+ },
166
+ [onWillDisappear],
167
+ );
168
+
169
+ const onDidDisappearCallback = React.useCallback(
170
+ (event: NativeSyntheticEvent<EmptyObject>) => {
171
+ console.log(
172
+ `TabsScreen [${componentNodeHandle.current}] onDidDisappear received`,
173
+ );
174
+ setNativeViewIsVisible(false);
175
+ onDidDisappear?.(event);
176
+ },
177
+ [onDidDisappear],
178
+ );
179
+
180
+ console.info(
181
+ `TabsScreen [${componentNodeHandle.current ?? -1}] render; tabKey: ${
182
+ rest.tabKey
183
+ } shouldFreeze: ${shouldFreeze}, isFocused: ${isFocused} nativeViewIsVisible: ${nativeViewIsVisible}`,
184
+ );
185
+
186
+ const iconProps = parseIconsToNativeProps(icon, selectedIcon);
187
+
188
+ return (
189
+ <BottomTabsScreenNativeComponent
190
+ collapsable={false}
191
+ style={styles.fillParent}
192
+ onWillAppear={onWillAppearCallback}
193
+ onDidAppear={onDidAppearCallback}
194
+ onWillDisappear={onWillDisappearCallback}
195
+ onDidDisappear={onDidDisappearCallback}
196
+ isFocused={isFocused}
197
+ {...iconProps}
198
+ // @ts-ignore - This is debug only anyway
199
+ ref={componentNodeRef}
200
+ {...rest}>
201
+ <Freeze freeze={shouldFreeze} placeholder={rest.placeholder}>
202
+ {rest.children}
203
+ </Freeze>
204
+ </BottomTabsScreenNativeComponent>
205
+ );
206
+ }
207
+
208
+ function parseIconToNativeProps(icon: Icon | undefined): {
209
+ iconType?: IconType;
210
+ iconImageSource?: ImageSourcePropType;
211
+ iconSfSymbolName?: string;
212
+ } {
213
+ if (!icon) {
214
+ return {};
215
+ }
216
+
217
+ if ('sfSymbolName' in icon) {
218
+ // iOS-specific: SFSymbol usage
219
+ return {
220
+ iconType: 'sfSymbol',
221
+ iconSfSymbolName: icon.sfSymbolName,
222
+ };
223
+ } else if ('imageSource' in icon) {
224
+ return {
225
+ iconType: 'image',
226
+ iconImageSource: icon.imageSource,
227
+ };
228
+ } else if ('templateSource' in icon) {
229
+ // iOS-specifig: image as a template usage
230
+ return {
231
+ iconType: 'template',
232
+ iconImageSource: icon.templateSource,
233
+ };
234
+ } else {
235
+ // iOS-specific: SFSymbol, image as a template usage
236
+ throw new Error(
237
+ '[RNScreens] Incorrect icon format. You must provide sfSymbolName, imageSource or templateSource.',
238
+ );
239
+ }
240
+ }
241
+
242
+ function parseIconsToNativeProps(
243
+ icon: Icon | undefined,
244
+ selectedIcon: Icon | undefined,
245
+ ): {
246
+ iconType?: IconType;
247
+ iconImageSource?: ImageSourcePropType;
248
+ iconSfSymbolName?: string;
249
+ selectedIconImageSource?: ImageSourcePropType;
250
+ selectedIconSfSymbolName?: string;
251
+ } {
252
+ const { iconImageSource, iconSfSymbolName, iconType } =
253
+ parseIconToNativeProps(icon);
254
+ const {
255
+ iconImageSource: selectedIconImageSource,
256
+ iconSfSymbolName: selectedIconSfSymbolName,
257
+ iconType: selectedIconType,
258
+ } = parseIconToNativeProps(selectedIcon);
259
+
260
+ if (
261
+ iconType !== undefined &&
262
+ selectedIconType !== undefined &&
263
+ iconType !== selectedIconType
264
+ ) {
265
+ throw new Error('[RNScreens] icon and selectedIcon must be same type.');
266
+ } else if (iconType === undefined && selectedIconType !== undefined) {
267
+ // iOS-specific: UIKit requirement
268
+ throw new Error(
269
+ '[RNScreens] To use selectedIcon prop, the icon prop must also be provided.',
270
+ );
271
+ }
272
+
273
+ return {
274
+ iconType,
275
+ iconImageSource,
276
+ iconSfSymbolName,
277
+ selectedIconImageSource,
278
+ selectedIconSfSymbolName,
279
+ };
280
+ }
281
+
282
+ export default BottomTabsScreen;
283
+
284
+ const styles = StyleSheet.create({
285
+ fillParent: {
286
+ position: 'absolute',
287
+ flex: 1,
288
+ width: '100%',
289
+ height: '100%',
290
+ },
291
+ });
@@ -0,0 +1,32 @@
1
+ import React from 'react';
2
+ import { StyleSheet } from 'react-native';
3
+ import type { ViewProps } from 'react-native';
4
+ import type { NativeProps } from '../../fabric/gamma/ScreenStackHostNativeComponent';
5
+ import ScreenStackHostNativeComponent from '../../fabric/gamma/ScreenStackHostNativeComponent';
6
+
7
+ export type ScreenStackNativeProps = NativeProps & {
8
+ // Overrides
9
+ };
10
+
11
+ type ScreenStackHostProps = {
12
+ children?: ViewProps['children'];
13
+ } & ScreenStackNativeProps;
14
+
15
+ /**
16
+ * EXPERIMENTAL API, MIGHT CHANGE W/O ANY NOTICE
17
+ */
18
+ function ScreenStackHost({ children }: ScreenStackHostProps) {
19
+ return (
20
+ <ScreenStackHostNativeComponent style={styles.container}>
21
+ {children}
22
+ </ScreenStackHostNativeComponent>
23
+ );
24
+ }
25
+
26
+ const styles = StyleSheet.create({
27
+ container: {
28
+ flex: 1,
29
+ },
30
+ });
31
+
32
+ export default ScreenStackHost;
@@ -0,0 +1,84 @@
1
+ import React from 'react';
2
+ import { StyleSheet } from 'react-native';
3
+ import type { ViewProps } from 'react-native';
4
+ import SplitViewHostNativeComponent from '../../fabric/gamma/SplitViewHostNativeComponent';
5
+ import type {
6
+ NativeProps,
7
+ SplitViewDisplayMode,
8
+ SplitViewSplitBehavior,
9
+ } from '../../fabric/gamma/SplitViewHostNativeComponent';
10
+
11
+ export type SplitViewNativeProps = NativeProps & {
12
+ // Overrides
13
+ };
14
+
15
+ type SplitViewHostProps = {
16
+ children?: ViewProps['children'];
17
+ } & SplitViewNativeProps;
18
+
19
+ // According to the UIKit documentation: https://developer.apple.com/documentation/uikit/uisplitviewcontroller/displaymode-swift.enum
20
+ // Only specific pairs for displayMode - splitBehavior are valid and others may lead to unexpected results.
21
+ // Therefore, we're adding check on the JS side to return a feedback to the client when that pairing isn't valid.
22
+ // However, we're not blocking these props to be set on the native side, because it doesn't crash, just the result or transitions may not work as expected.
23
+ const displayModeForSplitViewCompatibilityMap: Record<
24
+ SplitViewSplitBehavior,
25
+ SplitViewDisplayMode[]
26
+ > = {
27
+ tile: ['secondaryOnly', 'oneBesideSecondary', 'twoBesideSecondary'],
28
+ overlay: ['secondaryOnly', 'oneOverSecondary', 'twoOverSecondary'],
29
+ displace: ['secondaryOnly', 'oneBesideSecondary', 'twoDisplaceSecondary'],
30
+ automatic: [], // placeholder for satisfying types; we'll handle it specially in logic
31
+ };
32
+
33
+ const isValidDisplayModeForSplitBehavior = (
34
+ displayMode: SplitViewDisplayMode,
35
+ splitBehavior: SplitViewSplitBehavior,
36
+ ) => {
37
+ if (splitBehavior === 'automatic') {
38
+ // for automatic we cannot easily verify the compatibility, because it depends on the system preference for display mode, therefore we're assuming that 'automatic' has only valid combinations
39
+ return true;
40
+ }
41
+ return displayModeForSplitViewCompatibilityMap[splitBehavior].includes(
42
+ displayMode,
43
+ );
44
+ };
45
+
46
+ /**
47
+ * EXPERIMENTAL API, MIGHT CHANGE W/O ANY NOTICE
48
+ */
49
+ function SplitViewHost(props: SplitViewHostProps) {
50
+ const { displayMode, splitBehavior } = props;
51
+
52
+ React.useEffect(() => {
53
+ if (displayMode && splitBehavior) {
54
+ const isValid = isValidDisplayModeForSplitBehavior(
55
+ displayMode,
56
+ splitBehavior,
57
+ );
58
+ if (!isValid) {
59
+ const validDisplayModes =
60
+ displayModeForSplitViewCompatibilityMap[splitBehavior];
61
+ console.warn(
62
+ `Invalid display mode "${displayMode}" for split behavior "${splitBehavior}".` +
63
+ `\nValid modes for "${splitBehavior}" are: ${validDisplayModes.join(
64
+ ', ',
65
+ )}.`,
66
+ );
67
+ }
68
+ }
69
+ }, [displayMode, splitBehavior]);
70
+
71
+ return (
72
+ <SplitViewHostNativeComponent {...props} style={styles.container}>
73
+ {props.children}
74
+ </SplitViewHostNativeComponent>
75
+ );
76
+ }
77
+
78
+ const styles = StyleSheet.create({
79
+ container: {
80
+ flex: 1,
81
+ },
82
+ });
83
+
84
+ export default SplitViewHost;
@@ -0,0 +1,26 @@
1
+ import React from 'react';
2
+ import { StyleSheet } from 'react-native';
3
+ import type { ViewProps } from 'react-native';
4
+ import SplitViewScreenNativeComponent from '../../fabric/gamma/SplitViewScreenNativeComponent';
5
+ import type { NativeProps } from '../../fabric/gamma/SplitViewScreenNativeComponent';
6
+
7
+ export type SplitViewScreenNativeProps = NativeProps & {
8
+ // Overrides
9
+ };
10
+
11
+ type SplitViewScreenProps = {
12
+ children?: ViewProps['children'];
13
+ } & SplitViewScreenNativeProps;
14
+
15
+ /**
16
+ * EXPERIMENTAL API, MIGHT CHANGE W/O ANY NOTICE
17
+ */
18
+ function SplitViewScreen({ children }: SplitViewScreenProps) {
19
+ return (
20
+ <SplitViewScreenNativeComponent style={StyleSheet.absoluteFill}>
21
+ {children}
22
+ </SplitViewScreenNativeComponent>
23
+ );
24
+ }
25
+
26
+ export default SplitViewScreen;
@@ -0,0 +1,64 @@
1
+ import React from 'react';
2
+ import { StyleSheet } from 'react-native';
3
+ import StackScreenNativeComponent from '../../fabric/gamma/StackScreenNativeComponent';
4
+ import type { NativeSyntheticEvent, ViewProps } from 'react-native';
5
+ import type { NativeProps } from '../../fabric/gamma/StackScreenNativeComponent';
6
+
7
+ export const StackScreenLifecycleState = {
8
+ INITIAL: 0,
9
+ DETACHED: 1,
10
+ ATTACHED: 2,
11
+ } as const;
12
+
13
+ export type StackScreenNativeProps = NativeProps & {
14
+ // Overrides
15
+ maxLifecycleState: (typeof StackScreenLifecycleState)[keyof typeof StackScreenLifecycleState];
16
+ };
17
+
18
+ type StackScreenProps = {
19
+ children?: ViewProps['children'];
20
+ // Custom events
21
+ onPop?: (screenKey: string) => void;
22
+ } & StackScreenNativeProps;
23
+
24
+ /**
25
+ * EXPERIMENTAL API, MIGHT CHANGE W/O ANY NOTICE
26
+ */
27
+ function StackScreen({
28
+ children,
29
+ // Control
30
+ maxLifecycleState,
31
+ screenKey,
32
+ // Events
33
+ onWillAppear,
34
+ onWillDisappear,
35
+ onDidAppear,
36
+ onDidDisappear,
37
+ // Custom events
38
+ onPop,
39
+ }: StackScreenProps) {
40
+ const handleOnDidDisappear = React.useCallback(
41
+ (e: NativeSyntheticEvent<Record<string, never>>) => {
42
+ onDidDisappear?.(e);
43
+ onPop?.(screenKey);
44
+ },
45
+ [onDidDisappear, onPop, screenKey],
46
+ );
47
+
48
+ return (
49
+ <StackScreenNativeComponent
50
+ style={StyleSheet.absoluteFill}
51
+ // Control
52
+ maxLifecycleState={maxLifecycleState}
53
+ screenKey={screenKey}
54
+ // Events
55
+ onWillAppear={onWillAppear}
56
+ onDidAppear={onDidAppear}
57
+ onWillDisappear={onWillDisappear}
58
+ onDidDisappear={handleOnDidDisappear}>
59
+ {children}
60
+ </StackScreenNativeComponent>
61
+ );
62
+ }
63
+
64
+ export default StackScreen;
@@ -0,0 +1,82 @@
1
+ 'use client';
2
+
3
+ import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
4
+ import type { ColorValue, ViewProps } from 'react-native';
5
+ import type {
6
+ DirectEventHandler,
7
+ Float,
8
+ WithDefault,
9
+ } from 'react-native/Libraries/Types/CodegenTypes';
10
+
11
+ // TODO: Report issue on RN repo, that nesting color value inside a struct does not work.
12
+ // Generated code is ok, but the value is not passed down correctly - whatever color is set
13
+ // host component receives RGBA(0, 0, 0, 0) anyway.
14
+ // type TabBarAppearance = {
15
+ // backgroundColor?: ColorValue;
16
+ // };
17
+
18
+ export type NativeFocusChangeEvent = {
19
+ tabKey: string;
20
+ };
21
+
22
+ export type BlurEffect =
23
+ | 'none'
24
+ | 'extraLight'
25
+ | 'light'
26
+ | 'dark'
27
+ | 'regular'
28
+ | 'prominent'
29
+ | 'systemUltraThinMaterial'
30
+ | 'systemThinMaterial'
31
+ | 'systemMaterial'
32
+ | 'systemThickMaterial'
33
+ | 'systemChromeMaterial'
34
+ | 'systemUltraThinMaterialLight'
35
+ | 'systemThinMaterialLight'
36
+ | 'systemMaterialLight'
37
+ | 'systemThickMaterialLight'
38
+ | 'systemChromeMaterialLight'
39
+ | 'systemUltraThinMaterialDark'
40
+ | 'systemThinMaterialDark'
41
+ | 'systemMaterialDark'
42
+ | 'systemThickMaterialDark'
43
+ | 'systemChromeMaterialDark';
44
+
45
+ export interface NativeProps extends ViewProps {
46
+ // Events
47
+ onNativeFocusChange?: DirectEventHandler<NativeFocusChangeEvent>;
48
+
49
+ // Appearance
50
+ // tabBarAppearance?: TabBarAppearance; // Does not work due to codegen issue.
51
+ tabBarBackgroundColor?: ColorValue;
52
+ tabBarBlurEffect?: WithDefault<BlurEffect, 'none'>;
53
+ tabBarTintColor?: ColorValue;
54
+
55
+ tabBarItemTitleFontFamily?: string;
56
+ tabBarItemTitleFontSize?: Float;
57
+ tabBarItemTitleFontWeight?: string;
58
+ tabBarItemTitleFontStyle?: string;
59
+ tabBarItemTitleFontColor?: ColorValue;
60
+ tabBarItemTitlePositionAdjustment?: {
61
+ horizontal?: Float;
62
+ vertical?: Float;
63
+ };
64
+
65
+ tabBarItemIconColor?: ColorValue;
66
+
67
+ tabBarItemBadgeBackgroundColor?: ColorValue;
68
+
69
+ // Android
70
+ tabBarItemTitleFontColorActive?: ColorValue;
71
+ tabBarItemIconColorActive?: ColorValue;
72
+ tabBarItemTitleFontSizeActive?: Float;
73
+
74
+ // Control
75
+
76
+ // Experimental support
77
+ controlNavigationStateInJS?: WithDefault<boolean, false>;
78
+ }
79
+
80
+ export default codegenNativeComponent<NativeProps>('RNSBottomTabs', {
81
+ interfaceOnly: true,
82
+ });
@@ -0,0 +1,107 @@
1
+ 'use client';
2
+
3
+ import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
4
+ import type { ColorValue, ViewProps } from 'react-native';
5
+ import {
6
+ DirectEventHandler,
7
+ Float,
8
+ Int32,
9
+ WithDefault,
10
+ } from 'react-native/Libraries/Types/CodegenTypes';
11
+
12
+ // @ts-ignore: ImageSource type has been recently added: https://github.com/facebook/react-native/pull/51969
13
+ import type { ImageSource } from 'react-native/Libraries/Image/ImageSource';
14
+
15
+ // iOS-specific: SFSymbol, image as a template usage
16
+ export type IconType = 'image' | 'template' | 'sfSymbol';
17
+
18
+ // eslint-disable-next-line @typescript-eslint/ban-types
19
+ export type GenericEmptyEvent = Readonly<{}>;
20
+
21
+ export type LifecycleStateChangeEvent = Readonly<{
22
+ previousState: Int32;
23
+ newState: Int32;
24
+ }>;
25
+
26
+ export type BlurEffect =
27
+ | 'none'
28
+ | 'extraLight'
29
+ | 'light'
30
+ | 'dark'
31
+ | 'regular'
32
+ | 'prominent'
33
+ | 'systemUltraThinMaterial'
34
+ | 'systemThinMaterial'
35
+ | 'systemMaterial'
36
+ | 'systemThickMaterial'
37
+ | 'systemChromeMaterial'
38
+ | 'systemUltraThinMaterialLight'
39
+ | 'systemThinMaterialLight'
40
+ | 'systemMaterialLight'
41
+ | 'systemThickMaterialLight'
42
+ | 'systemChromeMaterialLight'
43
+ | 'systemUltraThinMaterialDark'
44
+ | 'systemThinMaterialDark'
45
+ | 'systemMaterialDark'
46
+ | 'systemThickMaterialDark'
47
+ | 'systemChromeMaterialDark';
48
+
49
+ export interface NativeProps extends ViewProps {
50
+ // Events
51
+ onLifecycleStateChange?: DirectEventHandler<LifecycleStateChangeEvent>;
52
+ onWillAppear?: DirectEventHandler<GenericEmptyEvent>;
53
+ onDidAppear?: DirectEventHandler<GenericEmptyEvent>;
54
+ onWillDisappear?: DirectEventHandler<GenericEmptyEvent>;
55
+ onDidDisappear?: DirectEventHandler<GenericEmptyEvent>;
56
+
57
+ // Control
58
+ isFocused?: boolean;
59
+ tabKey: string;
60
+
61
+ // Tab Bar Appearance
62
+ // tabBarAppearance?: TabBarAppearance; // Does not work due to codegen issue.
63
+ tabBarBackgroundColor?: ColorValue;
64
+ tabBarBlurEffect?: WithDefault<BlurEffect, 'none'>;
65
+
66
+ tabBarItemTitleFontFamily?: string;
67
+ tabBarItemTitleFontSize?: Float;
68
+ tabBarItemTitleFontWeight?: string;
69
+ tabBarItemTitleFontStyle?: string;
70
+ tabBarItemTitleFontColor?: ColorValue;
71
+ tabBarItemTitlePositionAdjustment?: {
72
+ horizontal?: Float;
73
+ vertical?: Float;
74
+ };
75
+
76
+ tabBarItemIconColor?: ColorValue;
77
+
78
+ tabBarItemBadgeBackgroundColor?: ColorValue;
79
+
80
+ // General
81
+ title?: string | undefined | null;
82
+
83
+ // Android-specific image handling
84
+ iconResourceName?: string;
85
+
86
+ // iOS-specific: SFSymbol usage
87
+ iconType?: WithDefault<IconType, 'sfSymbol'>;
88
+
89
+ iconImageSource?: ImageSource;
90
+ iconSfSymbolName?: string;
91
+
92
+ selectedIconImageSource?: ImageSource;
93
+ selectedIconSfSymbolName?: string;
94
+
95
+ badgeValue?: string;
96
+
97
+ specialEffects?: {
98
+ repeatedTabSelection?: {
99
+ popToRoot?: WithDefault<boolean, true>;
100
+ scrollToTop?: WithDefault<boolean, true>;
101
+ };
102
+ };
103
+
104
+ overrideScrollViewContentInsetAdjustmentBehavior?: WithDefault<boolean, true>;
105
+ }
106
+
107
+ export default codegenNativeComponent<NativeProps>('RNSBottomTabsScreen', {});
@@ -0,0 +1,8 @@
1
+ 'use client';
2
+
3
+ import type { ViewProps } from 'react-native';
4
+ import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
5
+
6
+ export interface NativeProps extends ViewProps {}
7
+
8
+ export default codegenNativeComponent<NativeProps>('RNSScreenStackHost', {});