react-native-screens 5.0.0-alpha.2 → 5.0.0-alpha.3

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 (237) hide show
  1. package/Package.swift +87 -0
  2. package/README.md +0 -7
  3. package/android/src/main/cpp/NativeProxy.cpp +30 -6
  4. package/android/src/main/cpp/NativeProxy.h +7 -1
  5. package/android/src/main/java/com/swmansion/rnscreens/common/container/Container.kt +8 -0
  6. package/android/src/main/java/com/swmansion/rnscreens/common/container/ContainerItem.kt +13 -1
  7. package/android/src/main/java/com/swmansion/rnscreens/common/text/ReactTextAppearance.kt +62 -0
  8. package/android/src/main/java/com/swmansion/rnscreens/common/text/TextAppearance.kt +20 -0
  9. package/android/src/main/java/com/swmansion/rnscreens/common/text/TextAppearanceDefaults.kt +65 -0
  10. package/android/src/main/java/com/swmansion/rnscreens/helpers/PropIconResolver.kt +17 -23
  11. package/android/src/main/java/com/swmansion/rnscreens/legacy/Screen.kt +3 -1
  12. package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenStack.kt +2 -0
  13. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/coordinator/FormSheetBehaviorController.kt +49 -18
  14. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/coordinator/FormSheetDimensionsCoordinator.kt +65 -40
  15. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/coordinator/FormSheetKeyboardCoordinator.kt +101 -0
  16. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/coordinator/FormSheetNativeDismissCoordinator.kt +0 -6
  17. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/core/FormSheetAvailableHeightProvider.kt +44 -0
  18. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/core/FormSheetDialog.kt +35 -3
  19. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/core/FormSheetDialogManager.kt +33 -106
  20. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/interfaces/FormSheetDialogEventEmitter.kt +2 -0
  21. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/model/FormSheetDetents.kt +61 -15
  22. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/presentation/FormSheetAnimatorFactory.kt +8 -9
  23. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/presentation/FormSheetDimmingManager.kt +115 -0
  24. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/presentation/FormSheetDismissalOrigin.kt +22 -0
  25. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/presentation/FormSheetPresentation.kt +173 -0
  26. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/presentation/FormSheetPresentationManager.kt +141 -49
  27. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/presentation/FormSheetPresentationState.kt +1 -1
  28. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/presentation/FormSheetStackRegistry.kt +28 -0
  29. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/react/event/FormSheetDismissEvent.kt +29 -0
  30. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/react/host/FormSheetHostEventEmitter.kt +7 -0
  31. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/react/host/FormSheetHostViewManager.kt +2 -0
  32. package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderApplicator.kt +369 -58
  33. package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderBackPressHandler.kt +11 -0
  34. package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderCoordinatorLayout.kt +143 -98
  35. package/android/src/main/java/com/swmansion/rnscreens/stack/header/appbar/StackHeaderAppBarLayout.kt +155 -23
  36. package/android/src/main/java/com/swmansion/rnscreens/stack/header/appbar/StackHeaderContentScrimDrawable.kt +36 -0
  37. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderCollapsedTitleGravityMode.kt +6 -0
  38. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfig.kt +170 -167
  39. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigViewManager.kt +385 -12
  40. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigurationObserver.kt +0 -4
  41. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigurationProviding.kt +32 -3
  42. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderDelegate.kt +0 -7
  43. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderInvalidationFlags.kt +7 -2
  44. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuApplicator.kt +27 -280
  45. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuController.kt +448 -0
  46. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuDelegate.kt +10 -0
  47. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuMapper.kt +28 -20
  48. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/model/StackHeaderToolbarMenuConfig.kt +3 -55
  49. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/model/StackHeaderToolbarMenuGroupMetadata.kt +1 -10
  50. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/model/StackHeaderToolbarMenuItemConfig.kt +1 -3
  51. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/model/StackHeaderToolbarMenuModel.kt +180 -0
  52. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuElementOptions.kt +57 -6
  53. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuElementRawUpdate.kt +3 -1
  54. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuElementUpdate.kt +1 -0
  55. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuIconResolver.kt +4 -3
  56. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuUpdateQueue.kt +23 -9
  57. package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackContainer.kt +103 -3
  58. package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackHost.kt +13 -0
  59. package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackHostViewManager.kt +14 -0
  60. package/android/src/main/java/com/swmansion/rnscreens/stack/screen/StackScreen.kt +4 -0
  61. package/android/src/main/java/com/swmansion/rnscreens/stack/screen/StackScreenFragment.kt +20 -1
  62. package/android/src/main/java/com/swmansion/rnscreens/stack/screen/StackScreenFragmentDelegate.kt +12 -0
  63. package/android/src/main/java/com/swmansion/rnscreens/tabs/appearance/TabsAppearanceCoordinator.kt +2 -4
  64. package/android/src/main/java/com/swmansion/rnscreens/tabs/container/MenuHelpers.kt +5 -23
  65. package/android/src/main/java/com/swmansion/rnscreens/tabs/container/TabsContainer.kt +46 -25
  66. package/android/src/main/java/com/swmansion/rnscreens/tabs/host/TabsHost.kt +10 -0
  67. package/android/src/main/java/com/swmansion/rnscreens/tabs/host/TabsHostA11yCoordinator.kt +23 -2
  68. package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreen.kt +17 -0
  69. package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreenFragment.kt +3 -0
  70. package/android/src/main/java/com/swmansion/rnscreens/utils/DimensionUtils.kt +7 -0
  71. package/android/src/main/java/com/swmansion/rnscreens/utils/StyleUtils.kt +22 -0
  72. package/android/src/main/res/base/layout/rns_collapsing_toolbar_large_available_space.xml +8 -0
  73. package/android/src/main/res/base/layout/rns_collapsing_toolbar_large_entire_space.xml +8 -0
  74. package/android/src/main/res/base/layout/rns_collapsing_toolbar_medium_available_space.xml +8 -0
  75. package/android/src/main/res/base/layout/rns_collapsing_toolbar_medium_entire_space.xml +8 -0
  76. package/cpp/legacy/RNSScreenRemovalListener.cpp +31 -1
  77. package/cpp/legacy/RNSScreenRemovalListener.h +18 -3
  78. package/ios/RNSEnums.h +2 -0
  79. package/ios/conversion/RNSConversions.h +7 -108
  80. package/ios/legacy/RNSFullWindowOverlay.mm +1 -1
  81. package/ios/legacy/RNSModalScreen.mm +1 -1
  82. package/ios/legacy/RNSScreen.mm +8 -19
  83. package/ios/legacy/RNSScreenStackHeaderConfig.mm +3 -1
  84. package/ios/legacy/RNSScreenStackHeaderSubview.mm +1 -1
  85. package/ios/legacy/RNSScreenWindowTraits.mm +5 -13
  86. package/ios/modals/form-sheet/RNSFormSheetConfigurationApplicator.h +1 -3
  87. package/ios/modals/form-sheet/RNSFormSheetConfigurationApplicator.mm +11 -22
  88. package/ios/modals/form-sheet/RNSFormSheetContentController.h +1 -1
  89. package/ios/modals/form-sheet/RNSFormSheetContentController.mm +7 -18
  90. package/ios/modals/form-sheet/RNSFormSheetHostComponentView.mm +4 -4
  91. package/ios/modals/form-sheet/RNSFormSheetHostShadowStateProxy.mm +2 -2
  92. package/ios/modals/form-sheet/RNSFormSheetUpdateFlags.h +3 -0
  93. package/ios/safe-area/RNSSafeAreaViewComponentView.mm +2 -2
  94. package/ios/{conversion → scroll-view-marker/conversion}/RNSConversions-ScrollViewMarker.mm +2 -3
  95. package/ios/split/RNSSplitAppearanceApplicator.h +4 -4
  96. package/ios/split/RNSSplitAppearanceApplicator.mm +53 -56
  97. package/ios/split/RNSSplitHostComponentEventEmitter.h +1 -0
  98. package/ios/split/RNSSplitHostComponentEventEmitter.mm +1 -1
  99. package/ios/split/RNSSplitHostComponentView.h +5 -15
  100. package/ios/split/RNSSplitHostComponentView.mm +55 -6
  101. package/ios/split/RNSSplitHostController.h +25 -6
  102. package/ios/split/RNSSplitHostController.mm +24 -92
  103. package/ios/split/RNSSplitHostProviders.h +67 -0
  104. package/ios/split/RNSSplitScreenComponentView.h +0 -39
  105. package/ios/split/RNSSplitScreenComponentView.mm +27 -10
  106. package/ios/split/RNSSplitScreenController.h +26 -3
  107. package/ios/split/RNSSplitScreenController.mm +13 -30
  108. package/ios/split/RNSSplitScreenShadowStateProxy.h +1 -40
  109. package/ios/split/RNSSplitScreenShadowStateProxy.mm +1 -26
  110. package/ios/split/conversion/RNSConversions-SplitView.h +56 -0
  111. package/ios/{conversion → split/conversion}/RNSConversions-SplitView.mm +4 -1
  112. package/ios/stack/conversion/RNSConversions-Stack.h +32 -0
  113. package/ios/stack/conversion/RNSConversions-Stack.mm +55 -0
  114. package/ios/stack/header/RNSStackHeaderAppearanceMapper.h +26 -0
  115. package/ios/stack/header/RNSStackHeaderAppearanceMapper.mm +88 -0
  116. package/ios/stack/header/RNSStackHeaderConfigComponentView.h +10 -1
  117. package/ios/stack/header/RNSStackHeaderConfigComponentView.mm +67 -35
  118. package/ios/stack/header/RNSStackHeaderConfigDataProviding.h +6 -0
  119. package/ios/stack/header/RNSStackHeaderConfigShadowStateProxy.mm +1 -1
  120. package/ios/stack/header/RNSStackHeaderIconResolver.mm +7 -0
  121. package/ios/stack/header/RNSStackHeaderItemComponentView.h +3 -1
  122. package/ios/stack/header/RNSStackHeaderItemComponentView.mm +15 -2
  123. package/ios/stack/header/RNSStackHeaderItemDataProviding.h +2 -0
  124. package/ios/stack/header/RNSStackHeaderItemShadowStateProxy.mm +1 -1
  125. package/ios/stack/header/RNSStackHeaderItemSpacerComponentView.mm +2 -1
  126. package/ios/stack/header/RNSStackHeaderMenuMapper.mm +4 -0
  127. package/ios/stack/host/RNSStackNavigationBar.h +25 -0
  128. package/ios/stack/host/RNSStackNavigationBar.mm +80 -0
  129. package/ios/stack/host/RNSStackNavigationBarCoordinator.h +8 -0
  130. package/ios/stack/host/RNSStackNavigationBarCoordinator.mm +11 -0
  131. package/ios/stack/host/RNSStackNavigationController.mm +13 -5
  132. package/ios/stack/host/RNSStackOperation.h +0 -2
  133. package/ios/stack/screen/RNSStackScreenComponentView.mm +9 -2
  134. package/ios/stack/screen/RNSStackScreenController.mm +12 -0
  135. package/ios/stack/screen/RNSStackScreenHeaderCoordinator.h +8 -0
  136. package/ios/stack/screen/RNSStackScreenHeaderCoordinator.mm +98 -16
  137. package/ios/tabs/RNSTabBarAppearanceCoordinator.mm +40 -9
  138. package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryComponentView.h +1 -1
  139. package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryComponentView.mm +1 -1
  140. package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryContentComponentView.mm +1 -1
  141. package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryEventEmitter.mm +1 -1
  142. package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryShadowStateProxy.mm +1 -1
  143. package/ios/tabs/conversion/RNSConversions-Tabs.h +78 -0
  144. package/ios/{conversion → tabs/conversion}/RNSConversions-Tabs.mm +8 -71
  145. package/ios/tabs/extensions/RNSTabsHostComponentView+RNSImageLoader.h +1 -1
  146. package/ios/tabs/host/RNSTabsHostComponentView.h +2 -0
  147. package/ios/tabs/host/RNSTabsHostComponentView.mm +10 -3
  148. package/ios/tabs/host/RNSTabsHostEventEmitter.mm +1 -1
  149. package/ios/tabs/screen/RNSTabsScreenComponentView.mm +20 -5
  150. package/ios/utils/RNSDefines.h +3 -0
  151. package/lib/commonjs/components/stack/header/StackHeaderConfig.android.js +34 -19
  152. package/lib/commonjs/components/stack/header/StackHeaderConfig.android.js.map +1 -1
  153. package/lib/commonjs/components/stack/header/StackHeaderConfig.ios.js +33 -1
  154. package/lib/commonjs/components/stack/header/StackHeaderConfig.ios.js.map +1 -1
  155. package/lib/commonjs/components/stack/host/StackHost.js +9 -6
  156. package/lib/commonjs/components/stack/host/StackHost.js.map +1 -1
  157. package/lib/commonjs/components/stack/index.js.map +1 -1
  158. package/lib/commonjs/components/tabs/host/TabsHost.ios.js +1 -0
  159. package/lib/commonjs/components/tabs/host/TabsHost.ios.js.map +1 -1
  160. package/lib/commonjs/fabric/stack/StackHeaderConfigAndroidNativeComponent.js.map +1 -1
  161. package/lib/commonjs/fabric/stack/StackHeaderConfigIOSNativeComponent.js.map +1 -1
  162. package/lib/commonjs/fabric/stack/StackHeaderItemIOSNativeComponent.js.map +1 -1
  163. package/lib/commonjs/fabric/stack/StackHostNativeComponent.js.map +1 -1
  164. package/lib/commonjs/fabric/tabs/TabsHostIOSNativeComponent.js.map +1 -1
  165. package/lib/module/components/stack/header/StackHeaderConfig.android.js +35 -20
  166. package/lib/module/components/stack/header/StackHeaderConfig.android.js.map +1 -1
  167. package/lib/module/components/stack/header/StackHeaderConfig.ios.js +34 -2
  168. package/lib/module/components/stack/header/StackHeaderConfig.ios.js.map +1 -1
  169. package/lib/module/components/stack/host/StackHost.js +9 -6
  170. package/lib/module/components/stack/host/StackHost.js.map +1 -1
  171. package/lib/module/components/stack/index.js.map +1 -1
  172. package/lib/module/components/tabs/host/TabsHost.ios.js +1 -0
  173. package/lib/module/components/tabs/host/TabsHost.ios.js.map +1 -1
  174. package/lib/module/fabric/stack/StackHeaderConfigAndroidNativeComponent.js.map +1 -1
  175. package/lib/module/fabric/stack/StackHeaderConfigIOSNativeComponent.js.map +1 -1
  176. package/lib/module/fabric/stack/StackHeaderItemIOSNativeComponent.js.map +1 -1
  177. package/lib/module/fabric/stack/StackHostNativeComponent.js.map +1 -1
  178. package/lib/module/fabric/tabs/TabsHostIOSNativeComponent.js.map +1 -1
  179. package/lib/typescript/components/modals/form-sheet/FormSheet.types.d.ts +1 -1
  180. package/lib/typescript/components/stack/header/StackHeaderConfig.android.d.ts.map +1 -1
  181. package/lib/typescript/components/stack/header/StackHeaderConfig.android.types.d.ts +616 -21
  182. package/lib/typescript/components/stack/header/StackHeaderConfig.android.types.d.ts.map +1 -1
  183. package/lib/typescript/components/stack/header/StackHeaderConfig.ios.d.ts.map +1 -1
  184. package/lib/typescript/components/stack/header/StackHeaderConfig.ios.types.d.ts +226 -2
  185. package/lib/typescript/components/stack/header/StackHeaderConfig.ios.types.d.ts.map +1 -1
  186. package/lib/typescript/components/stack/header/StackHeaderConfig.types.d.ts +2 -2
  187. package/lib/typescript/components/stack/header/ios/StackHeaderItem.ios.types.d.ts +2 -0
  188. package/lib/typescript/components/stack/header/ios/StackHeaderItem.ios.types.d.ts.map +1 -1
  189. package/lib/typescript/components/stack/host/StackHost.d.ts +1 -1
  190. package/lib/typescript/components/stack/host/StackHost.d.ts.map +1 -1
  191. package/lib/typescript/components/stack/host/StackHost.types.d.ts +24 -0
  192. package/lib/typescript/components/stack/host/StackHost.types.d.ts.map +1 -1
  193. package/lib/typescript/components/stack/index.d.ts +2 -2
  194. package/lib/typescript/components/stack/index.d.ts.map +1 -1
  195. package/lib/typescript/components/tabs/host/TabsHost.ios.d.ts.map +1 -1
  196. package/lib/typescript/components/tabs/host/TabsHost.ios.types.d.ts +16 -0
  197. package/lib/typescript/components/tabs/host/TabsHost.ios.types.d.ts.map +1 -1
  198. package/lib/typescript/components/tabs/host/TabsHost.types.d.ts +3 -0
  199. package/lib/typescript/components/tabs/host/TabsHost.types.d.ts.map +1 -1
  200. package/lib/typescript/fabric/stack/StackHeaderConfigAndroidNativeComponent.d.ts +52 -0
  201. package/lib/typescript/fabric/stack/StackHeaderConfigAndroidNativeComponent.d.ts.map +1 -1
  202. package/lib/typescript/fabric/stack/StackHeaderConfigIOSNativeComponent.d.ts +25 -1
  203. package/lib/typescript/fabric/stack/StackHeaderConfigIOSNativeComponent.d.ts.map +1 -1
  204. package/lib/typescript/fabric/stack/StackHeaderItemIOSNativeComponent.d.ts +2 -0
  205. package/lib/typescript/fabric/stack/StackHeaderItemIOSNativeComponent.d.ts.map +1 -1
  206. package/lib/typescript/fabric/stack/StackHostNativeComponent.d.ts +3 -1
  207. package/lib/typescript/fabric/stack/StackHostNativeComponent.d.ts.map +1 -1
  208. package/lib/typescript/fabric/tabs/TabsHostIOSNativeComponent.d.ts +1 -0
  209. package/lib/typescript/fabric/tabs/TabsHostIOSNativeComponent.d.ts.map +1 -1
  210. package/package.json +8 -7
  211. package/react-native.config.js +3 -0
  212. package/src/components/modals/form-sheet/FormSheet.types.ts +1 -1
  213. package/src/components/stack/header/StackHeaderConfig.android.tsx +48 -23
  214. package/src/components/stack/header/StackHeaderConfig.android.types.ts +637 -21
  215. package/src/components/stack/header/StackHeaderConfig.ios.tsx +45 -1
  216. package/src/components/stack/header/StackHeaderConfig.ios.types.ts +238 -2
  217. package/src/components/stack/header/StackHeaderConfig.types.ts +2 -2
  218. package/src/components/stack/header/ios/StackHeaderItem.ios.types.ts +2 -0
  219. package/src/components/stack/host/StackHost.tsx +4 -2
  220. package/src/components/stack/host/StackHost.types.ts +26 -0
  221. package/src/components/stack/index.ts +6 -1
  222. package/src/components/tabs/host/TabsHost.ios.tsx +1 -0
  223. package/src/components/tabs/host/TabsHost.ios.types.ts +16 -0
  224. package/src/components/tabs/host/TabsHost.types.ts +3 -0
  225. package/src/fabric/stack/StackHeaderConfigAndroidNativeComponent.ts +78 -0
  226. package/src/fabric/stack/StackHeaderConfigIOSNativeComponent.ts +32 -0
  227. package/src/fabric/stack/StackHeaderItemIOSNativeComponent.ts +2 -0
  228. package/src/fabric/stack/StackHostNativeComponent.ts +11 -2
  229. package/src/fabric/tabs/TabsHostIOSNativeComponent.ts +1 -0
  230. package/android/src/main/java/com/swmansion/rnscreens/modals/dimmingview/DimmingView.kt +0 -83
  231. package/android/src/main/java/com/swmansion/rnscreens/modals/dimmingview/DimmingViewManager.kt +0 -89
  232. package/android/src/main/java/com/swmansion/rnscreens/modals/dimmingview/DimmingViewPointerEvents.kt +0 -18
  233. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuSelectionController.kt +0 -83
  234. package/ios/conversion/RNSConversions-Stack.h +0 -32
  235. package/ios/conversion/RNSConversions-Stack.mm +0 -41
  236. package/ios/conversion/always_false.h +0 -31
  237. /package/ios/{conversion → scroll-view-marker/conversion}/RNSConversions-ScrollViewMarker.h +0 -0
@@ -0,0 +1,88 @@
1
+ #import "RNSStackHeaderAppearanceMapper.h"
2
+ #import "RNSDefines.h"
3
+
4
+ #import <React/RCTConvert.h>
5
+ #import <React/RCTFont.h>
6
+
7
+ @implementation RNSStackHeaderAppearanceMapper
8
+
9
+ + (nullable UINavigationBarAppearance *)appearanceFromDictionary:(nullable NSDictionary *)appearanceDict
10
+ {
11
+ if (appearanceDict.count == 0) {
12
+ return nil;
13
+ }
14
+
15
+ UINavigationBarAppearance *appearance = [UINavigationBarAppearance new];
16
+ [self applyTextAttributesFromDictionary:appearanceDict toAppearance:appearance];
17
+ return appearance;
18
+ }
19
+
20
+ + (nullable UINavigationBarAppearance *)scrollEdgeAppearanceFromDictionary:(nullable NSDictionary *)appearanceDict
21
+ {
22
+ if (appearanceDict.count == 0) {
23
+ return nil;
24
+ }
25
+
26
+ UINavigationBarAppearance *appearance = [UINavigationBarAppearance new];
27
+
28
+ // A nil navigationItem.scrollEdgeAppearance natively resolves to the item's (or bar's)
29
+ // standard appearance with a transparent background. Start the explicit scroll edge
30
+ // appearance from the same transparent base so that a text-only appearance prop does
31
+ // not suddenly bring back the default bar background at the scroll edge.
32
+ [appearance configureWithTransparentBackground];
33
+
34
+ [self applyTextAttributesFromDictionary:appearanceDict toAppearance:appearance];
35
+ return appearance;
36
+ }
37
+
38
+ + (void)applyTextAttributesFromDictionary:(nullable NSDictionary *)appearanceDict
39
+ toAppearance:(nonnull UINavigationBarAppearance *)appearance
40
+ {
41
+ appearance.titleTextAttributes = [self textAttributes:appearance.titleTextAttributes
42
+ updatedWithDictionary:appearanceDict
43
+ keyPrefix:@"title"];
44
+ appearance.largeTitleTextAttributes = [self textAttributes:appearance.largeTitleTextAttributes
45
+ updatedWithDictionary:appearanceDict
46
+ keyPrefix:@"largeTitle"];
47
+
48
+ #if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0)
49
+ if (@available(iOS 26.0, *)) {
50
+ // UIKit derives both the regular and the large subtitle appearance from
51
+ // subtitleTextAttributes; largeSubtitleTextAttributes is ignored.
52
+ appearance.subtitleTextAttributes = [self textAttributes:appearance.subtitleTextAttributes
53
+ updatedWithDictionary:appearanceDict
54
+ keyPrefix:@"subtitle"];
55
+ }
56
+ #endif // RNS_IPHONE_OS_VERSION_AVAILABLE(26_0)
57
+ }
58
+
59
+ + (nonnull NSDictionary *)textAttributes:(nullable NSDictionary *)baseAttributes
60
+ updatedWithDictionary:(nullable NSDictionary *)appearanceDict
61
+ keyPrefix:(nonnull NSString *)keyPrefix
62
+ {
63
+ id fontFamily = appearanceDict[[keyPrefix stringByAppendingString:@"FontFamily"]];
64
+ id fontSize = appearanceDict[[keyPrefix stringByAppendingString:@"FontSize"]];
65
+ id fontWeight = appearanceDict[[keyPrefix stringByAppendingString:@"FontWeight"]];
66
+ id fontStyle = appearanceDict[[keyPrefix stringByAppendingString:@"FontStyle"]];
67
+ id fontColor = appearanceDict[[keyPrefix stringByAppendingString:@"FontColor"]];
68
+
69
+ NSMutableDictionary *textAttributes = [baseAttributes mutableCopy] ?: [NSMutableDictionary new];
70
+
71
+ if (fontFamily != nil || fontSize != nil || fontWeight != nil || fontStyle != nil) {
72
+ textAttributes[NSFontAttributeName] = [RCTFont updateFont:baseAttributes[NSFontAttributeName]
73
+ withFamily:fontFamily
74
+ size:fontSize
75
+ weight:fontWeight
76
+ style:fontStyle
77
+ variant:nil
78
+ scaleMultiplier:1.0];
79
+ }
80
+
81
+ if (fontColor != nil) {
82
+ textAttributes[NSForegroundColorAttributeName] = [RCTConvert UIColor:fontColor];
83
+ }
84
+
85
+ return textAttributes;
86
+ }
87
+
88
+ @end
@@ -5,6 +5,7 @@
5
5
  #import "RNSStackHeaderConfigDataProviding.h"
6
6
  #import "RNSStackHeaderEventsDelegate.h"
7
7
  #import "RNSStackHeaderItemInvalidationDelegate.h"
8
+ #import "RNSStackScreenHeaderCoordinator.h"
8
9
  #import "RNSViewFrameChangeDelegate.h"
9
10
 
10
11
  NS_ASSUME_NONNULL_BEGIN
@@ -21,9 +22,17 @@ NS_ASSUME_NONNULL_BEGIN
21
22
  @property (nonatomic, readonly, nullable) NSString *largeTitle;
22
23
  @property (nonatomic, readonly, nullable) NSString *largeSubtitle;
23
24
  @property (nonatomic, readonly) BOOL largeTitleEnabled;
25
+ @property (nonatomic, readonly, nullable) NSString *prompt;
26
+ @property (nonatomic, readonly, nullable) NSString *backButtonTitle;
27
+ @property (nonatomic, readonly) UINavigationItemBackButtonDisplayMode backButtonDisplayMode;
28
+ @property (nonatomic, readonly) BOOL backButtonMenuEnabled;
24
29
  @property (nonatomic, readonly, nullable) RNSStackHeaderMenuData *titleMenu;
30
+ @property (nonatomic, readonly, nullable) UINavigationBarAppearance *standardAppearance;
31
+ @property (nonatomic, readonly, nullable) UINavigationBarAppearance *scrollEdgeAppearance;
25
32
  @property (nonatomic, readonly) NSArray<id> *children;
26
33
 
34
+ @property (nonatomic, weak, nullable) RNSStackScreenHeaderCoordinator *headerCoordinator;
35
+
27
36
  - (void)resetProps;
28
37
 
29
38
  @end
@@ -34,7 +43,7 @@ NS_ASSUME_NONNULL_END
34
43
 
35
44
  #if defined(__cplusplus)
36
45
 
37
- #import <rnscreens/RNSStackHeaderConfigComponentDescriptor.h>
46
+ #import <react/renderer/components/rnscreens/RNSStackHeaderConfigComponentDescriptor.h>
38
47
 
39
48
  @interface RNSStackHeaderConfigComponentView ()
40
49
 
@@ -1,6 +1,8 @@
1
1
  #import "RNSStackHeaderConfigComponentView.h"
2
2
  #import "RNSConversions.h"
3
+ #import "RNSConversions-Stack.h"
3
4
  #import "RNSImageLoadingHelper.h"
5
+ #import "RNSStackHeaderAppearanceMapper.h"
4
6
  #import "RNSStackHeaderConfigEventEmitter.h"
5
7
  #import "RNSStackHeaderConfigShadowStateProxy.h"
6
8
  #import "RNSStackHeaderItemComponentView.h"
@@ -12,7 +14,6 @@
12
14
  #import "RNSStackNavigationController.h"
13
15
  #import "RNSStackScreenComponentView.h"
14
16
  #import "RNSStackScreenController.h"
15
- #import "RNSStackScreenHeaderCoordinator.h"
16
17
 
17
18
  #import <React/RCTConversions.h>
18
19
  #import <React/RCTConvert.h>
@@ -21,7 +22,7 @@
21
22
  #import <react/renderer/components/rnscreens/Props.h>
22
23
  #import <react/renderer/components/rnscreens/RCTComponentViewHelpers.h>
23
24
  #import <react/utils/ManagedObjectWrapper.h>
24
- #import <rnscreens/RNSStackHeaderConfigComponentDescriptor.h>
25
+ #import <react/renderer/components/rnscreens/RNSStackHeaderConfigComponentDescriptor.h>
25
26
 
26
27
  namespace react = facebook::react;
27
28
 
@@ -67,7 +68,13 @@ static void RNSAssertIsValidHeaderChild(UIView *child)
67
68
  _largeTitle = nil;
68
69
  _largeSubtitle = nil;
69
70
  _largeTitleEnabled = NO;
71
+ _prompt = nil;
72
+ _backButtonTitle = nil;
73
+ _backButtonDisplayMode = UINavigationItemBackButtonDisplayModeDefault;
74
+ _backButtonMenuEnabled = YES;
70
75
  _titleMenu = nil;
76
+ _standardAppearance = nil;
77
+ _scrollEdgeAppearance = nil;
71
78
  }
72
79
 
73
80
  - (NSArray<id> *)children
@@ -123,18 +130,7 @@ static void RNSAssertIsValidHeaderChild(UIView *child)
123
130
  {
124
131
  if (self.window != nil) {
125
132
  [[self requireNavigationController] setNavigationBarFrameChangeDelegate:self];
126
- RNSStackScreenHeaderCoordinator *coordinator = [self headerCoordinator];
127
- coordinator.configDataProvider = self;
128
- coordinator.frameChangeDelegate = self;
129
- coordinator.eventsDelegate = self;
130
- coordinator.imageLoader = self;
131
- [coordinator rebuild];
132
- } else {
133
- RNSStackScreenHeaderCoordinator *coordinator = [self headerCoordinator];
134
- coordinator.configDataProvider = nil;
135
- coordinator.frameChangeDelegate = nil;
136
- coordinator.eventsDelegate = nil;
137
- coordinator.imageLoader = nil;
133
+ [self.headerCoordinator rebuild];
138
134
  }
139
135
  [super didMoveToWindow];
140
136
  }
@@ -155,7 +151,7 @@ static void RNSAssertIsValidHeaderChild(UIView *child)
155
151
  ((RNSStackHeaderItemSpacerComponentView *)childComponentView).invalidationDelegate = self;
156
152
  }
157
153
 
158
- [[self headerCoordinator] rebuild];
154
+ [self.headerCoordinator rebuild];
159
155
  }
160
156
 
161
157
  - (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
@@ -169,7 +165,7 @@ static void RNSAssertIsValidHeaderChild(UIView *child)
169
165
  }
170
166
 
171
167
  [_children removeObjectAtIndex:index];
172
- [[self headerCoordinator] rebuild];
168
+ [self.headerCoordinator rebuild];
173
169
  }
174
170
 
175
171
  #pragma mark - RNSStackHeaderItemInvalidationDelegate
@@ -178,22 +174,21 @@ static void RNSAssertIsValidHeaderChild(UIView *child)
178
174
  {
179
175
  if (itemId == nil) {
180
176
  RCTLogWarn(@"[RNScreens] headerItemDidInvalidateWithId called with nil id, will run full header rebuild");
181
- [[self headerCoordinator] rebuild];
177
+ [self.headerCoordinator rebuild];
182
178
  return;
183
179
  }
184
- [[self headerCoordinator] rebuildItemWithId:itemId];
180
+ [self.headerCoordinator rebuildItemWithId:itemId];
185
181
  }
186
182
 
187
183
  - (void)headerItemMenuDidChangeWithId:(NSString *)itemId
188
184
  {
189
185
  if (itemId == nil) {
190
186
  RCTLogWarn(@"[RNScreens] headerItemMenuDidChangeWithId called with nil id, will run full header rebuild");
191
- [[self headerCoordinator] rebuild];
187
+ [self.headerCoordinator rebuild];
192
188
  return;
193
189
  }
194
- RNSStackScreenHeaderCoordinator *coordinator = [self headerCoordinator];
195
- [coordinator resetTrackerForItemWithId:itemId];
196
- [coordinator reapplyMenuForItemWithId:itemId];
190
+ [self.headerCoordinator resetTrackerForItemWithId:itemId];
191
+ [self.headerCoordinator reapplyMenuForItemWithId:itemId];
197
192
  }
198
193
 
199
194
  /**
@@ -204,15 +199,15 @@ static void RNSAssertIsValidHeaderChild(UIView *child)
204
199
  if (itemId == nil) {
205
200
  RCTLogWarn(
206
201
  @"[RNScreens] headerItemMenuDidUpdateFromCommandWithId called with nil id, will run full header rebuild");
207
- [[self headerCoordinator] rebuild];
202
+ [self.headerCoordinator rebuild];
208
203
  return;
209
204
  }
210
- [[self headerCoordinator] reapplyMenuForItemWithId:itemId];
205
+ [self.headerCoordinator reapplyMenuForItemWithId:itemId];
211
206
  }
212
207
 
213
208
  - (void)headerItemSpacerDidInvalidate
214
209
  {
215
- [[self headerCoordinator] rebuild];
210
+ [self.headerCoordinator rebuild];
216
211
  }
217
212
 
218
213
  #pragma mark - RNSStackHeaderEventsDelegate
@@ -295,11 +290,11 @@ static void RNSAssertIsValidHeaderChild(UIView *child)
295
290
  (oldItemData.itemType == RNSMenuItemTypeAutomatic &&
296
291
  [RNSStackHeaderMenuFinder singleSelectionRootForElementWithId:menuItemId inMenu:locator.rootMenu] != nil);
297
292
  if (isToggle) {
298
- [[self headerCoordinator] setToggleState:updateOptions.toggleState
299
- forMenuElementId:menuItemId
300
- trackerItemId:locator.trackerItemId
301
- rootMenu:locator.rootMenu
302
- parentMenu:locator.searchResult.parentMenu];
293
+ [self.headerCoordinator setToggleState:updateOptions.toggleState
294
+ forMenuElementId:menuItemId
295
+ trackerItemId:locator.trackerItemId
296
+ rootMenu:locator.rootMenu
297
+ parentMenu:locator.searchResult.parentMenu];
303
298
  }
304
299
  }
305
300
 
@@ -318,7 +313,7 @@ static void RNSAssertIsValidHeaderChild(UIView *child)
318
313
  replacingChildWithId:menuItemId
319
314
  withElement:newItemData];
320
315
  }
321
- [[self headerCoordinator] reapplyTitleMenu];
316
+ [self.headerCoordinator reapplyTitleMenu];
322
317
  break;
323
318
  case RNSMenuElementPositionOverflow:
324
319
  // TODO: handle overflow menu
@@ -366,7 +361,7 @@ static void RNSAssertIsValidHeaderChild(UIView *child)
366
361
  replacingChildWithId:menuElementId
367
362
  withElement:newMenuItem];
368
363
  }
369
- [[self headerCoordinator] reapplyTitleMenu];
364
+ [self.headerCoordinator reapplyTitleMenu];
370
365
  break;
371
366
  case RNSMenuElementPositionOverflow:
372
367
  // TODO: handle overflow menu
@@ -444,6 +439,34 @@ static void RNSAssertIsValidHeaderChild(UIView *child)
444
439
  _largeTitleEnabled = newHeaderProps.largeTitleEnabled;
445
440
  }
446
441
 
442
+ if (oldHeaderProps.prompt != newHeaderProps.prompt) {
443
+ _prompt = RCTNSStringFromStringNilIfEmpty(newHeaderProps.prompt);
444
+ }
445
+
446
+ if (oldHeaderProps.backButtonTitle != newHeaderProps.backButtonTitle) {
447
+ _backButtonTitle = RCTNSStringFromStringNilIfEmpty(newHeaderProps.backButtonTitle);
448
+ }
449
+
450
+ if (oldHeaderProps.backButtonDisplayMode != newHeaderProps.backButtonDisplayMode) {
451
+ _backButtonDisplayMode =
452
+ rnscreens::conversion::UINavigationItemBackButtonDisplayModeFromReactRNSStackHeaderConfigIOSBackButtonDisplayMode(
453
+ newHeaderProps.backButtonDisplayMode);
454
+ }
455
+
456
+ if (oldHeaderProps.backButtonMenuEnabled != newHeaderProps.backButtonMenuEnabled) {
457
+ _backButtonMenuEnabled = newHeaderProps.backButtonMenuEnabled;
458
+ }
459
+
460
+ if (oldHeaderProps.standardAppearance != newHeaderProps.standardAppearance) {
461
+ _standardAppearance = [RNSStackHeaderAppearanceMapper
462
+ appearanceFromDictionary:[self dictionaryFromAppearanceProp:newHeaderProps.standardAppearance]];
463
+ }
464
+
465
+ if (oldHeaderProps.scrollEdgeAppearance != newHeaderProps.scrollEdgeAppearance) {
466
+ _scrollEdgeAppearance = [RNSStackHeaderAppearanceMapper
467
+ scrollEdgeAppearanceFromDictionary:[self dictionaryFromAppearanceProp:newHeaderProps.scrollEdgeAppearance]];
468
+ }
469
+
447
470
  if (oldHeaderProps.titleMenu != newHeaderProps.titleMenu) {
448
471
  _titleMenu = [RNSStackHeaderMenuMapper
449
472
  menuFromDictionary:rnscreens::conversion::RNSConvertFollyDynamicToId(newHeaderProps.titleMenu)];
@@ -452,14 +475,14 @@ static void RNSAssertIsValidHeaderChild(UIView *child)
452
475
 
453
476
  [super updateProps:props oldProps:oldProps];
454
477
 
455
- [[self headerCoordinator] applyConfigProperties];
478
+ [self.headerCoordinator applyConfigProperties];
456
479
 
457
480
  if (titleMenuDidChange) {
458
481
  // title menu is a prop on the navigation item, not on one of the bar button items
459
482
  // thus it is not configured with matching RNSStackHeaderItemComponentView
460
483
  // but here directly
461
- [[self headerCoordinator] resetTitleMenuTracker];
462
- [[self headerCoordinator] reapplyTitleMenu];
484
+ [self.headerCoordinator resetTitleMenuTracker];
485
+ [self.headerCoordinator reapplyTitleMenu];
463
486
  }
464
487
  }
465
488
 
@@ -482,6 +505,15 @@ static void RNSAssertIsValidHeaderChild(UIView *child)
482
505
 
483
506
  #pragma mark - Private
484
507
 
508
+ - (nullable NSDictionary *)dictionaryFromAppearanceProp:(const folly::dynamic &)appearanceProp
509
+ {
510
+ if (appearanceProp.type() != folly::dynamic::OBJECT) {
511
+ return nil;
512
+ }
513
+
514
+ return rnscreens::conversion::RNSConvertFollyDynamicToId(appearanceProp);
515
+ }
516
+
485
517
  - (nullable RNSStackScreenHeaderCoordinator *)headerCoordinator
486
518
  {
487
519
  if (self.superview == nil) {
@@ -14,7 +14,13 @@ NS_ASSUME_NONNULL_BEGIN
14
14
  @property (nonatomic, readonly, nullable) NSString *largeTitle;
15
15
  @property (nonatomic, readonly, nullable) NSString *largeSubtitle;
16
16
  @property (nonatomic, readonly) BOOL largeTitleEnabled;
17
+ @property (nonatomic, readonly, nullable) NSString *prompt;
18
+ @property (nonatomic, readonly, nullable) NSString *backButtonTitle;
19
+ @property (nonatomic, readonly) UINavigationItemBackButtonDisplayMode backButtonDisplayMode;
20
+ @property (nonatomic, readonly) BOOL backButtonMenuEnabled;
17
21
  @property (nonatomic, readonly, nullable) RNSStackHeaderMenuData *titleMenu;
22
+ @property (nonatomic, readonly, nullable) UINavigationBarAppearance *standardAppearance;
23
+ @property (nonatomic, readonly, nullable) UINavigationBarAppearance *scrollEdgeAppearance;
18
24
 
19
25
  /**
20
26
  Children are expected to conform to either RNSStackHeaderItemDataProviding
@@ -2,7 +2,7 @@
2
2
  #import "RNSStackHeaderConfigComponentView.h"
3
3
 
4
4
  #import <React/RCTConversions.h>
5
- #import <rnscreens/RNSStackHeaderConfigComponentDescriptor.h>
5
+ #import <react/renderer/components/rnscreens/RNSStackHeaderConfigComponentDescriptor.h>
6
6
 
7
7
  namespace react = facebook::react;
8
8
 
@@ -1,4 +1,5 @@
1
1
  #import "RNSStackHeaderIconResolver.h"
2
+ #import <React/RCTLog.h>
2
3
 
3
4
  @implementation RNSStackHeaderIconResolver
4
5
 
@@ -18,11 +19,17 @@
18
19
  switch (iconData.iconType) {
19
20
  case RNSStackHeaderIconTypeSfSymbol: {
20
21
  UIImage *image = [UIImage systemImageNamed:iconData.resourceName];
22
+ if (image == nil && iconData.resourceName != nil) {
23
+ RCTLogWarn(@"[RNScreens] Failed to load SF Symbol \"%@\" for header icon", iconData.resourceName);
24
+ }
21
25
  iconData.resolvedImage = image;
22
26
  return image;
23
27
  }
24
28
  case RNSStackHeaderIconTypeXcasset: {
25
29
  UIImage *image = [UIImage imageNamed:iconData.resourceName];
30
+ if (image == nil && iconData.resourceName != nil) {
31
+ RCTLogWarn(@"[RNScreens] Failed to load xcasset \"%@\" for header icon", iconData.resourceName);
32
+ }
26
33
  iconData.resolvedImage = image;
27
34
  return image;
28
35
  }
@@ -12,11 +12,13 @@ NS_ASSUME_NONNULL_BEGIN
12
12
 
13
13
  @property (nonatomic, readonly) RNSHeaderItemPlacement placement;
14
14
  @property (nonatomic, readonly, nullable) NSString *itemId;
15
+ @property (nonatomic, readonly, nullable) NSString *identifier;
15
16
  @property (nonatomic, readonly, nullable) NSString *title;
16
17
  @property (nonatomic, readonly, nullable) RNSStackHeaderIconData *icon;
17
18
  @property (nonatomic, readonly, nullable) RNSStackHeaderMenuData *menu;
18
19
  @property (nonatomic, readonly, nullable) UIView *customView;
19
20
  @property (nonatomic, readonly) BOOL respondsToOnPress;
21
+ @property (nonatomic, readonly) BOOL hidesSharedBackground;
20
22
 
21
23
  @property (nonatomic, nullable) NSString *titleProp;
22
24
  @property (nonatomic, nullable) RNSStackHeaderIconData *iconProp;
@@ -42,7 +44,7 @@ NS_ASSUME_NONNULL_END
42
44
 
43
45
  #if defined(__cplusplus)
44
46
 
45
- #import <rnscreens/RNSStackHeaderItemComponentDescriptor.h>
47
+ #import <react/renderer/components/rnscreens/RNSStackHeaderItemComponentDescriptor.h>
46
48
 
47
49
  @interface RNSStackHeaderItemComponentView ()
48
50
 
@@ -13,7 +13,7 @@
13
13
  #import <React/RCTLog.h>
14
14
  #import <react/renderer/components/rnscreens/Props.h>
15
15
  #import <react/renderer/components/rnscreens/RCTComponentViewHelpers.h>
16
- #import <rnscreens/RNSStackHeaderItemComponentDescriptor.h>
16
+ #import <react/renderer/components/rnscreens/RNSStackHeaderItemComponentDescriptor.h>
17
17
 
18
18
  namespace react = facebook::react;
19
19
 
@@ -45,12 +45,14 @@ namespace react = facebook::react;
45
45
  - (void)resetProps
46
46
  {
47
47
  _itemId = nil;
48
+ _identifier = nil;
48
49
  [self setTitleProp:nil];
49
50
  [self setIconProp:nil];
50
51
  [self setMenuProp:nil];
51
52
  _placement = RNSHeaderItemPlacementTrailing;
52
53
  _didSetHeaderItemPlacement = NO;
53
54
  _respondsToOnPress = NO;
55
+ _hidesSharedBackground = NO;
54
56
  }
55
57
 
56
58
  - (void)setTitleProp:(NSString *)titleProp
@@ -183,11 +185,17 @@ RNS_IGNORE_SUPER_CALL_END
183
185
  _itemId = RCTNSStringFromStringNilIfEmpty(newItemProps.itemId);
184
186
  }
185
187
 
188
+ if (oldItemProps.identifier != newItemProps.identifier) {
189
+ _identifier = RCTNSStringFromStringNilIfEmpty(newItemProps.identifier);
190
+ needsUpdate = YES;
191
+ }
192
+
186
193
  if (oldItemProps.placement != newItemProps.placement) {
187
194
  if (_didSetHeaderItemPlacement) {
188
195
  RCTLogWarn(@"[RNScreens] Changing header item placement at runtime is not supported");
189
196
  } else {
190
- _placement = rnscreens::conversion::convert<RNSHeaderItemPlacement>(newItemProps.placement);
197
+ _placement =
198
+ rnscreens::conversion::RNSHeaderItemPlacementFromReactRNSStackHeaderItemIOSPlacement(newItemProps.placement);
191
199
  }
192
200
  }
193
201
  _didSetHeaderItemPlacement = YES;
@@ -214,6 +222,11 @@ RNS_IGNORE_SUPER_CALL_END
214
222
  needsUpdate = YES;
215
223
  }
216
224
 
225
+ if (oldItemProps.hidesSharedBackground != newItemProps.hidesSharedBackground) {
226
+ _hidesSharedBackground = newItemProps.hidesSharedBackground;
227
+ needsUpdate = YES;
228
+ }
229
+
217
230
  [super updateProps:props oldProps:oldProps];
218
231
 
219
232
  if (needsUpdate) {
@@ -12,11 +12,13 @@ NS_ASSUME_NONNULL_BEGIN
12
12
 
13
13
  @property (nonatomic, readonly) RNSHeaderItemPlacement placement;
14
14
  @property (nonatomic, readonly, nullable) NSString *itemId;
15
+ @property (nonatomic, readonly, nullable) NSString *identifier;
15
16
  @property (nonatomic, readonly, nullable) NSString *title;
16
17
  @property (nonatomic, readonly, nullable) RNSStackHeaderIconData *icon;
17
18
  @property (nonatomic, readonly, nullable) RNSStackHeaderMenuData *menu;
18
19
  @property (nonatomic, readonly, nullable) UIView *customView;
19
20
  @property (nonatomic, readonly) BOOL respondsToOnPress;
21
+ @property (nonatomic, readonly) BOOL hidesSharedBackground;
20
22
 
21
23
  @end
22
24
 
@@ -2,7 +2,7 @@
2
2
  #import "RNSStackHeaderItemComponentView.h"
3
3
 
4
4
  #import <React/RCTConversions.h>
5
- #import <rnscreens/RNSStackHeaderItemComponentDescriptor.h>
5
+ #import <react/renderer/components/rnscreens/RNSStackHeaderItemComponentDescriptor.h>
6
6
 
7
7
  namespace react = facebook::react;
8
8
 
@@ -43,7 +43,8 @@ namespace react = facebook::react;
43
43
  if (_didSetHeaderItemSpacerPlacement) {
44
44
  RCTLogWarn(@"[RNScreens] Changing header item spacer placement at runtime is not supported");
45
45
  } else {
46
- _placement = rnscreens::conversion::convert<RNSHeaderItemSpacerPlacement>(newSpacerProps.placement);
46
+ _placement = rnscreens::conversion::RNSHeaderItemSpacerPlacementFromReactRNSStackHeaderItemSpacerIOSPlacement(
47
+ newSpacerProps.placement);
47
48
  }
48
49
  }
49
50
  _didSetHeaderItemSpacerPlacement = YES;
@@ -88,18 +88,22 @@ static NSSet<NSString *> *const kRNSAllowedMenuItemKeys = [NSSet
88
88
 
89
89
  + (void)validateMenuKeys:(NSDictionary *)dict
90
90
  {
91
+ #ifndef NS_BLOCK_ASSERTIONS
91
92
  for (NSString *key in dict) {
92
93
  RCTAssert([kRNSAllowedMenuKeys containsObject:key], @"[RNScreens] Invalid key \"%@\" found in menu", key);
93
94
  }
95
+ #endif // !NS_BLOCK_ASSERTIONS
94
96
  RCTAssert(dict[@"children"], @"[RNScreens] missing key \"children\" in menu");
95
97
  RCTAssert(dict[@"id"], @"[RNScreens] missing id on one of menu elements");
96
98
  }
97
99
 
98
100
  + (void)validateMenuItemKeys:(NSDictionary *)dict
99
101
  {
102
+ #ifndef NS_BLOCK_ASSERTIONS
100
103
  for (NSString *key in dict) {
101
104
  RCTAssert([kRNSAllowedMenuItemKeys containsObject:key], @"[RNScreens] Invalid key \"%@\" found in menu item", key);
102
105
  }
106
+ #endif // !NS_BLOCK_ASSERTIONS
103
107
  RCTAssert(dict[@"id"], @"[RNScreens] missing id on one of menu elements");
104
108
  }
105
109
 
@@ -0,0 +1,25 @@
1
+ #pragma once
2
+
3
+ #import <UIKit/UIKit.h>
4
+
5
+ NS_ASSUME_NONNULL_BEGIN
6
+
7
+ /**
8
+ * Navigation bar subclass used by RNSStackNavigationController.
9
+ *
10
+ * Its responsibility is to suppress the back button's navigation history
11
+ * menu (long press and pointer secondary click).
12
+ */
13
+ @interface RNSStackNavigationBar : UINavigationBar
14
+
15
+ #if !TARGET_OS_TV
16
+ /**
17
+ * When NO, the back button's navigation history menu (long press and pointer
18
+ * secondary click) is suppressed. Tapping the back button is unaffected.
19
+ */
20
+ @property (nonatomic) BOOL backButtonMenuEnabled;
21
+ #endif // !TARGET_OS_TV
22
+
23
+ @end
24
+
25
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,80 @@
1
+ #import "RNSStackNavigationBar.h"
2
+ #import "UINavigationBar+RNSUtility.h"
3
+
4
+ static void *const RNSBackButtonMenuEnabledKVOContext = (void *)&RNSBackButtonMenuEnabledKVOContext;
5
+
6
+ @implementation RNSStackNavigationBar
7
+ #if !TARGET_OS_TV
8
+ {
9
+ UIControl *_Nullable _observedBackButtonWrapper;
10
+ }
11
+
12
+ - (instancetype)initWithFrame:(CGRect)frame
13
+ {
14
+ if (self = [super initWithFrame:frame]) {
15
+ _backButtonMenuEnabled = YES;
16
+ }
17
+ return self;
18
+ }
19
+
20
+ - (void)setBackButtonMenuEnabled:(BOOL)backButtonMenuEnabled
21
+ {
22
+ _backButtonMenuEnabled = backButtonMenuEnabled;
23
+ [self enforceBackButtonMenuState];
24
+ }
25
+
26
+ - (void)layoutSubviews
27
+ {
28
+ [super layoutSubviews];
29
+ // The back button wrapper may have been replaced by this layout pass
30
+ [self enforceBackButtonMenuState];
31
+ }
32
+
33
+ - (void)enforceBackButtonMenuState
34
+ {
35
+ UIView *wrapperView = [self rnscreens_findBackButtonWrapperView];
36
+ if (wrapperView != _observedBackButtonWrapper) {
37
+ [_observedBackButtonWrapper removeObserver:self
38
+ forKeyPath:@"contextMenuInteractionEnabled"
39
+ context:RNSBackButtonMenuEnabledKVOContext];
40
+ _observedBackButtonWrapper = nil;
41
+
42
+ if ([wrapperView isKindOfClass:UIControl.class]) {
43
+ _observedBackButtonWrapper = (UIControl *)wrapperView;
44
+ [_observedBackButtonWrapper addObserver:self
45
+ forKeyPath:@"contextMenuInteractionEnabled"
46
+ options:NSKeyValueObservingOptionNew
47
+ context:RNSBackButtonMenuEnabledKVOContext];
48
+ }
49
+ }
50
+
51
+ _observedBackButtonWrapper.contextMenuInteractionEnabled = _backButtonMenuEnabled;
52
+ }
53
+
54
+ - (void)observeValueForKeyPath:(NSString *)keyPath
55
+ ofObject:(id)object
56
+ change:(NSDictionary<NSKeyValueChangeKey, id> *)change
57
+ context:(void *)context
58
+ {
59
+ if (context != RNSBackButtonMenuEnabledKVOContext) {
60
+ [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
61
+ return;
62
+ }
63
+
64
+ // UIKit re-asserts the interaction on every back button reconfigure
65
+ // - flip it back off immediately.
66
+ if (!_backButtonMenuEnabled && [change[NSKeyValueChangeNewKey] boolValue] && object == _observedBackButtonWrapper) {
67
+ _observedBackButtonWrapper.contextMenuInteractionEnabled = NO;
68
+ }
69
+ }
70
+
71
+ - (void)dealloc
72
+ {
73
+ [_observedBackButtonWrapper removeObserver:self
74
+ forKeyPath:@"contextMenuInteractionEnabled"
75
+ context:RNSBackButtonMenuEnabledKVOContext];
76
+ }
77
+
78
+ #endif // !TARGET_OS_TV
79
+
80
+ @end
@@ -10,6 +10,14 @@ NS_ASSUME_NONNULL_BEGIN
10
10
  forNavigationController:(UINavigationController *)navigationController
11
11
  animated:(BOOL)animated;
12
12
 
13
+ #if !TARGET_OS_TV
14
+ /**
15
+ * Enables or disables the back button's long-press navigation history menu.
16
+ * Takes effect only when the navigation bar is an RNSStackNavigationBar.
17
+ */
18
+ - (void)setBackButtonMenuEnabled:(BOOL)enabled forNavigationController:(UINavigationController *)navigationController;
19
+ #endif // !TARGET_OS_TV
20
+
13
21
  - (void)initializeNavigationBarOfNavigationController:(UINavigationController *)navigationController;
14
22
 
15
23
  @end