@amazon-devices/react-native-screens 2.0.1758683737

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 (381) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +223 -0
  3. package/RNScreens.podspec +53 -0
  4. package/SystemBundles/8f5a820b958535e533acb38dbc0c72c1837721b9db075f4a1740e42b9fee3910.bundle +33668 -0
  5. package/SystemBundles/8f5a820b958535e533acb38dbc0c72c1837721b9db075f4a1740e42b9fee3910.map +1 -0
  6. package/SystemModules/amzn__react-native-screens.modules.txt +101 -0
  7. package/SystemModules/amzn__react-native-screens.private.modules.txt +244 -0
  8. package/SystemModules/keplerscript-system-bundle-config.json +7 -0
  9. package/THIRD_PARTY_NOTICES.txt +707 -0
  10. package/android/build.gradle +133 -0
  11. package/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +49 -0
  12. package/android/src/main/AndroidManifest.xml +5 -0
  13. package/android/src/main/java/com/swmansion/rnscreens/CustomSearchView.kt +77 -0
  14. package/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt +7 -0
  15. package/android/src/main/java/com/swmansion/rnscreens/FragmentBackPressOverrider.kt +29 -0
  16. package/android/src/main/java/com/swmansion/rnscreens/FragmentHolder.kt +7 -0
  17. package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +21 -0
  18. package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +289 -0
  19. package/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.kt +372 -0
  20. package/android/src/main/java/com/swmansion/rnscreens/ScreenContainerViewManager.kt +40 -0
  21. package/android/src/main/java/com/swmansion/rnscreens/ScreenEventDispatcher.kt +21 -0
  22. package/android/src/main/java/com/swmansion/rnscreens/ScreenFragment.kt +331 -0
  23. package/android/src/main/java/com/swmansion/rnscreens/ScreenFragmentWrapper.kt +22 -0
  24. package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +336 -0
  25. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +282 -0
  26. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragmentWrapper.kt +15 -0
  27. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +398 -0
  28. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt +204 -0
  29. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubview.kt +38 -0
  30. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubviewManager.kt +41 -0
  31. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackViewManager.kt +75 -0
  32. package/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt +186 -0
  33. package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +296 -0
  34. package/android/src/main/java/com/swmansion/rnscreens/ScreensShadowNode.kt +19 -0
  35. package/android/src/main/java/com/swmansion/rnscreens/SearchBarManager.kt +133 -0
  36. package/android/src/main/java/com/swmansion/rnscreens/SearchBarView.kt +178 -0
  37. package/android/src/main/java/com/swmansion/rnscreens/SearchViewFormatter.kt +67 -0
  38. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderAttachedEvent.kt +22 -0
  39. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderBackButtonClickedEvent.kt +22 -0
  40. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderDetachedEvent.kt +22 -0
  41. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderHeightChangeEvent.kt +26 -0
  42. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenAppearEvent.kt +18 -0
  43. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenDisappearEvent.kt +18 -0
  44. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenDismissedEvent.kt +20 -0
  45. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenTransitionProgressEvent.kt +32 -0
  46. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenWillAppearEvent.kt +18 -0
  47. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenWillDisappearEvent.kt +18 -0
  48. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarBlurEvent.kt +22 -0
  49. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarChangeTextEvent.kt +28 -0
  50. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarCloseEvent.kt +22 -0
  51. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarFocusEvent.kt +22 -0
  52. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarOpenEvent.kt +22 -0
  53. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarSearchButtonPressEvent.kt +24 -0
  54. package/android/src/main/java/com/swmansion/rnscreens/events/StackFinishTransitioningEvent.kt +18 -0
  55. package/android/src/main/java/com/swmansion/rnscreens/utils/DeviceUtils.kt +12 -0
  56. package/android/src/main/jni/CMakeLists.txt +72 -0
  57. package/android/src/main/jni/rnscreens.cpp +16 -0
  58. package/android/src/main/jni/rnscreens.h +28 -0
  59. package/android/src/main/res/base/anim/rns_default_enter_in.xml +18 -0
  60. package/android/src/main/res/base/anim/rns_default_enter_out.xml +19 -0
  61. package/android/src/main/res/base/anim/rns_default_exit_in.xml +17 -0
  62. package/android/src/main/res/base/anim/rns_default_exit_out.xml +18 -0
  63. package/android/src/main/res/base/anim/rns_fade_from_bottom.xml +14 -0
  64. package/android/src/main/res/base/anim/rns_fade_in.xml +7 -0
  65. package/android/src/main/res/base/anim/rns_fade_out.xml +7 -0
  66. package/android/src/main/res/base/anim/rns_fade_to_bottom.xml +15 -0
  67. package/android/src/main/res/base/anim/rns_no_animation_20.xml +6 -0
  68. package/android/src/main/res/base/anim/rns_no_animation_250.xml +7 -0
  69. package/android/src/main/res/base/anim/rns_no_animation_350.xml +6 -0
  70. package/android/src/main/res/base/anim/rns_no_animation_medium.xml +7 -0
  71. package/android/src/main/res/base/anim/rns_slide_in_from_bottom.xml +7 -0
  72. package/android/src/main/res/base/anim/rns_slide_in_from_left.xml +5 -0
  73. package/android/src/main/res/base/anim/rns_slide_in_from_right.xml +5 -0
  74. package/android/src/main/res/base/anim/rns_slide_out_to_bottom.xml +7 -0
  75. package/android/src/main/res/base/anim/rns_slide_out_to_left.xml +5 -0
  76. package/android/src/main/res/base/anim/rns_slide_out_to_right.xml +5 -0
  77. package/android/src/main/res/base/anim/rns_standard_accelerate_interpolator.xml +6 -0
  78. package/android/src/main/res/v33/anim-v33/rns_default_enter_in.xml +38 -0
  79. package/android/src/main/res/v33/anim-v33/rns_default_enter_out.xml +38 -0
  80. package/android/src/main/res/v33/anim-v33/rns_default_exit_in.xml +38 -0
  81. package/android/src/main/res/v33/anim-v33/rns_default_exit_out.xml +38 -0
  82. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerDelegate.java +111 -0
  83. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerInterface.java +44 -0
  84. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerDelegate.java +107 -0
  85. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerInterface.java +42 -0
  86. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderSubviewManagerDelegate.java +31 -0
  87. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderSubviewManagerInterface.java +17 -0
  88. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackManagerDelegate.java +25 -0
  89. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackManagerInterface.java +16 -0
  90. package/android/src/paper/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +10 -0
  91. package/common/cpp/react/renderer/components/rnscreens/RNSScreenComponentDescriptor.h +41 -0
  92. package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.cpp +9 -0
  93. package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.h +30 -0
  94. package/common/cpp/react/renderer/components/rnscreens/RNSScreenState.cpp +14 -0
  95. package/common/cpp/react/renderer/components/rnscreens/RNSScreenState.h +45 -0
  96. package/ios/RCTImageComponentView+RNSScreenStackHeaderConfig.h +11 -0
  97. package/ios/RCTImageComponentView+RNSScreenStackHeaderConfig.mm +14 -0
  98. package/ios/RNSConvert.h +36 -0
  99. package/ios/RNSConvert.mm +154 -0
  100. package/ios/RNSEnums.h +71 -0
  101. package/ios/RNSFullWindowOverlay.h +34 -0
  102. package/ios/RNSFullWindowOverlay.mm +241 -0
  103. package/ios/RNSScreen.h +144 -0
  104. package/ios/RNSScreen.mm +1599 -0
  105. package/ios/RNSScreenContainer.h +45 -0
  106. package/ios/RNSScreenContainer.mm +343 -0
  107. package/ios/RNSScreenNavigationContainer.h +16 -0
  108. package/ios/RNSScreenNavigationContainer.mm +66 -0
  109. package/ios/RNSScreenStack.h +37 -0
  110. package/ios/RNSScreenStack.mm +1111 -0
  111. package/ios/RNSScreenStackAnimator.h +8 -0
  112. package/ios/RNSScreenStackAnimator.mm +320 -0
  113. package/ios/RNSScreenStackHeaderConfig.h +74 -0
  114. package/ios/RNSScreenStackHeaderConfig.mm +967 -0
  115. package/ios/RNSScreenStackHeaderSubview.h +44 -0
  116. package/ios/RNSScreenStackHeaderSubview.mm +147 -0
  117. package/ios/RNSScreenWindowTraits.h +26 -0
  118. package/ios/RNSScreenWindowTraits.mm +266 -0
  119. package/ios/RNSSearchBar.h +43 -0
  120. package/ios/RNSSearchBar.mm +465 -0
  121. package/ios/RNScreens.xcodeproj/project.pbxproj +461 -0
  122. package/ios/UIViewController+RNScreens.h +9 -0
  123. package/ios/UIViewController+RNScreens.mm +78 -0
  124. package/ios/UIWindow+RNScreens.h +9 -0
  125. package/ios/UIWindow+RNScreens.mm +17 -0
  126. package/ios/events/RNSHeaderHeightChangeEvent.h +8 -0
  127. package/ios/events/RNSHeaderHeightChangeEvent.mm +44 -0
  128. package/ios/events/RNSScreenViewEvent.h +12 -0
  129. package/ios/events/RNSScreenViewEvent.mm +59 -0
  130. package/ios/utils/RNSUIBarButtonItem.h +5 -0
  131. package/ios/utils/RNSUIBarButtonItem.mm +22 -0
  132. package/kepler-compatibility.json +8 -0
  133. package/kepler-transformed-package-info.json +3 -0
  134. package/lib/commonjs/TransitionProgressContext.js +11 -0
  135. package/lib/commonjs/TransitionProgressContext.js.map +1 -0
  136. package/lib/commonjs/fabric/FullWindowOverlayNativeComponent.js +11 -0
  137. package/lib/commonjs/fabric/FullWindowOverlayNativeComponent.js.map +1 -0
  138. package/lib/commonjs/fabric/ScreenContainerNativeComponent.js +33 -0
  139. package/lib/commonjs/fabric/ScreenContainerNativeComponent.js.map +1 -0
  140. package/lib/commonjs/fabric/ScreenNativeComponent.js +70 -0
  141. package/lib/commonjs/fabric/ScreenNativeComponent.js.map +1 -0
  142. package/lib/commonjs/fabric/ScreenNavigationContainerNativeComponent.js +11 -0
  143. package/lib/commonjs/fabric/ScreenNavigationContainerNativeComponent.js.map +1 -0
  144. package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js +31 -0
  145. package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -0
  146. package/lib/commonjs/fabric/ScreenStackHeaderSubviewNativeComponent.js +12 -0
  147. package/lib/commonjs/fabric/ScreenStackHeaderSubviewNativeComponent.js.map +1 -0
  148. package/lib/commonjs/fabric/ScreenStackNativeComponent.js +35 -0
  149. package/lib/commonjs/fabric/ScreenStackNativeComponent.js.map +1 -0
  150. package/lib/commonjs/fabric/SearchBarNativeComponent.js +19 -0
  151. package/lib/commonjs/fabric/SearchBarNativeComponent.js.map +1 -0
  152. package/lib/commonjs/index.js +147 -0
  153. package/lib/commonjs/index.js.map +1 -0
  154. package/lib/commonjs/index.native.js +407 -0
  155. package/lib/commonjs/index.native.js.map +1 -0
  156. package/lib/commonjs/native-stack/index.js +49 -0
  157. package/lib/commonjs/native-stack/index.js.map +1 -0
  158. package/lib/commonjs/native-stack/navigators/createNativeStackNavigator.js +75 -0
  159. package/lib/commonjs/native-stack/navigators/createNativeStackNavigator.js.map +1 -0
  160. package/lib/commonjs/native-stack/types.js +6 -0
  161. package/lib/commonjs/native-stack/types.js.map +1 -0
  162. package/lib/commonjs/native-stack/utils/AnimatedHeaderHeightContext.js +12 -0
  163. package/lib/commonjs/native-stack/utils/AnimatedHeaderHeightContext.js.map +1 -0
  164. package/lib/commonjs/native-stack/utils/HeaderHeightContext.js +12 -0
  165. package/lib/commonjs/native-stack/utils/HeaderHeightContext.js.map +1 -0
  166. package/lib/commonjs/native-stack/utils/SafeAreaProviderCompat.js +75 -0
  167. package/lib/commonjs/native-stack/utils/SafeAreaProviderCompat.js.map +1 -0
  168. package/lib/commonjs/native-stack/utils/getDefaultHeaderHeight.js +35 -0
  169. package/lib/commonjs/native-stack/utils/getDefaultHeaderHeight.js.map +1 -0
  170. package/lib/commonjs/native-stack/utils/useAnimatedHeaderHeight.js +19 -0
  171. package/lib/commonjs/native-stack/utils/useAnimatedHeaderHeight.js.map +1 -0
  172. package/lib/commonjs/native-stack/utils/useBackPressSubscription.js +54 -0
  173. package/lib/commonjs/native-stack/utils/useBackPressSubscription.js.map +1 -0
  174. package/lib/commonjs/native-stack/utils/useHeaderHeight.js +19 -0
  175. package/lib/commonjs/native-stack/utils/useHeaderHeight.js.map +1 -0
  176. package/lib/commonjs/native-stack/views/FontProcessor.js +21 -0
  177. package/lib/commonjs/native-stack/views/FontProcessor.js.map +1 -0
  178. package/lib/commonjs/native-stack/views/HeaderConfig.js +141 -0
  179. package/lib/commonjs/native-stack/views/HeaderConfig.js.map +1 -0
  180. package/lib/commonjs/native-stack/views/NativeStackView.js +354 -0
  181. package/lib/commonjs/native-stack/views/NativeStackView.js.map +1 -0
  182. package/lib/commonjs/reanimated/ReanimatedHeaderHeightContext.js +12 -0
  183. package/lib/commonjs/reanimated/ReanimatedHeaderHeightContext.js.map +1 -0
  184. package/lib/commonjs/reanimated/ReanimatedNativeStackScreen.js +101 -0
  185. package/lib/commonjs/reanimated/ReanimatedNativeStackScreen.js.map +1 -0
  186. package/lib/commonjs/reanimated/ReanimatedScreen.js +22 -0
  187. package/lib/commonjs/reanimated/ReanimatedScreen.js.map +1 -0
  188. package/lib/commonjs/reanimated/ReanimatedScreenProvider.js +47 -0
  189. package/lib/commonjs/reanimated/ReanimatedScreenProvider.js.map +1 -0
  190. package/lib/commonjs/reanimated/ReanimatedTransitionProgressContext.js +12 -0
  191. package/lib/commonjs/reanimated/ReanimatedTransitionProgressContext.js.map +1 -0
  192. package/lib/commonjs/reanimated/index.js +28 -0
  193. package/lib/commonjs/reanimated/index.js.map +1 -0
  194. package/lib/commonjs/reanimated/useReanimatedHeaderHeight.js +19 -0
  195. package/lib/commonjs/reanimated/useReanimatedHeaderHeight.js.map +1 -0
  196. package/lib/commonjs/reanimated/useReanimatedTransitionProgress.js +19 -0
  197. package/lib/commonjs/reanimated/useReanimatedTransitionProgress.js.map +1 -0
  198. package/lib/commonjs/types.js +6 -0
  199. package/lib/commonjs/types.js.map +1 -0
  200. package/lib/commonjs/useTransitionProgress.js +19 -0
  201. package/lib/commonjs/useTransitionProgress.js.map +1 -0
  202. package/lib/commonjs/utils.js +21 -0
  203. package/lib/commonjs/utils.js.map +1 -0
  204. package/lib/module/TransitionProgressContext.js +3 -0
  205. package/lib/module/TransitionProgressContext.js.map +1 -0
  206. package/lib/module/fabric/FullWindowOverlayNativeComponent.js +4 -0
  207. package/lib/module/fabric/FullWindowOverlayNativeComponent.js.map +1 -0
  208. package/lib/module/fabric/ScreenContainerNativeComponent.js +25 -0
  209. package/lib/module/fabric/ScreenContainerNativeComponent.js.map +1 -0
  210. package/lib/module/fabric/ScreenNativeComponent.js +63 -0
  211. package/lib/module/fabric/ScreenNativeComponent.js.map +1 -0
  212. package/lib/module/fabric/ScreenNavigationContainerNativeComponent.js +4 -0
  213. package/lib/module/fabric/ScreenNavigationContainerNativeComponent.js.map +1 -0
  214. package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js +23 -0
  215. package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -0
  216. package/lib/module/fabric/ScreenStackHeaderSubviewNativeComponent.js +7 -0
  217. package/lib/module/fabric/ScreenStackHeaderSubviewNativeComponent.js.map +1 -0
  218. package/lib/module/fabric/ScreenStackNativeComponent.js +28 -0
  219. package/lib/module/fabric/ScreenStackNativeComponent.js.map +1 -0
  220. package/lib/module/fabric/SearchBarNativeComponent.js +10 -0
  221. package/lib/module/fabric/SearchBarNativeComponent.js.map +1 -0
  222. package/lib/module/index.js +67 -0
  223. package/lib/module/index.js.map +1 -0
  224. package/lib/module/index.native.js +410 -0
  225. package/lib/module/index.native.js.map +1 -0
  226. package/lib/module/native-stack/index.js +22 -0
  227. package/lib/module/native-stack/index.js.map +1 -0
  228. package/lib/module/native-stack/navigators/createNativeStackNavigator.js +72 -0
  229. package/lib/module/native-stack/navigators/createNativeStackNavigator.js.map +1 -0
  230. package/lib/module/native-stack/types.js +2 -0
  231. package/lib/module/native-stack/types.js.map +1 -0
  232. package/lib/module/native-stack/utils/AnimatedHeaderHeightContext.js +4 -0
  233. package/lib/module/native-stack/utils/AnimatedHeaderHeightContext.js.map +1 -0
  234. package/lib/module/native-stack/utils/HeaderHeightContext.js +4 -0
  235. package/lib/module/native-stack/utils/HeaderHeightContext.js.map +1 -0
  236. package/lib/module/native-stack/utils/SafeAreaProviderCompat.js +68 -0
  237. package/lib/module/native-stack/utils/SafeAreaProviderCompat.js.map +1 -0
  238. package/lib/module/native-stack/utils/getDefaultHeaderHeight.js +29 -0
  239. package/lib/module/native-stack/utils/getDefaultHeaderHeight.js.map +1 -0
  240. package/lib/module/native-stack/utils/useAnimatedHeaderHeight.js +10 -0
  241. package/lib/module/native-stack/utils/useAnimatedHeaderHeight.js.map +1 -0
  242. package/lib/module/native-stack/utils/useBackPressSubscription.js +47 -0
  243. package/lib/module/native-stack/utils/useBackPressSubscription.js.map +1 -0
  244. package/lib/module/native-stack/utils/useHeaderHeight.js +10 -0
  245. package/lib/module/native-stack/utils/useHeaderHeight.js.map +1 -0
  246. package/lib/module/native-stack/views/FontProcessor.js +13 -0
  247. package/lib/module/native-stack/views/FontProcessor.js.map +1 -0
  248. package/lib/module/native-stack/views/HeaderConfig.js +132 -0
  249. package/lib/module/native-stack/views/HeaderConfig.js.map +1 -0
  250. package/lib/module/native-stack/views/NativeStackView.js +355 -0
  251. package/lib/module/native-stack/views/NativeStackView.js.map +1 -0
  252. package/lib/module/reanimated/ReanimatedHeaderHeightContext.js +5 -0
  253. package/lib/module/reanimated/ReanimatedHeaderHeightContext.js.map +1 -0
  254. package/lib/module/reanimated/ReanimatedNativeStackScreen.js +97 -0
  255. package/lib/module/reanimated/ReanimatedNativeStackScreen.js.map +1 -0
  256. package/lib/module/reanimated/ReanimatedScreen.js +17 -0
  257. package/lib/module/reanimated/ReanimatedScreen.js.map +1 -0
  258. package/lib/module/reanimated/ReanimatedScreenProvider.js +40 -0
  259. package/lib/module/reanimated/ReanimatedScreenProvider.js.map +1 -0
  260. package/lib/module/reanimated/ReanimatedTransitionProgressContext.js +5 -0
  261. package/lib/module/reanimated/ReanimatedTransitionProgressContext.js.map +1 -0
  262. package/lib/module/reanimated/index.js +4 -0
  263. package/lib/module/reanimated/index.js.map +1 -0
  264. package/lib/module/reanimated/useReanimatedHeaderHeight.js +10 -0
  265. package/lib/module/reanimated/useReanimatedHeaderHeight.js.map +1 -0
  266. package/lib/module/reanimated/useReanimatedTransitionProgress.js +10 -0
  267. package/lib/module/reanimated/useReanimatedTransitionProgress.js.map +1 -0
  268. package/lib/module/types.js +2 -0
  269. package/lib/module/types.js.map +1 -0
  270. package/lib/module/useTransitionProgress.js +10 -0
  271. package/lib/module/useTransitionProgress.js.map +1 -0
  272. package/lib/module/utils.js +14 -0
  273. package/lib/module/utils.js.map +1 -0
  274. package/lib/typescript/TransitionProgressContext.d.ts +9 -0
  275. package/lib/typescript/fabric/FullWindowOverlayNativeComponent.d.ts +7 -0
  276. package/lib/typescript/fabric/ScreenContainerNativeComponent.d.ts +5 -0
  277. package/lib/typescript/fabric/ScreenNativeComponent.d.ts +66 -0
  278. package/lib/typescript/fabric/ScreenNavigationContainerNativeComponent.d.ts +7 -0
  279. package/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts +33 -0
  280. package/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts +10 -0
  281. package/lib/typescript/fabric/ScreenStackNativeComponent.d.ts +8 -0
  282. package/lib/typescript/fabric/SearchBarNativeComponent.d.ts +49 -0
  283. package/lib/typescript/index.d.ts +33 -0
  284. package/lib/typescript/index.native.d.ts +2 -0
  285. package/lib/typescript/native-stack/index.d.ts +19 -0
  286. package/lib/typescript/native-stack/navigators/createNativeStackNavigator.d.ts +6 -0
  287. package/lib/typescript/native-stack/types.d.ts +438 -0
  288. package/lib/typescript/native-stack/utils/AnimatedHeaderHeightContext.d.ts +4 -0
  289. package/lib/typescript/native-stack/utils/HeaderHeightContext.d.ts +3 -0
  290. package/lib/typescript/native-stack/utils/SafeAreaProviderCompat.d.ts +11 -0
  291. package/lib/typescript/native-stack/utils/getDefaultHeaderHeight.d.ts +7 -0
  292. package/lib/typescript/native-stack/utils/useAnimatedHeaderHeight.d.ts +1 -0
  293. package/lib/typescript/native-stack/utils/useBackPressSubscription.d.ts +16 -0
  294. package/lib/typescript/native-stack/utils/useHeaderHeight.d.ts +1 -0
  295. package/lib/typescript/native-stack/views/FontProcessor.d.ts +1 -0
  296. package/lib/typescript/native-stack/views/HeaderConfig.d.ts +8 -0
  297. package/lib/typescript/native-stack/views/NativeStackView.d.ts +10 -0
  298. package/lib/typescript/reanimated/ReanimatedHeaderHeightContext.d.ts +4 -0
  299. package/lib/typescript/reanimated/ReanimatedNativeStackScreen.d.ts +5 -0
  300. package/lib/typescript/reanimated/ReanimatedScreen.d.ts +5 -0
  301. package/lib/typescript/reanimated/ReanimatedScreenProvider.d.ts +2 -0
  302. package/lib/typescript/reanimated/ReanimatedTransitionProgressContext.d.ts +9 -0
  303. package/lib/typescript/reanimated/index.d.ts +3 -0
  304. package/lib/typescript/reanimated/useReanimatedHeaderHeight.d.ts +3 -0
  305. package/lib/typescript/reanimated/useReanimatedTransitionProgress.d.ts +11 -0
  306. package/lib/typescript/types.d.ts +612 -0
  307. package/lib/typescript/useTransitionProgress.d.ts +5 -0
  308. package/lib/typescript/utils.d.ts +3 -0
  309. package/native-stack/README.md +814 -0
  310. package/native-stack/package.json +6 -0
  311. package/package.json +1 -0
  312. package/react-native.config.js +42 -0
  313. package/reanimated/package.json +6 -0
  314. package/src/TransitionProgressContext.tsx +12 -0
  315. package/src/fabric/FullWindowOverlayNativeComponent.ts +7 -0
  316. package/src/fabric/ScreenContainerNativeComponent.ts +28 -0
  317. package/src/fabric/ScreenNativeComponent.ts +158 -0
  318. package/src/fabric/ScreenNavigationContainerNativeComponent.ts +10 -0
  319. package/src/fabric/ScreenStackHeaderConfigNativeComponent.ts +61 -0
  320. package/src/fabric/ScreenStackHeaderSubviewNativeComponent.ts +22 -0
  321. package/src/fabric/ScreenStackNativeComponent.ts +33 -0
  322. package/src/fabric/SearchBarNativeComponent.ts +79 -0
  323. package/src/index.native.tsx +599 -0
  324. package/src/index.tsx +119 -0
  325. package/src/native-stack/index.tsx +27 -0
  326. package/src/native-stack/navigators/createNativeStackNavigator.tsx +107 -0
  327. package/src/native-stack/types.tsx +486 -0
  328. package/src/native-stack/utils/AnimatedHeaderHeightContext.tsx +8 -0
  329. package/src/native-stack/utils/HeaderHeightContext.tsx +5 -0
  330. package/src/native-stack/utils/SafeAreaProviderCompat.tsx +78 -0
  331. package/src/native-stack/utils/getDefaultHeaderHeight.tsx +41 -0
  332. package/src/native-stack/utils/useAnimatedHeaderHeight.tsx +15 -0
  333. package/src/native-stack/utils/useBackPressSubscription.tsx +66 -0
  334. package/src/native-stack/utils/useHeaderHeight.tsx +15 -0
  335. package/src/native-stack/views/FontProcessor.tsx +14 -0
  336. package/src/native-stack/views/HeaderConfig.tsx +187 -0
  337. package/src/native-stack/views/NativeStackView.tsx +466 -0
  338. package/src/reanimated/ReanimatedHeaderHeightContext.tsx +7 -0
  339. package/src/reanimated/ReanimatedNativeStackScreen.tsx +130 -0
  340. package/src/reanimated/ReanimatedScreen.tsx +25 -0
  341. package/src/reanimated/ReanimatedScreenProvider.tsx +42 -0
  342. package/src/reanimated/ReanimatedTransitionProgressContext.tsx +13 -0
  343. package/src/reanimated/index.tsx +3 -0
  344. package/src/reanimated/useReanimatedHeaderHeight.tsx +14 -0
  345. package/src/reanimated/useReanimatedTransitionProgress.tsx +14 -0
  346. package/src/types.tsx +699 -0
  347. package/src/useTransitionProgress.tsx +15 -0
  348. package/src/utils.ts +18 -0
  349. package/windows/README.md +25 -0
  350. package/windows/RNScreens/PropertySheet.props +16 -0
  351. package/windows/RNScreens/RNScreens.cpp +66 -0
  352. package/windows/RNScreens/RNScreens.def +3 -0
  353. package/windows/RNScreens/RNScreens.h +41 -0
  354. package/windows/RNScreens/RNScreens.idl +8 -0
  355. package/windows/RNScreens/RNScreens.vcxproj +187 -0
  356. package/windows/RNScreens/RNScreens.vcxproj.filters +52 -0
  357. package/windows/RNScreens/ReactPackageProvider.cpp +30 -0
  358. package/windows/RNScreens/ReactPackageProvider.h +17 -0
  359. package/windows/RNScreens/ReactPackageProvider.idl +9 -0
  360. package/windows/RNScreens/Screen.cpp +122 -0
  361. package/windows/RNScreens/Screen.h +64 -0
  362. package/windows/RNScreens/ScreenContainer.cpp +49 -0
  363. package/windows/RNScreens/ScreenContainer.h +23 -0
  364. package/windows/RNScreens/ScreenContainerViewManager.cpp +133 -0
  365. package/windows/RNScreens/ScreenContainerViewManager.h +78 -0
  366. package/windows/RNScreens/ScreenStack.cpp +65 -0
  367. package/windows/RNScreens/ScreenStack.h +23 -0
  368. package/windows/RNScreens/ScreenStackHeaderConfig.cpp +19 -0
  369. package/windows/RNScreens/ScreenStackHeaderConfig.h +14 -0
  370. package/windows/RNScreens/ScreenStackHeaderConfigViewManager.cpp +89 -0
  371. package/windows/RNScreens/ScreenStackHeaderConfigViewManager.h +62 -0
  372. package/windows/RNScreens/ScreenStackViewManager.cpp +132 -0
  373. package/windows/RNScreens/ScreenStackViewManager.h +78 -0
  374. package/windows/RNScreens/ScreenViewManager.cpp +154 -0
  375. package/windows/RNScreens/ScreenViewManager.h +78 -0
  376. package/windows/RNScreens/packages.config +4 -0
  377. package/windows/RNScreens/pch.cpp +1 -0
  378. package/windows/RNScreens/pch.h +9 -0
  379. package/windows/RNScreens62.sln +254 -0
  380. package/windows/RNScreens63.sln +225 -0
  381. package/windows/RNScreens65.sln +144 -0
@@ -0,0 +1,967 @@
1
+ #ifdef RCT_NEW_ARCH_ENABLED
2
+ #import <React/RCTConversions.h>
3
+ #import <React/RCTFabricComponentsPlugins.h>
4
+ #import <React/RCTImageComponentView.h>
5
+ #import <React/UIView+React.h>
6
+ #import <react/renderer/components/image/ImageProps.h>
7
+ #import <react/renderer/components/rnscreens/ComponentDescriptors.h>
8
+ #import <react/renderer/components/rnscreens/EventEmitters.h>
9
+ #import <react/renderer/components/rnscreens/Props.h>
10
+ #import <react/renderer/components/rnscreens/RCTComponentViewHelpers.h>
11
+ #import "RCTImageComponentView+RNSScreenStackHeaderConfig.h"
12
+ #else
13
+ #import <React/RCTImageView.h>
14
+ #import <React/RCTShadowView.h>
15
+ #import <React/RCTUIManager.h>
16
+ #import <React/RCTUIManagerUtils.h>
17
+ #endif
18
+ #import <React/RCTBridge.h>
19
+ #import <React/RCTFont.h>
20
+ #import <React/RCTImageLoader.h>
21
+ #import <React/RCTImageSource.h>
22
+ #import "RNSScreen.h"
23
+ #import "RNSScreenStackHeaderConfig.h"
24
+ #import "RNSSearchBar.h"
25
+ #import "RNSUIBarButtonItem.h"
26
+
27
+ #ifdef RCT_NEW_ARCH_ENABLED
28
+ namespace react = facebook::react;
29
+ #endif // RCT_NEW_ARCH_ENABLED
30
+
31
+ #ifndef RCT_NEW_ARCH_ENABLED
32
+ // Some RN private method hacking below. Couldn't figure out better way to access image data
33
+ // of a given RCTImageView. See more comments in the code section processing SubviewTypeBackButton
34
+ @interface RCTImageView (Private)
35
+ - (UIImage *)image;
36
+ @end
37
+ #endif // !RCT_NEW_ARCH_ENABLED
38
+
39
+ @interface RCTImageLoader (Private)
40
+ - (id<RCTImageCache>)imageCache;
41
+ @end
42
+
43
+ @implementation NSString (RNSStringUtil)
44
+
45
+ + (BOOL)RNSisBlank:(NSString *)string
46
+ {
47
+ if (string == nil) {
48
+ return YES;
49
+ }
50
+ return [[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0;
51
+ }
52
+
53
+ @end
54
+
55
+ @implementation RNSScreenStackHeaderConfig {
56
+ NSMutableArray<RNSScreenStackHeaderSubview *> *_reactSubviews;
57
+ #ifdef RCT_NEW_ARCH_ENABLED
58
+ BOOL _initialPropsSet;
59
+ #else
60
+ #endif
61
+ }
62
+
63
+ #ifdef RCT_NEW_ARCH_ENABLED
64
+ - (instancetype)initWithFrame:(CGRect)frame
65
+ {
66
+ if (self = [super initWithFrame:frame]) {
67
+ static const auto defaultProps = std::make_shared<const react::RNSScreenStackHeaderConfigProps>();
68
+ _props = defaultProps;
69
+ _show = YES;
70
+ _translucent = NO;
71
+ [self initProps];
72
+ }
73
+ return self;
74
+ }
75
+ #else
76
+ - (instancetype)init
77
+ {
78
+ if (self = [super init]) {
79
+ _translucent = YES;
80
+ [self initProps];
81
+ }
82
+ return self;
83
+ }
84
+ #endif
85
+
86
+ - (void)initProps
87
+ {
88
+ self.hidden = YES;
89
+ _reactSubviews = [NSMutableArray new];
90
+ _backTitleVisible = YES;
91
+ }
92
+
93
+ - (UIView *)reactSuperview
94
+ {
95
+ return _screenView;
96
+ }
97
+
98
+ - (NSArray<UIView *> *)reactSubviews
99
+ {
100
+ return _reactSubviews;
101
+ }
102
+
103
+ - (void)removeFromSuperview
104
+ {
105
+ [super removeFromSuperview];
106
+ _screenView = nil;
107
+ }
108
+
109
+ // this method is never invoked by the system since this view
110
+ // is not added to native view hierarchy so we can apply our logic
111
+ - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
112
+ {
113
+ for (RNSScreenStackHeaderSubview *subview in _reactSubviews) {
114
+ if (subview.type == RNSScreenStackHeaderSubviewTypeLeft || subview.type == RNSScreenStackHeaderSubviewTypeRight) {
115
+ // we wrap the headerLeft/Right component in a UIBarButtonItem
116
+ // so we need to use the only subview of it to retrieve the correct view
117
+ UIView *headerComponent = subview.subviews.firstObject;
118
+ // we convert the point to RNSScreenStackView since it always contains the header inside it
119
+ CGPoint convertedPoint = [_screenView.reactSuperview convertPoint:point toView:headerComponent];
120
+
121
+ UIView *hitTestResult = [headerComponent hitTest:convertedPoint withEvent:event];
122
+ if (hitTestResult != nil) {
123
+ return hitTestResult;
124
+ }
125
+ }
126
+ }
127
+ return nil;
128
+ }
129
+
130
+ - (void)updateViewControllerIfNeeded
131
+ {
132
+ UIViewController *vc = _screenView.controller;
133
+ UINavigationController *nav = (UINavigationController *)vc.parentViewController;
134
+ UIViewController *nextVC = nav.visibleViewController;
135
+ if (nav.transitionCoordinator != nil) {
136
+ // if navigator is performing transition instead of allowing to update of `visibleConttroller`
137
+ // we look at `topController`. This is because during transitiong the `visibleController` won't
138
+ // point to the controller that is going to be revealed after transition. This check fixes the
139
+ // problem when config gets updated while the transition is ongoing.
140
+ nextVC = nav.topViewController;
141
+ }
142
+
143
+ // we want updates sent to the VC below modal too since it is also visible
144
+ BOOL isPresentingVC = nextVC != nil && vc.presentedViewController == nextVC;
145
+
146
+ BOOL isInFullScreenModal = nav == nil && _screenView.stackPresentation == RNSScreenStackPresentationFullScreenModal;
147
+ // if nav is nil, it means we can be in a fullScreen modal, so there is no nextVC, but we still want to update
148
+ if (vc != nil && (nextVC == vc || isInFullScreenModal || isPresentingVC)) {
149
+ [RNSScreenStackHeaderConfig updateViewController:self.screenView.controller withConfig:self animated:YES];
150
+ }
151
+ }
152
+
153
+ - (void)layoutNavigationControllerView
154
+ {
155
+ // We need to layout navigation controller view after translucent prop changes, because otherwise
156
+ // frame of RNSScreen will not be changed and screen content will remain the same size.
157
+ // For more details look at https://github.com/software-mansion/react-native-screens/issues/1158
158
+ UIViewController *vc = _screenView.controller;
159
+ UINavigationController *navctr = vc.navigationController;
160
+ [navctr.view setNeedsLayout];
161
+ }
162
+
163
+ + (void)setAnimatedConfig:(UIViewController *)vc withConfig:(RNSScreenStackHeaderConfig *)config
164
+ {
165
+ UINavigationBar *navbar = ((UINavigationController *)vc.parentViewController).navigationBar;
166
+ // It is workaround for loading custom back icon when transitioning from a screen without header to the screen which
167
+ // has one. This action fails when navigating to the screen with header for the second time and loads default back
168
+ // button. It looks like changing the tint color of navbar triggers an update of the items belonging to it and it
169
+ // seems to load the custom back image so we change the tint color's alpha by a very small amount and then set it to
170
+ // the one it should have.
171
+ #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_14_0) && \
172
+ __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0
173
+ // it brakes the behavior of `headerRight` in iOS 14, where the bug desribed above seems to be fixed, so we do nothing
174
+ // in iOS 14
175
+ if (@available(iOS 14.0, *)) {
176
+ } else
177
+ #endif
178
+ {
179
+ [navbar setTintColor:[config.color colorWithAlphaComponent:CGColorGetAlpha(config.color.CGColor) - 0.01]];
180
+ }
181
+ [navbar setTintColor:config.color];
182
+
183
+ #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \
184
+ __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
185
+ if (@available(iOS 13.0, *)) {
186
+ // font customized on the navigation item level, so nothing to do here
187
+ } else
188
+ #endif
189
+ {
190
+ BOOL hideShadow = config.hideShadow;
191
+
192
+ if (config.backgroundColor && CGColorGetAlpha(config.backgroundColor.CGColor) == 0.) {
193
+ [navbar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
194
+ [navbar setBarTintColor:[UIColor clearColor]];
195
+ hideShadow = YES;
196
+ } else {
197
+ [navbar setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
198
+ [navbar setBarTintColor:config.backgroundColor];
199
+ }
200
+ [navbar setTranslucent:config.translucent];
201
+ [navbar setValue:@(hideShadow ? YES : NO) forKey:@"hidesShadow"];
202
+
203
+ if (config.titleFontFamily || config.titleFontSize || config.titleFontWeight || config.titleColor) {
204
+ NSMutableDictionary *attrs = [NSMutableDictionary new];
205
+
206
+ if (config.titleColor) {
207
+ attrs[NSForegroundColorAttributeName] = config.titleColor;
208
+ }
209
+
210
+ NSString *family = config.titleFontFamily ?: nil;
211
+ NSNumber *size = config.titleFontSize ?: @17;
212
+ NSString *weight = config.titleFontWeight ?: nil;
213
+ if (family || weight) {
214
+ attrs[NSFontAttributeName] = [RCTFont updateFont:nil
215
+ withFamily:family
216
+ size:size
217
+ weight:weight
218
+ style:nil
219
+ variant:nil
220
+ scaleMultiplier:1.0];
221
+ } else {
222
+ attrs[NSFontAttributeName] = [UIFont boldSystemFontOfSize:[size floatValue]];
223
+ }
224
+ [navbar setTitleTextAttributes:attrs];
225
+ }
226
+
227
+ #if !TARGET_OS_TV
228
+ if (@available(iOS 11.0, *)) {
229
+ if (config.largeTitle &&
230
+ (config.largeTitleFontFamily || config.largeTitleFontSize || config.largeTitleFontWeight ||
231
+ config.largeTitleColor || config.titleColor)) {
232
+ NSMutableDictionary *largeAttrs = [NSMutableDictionary new];
233
+ if (config.largeTitleColor || config.titleColor) {
234
+ largeAttrs[NSForegroundColorAttributeName] =
235
+ config.largeTitleColor ? config.largeTitleColor : config.titleColor;
236
+ }
237
+ NSString *largeFamily = config.largeTitleFontFamily ?: nil;
238
+ NSNumber *largeSize = config.largeTitleFontSize ?: @34;
239
+ NSString *largeWeight = config.largeTitleFontWeight ?: nil;
240
+ if (largeFamily || largeWeight) {
241
+ largeAttrs[NSFontAttributeName] = [RCTFont updateFont:nil
242
+ withFamily:largeFamily
243
+ size:largeSize
244
+ weight:largeWeight
245
+ style:nil
246
+ variant:nil
247
+ scaleMultiplier:1.0];
248
+ } else {
249
+ largeAttrs[NSFontAttributeName] = [UIFont systemFontOfSize:[largeSize floatValue] weight:UIFontWeightBold];
250
+ }
251
+ [navbar setLargeTitleTextAttributes:largeAttrs];
252
+ }
253
+ }
254
+ #endif
255
+ }
256
+ }
257
+
258
+ + (void)setTitleAttibutes:(NSDictionary *)attrs forButton:(UIBarButtonItem *)button
259
+ {
260
+ [button setTitleTextAttributes:attrs forState:UIControlStateNormal];
261
+ [button setTitleTextAttributes:attrs forState:UIControlStateHighlighted];
262
+ [button setTitleTextAttributes:attrs forState:UIControlStateDisabled];
263
+ [button setTitleTextAttributes:attrs forState:UIControlStateSelected];
264
+ [button setTitleTextAttributes:attrs forState:UIControlStateFocused];
265
+ }
266
+
267
+ + (UIImage *)loadBackButtonImageInViewController:(UIViewController *)vc withConfig:(RNSScreenStackHeaderConfig *)config
268
+ {
269
+ BOOL hasBackButtonImage = NO;
270
+ for (RNSScreenStackHeaderSubview *subview in config.reactSubviews) {
271
+ if (subview.type == RNSScreenStackHeaderSubviewTypeBackButton && subview.subviews.count > 0) {
272
+ hasBackButtonImage = YES;
273
+ #ifdef RCT_NEW_ARCH_ENABLED
274
+ RCTImageComponentView *imageView = subview.subviews[0];
275
+ #else
276
+ RCTImageView *imageView = subview.subviews[0];
277
+ #endif // RCT_NEW_ARCH_ENABLED
278
+ if (imageView.image == nil) {
279
+ // This is yet another workaround for loading custom back icon. It turns out that under
280
+ // certain circumstances image attribute can be null despite the app running in production
281
+ // mode (when images are loaded from the filesystem). This can happen because image attribute
282
+ // is reset when image view is detached from window, and also in some cases initialization
283
+ // does not populate the frame of the image view before the loading start. The latter result
284
+ // in the image attribute not being updated. We manually set frame to the size of an image
285
+ // in order to trigger proper reload that'd update the image attribute.
286
+ RCTImageSource *imageSource = [RNSScreenStackHeaderConfig imageSourceFromImageView:imageView];
287
+ [imageView reactSetFrame:CGRectMake(
288
+ imageView.frame.origin.x,
289
+ imageView.frame.origin.y,
290
+ imageSource.size.width,
291
+ imageSource.size.height)];
292
+ }
293
+
294
+ UIImage *image = imageView.image;
295
+
296
+ // IMPORTANT!!!
297
+ // image can be nil in DEV MODE ONLY
298
+ //
299
+ // It is so, because in dev mode images are loaded over HTTP from the packager. In that case
300
+ // we first check if image is already loaded in cache and if it is, we take it from cache and
301
+ // display immediately. Otherwise we wait for the transition to finish and retry updating
302
+ // header config.
303
+ // Unfortunately due to some problems in UIKit we cannot update the image while the screen
304
+ // transition is ongoing. This results in the settings being reset after the transition is done
305
+ // to the state from before the transition.
306
+ if (image == nil) {
307
+ // in DEV MODE we try to load from cache (we use private API for that as it is not exposed
308
+ // publically in headers).
309
+ RCTImageSource *imageSource = [RNSScreenStackHeaderConfig imageSourceFromImageView:imageView];
310
+ RCTImageLoader *imageLoader = [subview.bridge moduleForClass:[RCTImageLoader class]];
311
+
312
+ image = [imageLoader.imageCache
313
+ imageForUrl:imageSource.request.URL.absoluteString
314
+ size:imageSource.size
315
+ scale:imageSource.scale
316
+ #ifdef RCT_NEW_ARCH_ENABLED
317
+ resizeMode:resizeModeFromCppEquiv(
318
+ std::static_pointer_cast<const react::ImageProps>(imageView.props)->resizeMode)];
319
+ #else
320
+ resizeMode:imageView.resizeMode];
321
+ #endif // RCT_NEW_ARCH_ENABLED
322
+ }
323
+ if (image == nil) {
324
+ // This will be triggered if the image is not in the cache yet. What we do is we wait until
325
+ // the end of transition and run header config updates again. We could potentially wait for
326
+ // image on load to trigger, but that would require even more private method hacking.
327
+ if (vc.transitionCoordinator) {
328
+ [vc.transitionCoordinator
329
+ animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
330
+ // nothing, we just want completion
331
+ }
332
+ completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
333
+ // in order for new back button image to be loaded we need to trigger another change
334
+ // in back button props that'd make UIKit redraw the button. Otherwise the changes are
335
+ // not reflected. Here we change back button visibility which is then immediately restored
336
+ #if !TARGET_OS_TV
337
+ vc.navigationItem.hidesBackButton = YES;
338
+ #endif
339
+ [config updateViewControllerIfNeeded];
340
+ }];
341
+ }
342
+ return [UIImage new];
343
+ } else {
344
+ return image;
345
+ }
346
+ }
347
+ }
348
+ return nil;
349
+ }
350
+
351
+ + (void)willShowViewController:(UIViewController *)vc
352
+ animated:(BOOL)animated
353
+ withConfig:(RNSScreenStackHeaderConfig *)config
354
+ {
355
+ [self updateViewController:vc withConfig:config animated:animated];
356
+ }
357
+
358
+ #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \
359
+ __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
360
+ + (UINavigationBarAppearance *)buildAppearance:(UIViewController *)vc
361
+ withConfig:(RNSScreenStackHeaderConfig *)config API_AVAILABLE(ios(13.0))
362
+ {
363
+ UINavigationBarAppearance *appearance = [UINavigationBarAppearance new];
364
+
365
+ if (config.backgroundColor && CGColorGetAlpha(config.backgroundColor.CGColor) == 0.) {
366
+ // transparent background color
367
+ [appearance configureWithTransparentBackground];
368
+ } else {
369
+ [appearance configureWithOpaqueBackground];
370
+ }
371
+
372
+ // set background color if specified
373
+ if (config.backgroundColor) {
374
+ appearance.backgroundColor = config.backgroundColor;
375
+ }
376
+
377
+ // TODO: implement blurEffect on Fabric
378
+ #ifdef RCT_NEW_ARCH_ENABLED
379
+ #else
380
+ if (config.blurEffect) {
381
+ appearance.backgroundEffect = [UIBlurEffect effectWithStyle:config.blurEffect];
382
+ }
383
+ #endif
384
+
385
+ if (config.hideShadow) {
386
+ appearance.shadowColor = nil;
387
+ }
388
+
389
+ if (config.titleFontFamily || config.titleFontSize || config.titleFontWeight || config.titleColor) {
390
+ NSMutableDictionary *attrs = [NSMutableDictionary new];
391
+
392
+ if (config.titleColor) {
393
+ attrs[NSForegroundColorAttributeName] = config.titleColor;
394
+ }
395
+
396
+ NSString *family = config.titleFontFamily ?: nil;
397
+ NSNumber *size = config.titleFontSize ?: @17;
398
+ NSString *weight = config.titleFontWeight ?: nil;
399
+ if (family || weight) {
400
+ attrs[NSFontAttributeName] = [RCTFont updateFont:nil
401
+ withFamily:config.titleFontFamily
402
+ size:size
403
+ weight:weight
404
+ style:nil
405
+ variant:nil
406
+ scaleMultiplier:1.0];
407
+ } else {
408
+ attrs[NSFontAttributeName] = [UIFont boldSystemFontOfSize:[size floatValue]];
409
+ }
410
+ appearance.titleTextAttributes = attrs;
411
+ }
412
+
413
+ if (config.largeTitleFontFamily || config.largeTitleFontSize || config.largeTitleFontWeight ||
414
+ config.largeTitleColor || config.titleColor) {
415
+ NSMutableDictionary *largeAttrs = [NSMutableDictionary new];
416
+
417
+ if (config.largeTitleColor || config.titleColor) {
418
+ largeAttrs[NSForegroundColorAttributeName] = config.largeTitleColor ? config.largeTitleColor : config.titleColor;
419
+ }
420
+
421
+ NSString *largeFamily = config.largeTitleFontFamily ?: nil;
422
+ NSNumber *largeSize = config.largeTitleFontSize ?: @34;
423
+ NSString *largeWeight = config.largeTitleFontWeight ?: nil;
424
+ if (largeFamily || largeWeight) {
425
+ largeAttrs[NSFontAttributeName] = [RCTFont updateFont:nil
426
+ withFamily:largeFamily
427
+ size:largeSize
428
+ weight:largeWeight
429
+ style:nil
430
+ variant:nil
431
+ scaleMultiplier:1.0];
432
+ } else {
433
+ largeAttrs[NSFontAttributeName] = [UIFont systemFontOfSize:[largeSize floatValue] weight:UIFontWeightBold];
434
+ }
435
+
436
+ appearance.largeTitleTextAttributes = largeAttrs;
437
+ }
438
+
439
+ UIImage *backButtonImage = [self loadBackButtonImageInViewController:vc withConfig:config];
440
+ if (backButtonImage) {
441
+ [appearance setBackIndicatorImage:backButtonImage transitionMaskImage:backButtonImage];
442
+ } else if (appearance.backIndicatorImage) {
443
+ [appearance setBackIndicatorImage:nil transitionMaskImage:nil];
444
+ }
445
+ return appearance;
446
+ }
447
+ #endif // Check for >= iOS 13.0
448
+
449
+ + (void)updateViewController:(UIViewController *)vc
450
+ withConfig:(RNSScreenStackHeaderConfig *)config
451
+ animated:(BOOL)animated
452
+ {
453
+ UINavigationItem *navitem = vc.navigationItem;
454
+ UINavigationController *navctr = (UINavigationController *)vc.parentViewController;
455
+
456
+ NSUInteger currentIndex = [navctr.viewControllers indexOfObject:vc];
457
+ UINavigationItem *prevItem =
458
+ currentIndex > 0 ? [navctr.viewControllers objectAtIndex:currentIndex - 1].navigationItem : nil;
459
+
460
+ BOOL wasHidden = navctr.navigationBarHidden;
461
+ #ifdef RCT_NEW_ARCH_ENABLED
462
+ BOOL shouldHide = config == nil || !config.show;
463
+ #else
464
+ BOOL shouldHide = config == nil || config.hide;
465
+ #endif
466
+
467
+ if (!shouldHide && !config.translucent) {
468
+ // when nav bar is not translucent we chage edgesForExtendedLayout to avoid system laying out
469
+ // the screen underneath navigation controllers
470
+ vc.edgesForExtendedLayout = UIRectEdgeNone;
471
+ } else {
472
+ // system default is UIRectEdgeAll
473
+ vc.edgesForExtendedLayout = UIRectEdgeAll;
474
+ }
475
+
476
+ [navctr setNavigationBarHidden:shouldHide animated:animated];
477
+
478
+ if ((config.direction == UISemanticContentAttributeForceLeftToRight ||
479
+ config.direction == UISemanticContentAttributeForceRightToLeft) &&
480
+ // iOS 12 cancels swipe gesture when direction is changed. See #1091
481
+ navctr.view.semanticContentAttribute != config.direction) {
482
+ navctr.view.semanticContentAttribute = config.direction;
483
+ navctr.navigationBar.semanticContentAttribute = config.direction;
484
+ }
485
+
486
+ if (shouldHide) {
487
+ navitem.title = config.title;
488
+ return;
489
+ }
490
+
491
+ #if !TARGET_OS_TV
492
+ const auto isBackTitleBlank = [NSString RNSisBlank:config.backTitle] == YES;
493
+ NSString *resolvedBackTitle = isBackTitleBlank ? prevItem.title : config.backTitle;
494
+ RNSUIBarButtonItem *backBarButtonItem = [[RNSUIBarButtonItem alloc] initWithTitle:resolvedBackTitle
495
+ style:UIBarButtonItemStylePlain
496
+ target:nil
497
+ action:nil];
498
+ [backBarButtonItem setMenuHidden:config.disableBackButtonMenu];
499
+
500
+ if (config.isBackTitleVisible) {
501
+ if (config.backTitleFontFamily || config.backTitleFontSize) {
502
+ NSMutableDictionary *attrs = [NSMutableDictionary new];
503
+ NSNumber *size = config.backTitleFontSize ?: @17;
504
+ if (config.backTitleFontFamily) {
505
+ attrs[NSFontAttributeName] = [RCTFont updateFont:nil
506
+ withFamily:config.backTitleFontFamily
507
+ size:size
508
+ weight:nil
509
+ style:nil
510
+ variant:nil
511
+ scaleMultiplier:1.0];
512
+ } else {
513
+ attrs[NSFontAttributeName] = [UIFont boldSystemFontOfSize:[size floatValue]];
514
+ }
515
+ [self setTitleAttibutes:attrs forButton:backBarButtonItem];
516
+ }
517
+ } else {
518
+ // back button title should be not visible next to back button,
519
+ // but it should still appear in back menu (if one is enabled)
520
+
521
+ // When backBarButtonItem's title is null, back menu will use value
522
+ // of backButtonTitle
523
+ [backBarButtonItem setTitle:nil];
524
+ prevItem.backButtonTitle = resolvedBackTitle;
525
+ }
526
+ prevItem.backBarButtonItem = backBarButtonItem;
527
+
528
+ if (@available(iOS 11.0, *)) {
529
+ if (config.largeTitle) {
530
+ navctr.navigationBar.prefersLargeTitles = YES;
531
+ }
532
+ navitem.largeTitleDisplayMode =
533
+ config.largeTitle ? UINavigationItemLargeTitleDisplayModeAlways : UINavigationItemLargeTitleDisplayModeNever;
534
+ }
535
+ #endif
536
+
537
+ #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \
538
+ __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
539
+ if (@available(iOS 13.0, tvOS 13.0, *)) {
540
+ UINavigationBarAppearance *appearance = [self buildAppearance:vc withConfig:config];
541
+ navitem.standardAppearance = appearance;
542
+ navitem.compactAppearance = appearance;
543
+
544
+ UINavigationBarAppearance *scrollEdgeAppearance =
545
+ [[UINavigationBarAppearance alloc] initWithBarAppearance:appearance];
546
+ if (config.largeTitleBackgroundColor != nil) {
547
+ scrollEdgeAppearance.backgroundColor = config.largeTitleBackgroundColor;
548
+ }
549
+ if (config.largeTitleHideShadow) {
550
+ scrollEdgeAppearance.shadowColor = nil;
551
+ }
552
+ navitem.scrollEdgeAppearance = scrollEdgeAppearance;
553
+ } else
554
+ #endif
555
+ {
556
+ #if !TARGET_OS_TV
557
+ // updating backIndicatotImage does not work when called during transition. On iOS pre 13 we need
558
+ // to update it before the navigation starts.
559
+ UIImage *backButtonImage = [self loadBackButtonImageInViewController:vc withConfig:config];
560
+ if (backButtonImage) {
561
+ navctr.navigationBar.backIndicatorImage = backButtonImage;
562
+ navctr.navigationBar.backIndicatorTransitionMaskImage = backButtonImage;
563
+ } else if (navctr.navigationBar.backIndicatorImage) {
564
+ navctr.navigationBar.backIndicatorImage = nil;
565
+ navctr.navigationBar.backIndicatorTransitionMaskImage = nil;
566
+ }
567
+ #endif
568
+ }
569
+ #if !TARGET_OS_TV
570
+ navitem.hidesBackButton = config.hideBackButton;
571
+ #endif
572
+ navitem.leftBarButtonItem = nil;
573
+ navitem.rightBarButtonItem = nil;
574
+ navitem.titleView = nil;
575
+
576
+ for (RNSScreenStackHeaderSubview *subview in config.reactSubviews) {
577
+ switch (subview.type) {
578
+ case RNSScreenStackHeaderSubviewTypeLeft: {
579
+ #if !TARGET_OS_TV
580
+ navitem.leftItemsSupplementBackButton = config.backButtonInCustomView;
581
+ #endif
582
+ UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:subview];
583
+ navitem.leftBarButtonItem = buttonItem;
584
+ break;
585
+ }
586
+ case RNSScreenStackHeaderSubviewTypeRight: {
587
+ UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:subview];
588
+ navitem.rightBarButtonItem = buttonItem;
589
+ break;
590
+ }
591
+ case RNSScreenStackHeaderSubviewTypeCenter:
592
+ case RNSScreenStackHeaderSubviewTypeTitle: {
593
+ navitem.titleView = subview;
594
+ break;
595
+ }
596
+ case RNSScreenStackHeaderSubviewTypeSearchBar: {
597
+ if (subview.subviews == nil || [subview.subviews count] == 0) {
598
+ RCTLogWarn(
599
+ @"Failed to attach search bar to the header. We recommend using `useLayoutEffect` when managing "
600
+ "searchBar properties dynamically. \n\nSee: github.com/software-mansion/react-native-screens/issues/1188");
601
+ break;
602
+ }
603
+
604
+ if ([subview.subviews[0] isKindOfClass:[RNSSearchBar class]]) {
605
+ #if !TARGET_OS_TV
606
+ if (@available(iOS 11.0, *)) {
607
+ RNSSearchBar *searchBar = subview.subviews[0];
608
+ navitem.searchController = searchBar.controller;
609
+ navitem.hidesSearchBarWhenScrolling = searchBar.hideWhenScrolling;
610
+ #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_16_0) && \
611
+ __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_16_0
612
+ if (@available(iOS 16.0, *)) {
613
+ navitem.preferredSearchBarPlacement = [searchBar placementAsUINavigationItemSearchBarPlacement];
614
+ }
615
+ #endif /* Check for iOS 16.0 */
616
+ }
617
+ #endif /* !TARGET_OS_TV */
618
+ }
619
+ break;
620
+ }
621
+ case RNSScreenStackHeaderSubviewTypeBackButton: {
622
+ break;
623
+ }
624
+ }
625
+ }
626
+
627
+ // This assignment should be done after `navitem.titleView = ...` assignment (iOS 16.0 bug).
628
+ // See: https://github.com/software-mansion/react-native-screens/issues/1570 (comments)
629
+ navitem.title = config.title;
630
+
631
+ if (animated && vc.transitionCoordinator != nil &&
632
+ vc.transitionCoordinator.presentationStyle == UIModalPresentationNone && !wasHidden) {
633
+ // when there is an ongoing transition we may need to update navbar setting in animation block
634
+ // using animateAlongsideTransition. However, we only do that given the transition is not a modal
635
+ // transition (presentationStyle == UIModalPresentationNone) and that the bar was not previously
636
+ // hidden. This is because both for modal transitions and transitions from screen with hidden bar
637
+ // the transition animation block does not get triggered. This is ok, because with both of those
638
+ // types of transitions there is no "shared" navigation bar that needs to be updated in an animated
639
+ // way.
640
+ [vc.transitionCoordinator
641
+ animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
642
+ [self setAnimatedConfig:vc withConfig:config];
643
+ }
644
+ completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
645
+ if ([context isCancelled]) {
646
+ UIViewController *fromVC = [context viewControllerForKey:UITransitionContextFromViewControllerKey];
647
+ RNSScreenStackHeaderConfig *config = nil;
648
+ for (UIView *subview in fromVC.view.reactSubviews) {
649
+ if ([subview isKindOfClass:[RNSScreenStackHeaderConfig class]]) {
650
+ config = (RNSScreenStackHeaderConfig *)subview;
651
+ break;
652
+ }
653
+ }
654
+ [self setAnimatedConfig:fromVC withConfig:config];
655
+ }
656
+ }];
657
+ } else {
658
+ [self setAnimatedConfig:vc withConfig:config];
659
+ }
660
+ }
661
+
662
+ - (void)insertReactSubview:(RNSScreenStackHeaderSubview *)subview atIndex:(NSInteger)atIndex
663
+ {
664
+ [_reactSubviews insertObject:subview atIndex:atIndex];
665
+ subview.reactSuperview = self;
666
+ }
667
+
668
+ - (void)removeReactSubview:(RNSScreenStackHeaderSubview *)subview
669
+ {
670
+ [_reactSubviews removeObject:subview];
671
+ }
672
+
673
+ - (void)didUpdateReactSubviews
674
+ {
675
+ [super didUpdateReactSubviews];
676
+ [self updateViewControllerIfNeeded];
677
+ }
678
+
679
+ #ifdef RCT_NEW_ARCH_ENABLED
680
+ #pragma mark - Fabric specific
681
+
682
+ - (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
683
+ {
684
+ if (![childComponentView isKindOfClass:[RNSScreenStackHeaderSubview class]]) {
685
+ RCTLogError(@"ScreenStackHeader only accepts children of type ScreenStackHeaderSubview");
686
+ return;
687
+ }
688
+
689
+ RCTAssert(
690
+ childComponentView.superview == nil,
691
+ @"Attempt to mount already mounted component view. (parent: %@, child: %@, index: %@, existing parent: %@)",
692
+ self,
693
+ childComponentView,
694
+ @(index),
695
+ @([childComponentView.superview tag]));
696
+
697
+ // [_reactSubviews insertObject:(RNSScreenStackHeaderSubview *)childComponentView atIndex:index];
698
+ [self insertReactSubview:(RNSScreenStackHeaderSubview *)childComponentView atIndex:index];
699
+ [self updateViewControllerIfNeeded];
700
+ }
701
+
702
+ - (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
703
+ {
704
+ [_reactSubviews removeObject:(RNSScreenStackHeaderSubview *)childComponentView];
705
+ [childComponentView removeFromSuperview];
706
+ }
707
+
708
+ static RCTResizeMode resizeModeFromCppEquiv(react::ImageResizeMode resizeMode)
709
+ {
710
+ switch (resizeMode) {
711
+ case react::ImageResizeMode::Cover:
712
+ return RCTResizeModeCover;
713
+ case react::ImageResizeMode::Contain:
714
+ return RCTResizeModeContain;
715
+ case react::ImageResizeMode::Stretch:
716
+ return RCTResizeModeStretch;
717
+ case react::ImageResizeMode::Center:
718
+ return RCTResizeModeCenter;
719
+ case react::ImageResizeMode::Repeat:
720
+ return RCTResizeModeRepeat;
721
+ }
722
+ }
723
+
724
+ /**
725
+ * Fabric implementation of helper method for +loadBackButtonImageInViewController:withConfig:
726
+ * There is corresponding Paper implementation (with different parameter type) in Paper specific section.
727
+ */
728
+ + (RCTImageSource *)imageSourceFromImageView:(RCTImageComponentView *)view
729
+ {
730
+ auto const imageProps = *std::static_pointer_cast<const react::ImageProps>(view.props);
731
+ react::ImageSource cppImageSource = imageProps.sources.at(0);
732
+ auto imageSize = CGSize{cppImageSource.size.width, cppImageSource.size.height};
733
+ NSURLRequest *request =
734
+ [NSURLRequest requestWithURL:[NSURL URLWithString:RCTNSStringFromStringNilIfEmpty(cppImageSource.uri)]];
735
+ RCTImageSource *imageSource = [[RCTImageSource alloc] initWithURLRequest:request
736
+ size:imageSize
737
+ scale:cppImageSource.scale];
738
+ return imageSource;
739
+ }
740
+
741
+ #pragma mark - RCTComponentViewProtocol
742
+
743
+ - (void)prepareForRecycle
744
+ {
745
+ [super prepareForRecycle];
746
+ _initialPropsSet = NO;
747
+ }
748
+
749
+ + (react::ComponentDescriptorProvider)componentDescriptorProvider
750
+ {
751
+ return react::concreteComponentDescriptorProvider<react::RNSScreenStackHeaderConfigComponentDescriptor>();
752
+ }
753
+
754
+ - (NSNumber *)getFontSizePropValue:(int)value
755
+ {
756
+ if (value > 0)
757
+ return [NSNumber numberWithInt:value];
758
+ return nil;
759
+ }
760
+
761
+ - (UISemanticContentAttribute)getDirectionPropValue:(react::RNSScreenStackHeaderConfigDirection)direction
762
+ {
763
+ switch (direction) {
764
+ case react::RNSScreenStackHeaderConfigDirection::Rtl:
765
+ return UISemanticContentAttributeForceRightToLeft;
766
+ case react::RNSScreenStackHeaderConfigDirection::Ltr:
767
+ return UISemanticContentAttributeForceLeftToRight;
768
+ }
769
+ }
770
+
771
+ - (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props::Shared const &)oldProps
772
+ {
773
+ const auto &oldScreenProps = *std::static_pointer_cast<const react::RNSScreenStackHeaderConfigProps>(_props);
774
+ const auto &newScreenProps = *std::static_pointer_cast<const react::RNSScreenStackHeaderConfigProps>(props);
775
+
776
+ BOOL needsNavigationControllerLayout = !_initialPropsSet;
777
+
778
+ if (newScreenProps.hidden != !_show) {
779
+ _show = !newScreenProps.hidden;
780
+ needsNavigationControllerLayout = YES;
781
+ }
782
+
783
+ if (newScreenProps.translucent != _translucent) {
784
+ _translucent = newScreenProps.translucent;
785
+ needsNavigationControllerLayout = YES;
786
+ }
787
+
788
+ if (newScreenProps.backButtonInCustomView != _backButtonInCustomView) {
789
+ [self setBackButtonInCustomView:newScreenProps.backButtonInCustomView];
790
+ }
791
+
792
+ _title = RCTNSStringFromStringNilIfEmpty(newScreenProps.title);
793
+ if (newScreenProps.titleFontFamily != oldScreenProps.titleFontFamily) {
794
+ _titleFontFamily = RCTNSStringFromStringNilIfEmpty(newScreenProps.titleFontFamily);
795
+ }
796
+ _titleFontWeight = RCTNSStringFromStringNilIfEmpty(newScreenProps.titleFontWeight);
797
+ _titleFontSize = [self getFontSizePropValue:newScreenProps.titleFontSize];
798
+ _hideShadow = newScreenProps.hideShadow;
799
+
800
+ _largeTitle = newScreenProps.largeTitle;
801
+ if (newScreenProps.largeTitleFontFamily != oldScreenProps.largeTitleFontFamily) {
802
+ _largeTitleFontFamily = RCTNSStringFromStringNilIfEmpty(newScreenProps.largeTitleFontFamily);
803
+ }
804
+ _largeTitleFontWeight = RCTNSStringFromStringNilIfEmpty(newScreenProps.largeTitleFontWeight);
805
+ _largeTitleFontSize = [self getFontSizePropValue:newScreenProps.largeTitleFontSize];
806
+ _largeTitleHideShadow = newScreenProps.largeTitleHideShadow;
807
+
808
+ _backTitle = RCTNSStringFromStringNilIfEmpty(newScreenProps.backTitle);
809
+ if (newScreenProps.backTitleFontFamily != oldScreenProps.backTitleFontFamily) {
810
+ _backTitleFontFamily = RCTNSStringFromStringNilIfEmpty(newScreenProps.backTitleFontFamily);
811
+ }
812
+ _backTitleFontSize = [self getFontSizePropValue:newScreenProps.backTitleFontSize];
813
+ _hideBackButton = newScreenProps.hideBackButton;
814
+ _disableBackButtonMenu = newScreenProps.disableBackButtonMenu;
815
+
816
+ if (newScreenProps.direction != oldScreenProps.direction) {
817
+ _direction = [self getDirectionPropValue:newScreenProps.direction];
818
+ }
819
+
820
+ _backTitleVisible = newScreenProps.backTitleVisible;
821
+
822
+ // We cannot compare SharedColor because it is shared value.
823
+ // We could compare color value, but it is more performant to just assign new value
824
+ _titleColor = RCTUIColorFromSharedColor(newScreenProps.titleColor);
825
+ _largeTitleColor = RCTUIColorFromSharedColor(newScreenProps.largeTitleColor);
826
+ _color = RCTUIColorFromSharedColor(newScreenProps.color);
827
+ _backgroundColor = RCTUIColorFromSharedColor(newScreenProps.backgroundColor);
828
+
829
+ [self updateViewControllerIfNeeded];
830
+
831
+ if (needsNavigationControllerLayout) {
832
+ [self layoutNavigationControllerView];
833
+ }
834
+
835
+ _initialPropsSet = YES;
836
+ _props = std::static_pointer_cast<react::RNSScreenStackHeaderConfigProps const>(props);
837
+
838
+ [super updateProps:props oldProps:oldProps];
839
+ }
840
+
841
+ #else
842
+ #pragma mark - Paper specific
843
+
844
+ - (void)didSetProps:(NSArray<NSString *> *)changedProps
845
+ {
846
+ [super didSetProps:changedProps];
847
+ [self updateViewControllerIfNeeded];
848
+ // We need to layout navigation controller view after translucent prop changes, because otherwise
849
+ // frame of RNSScreen will not be changed and screen content will remain the same size.
850
+ // For more details look at https://github.com/software-mansion/react-native-screens/issues/1158
851
+ if ([changedProps containsObject:@"translucent"]) {
852
+ [self layoutNavigationControllerView];
853
+ }
854
+ }
855
+
856
+ /**
857
+ * Paper implementation of helper method for +loadBackButtonImageInViewController:withConfig:
858
+ * There is corresponding Fabric implementation (with different parameter type) in Fabric specific section.
859
+ */
860
+ + (RCTImageSource *)imageSourceFromImageView:(RCTImageView *)view
861
+ {
862
+ return view.imageSources[0];
863
+ }
864
+
865
+ #endif
866
+ @end
867
+
868
+ #ifdef RCT_NEW_ARCH_ENABLED
869
+ Class<RCTComponentViewProtocol> RNSScreenStackHeaderConfigCls(void)
870
+ {
871
+ return RNSScreenStackHeaderConfig.class;
872
+ }
873
+ #endif
874
+
875
+ @implementation RNSScreenStackHeaderConfigManager
876
+
877
+ RCT_EXPORT_MODULE()
878
+
879
+ - (UIView *)view
880
+ {
881
+ return [RNSScreenStackHeaderConfig new];
882
+ }
883
+
884
+ RCT_EXPORT_VIEW_PROPERTY(title, NSString)
885
+ RCT_EXPORT_VIEW_PROPERTY(titleFontFamily, NSString)
886
+ RCT_EXPORT_VIEW_PROPERTY(titleFontSize, NSNumber)
887
+ RCT_EXPORT_VIEW_PROPERTY(titleFontWeight, NSString)
888
+ RCT_EXPORT_VIEW_PROPERTY(titleColor, UIColor)
889
+ RCT_EXPORT_VIEW_PROPERTY(backTitle, NSString)
890
+ RCT_EXPORT_VIEW_PROPERTY(backTitleFontFamily, NSString)
891
+ RCT_EXPORT_VIEW_PROPERTY(backTitleFontSize, NSNumber)
892
+ RCT_EXPORT_VIEW_PROPERTY(backgroundColor, UIColor)
893
+ RCT_EXPORT_VIEW_PROPERTY(backTitleVisible, BOOL)
894
+ RCT_EXPORT_VIEW_PROPERTY(blurEffect, UIBlurEffectStyle)
895
+ RCT_EXPORT_VIEW_PROPERTY(color, UIColor)
896
+ RCT_EXPORT_VIEW_PROPERTY(direction, UISemanticContentAttribute)
897
+ RCT_EXPORT_VIEW_PROPERTY(largeTitle, BOOL)
898
+ RCT_EXPORT_VIEW_PROPERTY(largeTitleFontFamily, NSString)
899
+ RCT_EXPORT_VIEW_PROPERTY(largeTitleFontSize, NSNumber)
900
+ RCT_EXPORT_VIEW_PROPERTY(largeTitleFontWeight, NSString)
901
+ RCT_EXPORT_VIEW_PROPERTY(largeTitleColor, UIColor)
902
+ RCT_EXPORT_VIEW_PROPERTY(largeTitleBackgroundColor, UIColor)
903
+ RCT_EXPORT_VIEW_PROPERTY(largeTitleHideShadow, BOOL)
904
+ RCT_EXPORT_VIEW_PROPERTY(hideBackButton, BOOL)
905
+ RCT_EXPORT_VIEW_PROPERTY(hideShadow, BOOL)
906
+ RCT_EXPORT_VIEW_PROPERTY(backButtonInCustomView, BOOL)
907
+ RCT_EXPORT_VIEW_PROPERTY(disableBackButtonMenu, BOOL)
908
+ // `hidden` is an UIView property, we need to use different name internally
909
+ RCT_REMAP_VIEW_PROPERTY(hidden, hide, BOOL)
910
+ RCT_EXPORT_VIEW_PROPERTY(translucent, BOOL)
911
+
912
+ @end
913
+
914
+ @implementation RCTConvert (RNSScreenStackHeader)
915
+
916
+ + (NSMutableDictionary *)blurEffectsForIOSVersion
917
+ {
918
+ NSMutableDictionary *blurEffects = [NSMutableDictionary new];
919
+ [blurEffects addEntriesFromDictionary:@{
920
+ @"extraLight" : @(UIBlurEffectStyleExtraLight),
921
+ @"light" : @(UIBlurEffectStyleLight),
922
+ @"dark" : @(UIBlurEffectStyleDark),
923
+ }];
924
+
925
+ if (@available(iOS 10.0, *)) {
926
+ [blurEffects addEntriesFromDictionary:@{
927
+ @"regular" : @(UIBlurEffectStyleRegular),
928
+ @"prominent" : @(UIBlurEffectStyleProminent),
929
+ }];
930
+ }
931
+ #if !TARGET_OS_TV && defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \
932
+ __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
933
+ if (@available(iOS 13.0, *)) {
934
+ [blurEffects addEntriesFromDictionary:@{
935
+ @"systemUltraThinMaterial" : @(UIBlurEffectStyleSystemUltraThinMaterial),
936
+ @"systemThinMaterial" : @(UIBlurEffectStyleSystemThinMaterial),
937
+ @"systemMaterial" : @(UIBlurEffectStyleSystemMaterial),
938
+ @"systemThickMaterial" : @(UIBlurEffectStyleSystemThickMaterial),
939
+ @"systemChromeMaterial" : @(UIBlurEffectStyleSystemChromeMaterial),
940
+ @"systemUltraThinMaterialLight" : @(UIBlurEffectStyleSystemUltraThinMaterialLight),
941
+ @"systemThinMaterialLight" : @(UIBlurEffectStyleSystemThinMaterialLight),
942
+ @"systemMaterialLight" : @(UIBlurEffectStyleSystemMaterialLight),
943
+ @"systemThickMaterialLight" : @(UIBlurEffectStyleSystemThickMaterialLight),
944
+ @"systemChromeMaterialLight" : @(UIBlurEffectStyleSystemChromeMaterialLight),
945
+ @"systemUltraThinMaterialDark" : @(UIBlurEffectStyleSystemUltraThinMaterialDark),
946
+ @"systemThinMaterialDark" : @(UIBlurEffectStyleSystemThinMaterialDark),
947
+ @"systemMaterialDark" : @(UIBlurEffectStyleSystemMaterialDark),
948
+ @"systemThickMaterialDark" : @(UIBlurEffectStyleSystemThickMaterialDark),
949
+ @"systemChromeMaterialDark" : @(UIBlurEffectStyleSystemChromeMaterialDark),
950
+ }];
951
+ }
952
+ #endif
953
+ return blurEffects;
954
+ }
955
+
956
+ RCT_ENUM_CONVERTER(
957
+ UISemanticContentAttribute,
958
+ (@{
959
+ @"ltr" : @(UISemanticContentAttributeForceLeftToRight),
960
+ @"rtl" : @(UISemanticContentAttributeForceRightToLeft),
961
+ }),
962
+ UISemanticContentAttributeUnspecified,
963
+ integerValue)
964
+
965
+ RCT_ENUM_CONVERTER(UIBlurEffectStyle, ([self blurEffectsForIOSVersion]), UIBlurEffectStyleExtraLight, integerValue)
966
+
967
+ @end