@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,282 @@
1
+ package com.swmansion.rnscreens
2
+
3
+ import android.annotation.SuppressLint
4
+ import android.content.Context
5
+ import android.graphics.Color
6
+ import android.os.Bundle
7
+ import android.view.LayoutInflater
8
+ import android.view.Menu
9
+ import android.view.MenuInflater
10
+ import android.view.MenuItem
11
+ import android.view.View
12
+ import android.view.ViewGroup
13
+ import android.view.animation.Animation
14
+ import android.view.animation.AnimationSet
15
+ import android.view.animation.Transformation
16
+ import android.widget.LinearLayout
17
+ import androidx.appcompat.widget.Toolbar
18
+ import androidx.coordinatorlayout.widget.CoordinatorLayout
19
+ import com.facebook.react.uimanager.PixelUtil
20
+ import com.google.android.material.appbar.AppBarLayout
21
+ import com.google.android.material.appbar.AppBarLayout.ScrollingViewBehavior
22
+ import com.swmansion.rnscreens.utils.DeviceUtils
23
+
24
+ class ScreenStackFragment : ScreenFragment, ScreenStackFragmentWrapper {
25
+ private var mAppBarLayout: AppBarLayout? = null
26
+ private var mToolbar: Toolbar? = null
27
+ private var mShadowHidden = false
28
+ private var mIsTranslucent = false
29
+
30
+ private var mLastFocusedChild: View? = null
31
+
32
+ var searchView: CustomSearchView? = null
33
+ var onSearchViewCreate: ((searchView: CustomSearchView) -> Unit)? = null
34
+
35
+ @SuppressLint("ValidFragment")
36
+ constructor(screenView: Screen) : super(screenView)
37
+
38
+ constructor() {
39
+ throw IllegalStateException(
40
+ "ScreenStack fragments should never be restored. Follow instructions from https://github.com/software-mansion/react-native-screens/issues/17#issuecomment-424704067 to properly configure your main activity."
41
+ )
42
+ }
43
+
44
+ override fun removeToolbar() {
45
+ mAppBarLayout?.let {
46
+ mToolbar?.let { toolbar ->
47
+ if (toolbar.parent === it) {
48
+ it.removeView(toolbar)
49
+ }
50
+ }
51
+ }
52
+ mToolbar = null
53
+ }
54
+
55
+ override fun setToolbar(toolbar: Toolbar) {
56
+ mAppBarLayout?.addView(toolbar)
57
+ toolbar.layoutParams = AppBarLayout.LayoutParams(
58
+ AppBarLayout.LayoutParams.MATCH_PARENT, AppBarLayout.LayoutParams.WRAP_CONTENT
59
+ ).apply { scrollFlags = 0 }
60
+ mToolbar = toolbar
61
+ }
62
+
63
+ override fun setToolbarShadowHidden(hidden: Boolean) {
64
+ if (mShadowHidden != hidden) {
65
+ mAppBarLayout?.targetElevation = if (hidden) 0f else PixelUtil.toPixelFromDIP(4f)
66
+ mShadowHidden = hidden
67
+ }
68
+ }
69
+
70
+ override fun setToolbarTranslucent(translucent: Boolean) {
71
+ if (mIsTranslucent != translucent) {
72
+ val params = screen.layoutParams
73
+ (params as CoordinatorLayout.LayoutParams).behavior =
74
+ if (translucent) null else ScrollingViewBehavior()
75
+ mIsTranslucent = translucent
76
+ }
77
+ }
78
+
79
+ override fun onContainerUpdate() {
80
+ screen.headerConfig?.onUpdate()
81
+ }
82
+
83
+ override fun onViewAnimationEnd() {
84
+ super.onViewAnimationEnd()
85
+ notifyViewAppearTransitionEnd()
86
+ }
87
+
88
+ private fun notifyViewAppearTransitionEnd() {
89
+ val screenStack = view?.parent
90
+ if (screenStack is ScreenStack) {
91
+ screenStack.onViewAppearTransitionEnd()
92
+ }
93
+ }
94
+
95
+ override fun onStart() {
96
+ mLastFocusedChild?.requestFocus()
97
+ super.onStart()
98
+ }
99
+
100
+ override fun onCreateView(
101
+ inflater: LayoutInflater,
102
+ container: ViewGroup?,
103
+ savedInstanceState: Bundle?
104
+ ): View? {
105
+ val view: ScreensCoordinatorLayout? =
106
+ context?.let { ScreensCoordinatorLayout(it, this) }
107
+
108
+ screen.layoutParams = CoordinatorLayout.LayoutParams(
109
+ LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT
110
+ ).apply { behavior = if (mIsTranslucent) null else ScrollingViewBehavior() }
111
+
112
+ view?.addView(recycleView(screen))
113
+
114
+ mAppBarLayout = context?.let { AppBarLayout(it) }?.apply {
115
+ // By default AppBarLayout will have a background color set but since we cover the whole layout
116
+ // with toolbar (that can be semi-transparent) the bar layout background color does not pay a
117
+ // role. On top of that it breaks screens animations when alfa offscreen compositing is off
118
+ // (which is the default)
119
+ setBackgroundColor(Color.TRANSPARENT)
120
+ layoutParams = AppBarLayout.LayoutParams(
121
+ AppBarLayout.LayoutParams.MATCH_PARENT, AppBarLayout.LayoutParams.WRAP_CONTENT
122
+ )
123
+ }
124
+
125
+ view?.addView(mAppBarLayout)
126
+ if (mShadowHidden) {
127
+ mAppBarLayout?.targetElevation = 0f
128
+ }
129
+ mToolbar?.let { mAppBarLayout?.addView(recycleView(it)) }
130
+ setHasOptionsMenu(true)
131
+ return view
132
+ }
133
+
134
+ override fun onStop() {
135
+ if (DeviceUtils.isPlatformAndroidTV(context))
136
+ mLastFocusedChild = findLastFocusedChild()
137
+
138
+ super.onStop()
139
+ }
140
+
141
+ override fun onPrepareOptionsMenu(menu: Menu) {
142
+ updateToolbarMenu(menu)
143
+ return super.onPrepareOptionsMenu(menu)
144
+ }
145
+
146
+ override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
147
+ updateToolbarMenu(menu)
148
+ return super.onCreateOptionsMenu(menu, inflater)
149
+ }
150
+
151
+ private fun shouldShowSearchBar(): Boolean {
152
+ val config = screen.headerConfig
153
+ val numberOfSubViews = config?.configSubviewsCount ?: 0
154
+ if (config != null && numberOfSubViews > 0) {
155
+ for (i in 0 until numberOfSubViews) {
156
+ val subView = config.getConfigSubview(i)
157
+ if (subView.type == ScreenStackHeaderSubview.Type.SEARCH_BAR) {
158
+ return true
159
+ }
160
+ }
161
+ }
162
+ return false
163
+ }
164
+
165
+ private fun updateToolbarMenu(menu: Menu) {
166
+ menu.clear()
167
+ if (shouldShowSearchBar()) {
168
+ val currentContext = context
169
+ if (searchView == null && currentContext != null) {
170
+ val newSearchView = CustomSearchView(currentContext, this)
171
+ searchView = newSearchView
172
+ onSearchViewCreate?.invoke(newSearchView)
173
+ }
174
+ menu.add("").apply {
175
+ setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)
176
+ actionView = searchView
177
+ }
178
+ }
179
+ }
180
+
181
+ private fun findLastFocusedChild(): View? {
182
+ var view: View? = screen
183
+ while (view != null) {
184
+ if (view.isFocused) return view
185
+ view = if (view is ViewGroup) view.focusedChild else null
186
+ }
187
+
188
+ return null
189
+ }
190
+
191
+ override fun canNavigateBack(): Boolean {
192
+ val container: ScreenContainer? = screen.container
193
+ check(container is ScreenStack) { "ScreenStackFragment added into a non-stack container" }
194
+ return if (container.rootScreen == screen) {
195
+ // this screen is the root of the container, if it is nested we can check parent container
196
+ // if it is also a root or not
197
+ val parentFragment = parentFragment
198
+ if (parentFragment is ScreenStackFragment) {
199
+ parentFragment.canNavigateBack()
200
+ } else {
201
+ false
202
+ }
203
+ } else {
204
+ true
205
+ }
206
+ }
207
+
208
+ override fun dismiss() {
209
+ val container: ScreenContainer? = screen.container
210
+ check(container is ScreenStack) { "ScreenStackFragment added into a non-stack container" }
211
+ container.dismiss(this)
212
+ }
213
+
214
+ private class ScreensCoordinatorLayout(
215
+ context: Context,
216
+ private val mFragment: ScreenFragment
217
+ ) : CoordinatorLayout(context) {
218
+ private val mAnimationListener: Animation.AnimationListener =
219
+ object : Animation.AnimationListener {
220
+ override fun onAnimationStart(animation: Animation) {
221
+ mFragment.onViewAnimationStart()
222
+ }
223
+
224
+ override fun onAnimationEnd(animation: Animation) {
225
+ mFragment.onViewAnimationEnd()
226
+ }
227
+
228
+ override fun onAnimationRepeat(animation: Animation) {}
229
+ }
230
+
231
+ override fun startAnimation(animation: Animation) {
232
+ // For some reason View##onAnimationEnd doesn't get called for
233
+ // exit transitions so we explicitly attach animation listener.
234
+ // We also have some animations that are an AnimationSet, so we don't wrap them
235
+ // in another set since it causes some visual glitches when going forward.
236
+ // We also set the listener only when going forward, since when going back,
237
+ // there is already a listener for dismiss action added, which would be overridden
238
+ // and also this is not necessary when going back since the lifecycle methods
239
+ // are correctly dispatched then.
240
+ // We also add fakeAnimation to the set of animations, which sends the progress of animation
241
+ val fakeAnimation = ScreensAnimation(mFragment).apply { duration = animation.duration }
242
+
243
+ if (animation is AnimationSet && !mFragment.isRemoving) {
244
+ animation.apply {
245
+ addAnimation(fakeAnimation)
246
+ setAnimationListener(mAnimationListener)
247
+ }.also {
248
+ super.startAnimation(it)
249
+ }
250
+ } else {
251
+ AnimationSet(true).apply {
252
+ addAnimation(animation)
253
+ addAnimation(fakeAnimation)
254
+ setAnimationListener(mAnimationListener)
255
+ }.also {
256
+ super.startAnimation(it)
257
+ }
258
+ }
259
+ }
260
+
261
+ /**
262
+ * This method implements a workaround for RN's autoFocus functionality. Because of the way
263
+ * autoFocus is implemented it dismisses soft keyboard in fragment transition
264
+ * due to change of visibility of the view at the start of the transition. Here we override the
265
+ * call to `clearFocus` when the visibility of view is `INVISIBLE` since `clearFocus` triggers the
266
+ * hiding of the keyboard in `ReactEditText.java`.
267
+ */
268
+ override fun clearFocus() {
269
+ if (visibility != INVISIBLE) {
270
+ super.clearFocus()
271
+ }
272
+ }
273
+ }
274
+
275
+ private class ScreensAnimation(private val mFragment: ScreenFragment) : Animation() {
276
+ override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
277
+ super.applyTransformation(interpolatedTime, t)
278
+ // interpolated time should be the progress of the current transition
279
+ mFragment.dispatchTransitionProgressEvent(interpolatedTime, !mFragment.isResumed)
280
+ }
281
+ }
282
+ }
@@ -0,0 +1,15 @@
1
+ package com.swmansion.rnscreens
2
+
3
+ import androidx.appcompat.widget.Toolbar
4
+
5
+ interface ScreenStackFragmentWrapper : ScreenFragmentWrapper {
6
+ // Toolbar management
7
+ fun removeToolbar()
8
+ fun setToolbar(toolbar: Toolbar)
9
+ fun setToolbarShadowHidden(hidden: Boolean)
10
+ fun setToolbarTranslucent(translucent: Boolean)
11
+
12
+ // Navigation
13
+ fun canNavigateBack(): Boolean
14
+ fun dismiss()
15
+ }
@@ -0,0 +1,398 @@
1
+ package com.swmansion.rnscreens
2
+
3
+ import android.content.Context
4
+ import android.graphics.PorterDuff
5
+ import android.os.Build
6
+ import android.text.TextUtils
7
+ import android.util.TypedValue
8
+ import android.view.Gravity
9
+ import android.view.View.OnClickListener
10
+ import android.view.ViewGroup
11
+ import android.widget.ImageView
12
+ import android.widget.TextView
13
+ import androidx.appcompat.app.AppCompatActivity
14
+ import androidx.appcompat.widget.Toolbar
15
+ import androidx.fragment.app.Fragment
16
+ import com.facebook.react.ReactApplication
17
+ import com.facebook.react.bridge.JSApplicationIllegalArgumentException
18
+ import com.facebook.react.bridge.ReactContext
19
+ import com.facebook.react.uimanager.UIManagerHelper
20
+ import com.facebook.react.views.text.ReactTypefaceUtils
21
+ import com.swmansion.rnscreens.events.HeaderAttachedEvent
22
+ import com.swmansion.rnscreens.events.HeaderDetachedEvent
23
+
24
+ class ScreenStackHeaderConfig(context: Context) : ViewGroup(context) {
25
+ private val mConfigSubviews = ArrayList<ScreenStackHeaderSubview>(3)
26
+ val toolbar: CustomToolbar
27
+ private var headerTopInset: Int? = null
28
+ private var mTitle: String? = null
29
+ private var mTitleColor = 0
30
+ private var mTitleFontFamily: String? = null
31
+ private var mDirection: String? = null
32
+ private var mTitleFontSize = 0f
33
+ private var mTitleFontWeight = 0
34
+ private var mBackgroundColor: Int? = null
35
+ private var mIsHidden = false
36
+ private var mIsBackButtonHidden = false
37
+ private var mIsShadowHidden = false
38
+ private var mDestroyed = false
39
+ private var mBackButtonInCustomView = false
40
+ private var mIsTopInsetEnabled = true
41
+ private var mIsTranslucent = false
42
+ private var mTintColor = 0
43
+ private var mIsAttachedToWindow = false
44
+ private val mDefaultStartInset: Int
45
+ private val mDefaultStartInsetWithNavigation: Int
46
+ private val mBackClickListener = OnClickListener {
47
+ screenFragment?.let {
48
+ val stack = screenStack
49
+ if (stack != null && stack.rootScreen == it.screen) {
50
+ val parentFragment = it.parentFragment
51
+ if (parentFragment is ScreenStackFragment) {
52
+ if (parentFragment.screen.nativeBackButtonDismissalEnabled) {
53
+ parentFragment.dismiss()
54
+ } else {
55
+ parentFragment.dispatchHeaderBackButtonClickedEvent()
56
+ }
57
+ }
58
+ } else {
59
+ if (it.screen.nativeBackButtonDismissalEnabled) {
60
+ it.dismiss()
61
+ } else {
62
+ it.dispatchHeaderBackButtonClickedEvent()
63
+ }
64
+ }
65
+ }
66
+ }
67
+
68
+ override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
69
+ // no-op
70
+ }
71
+
72
+ fun destroy() {
73
+ mDestroyed = true
74
+ }
75
+
76
+ override fun onAttachedToWindow() {
77
+ super.onAttachedToWindow()
78
+ mIsAttachedToWindow = true
79
+ val surfaceId = UIManagerHelper.getSurfaceId(this)
80
+ UIManagerHelper.getEventDispatcherForReactTag(context as ReactContext, id)
81
+ ?.dispatchEvent(HeaderAttachedEvent(surfaceId, id))
82
+ // we want to save the top inset before the status bar can be hidden, which would resolve in
83
+ // inset being 0
84
+ if (headerTopInset == null) {
85
+ headerTopInset = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
86
+ rootWindowInsets.systemWindowInsetTop
87
+ else
88
+ // Hacky fallback for old android. Before Marshmallow, the status bar height was always 25
89
+ (25 * resources.displayMetrics.density).toInt()
90
+ }
91
+ onUpdate()
92
+ }
93
+
94
+ override fun onDetachedFromWindow() {
95
+ super.onDetachedFromWindow()
96
+ mIsAttachedToWindow = false
97
+ val surfaceId = UIManagerHelper.getSurfaceId(this)
98
+ UIManagerHelper.getEventDispatcherForReactTag(context as ReactContext, id)
99
+ ?.dispatchEvent(HeaderDetachedEvent(surfaceId, id))
100
+ }
101
+
102
+ private val screen: Screen?
103
+ get() = parent as? Screen
104
+ private val screenStack: ScreenStack?
105
+ get() = screen?.container as? ScreenStack
106
+ val screenFragment: ScreenStackFragment?
107
+ get() {
108
+ val screen = parent
109
+ if (screen is Screen) {
110
+ val fragment: Fragment? = screen.fragment
111
+ if (fragment is ScreenStackFragment) {
112
+ return fragment
113
+ }
114
+ }
115
+ return null
116
+ }
117
+
118
+ fun onUpdate() {
119
+ val stack = screenStack
120
+ val isTop = stack == null || stack.topScreen == parent
121
+
122
+ if (!mIsAttachedToWindow || !isTop || mDestroyed) {
123
+ return
124
+ }
125
+
126
+ val activity = screenFragment?.activity as AppCompatActivity? ?: return
127
+ if (mDirection != null) {
128
+ if (mDirection == "rtl") {
129
+ toolbar.layoutDirection = LAYOUT_DIRECTION_RTL
130
+ } else if (mDirection == "ltr") {
131
+ toolbar.layoutDirection = LAYOUT_DIRECTION_LTR
132
+ }
133
+ }
134
+
135
+ // orientation and status bar management
136
+ screen?.let {
137
+ // we set the traits here too, not only when the prop for Screen is passed
138
+ // because sometimes we don't have the Fragment and Activity available then yet, e.g. on the
139
+ // first setting of props. Similar thing is done for Screens of ScreenContainers, but in
140
+ // `onContainerUpdate` of their Fragment
141
+ val reactContext = if (context is ReactContext) {
142
+ context as ReactContext
143
+ } else {
144
+ it.fragmentWrapper?.tryGetContext()
145
+ }
146
+ ScreenWindowTraits.trySetWindowTraits(it, activity, reactContext)
147
+ }
148
+
149
+ if (mIsHidden) {
150
+ if (toolbar.parent != null) {
151
+ screenFragment?.removeToolbar()
152
+ }
153
+ return
154
+ }
155
+
156
+ if (toolbar.parent == null) {
157
+ screenFragment?.setToolbar(toolbar)
158
+ }
159
+
160
+ if (mIsTopInsetEnabled) {
161
+ headerTopInset.let {
162
+ toolbar.setPadding(0, it ?: 0, 0, 0)
163
+ }
164
+ } else {
165
+ if (toolbar.paddingTop > 0) {
166
+ toolbar.setPadding(0, 0, 0, 0)
167
+ }
168
+ }
169
+
170
+ activity.setSupportActionBar(toolbar)
171
+ // non-null toolbar is set in the line above and it is used here
172
+ val actionBar = requireNotNull(activity.supportActionBar)
173
+
174
+ // Reset toolbar insets. By default we set symmetric inset for start and end to match iOS
175
+ // implementation where both right and left icons are offset from the edge by default. We also
176
+ // reset startWithNavigation inset which corresponds to the distance between navigation icon and
177
+ // title. If title isn't set we clear that value few lines below to give more space to custom
178
+ // center-mounted views.
179
+ toolbar.contentInsetStartWithNavigation = mDefaultStartInsetWithNavigation
180
+ toolbar.setContentInsetsRelative(mDefaultStartInset, mDefaultStartInset)
181
+
182
+ // hide back button
183
+ actionBar.setDisplayHomeAsUpEnabled(
184
+ screenFragment?.canNavigateBack() == true && !mIsBackButtonHidden
185
+ )
186
+
187
+ // when setSupportActionBar is called a toolbar wrapper gets initialized that overwrites
188
+ // navigation click listener. The default behavior set in the wrapper is to call into
189
+ // menu options handlers, but we prefer the back handling logic to stay here instead.
190
+ toolbar.setNavigationOnClickListener(mBackClickListener)
191
+
192
+ // shadow
193
+ screenFragment?.setToolbarShadowHidden(mIsShadowHidden)
194
+
195
+ // translucent
196
+ screenFragment?.setToolbarTranslucent(mIsTranslucent)
197
+
198
+ // title
199
+ actionBar.title = mTitle
200
+ if (TextUtils.isEmpty(mTitle)) {
201
+ // if title is empty we set start navigation inset to 0 to give more space to custom rendered
202
+ // views. When it is set to default it'd take up additional distance from the back button
203
+ // which would impact the position of custom header views rendered at the center.
204
+ toolbar.contentInsetStartWithNavigation = 0
205
+ }
206
+
207
+ val titleTextView = titleTextView
208
+ if (mTitleColor != 0) {
209
+ toolbar.setTitleTextColor(mTitleColor)
210
+ }
211
+
212
+ if (titleTextView != null) {
213
+ if (mTitleFontFamily != null || mTitleFontWeight > 0) {
214
+ val titleTypeface = ReactTypefaceUtils.applyStyles(
215
+ null, 0, mTitleFontWeight, mTitleFontFamily, context.assets
216
+ )
217
+ titleTextView.typeface = titleTypeface
218
+ }
219
+ if (mTitleFontSize > 0) {
220
+ titleTextView.textSize = mTitleFontSize
221
+ }
222
+ }
223
+
224
+ // background
225
+ mBackgroundColor?.let { toolbar.setBackgroundColor(it) }
226
+
227
+ // color
228
+ if (mTintColor != 0) {
229
+ toolbar.navigationIcon?.setColorFilter(mTintColor, PorterDuff.Mode.SRC_ATOP)
230
+ }
231
+
232
+ // subviews
233
+ for (i in toolbar.childCount - 1 downTo 0) {
234
+ if (toolbar.getChildAt(i) is ScreenStackHeaderSubview) {
235
+ toolbar.removeViewAt(i)
236
+ }
237
+ }
238
+
239
+ var i = 0
240
+ val size = mConfigSubviews.size
241
+ while (i < size) {
242
+ val view = mConfigSubviews[i]
243
+ val type = view.type
244
+ if (type === ScreenStackHeaderSubview.Type.BACK) {
245
+ // we special case BACK button header config type as we don't add it as a view into toolbar
246
+ // but instead just copy the drawable from imageview that's added as a first child to it.
247
+ val firstChild = view.getChildAt(0) as? ImageView
248
+ ?: throw JSApplicationIllegalArgumentException(
249
+ "Back button header config view should have Image as first child"
250
+ )
251
+ actionBar.setHomeAsUpIndicator(firstChild.drawable)
252
+ i++
253
+ continue
254
+ }
255
+ val params = Toolbar.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT)
256
+ when (type) {
257
+ ScreenStackHeaderSubview.Type.LEFT -> {
258
+ // when there is a left item we need to disable navigation icon by default
259
+ // we also hide title as there is no other way to display left side items
260
+ if (!mBackButtonInCustomView) {
261
+ toolbar.navigationIcon = null
262
+ }
263
+ toolbar.title = null
264
+ params.gravity = Gravity.START
265
+ }
266
+ ScreenStackHeaderSubview.Type.RIGHT -> params.gravity = Gravity.END
267
+ ScreenStackHeaderSubview.Type.CENTER -> {
268
+ params.width = LayoutParams.MATCH_PARENT
269
+ params.gravity = Gravity.CENTER_HORIZONTAL
270
+ toolbar.title = null
271
+ }
272
+ else -> {}
273
+ }
274
+ view.layoutParams = params
275
+ toolbar.addView(view)
276
+ i++
277
+ }
278
+ }
279
+
280
+ private fun maybeUpdate() {
281
+ if (parent != null && !mDestroyed) {
282
+ onUpdate()
283
+ }
284
+ }
285
+
286
+ fun getConfigSubview(index: Int): ScreenStackHeaderSubview = mConfigSubviews[index]
287
+
288
+ val configSubviewsCount: Int
289
+ get() = mConfigSubviews.size
290
+
291
+ fun removeConfigSubview(index: Int) {
292
+ mConfigSubviews.removeAt(index)
293
+ maybeUpdate()
294
+ }
295
+
296
+ fun removeAllConfigSubviews() {
297
+ mConfigSubviews.clear()
298
+ maybeUpdate()
299
+ }
300
+
301
+ fun addConfigSubview(child: ScreenStackHeaderSubview, index: Int) {
302
+ mConfigSubviews.add(index, child)
303
+ maybeUpdate()
304
+ }
305
+
306
+ private val titleTextView: TextView?
307
+ get() {
308
+ for (i in 0 until toolbar.childCount) {
309
+ val view = toolbar.getChildAt(i)
310
+ if (view is TextView) {
311
+ if (view.text == toolbar.title) {
312
+ return view
313
+ }
314
+ }
315
+ }
316
+ return null
317
+ }
318
+
319
+ fun setTitle(title: String?) {
320
+ mTitle = title
321
+ }
322
+
323
+ fun setTitleFontFamily(titleFontFamily: String?) {
324
+ mTitleFontFamily = titleFontFamily
325
+ }
326
+
327
+ fun setTitleFontWeight(fontWeightString: String?) {
328
+ mTitleFontWeight = ReactTypefaceUtils.parseFontWeight(fontWeightString)
329
+ }
330
+
331
+ fun setTitleFontSize(titleFontSize: Float) {
332
+ mTitleFontSize = titleFontSize
333
+ }
334
+
335
+ fun setTitleColor(color: Int) {
336
+ mTitleColor = color
337
+ }
338
+
339
+ fun setTintColor(color: Int) {
340
+ mTintColor = color
341
+ }
342
+
343
+ fun setTopInsetEnabled(topInsetEnabled: Boolean) {
344
+ mIsTopInsetEnabled = topInsetEnabled
345
+ }
346
+
347
+ fun setBackgroundColor(color: Int?) {
348
+ mBackgroundColor = color
349
+ }
350
+
351
+ fun setHideShadow(hideShadow: Boolean) {
352
+ mIsShadowHidden = hideShadow
353
+ }
354
+
355
+ fun setHideBackButton(hideBackButton: Boolean) {
356
+ mIsBackButtonHidden = hideBackButton
357
+ }
358
+
359
+ fun setHidden(hidden: Boolean) {
360
+ mIsHidden = hidden
361
+ }
362
+
363
+ fun setTranslucent(translucent: Boolean) {
364
+ mIsTranslucent = translucent
365
+ }
366
+
367
+ fun setBackButtonInCustomView(backButtonInCustomView: Boolean) {
368
+ mBackButtonInCustomView = backButtonInCustomView
369
+ }
370
+
371
+ fun setDirection(direction: String?) {
372
+ mDirection = direction
373
+ }
374
+
375
+ private class DebugMenuToolbar(context: Context, config: ScreenStackHeaderConfig) : CustomToolbar(context, config) {
376
+ override fun showOverflowMenu(): Boolean {
377
+ (context.applicationContext as ReactApplication)
378
+ .reactNativeHost
379
+ .reactInstanceManager
380
+ .showDevOptionsDialog()
381
+ return true
382
+ }
383
+ }
384
+
385
+ init {
386
+ visibility = GONE
387
+ toolbar = if (BuildConfig.DEBUG) DebugMenuToolbar(context, this) else CustomToolbar(context, this)
388
+ mDefaultStartInset = toolbar.contentInsetStart
389
+ mDefaultStartInsetWithNavigation = toolbar.contentInsetStartWithNavigation
390
+
391
+ // set primary color as background by default
392
+ val tv = TypedValue()
393
+ if (context.theme.resolveAttribute(R.attr.colorPrimary, tv, true)) {
394
+ toolbar.setBackgroundColor(tv.data)
395
+ }
396
+ toolbar.clipChildren = false
397
+ }
398
+ }