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

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 (456) hide show
  1. package/Package.swift +87 -0
  2. package/README.md +0 -11
  3. package/android/build.gradle +1 -0
  4. package/android/consumer-rules.pro +3 -0
  5. package/android/src/fabric/java/com/swmansion/rnscreens/legacy/FabricEnabledHeaderConfigViewGroup.kt +2 -0
  6. package/android/src/fabric/java/com/swmansion/rnscreens/legacy/FabricEnabledHeaderSubviewViewGroup.kt +2 -0
  7. package/android/src/fabric/java/com/swmansion/rnscreens/legacy/FabricEnabledViewGroup.kt +18 -3
  8. package/android/src/main/cpp/NativeProxy.cpp +30 -6
  9. package/android/src/main/cpp/NativeProxy.h +7 -1
  10. package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +2 -2
  11. package/android/src/main/java/com/swmansion/rnscreens/ScreensModule.kt +7 -3
  12. package/android/src/main/java/com/swmansion/rnscreens/common/colorscheme/ColorSchemeCoordinator.kt +11 -1
  13. package/android/src/main/java/com/swmansion/rnscreens/common/container/Container.kt +17 -0
  14. package/android/src/main/java/com/swmansion/rnscreens/common/container/ContainerItem.kt +13 -1
  15. package/android/src/main/java/com/swmansion/rnscreens/common/text/ReactTextAppearance.kt +62 -0
  16. package/android/src/main/java/com/swmansion/rnscreens/common/text/TextAppearance.kt +20 -0
  17. package/android/src/main/java/com/swmansion/rnscreens/common/text/TextAppearanceDefaults.kt +65 -0
  18. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/coordinator/FormSheetAppearanceCoordinator.kt +2 -2
  19. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/coordinator/FormSheetBehaviorController.kt +51 -20
  20. package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/coordinator/FormSheetDimensionsCoordinator.kt +159 -0
  21. package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/coordinator/FormSheetKeyboardCoordinator.kt +101 -0
  22. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/coordinator/FormSheetNativeDismissCoordinator.kt +2 -8
  23. package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/dialog/FormSheetAvailableHeightProvider.kt +44 -0
  24. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native/core → core/modals/formsheet/dialog}/FormSheetContainer.kt +1 -1
  25. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native/core → core/modals/formsheet/dialog}/FormSheetDialog.kt +36 -4
  26. package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/dialog/FormSheetDialogManager.kt +107 -0
  27. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/interfaces/FormSheetContentSizeChangeDelegate.kt +1 -1
  28. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/interfaces/FormSheetContentSizeChangeProvider.kt +1 -1
  29. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/interfaces/FormSheetDialogEventEmitter.kt +3 -1
  30. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/model/FormSheetConfig.kt +1 -1
  31. package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/model/FormSheetDetents.kt +152 -0
  32. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/presentation/FormSheetAnimatorFactory.kt +9 -10
  33. package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/presentation/FormSheetDimmingManager.kt +103 -0
  34. package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/presentation/FormSheetDismissalOrigin.kt +22 -0
  35. package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/presentation/FormSheetPresentation.kt +173 -0
  36. package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/presentation/FormSheetPresentationManager.kt +290 -0
  37. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/presentation/FormSheetPresentationState.kt +2 -2
  38. package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/presentation/FormSheetStackRegistry.kt +28 -0
  39. package/android/src/main/java/com/swmansion/rnscreens/ext/FragmentManagerExt.kt +6 -0
  40. package/android/src/main/java/com/swmansion/rnscreens/helpers/FragmentManagerHelper.kt +0 -3
  41. package/android/src/main/java/com/swmansion/rnscreens/helpers/NoTintDrawable.kt +31 -0
  42. package/android/src/main/java/com/swmansion/rnscreens/helpers/PropIconResolver.kt +17 -23
  43. package/android/src/main/java/com/swmansion/rnscreens/helpers/ViewFinder.kt +0 -17
  44. package/android/src/main/java/com/swmansion/rnscreens/legacy/Screen.kt +32 -3
  45. package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenContainer.kt +35 -3
  46. package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenStack.kt +15 -0
  47. package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenStackHeaderConfig.kt +7 -1
  48. package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenStackHeaderSubviewManager.kt +7 -0
  49. package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenStackViewManager.kt +6 -0
  50. package/android/src/main/java/com/swmansion/rnscreens/legacy/bottomsheet/DimmingView.kt +2 -0
  51. package/android/src/main/java/com/swmansion/rnscreens/legacy/stack/views/ScreensCoordinatorLayout.kt +2 -0
  52. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/contentwrapper/FormSheetContentWrapper.kt +3 -3
  53. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/contentwrapper/FormSheetContentWrapperViewManager.kt +1 -1
  54. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetDetentChangedEvent.kt +1 -1
  55. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetDidAppearEvent.kt +1 -1
  56. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetDidDisappearEvent.kt +1 -1
  57. package/android/src/main/java/com/swmansion/rnscreens/react/modals/formsheet/event/FormSheetDismissEvent.kt +29 -0
  58. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetNativeDismissEvent.kt +1 -1
  59. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetNativeDismissPreventedEvent.kt +1 -1
  60. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetSyncFlushEvent.kt +1 -1
  61. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetWillAppearEvent.kt +1 -1
  62. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetWillDisappearEvent.kt +1 -1
  63. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/host/FormSheetContentView.kt +3 -3
  64. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/host/FormSheetHost.kt +5 -3
  65. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/host/FormSheetHostEventEmitter.kt +17 -10
  66. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/host/FormSheetHostViewManager.kt +11 -9
  67. package/android/src/main/java/com/swmansion/rnscreens/safearea/OnInterfaceInsetsChangeListener.kt +15 -0
  68. package/android/src/main/java/com/swmansion/rnscreens/safearea/SafeAreaProvider.kt +8 -8
  69. package/android/src/main/java/com/swmansion/rnscreens/safearea/SafeAreaView.kt +3 -2
  70. package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderApplicator.kt +360 -101
  71. package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderBackPressHandler.kt +11 -0
  72. package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderCoordinatorLayout.kt +211 -113
  73. package/android/src/main/java/com/swmansion/rnscreens/stack/header/appbar/StackHeaderAppBarLayout.kt +156 -24
  74. package/android/src/main/java/com/swmansion/rnscreens/stack/header/appbar/StackHeaderContentScrimDrawable.kt +36 -0
  75. package/android/src/main/java/com/swmansion/rnscreens/stack/header/appbar/StackHeaderToolbar.kt +74 -0
  76. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderCollapsedTitleGravityMode.kt +6 -0
  77. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfig.kt +162 -228
  78. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigViewManager.kt +385 -12
  79. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigurationObserver.kt +5 -6
  80. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigurationProviding.kt +29 -6
  81. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderDelegate.kt +0 -7
  82. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderInvalidationFlags.kt +8 -7
  83. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuApplicator.kt +27 -280
  84. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuController.kt +448 -0
  85. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuDelegate.kt +10 -0
  86. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuMapper.kt +28 -20
  87. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/model/StackHeaderToolbarMenuConfig.kt +3 -55
  88. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/model/StackHeaderToolbarMenuGroupMetadata.kt +1 -10
  89. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/model/StackHeaderToolbarMenuItemConfig.kt +1 -3
  90. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/model/StackHeaderToolbarMenuModel.kt +180 -0
  91. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuElementOptions.kt +57 -6
  92. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuElementRawUpdate.kt +3 -1
  93. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuElementUpdate.kt +1 -0
  94. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuIconResolver.kt +4 -3
  95. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuUpdateQueue.kt +23 -9
  96. package/android/src/main/java/com/swmansion/rnscreens/stack/host/FragmentOperation.kt +1 -0
  97. package/android/src/main/java/com/swmansion/rnscreens/stack/host/FragmentOperationExecutor.kt +2 -1
  98. package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackContainer.kt +159 -21
  99. package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackContainerDelegate.kt +7 -0
  100. package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackContainerUpdateCoordinator.kt +5 -3
  101. package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackHost.kt +27 -5
  102. package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackHostViewManager.kt +14 -0
  103. package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackUpdateBatchStateProviding.kt +10 -0
  104. package/android/src/main/java/com/swmansion/rnscreens/stack/screen/PreventNativeDismissCallback.kt +2 -2
  105. package/android/src/main/java/com/swmansion/rnscreens/stack/screen/StackScreen.kt +4 -0
  106. package/android/src/main/java/com/swmansion/rnscreens/stack/screen/StackScreenFragment.kt +50 -10
  107. package/android/src/main/java/com/swmansion/rnscreens/stack/screen/StackScreenFragmentDelegate.kt +12 -0
  108. package/android/src/main/java/com/swmansion/rnscreens/tabs/appearance/TabsAppearanceApplicator.kt +106 -10
  109. package/android/src/main/java/com/swmansion/rnscreens/tabs/appearance/TabsAppearanceCoordinator.kt +46 -7
  110. package/android/src/main/java/com/swmansion/rnscreens/tabs/appearance/TabsAppearanceModel.kt +3 -0
  111. package/android/src/main/java/com/swmansion/rnscreens/tabs/container/CustomBottomNavigationView.kt +21 -1
  112. package/android/src/main/java/com/swmansion/rnscreens/tabs/container/MenuHelpers.kt +5 -23
  113. package/android/src/main/java/com/swmansion/rnscreens/tabs/container/TabsContainer.kt +72 -36
  114. package/android/src/main/java/com/swmansion/rnscreens/tabs/container/TabsContainerDelegate.kt +11 -0
  115. package/android/src/main/java/com/swmansion/rnscreens/tabs/host/TabsHost.kt +22 -2
  116. package/android/src/main/java/com/swmansion/rnscreens/tabs/host/TabsHostA11yCoordinator.kt +23 -2
  117. package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreen.kt +58 -17
  118. package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreenDelegate.kt +6 -0
  119. package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreenFragment.kt +3 -0
  120. package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreenIcon.kt +82 -0
  121. package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreenIconTinting.kt +17 -0
  122. package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreenViewManager.kt +26 -19
  123. package/android/src/main/java/com/swmansion/rnscreens/utils/DimensionUtils.kt +20 -6
  124. package/android/src/main/java/com/swmansion/rnscreens/utils/RNSLog.kt +22 -6
  125. package/android/src/main/java/com/swmansion/rnscreens/utils/StyleUtils.kt +22 -0
  126. package/android/src/main/res/base/layout/rns_collapsing_toolbar_large_available_space.xml +8 -0
  127. package/android/src/main/res/base/layout/rns_collapsing_toolbar_large_entire_space.xml +8 -0
  128. package/android/src/main/res/base/layout/rns_collapsing_toolbar_medium_available_space.xml +8 -0
  129. package/android/src/main/res/base/layout/rns_collapsing_toolbar_medium_entire_space.xml +8 -0
  130. package/cpp/legacy/RNSScreenRemovalListener.cpp +31 -1
  131. package/cpp/legacy/RNSScreenRemovalListener.h +18 -3
  132. package/ios/RNSEnums.h +16 -1
  133. package/ios/conversion/RNSConversions.h +7 -108
  134. package/ios/helpers/image/RNSImageLoadingHelper.h +7 -0
  135. package/ios/helpers/image/RNSImageLoadingHelper.mm +9 -0
  136. package/ios/legacy/RNSBarButtonItem.mm +15 -0
  137. package/ios/legacy/RNSConvert.h +6 -0
  138. package/ios/legacy/RNSConvert.mm +17 -0
  139. package/ios/legacy/RNSFullWindowOverlay.mm +1 -1
  140. package/ios/legacy/RNSModalScreen.mm +1 -1
  141. package/ios/legacy/RNSNavigationBar.h +31 -0
  142. package/ios/legacy/RNSNavigationBar.mm +15 -0
  143. package/ios/legacy/RNSScreen.mm +130 -31
  144. package/ios/legacy/RNSScreenContentWrapper.mm +4 -1
  145. package/ios/legacy/RNSScreenStack.mm +202 -15
  146. package/ios/legacy/RNSScreenStackHeaderConfig.h +30 -0
  147. package/ios/legacy/RNSScreenStackHeaderConfig.mm +72 -17
  148. package/ios/legacy/RNSScreenStackHeaderSubview.mm +34 -1
  149. package/ios/legacy/RNSScreenWindowTraits.mm +5 -13
  150. package/ios/modals/form-sheet/RNSFormSheetConfigurationApplicator.h +1 -3
  151. package/ios/modals/form-sheet/RNSFormSheetConfigurationApplicator.mm +11 -22
  152. package/ios/modals/form-sheet/RNSFormSheetContentController.h +1 -1
  153. package/ios/modals/form-sheet/RNSFormSheetContentController.mm +7 -18
  154. package/ios/modals/form-sheet/RNSFormSheetHostComponentView.mm +4 -4
  155. package/ios/modals/form-sheet/RNSFormSheetHostShadowStateProxy.mm +2 -2
  156. package/ios/modals/form-sheet/RNSFormSheetUpdateFlags.h +3 -0
  157. package/ios/safe-area/RNSSafeAreaViewComponentView.mm +3 -14
  158. package/ios/{conversion → scroll-view-marker/conversion}/RNSConversions-ScrollViewMarker.mm +2 -3
  159. package/ios/split/RNSSplitAppearanceApplicator.h +4 -4
  160. package/ios/split/RNSSplitAppearanceApplicator.mm +53 -56
  161. package/ios/split/RNSSplitHostComponentEventEmitter.h +1 -0
  162. package/ios/split/RNSSplitHostComponentEventEmitter.mm +1 -1
  163. package/ios/split/RNSSplitHostComponentView.h +5 -15
  164. package/ios/split/RNSSplitHostComponentView.mm +55 -6
  165. package/ios/split/RNSSplitHostController.h +25 -6
  166. package/ios/split/RNSSplitHostController.mm +24 -92
  167. package/ios/split/RNSSplitHostProviders.h +67 -0
  168. package/ios/split/RNSSplitScreenComponentView.h +0 -39
  169. package/ios/split/RNSSplitScreenComponentView.mm +27 -10
  170. package/ios/split/RNSSplitScreenController.h +26 -3
  171. package/ios/split/RNSSplitScreenController.mm +13 -30
  172. package/ios/split/RNSSplitScreenShadowStateProxy.h +1 -40
  173. package/ios/split/RNSSplitScreenShadowStateProxy.mm +1 -26
  174. package/ios/split/conversion/RNSConversions-SplitView.h +56 -0
  175. package/ios/{conversion → split/conversion}/RNSConversions-SplitView.mm +4 -1
  176. package/ios/stack/conversion/RNSConversions-Stack.h +62 -0
  177. package/ios/stack/conversion/RNSConversions-Stack.mm +134 -0
  178. package/ios/stack/header/RNSHeaderItemVisibilityPriority.h +9 -0
  179. package/ios/stack/header/RNSStackHeaderAppearanceMapper.h +26 -0
  180. package/ios/stack/header/RNSStackHeaderAppearanceMapper.mm +88 -0
  181. package/ios/stack/header/RNSStackHeaderConfigComponentView.h +14 -1
  182. package/ios/stack/header/RNSStackHeaderConfigComponentView.mm +103 -37
  183. package/ios/stack/header/RNSStackHeaderConfigDataProviding.h +11 -0
  184. package/ios/stack/header/RNSStackHeaderConfigShadowStateProxy.mm +1 -1
  185. package/ios/stack/header/RNSStackHeaderContentFactory.mm +3 -0
  186. package/ios/stack/header/RNSStackHeaderIconResolver.mm +7 -0
  187. package/ios/stack/header/RNSStackHeaderItemComponentView.h +12 -3
  188. package/ios/stack/header/RNSStackHeaderItemComponentView.mm +72 -5
  189. package/ios/stack/header/RNSStackHeaderItemDataProviding.h +7 -0
  190. package/ios/stack/header/RNSStackHeaderItemShadowStateProxy.mm +1 -1
  191. package/ios/stack/header/RNSStackHeaderItemSpacerComponentView.mm +2 -1
  192. package/ios/stack/header/RNSStackHeaderMenuCoordinator.h +13 -0
  193. package/ios/stack/header/RNSStackHeaderMenuCoordinator.mm +24 -0
  194. package/ios/stack/header/RNSStackHeaderMenuFinder.h +8 -1
  195. package/ios/stack/header/RNSStackHeaderMenuFinder.mm +26 -9
  196. package/ios/stack/header/RNSStackHeaderMenuMapper.mm +4 -0
  197. package/ios/stack/host/RNSStackNavigationBar.h +25 -0
  198. package/ios/stack/host/RNSStackNavigationBar.mm +80 -0
  199. package/ios/stack/host/RNSStackNavigationBarCoordinator.h +8 -0
  200. package/ios/stack/host/RNSStackNavigationBarCoordinator.mm +11 -0
  201. package/ios/stack/host/RNSStackNavigationController.mm +13 -5
  202. package/ios/stack/host/RNSStackOperation.h +0 -2
  203. package/ios/stack/screen/RNSStackScreenComponentView.h +2 -1
  204. package/ios/stack/screen/RNSStackScreenComponentView.mm +32 -2
  205. package/ios/stack/screen/RNSStackScreenController.mm +12 -0
  206. package/ios/stack/screen/RNSStackScreenHeaderCoordinator.h +8 -0
  207. package/ios/stack/screen/RNSStackScreenHeaderCoordinator.mm +179 -24
  208. package/ios/tabs/RNSTabBarAppearanceCoordinator.mm +110 -16
  209. package/ios/tabs/RNSTabBarItemCoordinator.h +16 -0
  210. package/ios/tabs/RNSTabBarItemCoordinator.mm +143 -0
  211. package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryComponentView.h +1 -1
  212. package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryComponentView.mm +1 -1
  213. package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryContentComponentView.mm +1 -1
  214. package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryEventEmitter.mm +1 -1
  215. package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryShadowStateProxy.mm +1 -1
  216. package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryWrapperView.h +24 -0
  217. package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryWrapperView.mm +22 -0
  218. package/ios/tabs/conversion/RNSConversions-Tabs.h +100 -0
  219. package/ios/{conversion → tabs/conversion}/RNSConversions-Tabs.mm +105 -74
  220. package/ios/tabs/extensions/RNSTabsHostComponentView+RNSImageLoader.h +1 -1
  221. package/ios/tabs/host/RNSTabBarController.h +16 -0
  222. package/ios/tabs/host/RNSTabBarController.mm +516 -107
  223. package/ios/tabs/host/RNSTabsHostComponentView.h +4 -0
  224. package/ios/tabs/host/RNSTabsHostComponentView.mm +41 -4
  225. package/ios/tabs/host/RNSTabsHostEventEmitter.mm +1 -1
  226. package/ios/tabs/screen/RNSTabsScreenComponentView.h +21 -0
  227. package/ios/tabs/screen/RNSTabsScreenComponentView.mm +56 -56
  228. package/ios/tabs/screen/RNSTabsScreenViewController.mm +1 -0
  229. package/ios/utils/RNSDefines.h +15 -7
  230. package/lib/commonjs/components/stack/header/StackHeaderConfig.android.js +37 -21
  231. package/lib/commonjs/components/stack/header/StackHeaderConfig.android.js.map +1 -1
  232. package/lib/commonjs/components/stack/header/StackHeaderConfig.ios.js +41 -4
  233. package/lib/commonjs/components/stack/header/StackHeaderConfig.ios.js.map +1 -1
  234. package/lib/commonjs/components/stack/header/StackHeaderConfig.js +17 -0
  235. package/lib/commonjs/components/stack/header/StackHeaderConfig.js.map +1 -0
  236. package/lib/commonjs/components/stack/header/ios/StackHeaderItem.ios.js +4 -1
  237. package/lib/commonjs/components/stack/header/ios/StackHeaderItem.ios.js.map +1 -1
  238. package/lib/commonjs/components/stack/host/StackHost.js +17 -7
  239. package/lib/commonjs/components/stack/host/StackHost.js.map +1 -1
  240. package/lib/commonjs/components/stack/host/StackHost.web.js +0 -2
  241. package/lib/commonjs/components/stack/host/StackHost.web.js.map +1 -1
  242. package/lib/commonjs/components/stack/index.js.map +1 -1
  243. package/lib/commonjs/components/tabs/host/TabsHost.ios.js +3 -0
  244. package/lib/commonjs/components/tabs/host/TabsHost.ios.js.map +1 -1
  245. package/lib/commonjs/components/tabs/host/{TabsHost.web.js → TabsHost.js} +1 -1
  246. package/lib/commonjs/components/tabs/host/TabsHost.js.map +1 -0
  247. package/lib/commonjs/components/tabs/index.js.map +1 -1
  248. package/lib/commonjs/components/tabs/screen/TabsScreen.android.js +3 -1
  249. package/lib/commonjs/components/tabs/screen/TabsScreen.android.js.map +1 -1
  250. package/lib/commonjs/components/tabs/screen/TabsScreen.ios.js +10 -1
  251. package/lib/commonjs/components/tabs/screen/TabsScreen.ios.js.map +1 -1
  252. package/lib/commonjs/components/tabs/screen/{TabsScreen.web.js → TabsScreen.js} +1 -1
  253. package/lib/commonjs/components/tabs/screen/TabsScreen.js.map +1 -0
  254. package/lib/commonjs/components/{stack/header/StackHeaderConfig.d.js → tabs/screen/TabsScreenIcon.types.js} +1 -1
  255. package/lib/commonjs/components/{stack/header/StackHeaderConfig.d.js.map → tabs/screen/TabsScreenIcon.types.js.map} +1 -1
  256. package/lib/commonjs/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.js.map +1 -1
  257. package/lib/commonjs/fabric/legacy/ScreenStackNativeComponent.js.map +1 -1
  258. package/lib/commonjs/fabric/stack/StackHeaderConfigAndroidNativeComponent.js.map +1 -1
  259. package/lib/commonjs/fabric/stack/StackHeaderConfigIOSNativeComponent.js.map +1 -1
  260. package/lib/commonjs/fabric/stack/StackHeaderItemIOSNativeComponent.js.map +1 -1
  261. package/lib/commonjs/fabric/stack/StackHostNativeComponent.js.map +1 -1
  262. package/lib/commonjs/fabric/tabs/TabsHostIOSNativeComponent.js.map +1 -1
  263. package/lib/commonjs/fabric/tabs/TabsScreenAndroidNativeComponent.js.map +1 -1
  264. package/lib/commonjs/fabric/tabs/TabsScreenIOSNativeComponent.js +1 -1
  265. package/lib/commonjs/fabric/tabs/TabsScreenIOSNativeComponent.js.map +1 -1
  266. package/lib/commonjs/legacy/components/ScreenStackItem.js +31 -11
  267. package/lib/commonjs/legacy/components/ScreenStackItem.js.map +1 -1
  268. package/lib/module/components/stack/header/StackHeaderConfig.android.js +39 -23
  269. package/lib/module/components/stack/header/StackHeaderConfig.android.js.map +1 -1
  270. package/lib/module/components/stack/header/StackHeaderConfig.ios.js +43 -6
  271. package/lib/module/components/stack/header/StackHeaderConfig.ios.js.map +1 -1
  272. package/lib/module/components/stack/header/StackHeaderConfig.js +10 -0
  273. package/lib/module/components/stack/header/StackHeaderConfig.js.map +1 -0
  274. package/lib/module/components/stack/header/ios/StackHeaderItem.ios.js +4 -1
  275. package/lib/module/components/stack/header/ios/StackHeaderItem.ios.js.map +1 -1
  276. package/lib/module/components/stack/host/StackHost.js +18 -8
  277. package/lib/module/components/stack/host/StackHost.js.map +1 -1
  278. package/lib/module/components/stack/host/StackHost.web.js +0 -3
  279. package/lib/module/components/stack/host/StackHost.web.js.map +1 -1
  280. package/lib/module/components/stack/index.js.map +1 -1
  281. package/lib/module/components/tabs/host/TabsHost.ios.js +3 -0
  282. package/lib/module/components/tabs/host/TabsHost.ios.js.map +1 -1
  283. package/{src/components/tabs/host/TabsHost.web.tsx → lib/module/components/tabs/host/TabsHost.js} +1 -2
  284. package/lib/module/components/tabs/host/TabsHost.js.map +1 -0
  285. package/lib/module/components/tabs/index.js.map +1 -1
  286. package/lib/module/components/tabs/screen/TabsScreen.android.js +3 -1
  287. package/lib/module/components/tabs/screen/TabsScreen.android.js.map +1 -1
  288. package/lib/module/components/tabs/screen/TabsScreen.ios.js +10 -1
  289. package/lib/module/components/tabs/screen/TabsScreen.ios.js.map +1 -1
  290. package/{src/components/tabs/screen/TabsScreen.web.tsx → lib/module/components/tabs/screen/TabsScreen.js} +1 -2
  291. package/lib/module/components/tabs/screen/TabsScreen.js.map +1 -0
  292. package/lib/module/components/tabs/screen/TabsScreenIcon.types.js +2 -0
  293. package/lib/module/components/{stack/header/StackHeaderConfig.d.js.map → tabs/screen/TabsScreenIcon.types.js.map} +1 -1
  294. package/lib/module/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.js.map +1 -1
  295. package/lib/module/fabric/legacy/ScreenStackNativeComponent.js.map +1 -1
  296. package/lib/module/fabric/stack/StackHeaderConfigAndroidNativeComponent.js.map +1 -1
  297. package/lib/module/fabric/stack/StackHeaderConfigIOSNativeComponent.js.map +1 -1
  298. package/lib/module/fabric/stack/StackHeaderItemIOSNativeComponent.js.map +1 -1
  299. package/lib/module/fabric/stack/StackHostNativeComponent.js.map +1 -1
  300. package/lib/module/fabric/tabs/TabsHostIOSNativeComponent.js.map +1 -1
  301. package/lib/module/fabric/tabs/TabsScreenAndroidNativeComponent.js.map +1 -1
  302. package/lib/module/fabric/tabs/TabsScreenIOSNativeComponent.js +1 -1
  303. package/lib/module/fabric/tabs/TabsScreenIOSNativeComponent.js.map +1 -1
  304. package/lib/module/legacy/components/ScreenStackItem.js +31 -11
  305. package/lib/module/legacy/components/ScreenStackItem.js.map +1 -1
  306. package/lib/typescript/components/modals/form-sheet/FormSheet.types.d.ts +1 -1
  307. package/lib/typescript/components/stack/header/StackHeaderConfig.android.d.ts +6 -3
  308. package/lib/typescript/components/stack/header/StackHeaderConfig.android.d.ts.map +1 -1
  309. package/lib/typescript/components/stack/header/StackHeaderConfig.android.types.d.ts +620 -24
  310. package/lib/typescript/components/stack/header/StackHeaderConfig.android.types.d.ts.map +1 -1
  311. package/lib/typescript/components/stack/header/StackHeaderConfig.d.ts +8 -0
  312. package/lib/typescript/components/stack/header/StackHeaderConfig.d.ts.map +1 -0
  313. package/lib/typescript/components/stack/header/StackHeaderConfig.ios.d.ts +6 -3
  314. package/lib/typescript/components/stack/header/StackHeaderConfig.ios.d.ts.map +1 -1
  315. package/lib/typescript/components/stack/header/StackHeaderConfig.ios.types.d.ts +361 -2
  316. package/lib/typescript/components/stack/header/StackHeaderConfig.ios.types.d.ts.map +1 -1
  317. package/lib/typescript/components/stack/header/StackHeaderConfig.types.d.ts +4 -2
  318. package/lib/typescript/components/stack/header/StackHeaderConfig.types.d.ts.map +1 -1
  319. package/lib/typescript/components/stack/header/ios/StackHeaderItem.ios.d.ts.map +1 -1
  320. package/lib/typescript/components/stack/header/ios/StackHeaderItem.ios.types.d.ts +7 -0
  321. package/lib/typescript/components/stack/header/ios/StackHeaderItem.ios.types.d.ts.map +1 -1
  322. package/lib/typescript/components/stack/host/StackHost.d.ts +1 -1
  323. package/lib/typescript/components/stack/host/StackHost.d.ts.map +1 -1
  324. package/lib/typescript/components/stack/host/StackHost.types.d.ts +47 -0
  325. package/lib/typescript/components/stack/host/StackHost.types.d.ts.map +1 -1
  326. package/lib/typescript/components/stack/host/StackHost.web.d.ts +1 -3
  327. package/lib/typescript/components/stack/host/StackHost.web.d.ts.map +1 -1
  328. package/lib/typescript/components/stack/index.d.ts +4 -3
  329. package/lib/typescript/components/stack/index.d.ts.map +1 -1
  330. package/lib/typescript/components/tabs/host/TabsHost.d.ts +5 -0
  331. package/lib/typescript/components/tabs/host/TabsHost.d.ts.map +1 -0
  332. package/lib/typescript/components/tabs/host/TabsHost.ios.d.ts.map +1 -1
  333. package/lib/typescript/components/tabs/host/TabsHost.ios.types.d.ts +72 -0
  334. package/lib/typescript/components/tabs/host/TabsHost.ios.types.d.ts.map +1 -1
  335. package/lib/typescript/components/tabs/host/TabsHost.types.d.ts +3 -0
  336. package/lib/typescript/components/tabs/host/TabsHost.types.d.ts.map +1 -1
  337. package/lib/typescript/components/tabs/index.d.ts +4 -6
  338. package/lib/typescript/components/tabs/index.d.ts.map +1 -1
  339. package/lib/typescript/components/tabs/screen/TabsScreen.android.d.ts.map +1 -1
  340. package/lib/typescript/components/tabs/screen/TabsScreen.android.types.d.ts +42 -7
  341. package/lib/typescript/components/tabs/screen/TabsScreen.android.types.d.ts.map +1 -1
  342. package/lib/typescript/components/tabs/screen/TabsScreen.d.ts +5 -0
  343. package/lib/typescript/components/tabs/screen/TabsScreen.d.ts.map +1 -0
  344. package/lib/typescript/components/tabs/screen/TabsScreen.ios.d.ts.map +1 -1
  345. package/lib/typescript/components/tabs/screen/TabsScreen.ios.types.d.ts +78 -13
  346. package/lib/typescript/components/tabs/screen/TabsScreen.ios.types.d.ts.map +1 -1
  347. package/lib/typescript/components/tabs/screen/TabsScreenIcon.types.d.ts +91 -0
  348. package/lib/typescript/components/tabs/screen/TabsScreenIcon.types.d.ts.map +1 -0
  349. package/lib/typescript/components/tabs/screen/index.d.ts +1 -0
  350. package/lib/typescript/components/tabs/screen/index.d.ts.map +1 -1
  351. package/lib/typescript/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.d.ts +2 -0
  352. package/lib/typescript/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.d.ts.map +1 -1
  353. package/lib/typescript/fabric/legacy/ScreenStackNativeComponent.d.ts +1 -0
  354. package/lib/typescript/fabric/legacy/ScreenStackNativeComponent.d.ts.map +1 -1
  355. package/lib/typescript/fabric/stack/StackHeaderConfigAndroidNativeComponent.d.ts +52 -0
  356. package/lib/typescript/fabric/stack/StackHeaderConfigAndroidNativeComponent.d.ts.map +1 -1
  357. package/lib/typescript/fabric/stack/StackHeaderConfigIOSNativeComponent.d.ts +29 -1
  358. package/lib/typescript/fabric/stack/StackHeaderConfigIOSNativeComponent.d.ts.map +1 -1
  359. package/lib/typescript/fabric/stack/StackHeaderItemIOSNativeComponent.d.ts +8 -0
  360. package/lib/typescript/fabric/stack/StackHeaderItemIOSNativeComponent.d.ts.map +1 -1
  361. package/lib/typescript/fabric/stack/StackHostNativeComponent.d.ts +3 -1
  362. package/lib/typescript/fabric/stack/StackHostNativeComponent.d.ts.map +1 -1
  363. package/lib/typescript/fabric/tabs/TabsHostIOSNativeComponent.d.ts +4 -0
  364. package/lib/typescript/fabric/tabs/TabsHostIOSNativeComponent.d.ts.map +1 -1
  365. package/lib/typescript/fabric/tabs/TabsScreenAndroidNativeComponent.d.ts +6 -0
  366. package/lib/typescript/fabric/tabs/TabsScreenAndroidNativeComponent.d.ts.map +1 -1
  367. package/lib/typescript/fabric/tabs/TabsScreenIOSNativeComponent.d.ts +10 -1
  368. package/lib/typescript/fabric/tabs/TabsScreenIOSNativeComponent.d.ts.map +1 -1
  369. package/lib/typescript/legacy/components/ScreenStackItem.d.ts +25 -0
  370. package/lib/typescript/legacy/components/ScreenStackItem.d.ts.map +1 -1
  371. package/lib/typescript/legacy/components/helpers/prepareHeaderBarButtonItems.d.ts +4 -0
  372. package/lib/typescript/legacy/components/helpers/prepareHeaderBarButtonItems.d.ts.map +1 -1
  373. package/lib/typescript/legacy/types.d.ts +30 -0
  374. package/lib/typescript/legacy/types.d.ts.map +1 -1
  375. package/package.json +11 -8
  376. package/react-native.config.js +3 -0
  377. package/src/components/modals/form-sheet/FormSheet.types.ts +1 -1
  378. package/src/components/stack/header/StackHeaderConfig.android.tsx +54 -43
  379. package/src/components/stack/header/StackHeaderConfig.android.types.ts +641 -24
  380. package/src/components/stack/header/StackHeaderConfig.ios.tsx +55 -17
  381. package/src/components/stack/header/StackHeaderConfig.ios.types.ts +384 -2
  382. package/src/components/stack/header/StackHeaderConfig.tsx +12 -0
  383. package/src/components/stack/header/StackHeaderConfig.types.ts +4 -2
  384. package/src/components/stack/header/ios/StackHeaderItem.ios.tsx +9 -1
  385. package/src/components/stack/header/ios/StackHeaderItem.ios.types.ts +7 -0
  386. package/src/components/stack/host/StackHost.tsx +12 -3
  387. package/src/components/stack/host/StackHost.types.ts +50 -0
  388. package/src/components/stack/host/StackHost.web.tsx +1 -4
  389. package/src/components/stack/index.ts +14 -1
  390. package/src/components/tabs/host/TabsHost.ios.tsx +3 -0
  391. package/src/components/tabs/host/TabsHost.ios.types.ts +76 -0
  392. package/src/components/tabs/host/TabsHost.tsx +7 -0
  393. package/src/components/tabs/host/TabsHost.types.ts +3 -0
  394. package/src/components/tabs/index.ts +9 -0
  395. package/src/components/tabs/screen/TabsScreen.android.tsx +8 -3
  396. package/src/components/tabs/screen/TabsScreen.android.types.ts +42 -7
  397. package/src/components/tabs/screen/TabsScreen.ios.tsx +22 -5
  398. package/src/components/tabs/screen/TabsScreen.ios.types.ts +79 -17
  399. package/src/components/tabs/screen/TabsScreen.tsx +7 -0
  400. package/src/components/tabs/screen/TabsScreenIcon.types.ts +117 -0
  401. package/src/components/tabs/screen/index.ts +1 -0
  402. package/src/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.ts +6 -0
  403. package/src/fabric/legacy/ScreenStackNativeComponent.ts +2 -0
  404. package/src/fabric/stack/StackHeaderConfigAndroidNativeComponent.ts +78 -0
  405. package/src/fabric/stack/StackHeaderConfigIOSNativeComponent.ts +43 -0
  406. package/src/fabric/stack/StackHeaderItemIOSNativeComponent.ts +13 -0
  407. package/src/fabric/stack/StackHostNativeComponent.ts +11 -2
  408. package/src/fabric/tabs/TabsHostIOSNativeComponent.ts +8 -0
  409. package/src/fabric/tabs/TabsScreenAndroidNativeComponent.ts +9 -0
  410. package/src/fabric/tabs/TabsScreenIOSNativeComponent.ts +20 -2
  411. package/src/legacy/components/ScreenStackItem.tsx +59 -12
  412. package/src/legacy/types.ts +31 -0
  413. package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenModalFragment.kt +0 -281
  414. package/android/src/main/java/com/swmansion/rnscreens/legacy/bottomsheet/BottomSheetDialogRootView.kt +0 -104
  415. package/android/src/main/java/com/swmansion/rnscreens/legacy/bottomsheet/BottomSheetDialogScreen.kt +0 -26
  416. package/android/src/main/java/com/swmansion/rnscreens/modals/dimmingview/DimmingView.kt +0 -83
  417. package/android/src/main/java/com/swmansion/rnscreens/modals/dimmingview/DimmingViewManager.kt +0 -89
  418. package/android/src/main/java/com/swmansion/rnscreens/modals/dimmingview/DimmingViewPointerEvents.kt +0 -18
  419. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/coordinator/FormSheetDimensionsCoordinator.kt +0 -134
  420. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/core/FormSheetDialogManager.kt +0 -162
  421. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/model/FormSheetDetents.kt +0 -106
  422. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/presentation/FormSheetPresentationManager.kt +0 -198
  423. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuSelectionController.kt +0 -83
  424. package/ios/conversion/RNSConversions-Stack.h +0 -32
  425. package/ios/conversion/RNSConversions-Stack.mm +0 -41
  426. package/ios/conversion/always_false.h +0 -31
  427. package/lib/commonjs/components/stack/header/StackHeaderConfig.web.js +0 -10
  428. package/lib/commonjs/components/stack/header/StackHeaderConfig.web.js.map +0 -1
  429. package/lib/commonjs/components/tabs/host/TabsHost.d.js +0 -2
  430. package/lib/commonjs/components/tabs/host/TabsHost.d.js.map +0 -1
  431. package/lib/commonjs/components/tabs/host/TabsHost.web.js.map +0 -1
  432. package/lib/commonjs/components/tabs/screen/TabsScreen.d.js +0 -2
  433. package/lib/commonjs/components/tabs/screen/TabsScreen.d.js.map +0 -1
  434. package/lib/commonjs/components/tabs/screen/TabsScreen.web.js.map +0 -1
  435. package/lib/module/components/stack/header/StackHeaderConfig.d.js +0 -2
  436. package/lib/module/components/stack/header/StackHeaderConfig.web.js +0 -4
  437. package/lib/module/components/stack/header/StackHeaderConfig.web.js.map +0 -1
  438. package/lib/module/components/tabs/host/TabsHost.d.js +0 -2
  439. package/lib/module/components/tabs/host/TabsHost.d.js.map +0 -1
  440. package/lib/module/components/tabs/host/TabsHost.web.js +0 -4
  441. package/lib/module/components/tabs/host/TabsHost.web.js.map +0 -1
  442. package/lib/module/components/tabs/screen/TabsScreen.d.js +0 -2
  443. package/lib/module/components/tabs/screen/TabsScreen.d.js.map +0 -1
  444. package/lib/module/components/tabs/screen/TabsScreen.web.js +0 -4
  445. package/lib/module/components/tabs/screen/TabsScreen.web.js.map +0 -1
  446. package/lib/typescript/components/stack/header/StackHeaderConfig.web.d.ts +0 -7
  447. package/lib/typescript/components/stack/header/StackHeaderConfig.web.d.ts.map +0 -1
  448. package/lib/typescript/components/tabs/host/TabsHost.web.d.ts +0 -7
  449. package/lib/typescript/components/tabs/host/TabsHost.web.d.ts.map +0 -1
  450. package/lib/typescript/components/tabs/screen/TabsScreen.web.d.ts +0 -7
  451. package/lib/typescript/components/tabs/screen/TabsScreen.web.d.ts.map +0 -1
  452. package/src/components/stack/header/StackHeaderConfig.d.ts +0 -22
  453. package/src/components/stack/header/StackHeaderConfig.web.tsx +0 -5
  454. package/src/components/tabs/host/TabsHost.d.ts +0 -12
  455. package/src/components/tabs/screen/TabsScreen.d.ts +0 -12
  456. /package/ios/{conversion → scroll-view-marker/conversion}/RNSConversions-ScrollViewMarker.h +0 -0
@@ -1,6 +1,7 @@
1
1
  #import "RNSStackScreenHeaderCoordinator.h"
2
2
  #import <React/RCTAssert.h>
3
3
  #import <React/RCTLog.h>
4
+ #import "RNSConversions-Stack.h"
4
5
  #import "RNSDefines.h"
5
6
  #import "RNSStackHeaderContentFactory.h"
6
7
  #import "RNSStackHeaderItemDataProviding.h"
@@ -15,6 +16,13 @@
15
16
  @implementation RNSStackScreenHeaderCoordinator {
16
17
  __weak RNSStackScreenController *_Nullable _screenController;
17
18
 
19
+ #if !TARGET_OS_TV
20
+ // Navigation item of the screen below, onto which the back button
21
+ // configuration has been applied. Kept so that the configuration can be
22
+ // cleared when the owning screen is popped from the stack.
23
+ __weak UINavigationItem *_Nullable _backButtonConfigTargetItem;
24
+ #endif // !TARGET_OS_TV
25
+
18
26
  RNSStackHeaderMenuTrackerRegistry *_Nonnull _trackerRegistry;
19
27
 
20
28
  NSMutableArray<UIBarButtonItem *> *_Nonnull _leadingBarButtonItems;
@@ -36,6 +44,17 @@
36
44
 
37
45
  #pragma mark - Public
38
46
 
47
+ - (void)updateNavigationBarVisibilityAnimated:(BOOL)animated
48
+ {
49
+ RNSStackNavigationController *navController = [self getNavigationController];
50
+ if (navController == nil || navController.topViewController != _screenController) {
51
+ return;
52
+ }
53
+
54
+ BOOL hidden = _configDataProvider == nil || _configDataProvider.hidden;
55
+ [navController.navigationBarCoordinator setHidden:hidden forNavigationController:navController animated:animated];
56
+ }
57
+
39
58
  - (void)rebuild
40
59
  {
41
60
  if (_configDataProvider == nil) {
@@ -104,7 +123,10 @@
104
123
  forController:controller];
105
124
 
106
125
  [self applyTitleMenuForController:controller];
107
- [self applyNavigationBarProperties];
126
+ [self updateNavigationBarVisibilityAnimated:YES];
127
+ #if !TARGET_OS_TV
128
+ [self updateBackButtonMenuEnabled];
129
+ #endif // !TARGET_OS_TV
108
130
  }
109
131
 
110
132
  - (void)applyConfigProperties
@@ -114,8 +136,24 @@
114
136
  }
115
137
 
116
138
  [self applyConfigPropertiesForController:[self requireScreenController]];
117
- [self applyNavigationBarProperties];
139
+ [self updateNavigationBarVisibilityAnimated:YES];
140
+ #if !TARGET_OS_TV
141
+ [self updateBackButtonMenuEnabled];
142
+ #endif // !TARGET_OS_TV
143
+ }
144
+
145
+ #if !TARGET_OS_TV
146
+ - (void)updateBackButtonMenuEnabled
147
+ {
148
+ RNSStackNavigationController *navController = [self getNavigationController];
149
+ if (navController == nil || navController.topViewController != _screenController) {
150
+ return;
151
+ }
152
+
153
+ BOOL enabled = _configDataProvider == nil || _configDataProvider.backButtonMenuEnabled;
154
+ [navController.navigationBarCoordinator setBackButtonMenuEnabled:enabled forNavigationController:navController];
118
155
  }
156
+ #endif // !TARGET_OS_TV
119
157
 
120
158
  /**
121
159
  Rebuilds an existing item: sets all props and applies the menu config.
@@ -266,6 +304,7 @@
266
304
  _configDataProvider = nil;
267
305
  _frameChangeDelegate = nil;
268
306
  _eventsDelegate = nil;
307
+ _imageLoader = nil;
269
308
 
270
309
  [_leadingBarButtonItems removeAllObjects];
271
310
  [_trailingBarButtonItems removeAllObjects];
@@ -277,6 +316,8 @@
277
316
 
278
317
  navItem.title = nil;
279
318
  navItem.titleView = nil;
319
+ navItem.standardAppearance = nil;
320
+ navItem.scrollEdgeAppearance = nil;
280
321
  [navItem setLeftBarButtonItems:@[] animated:YES];
281
322
  [navItem setRightBarButtonItems:@[] animated:YES];
282
323
 
@@ -296,14 +337,23 @@
296
337
  }
297
338
  #endif // RNS_IPHONE_OS_VERSION_AVAILABLE(26_0)
298
339
 
340
+ #if RNS_IPHONE_OS_VERSION_AVAILABLE(27_0)
341
+ if (@available(iOS 27.0, *)) {
342
+ navItem.navigationBarMinimization = [UIBarMinimization new];
343
+ }
344
+ #endif // Check for iOS >= 27
345
+
299
346
  #if !TARGET_OS_TV
347
+ navItem.prompt = nil;
300
348
  navItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeNever;
349
+
350
+ [self clearAppliedBackButtonConfig];
301
351
  #endif // !TARGET_OS_TV
302
352
 
303
- RNSStackNavigationController *navController = [self getNavigationController];
304
- if (navController != nil) {
305
- [navController.navigationBarCoordinator setHidden:NO forNavigationController:navController animated:YES];
306
- }
353
+ [self updateNavigationBarVisibilityAnimated:YES];
354
+ #if !TARGET_OS_TV
355
+ [self updateBackButtonMenuEnabled];
356
+ #endif // !TARGET_OS_TV
307
357
  }
308
358
 
309
359
  /**
@@ -328,19 +378,52 @@
328
378
 
329
379
  if (item.menu == nil) {
330
380
  barButtonItem.menu = nil;
381
+ } else {
382
+ RNSStackHeaderMenuToggleStateTracker *tracker = [_trackerRegistry trackerForItemId:itemId];
383
+ __weak auto weakSelf = self;
384
+ [RNSStackHeaderMenuCoordinator applyMenu:item.menu
385
+ toBarButtonItem:barButtonItem
386
+ withHeaderEventsDelegate:_eventsDelegate
387
+ stateTracker:tracker
388
+ withImageLoader:_imageLoader
389
+ menuInvalidatedCallback:^{
390
+ [weakSelf reapplyMenuForItemWithId:itemId];
391
+ }];
392
+ }
393
+
394
+ [self reapplyMenuRepresentationForItemWithId:itemId];
395
+ }
396
+
397
+ /**
398
+ Finds an existing barButtonItem and its corresponding config, then applies the menu
399
+ representation again. If the config is missing, it clears the representation.
400
+ */
401
+ - (void)reapplyMenuRepresentationForItemWithId:(NSString *)itemId
402
+ {
403
+ if (_configDataProvider == nil || itemId == nil) {
404
+ return;
405
+ }
406
+
407
+ UIBarButtonItem *barButtonItem = _barButtonItemsByItemId[itemId];
408
+ if (barButtonItem == nil) {
409
+ return;
410
+ }
411
+
412
+ id<RNSStackHeaderItemDataProviding> item = [self findItemWithId:itemId];
413
+ if (item == nil) {
331
414
  return;
332
415
  }
333
416
 
334
417
  RNSStackHeaderMenuToggleStateTracker *tracker = [_trackerRegistry trackerForItemId:itemId];
335
418
  __weak auto weakSelf = self;
336
- [RNSStackHeaderMenuCoordinator applyMenu:item.menu
337
- toBarButtonItem:barButtonItem
338
- withHeaderEventsDelegate:_eventsDelegate
339
- stateTracker:tracker
340
- withImageLoader:_imageLoader
341
- menuInvalidatedCallback:^{
342
- [weakSelf reapplyMenuForItemWithId:itemId];
343
- }];
419
+ [RNSStackHeaderMenuCoordinator applyMenuRepresentation:item.menuRepresentation
420
+ toBarButtonItem:barButtonItem
421
+ withHeaderEventsDelegate:_eventsDelegate
422
+ stateTracker:tracker
423
+ withImageLoader:_imageLoader
424
+ menuInvalidatedCallback:^{
425
+ [weakSelf reapplyMenuRepresentationForItemWithId:itemId];
426
+ }];
344
427
  }
345
428
 
346
429
  - (nullable id<RNSStackHeaderItemDataProviding>)findItemWithId:(NSString *)itemId
@@ -377,21 +460,25 @@
377
460
  return (RNSStackNavigationController *)navController;
378
461
  }
379
462
 
380
- - (void)applyNavigationBarProperties
381
- {
382
- RNSStackNavigationController *navController = [self getNavigationController];
383
- if (navController != nil) {
384
- [navController.navigationBarCoordinator setHidden:_configDataProvider.hidden
385
- forNavigationController:navController
386
- animated:YES];
387
- }
388
- }
389
-
390
463
  - (void)applyConfigPropertiesForController:(RNSStackScreenController *)controller
391
464
  {
392
465
  UINavigationItem *navItem = controller.navigationItem;
393
466
 
394
467
  navItem.title = _configDataProvider.title;
468
+ navItem.standardAppearance = _configDataProvider.standardAppearance;
469
+ navItem.scrollEdgeAppearance = _configDataProvider.scrollEdgeAppearance;
470
+
471
+ #if !TARGET_OS_TV
472
+ NSString *prompt = _configDataProvider.prompt;
473
+ if (navItem.prompt != prompt && ![navItem.prompt isEqualToString:prompt]) {
474
+ navItem.prompt = prompt;
475
+ // UIKit does not resize an already visible navigation bar when the prompt
476
+ // of its navigation item changes - request layout explicitly.
477
+ [controller.navigationController.view setNeedsLayout];
478
+ }
479
+
480
+ [self applyBackButtonConfigForController:controller];
481
+ #endif // !TARGET_OS_TV
395
482
 
396
483
  #if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0)
397
484
  if (@available(iOS 26.0, *)) {
@@ -401,12 +488,47 @@
401
488
  }
402
489
  #endif // RNS_IPHONE_OS_VERSION_AVAILABLE(26_0)
403
490
 
491
+ #if RNS_IPHONE_OS_VERSION_AVAILABLE(27_0)
492
+ if (@available(iOS 27.0, *)) {
493
+ UIBarMinimization *minimization = [UIBarMinimization new];
494
+ minimization.minimizationBehavior = _configDataProvider.minimizationBehavior;
495
+ minimization.restorationBehavior = _configDataProvider.restorationBehavior;
496
+ navItem.navigationBarMinimization = minimization;
497
+ }
498
+ #endif // Check for iOS >= 27
499
+
404
500
  #if !TARGET_OS_TV
405
501
  navItem.largeTitleDisplayMode = _configDataProvider.largeTitleEnabled ? UINavigationItemLargeTitleDisplayModeAlways
406
502
  : UINavigationItemLargeTitleDisplayModeNever;
407
503
  #endif // !TARGET_OS_TV
408
504
  }
409
505
 
506
+ #if !TARGET_OS_TV
507
+ - (void)applyBackButtonConfigForController:(RNSStackScreenController *)controller
508
+ {
509
+ NSArray<UIViewController *> *viewControllers = controller.navigationController.viewControllers;
510
+ NSUInteger index = [viewControllers indexOfObject:controller];
511
+ if (index == NSNotFound || index == 0) {
512
+ return;
513
+ }
514
+
515
+ UINavigationItem *prevItem = viewControllers[index - 1].navigationItem;
516
+ _backButtonConfigTargetItem = prevItem;
517
+ prevItem.backButtonTitle = _configDataProvider.backButtonTitle;
518
+ prevItem.backButtonDisplayMode = _configDataProvider.backButtonDisplayMode;
519
+ }
520
+ #endif // !TARGET_OS_TV
521
+
522
+ #if !TARGET_OS_TV
523
+ - (void)clearAppliedBackButtonConfig
524
+ {
525
+ UINavigationItem *targetItem = _backButtonConfigTargetItem;
526
+ _backButtonConfigTargetItem = nil;
527
+ targetItem.backButtonTitle = nil;
528
+ targetItem.backButtonDisplayMode = UINavigationItemBackButtonDisplayModeDefault;
529
+ }
530
+ #endif // !TARGET_OS_TV
531
+
410
532
  - (void)applyItemsWithTitleView:(nullable UIView *)titleView
411
533
  subtitleView:(nullable UIView *)subtitleView
412
534
  largeSubtitleView:(nullable UIView *)largeSubtitleView
@@ -471,6 +593,25 @@
471
593
  withHeaderEventsDelegate:_eventsDelegate
472
594
  withImageLoader:_imageLoader];
473
595
 
596
+ #if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0)
597
+ if (@available(iOS 26.0, *)) {
598
+ if (item.identifier != nil) {
599
+ barButtonItem.identifier = item.identifier;
600
+ }
601
+ barButtonItem.hidesSharedBackground = item.hidesSharedBackground;
602
+ }
603
+ #endif // RNS_IPHONE_OS_VERSION_AVAILABLE(26_0)
604
+
605
+ // tvOS and visionOS are excluded on purpose: `visibilityPriority` exists there, but the only
606
+ // supported value is `standard`, which is already the default.
607
+ #if RNS_IPHONE_OS_VERSION_AVAILABLE(27_0) && !TARGET_OS_TV && !TARGET_OS_VISION
608
+ if (@available(iOS 27.0, *)) {
609
+ barButtonItem.visibilityPriority =
610
+ rnscreens::conversion::UIBarButtonItemVisibilityPriorityFromRNSHeaderItemVisibilityPriority(
611
+ item.visibilityPriority);
612
+ }
613
+ #endif // RNS_IPHONE_OS_VERSION_AVAILABLE(27_0) && !TARGET_OS_TV && !TARGET_OS_VISION
614
+
474
615
  if (item.menu != nil && item.itemId != nil) {
475
616
  RNSStackHeaderMenuToggleStateTracker *tracker = [_trackerRegistry trackerForItemId:item.itemId];
476
617
  __weak auto weakSelf = self;
@@ -485,6 +626,20 @@
485
626
  }];
486
627
  }
487
628
 
629
+ if (item.menuRepresentation != nil && item.itemId != nil) {
630
+ RNSStackHeaderMenuToggleStateTracker *tracker = [_trackerRegistry trackerForItemId:item.itemId];
631
+ __weak auto weakSelf = self;
632
+ NSString *capturedItemId = item.itemId;
633
+ [RNSStackHeaderMenuCoordinator applyMenuRepresentation:item.menuRepresentation
634
+ toBarButtonItem:barButtonItem
635
+ withHeaderEventsDelegate:_eventsDelegate
636
+ stateTracker:tracker
637
+ withImageLoader:_imageLoader
638
+ menuInvalidatedCallback:^{
639
+ [weakSelf reapplyMenuRepresentationForItemWithId:capturedItemId];
640
+ }];
641
+ }
642
+
488
643
  if (item.itemId != nil) {
489
644
  _barButtonItemsByItemId[item.itemId] = barButtonItem;
490
645
  }
@@ -1,13 +1,29 @@
1
1
  #import "RNSTabBarAppearanceCoordinator.h"
2
2
  #import <React/RCTFont.h>
3
3
  #import <React/RCTImageLoader.h>
4
+ #import <React/RCTLog.h>
4
5
  #import "RCTConvert+RNSTabs.h"
5
- #import "RNSConversions.h"
6
+ #import "RNSConversions-Tabs.h"
7
+ #import "RNSDefines.h"
6
8
  #import "RNSImageLoadingHelper.h"
7
9
  #import "RNSTabBarController.h"
8
10
  #import "RNSTabsHostComponentView.h"
9
11
  #import "RNSTabsScreenViewController.h"
10
12
 
13
+ static UIImage *_Nullable RNSImageWithSymbolRenderingMode(UIImage *_Nullable image,
14
+ RNSTabsIconSymbolRenderingMode renderingMode)
15
+ {
16
+ switch (renderingMode) {
17
+ case RNSTabsIconSymbolRenderingModeMonochrome:
18
+ return [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
19
+ case RNSTabsIconSymbolRenderingModeOriginal:
20
+ return [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
21
+ case RNSTabsIconSymbolRenderingModeDefault:
22
+ default:
23
+ return image;
24
+ }
25
+ }
26
+
11
27
  @implementation RNSTabBarAppearanceCoordinator
12
28
 
13
29
  - (void)updateAppearanceOfTabBar:(nullable UITabBar *)tabBar
@@ -55,42 +71,94 @@
55
71
  withImageLoader:imageLoader];
56
72
  }
57
73
 
74
+ /// Sets the normal icon on both the item (renders the iPhone bar) and the UITab (renders the
75
+ /// iPad floating bar / sidebar, which never reads the item).
76
+ - (void)setTabImage:(nullable UIImage *)image
77
+ forTabBarItem:(nonnull UITabBarItem *)tabBarItem
78
+ screenView:(nullable RNSTabsScreenComponentView *)screenView
79
+ {
80
+ #if RNS_UITAB_API_SDK_AVAILABLE
81
+ if (RNS_UITAB_API_ENABLED) {
82
+ screenView.controller.tab.image = image;
83
+ }
84
+ #endif // RNS_UITAB_API_SDK_AVAILABLE
85
+ // This needs to be called after tab.image assignment
86
+ // (see https://github.com/software-mansion/react-native-screens/pull/4813)
87
+ tabBarItem.image = image;
88
+ }
89
+
58
90
  - (void)setIconsForTabBarItem:(UITabBarItem *)tabBarItem
59
91
  fromScreenView:(RNSTabsScreenComponentView *)screenView
60
92
  withImageLoader:(RCTImageLoader *_Nullable)imageLoader
61
93
  {
62
94
  if (screenView.iconType == RNSTabsIconTypeSfSymbol || screenView.iconType == RNSTabsIconTypeXcasset) {
63
95
  if (screenView.iconResourceName != nil) {
96
+ UIImage *image;
64
97
  if (screenView.iconType == RNSTabsIconTypeSfSymbol) {
65
- tabBarItem.image = [UIImage systemImageNamed:screenView.iconResourceName];
98
+ image = [RNSImageLoadingHelper symbolImageNamed:screenView.iconResourceName];
99
+ if (image == nil) {
100
+ RCTLogWarn(@"[RNScreens] Failed to load SF Symbol \"%@\" for tab bar item", screenView.iconResourceName);
101
+ }
66
102
  } else {
67
- tabBarItem.image = [UIImage imageNamed:screenView.iconResourceName];
103
+ image = [UIImage imageNamed:screenView.iconResourceName];
104
+ if (image == nil) {
105
+ RCTLogWarn(@"[RNScreens] Failed to load xcasset \"%@\" for tab bar item", screenView.iconResourceName);
106
+ }
68
107
  }
108
+ [self setTabImage:RNSImageWithSymbolRenderingMode(image, screenView.iconSymbolRenderingMode)
109
+ forTabBarItem:tabBarItem
110
+ screenView:screenView];
69
111
  } else if (screenView.systemItem != RNSTabsScreenSystemItemNone) {
70
112
  // Restore default system item icon
71
- UITabBarSystemItem systemItem =
113
+ std::optional<UITabBarSystemItem> systemItem =
72
114
  rnscreens::conversion::RNSTabsScreenSystemItemToUITabBarSystemItem(screenView.systemItem);
73
- tabBarItem.image = [[UITabBarItem alloc] initWithTabBarSystemItem:systemItem tag:0].image;
115
+ if (!systemItem) {
116
+ RCTLogError(
117
+ @"[RNScreens] Conversion from tabs screen systemItem to UITabBarSystemItem failed for systemItem [%ld]",
118
+ (long)screenView.systemItem);
119
+ return;
120
+ }
121
+ UIImage *_Nullable systemItemImage =
122
+ [[UITabBarItem alloc] initWithTabBarSystemItem:systemItem.value() tag:0].image;
123
+ [self setTabImage:systemItemImage forTabBarItem:tabBarItem screenView:screenView];
74
124
  } else {
75
- tabBarItem.image = nil;
125
+ [self setTabImage:nil forTabBarItem:tabBarItem screenView:screenView];
76
126
  }
77
127
 
78
128
  if (screenView.selectedIconResourceName != nil) {
129
+ UIImage *selectedImage;
79
130
  if (screenView.iconType == RNSTabsIconTypeSfSymbol) {
80
- tabBarItem.selectedImage = [UIImage systemImageNamed:screenView.selectedIconResourceName];
131
+ selectedImage = [RNSImageLoadingHelper symbolImageNamed:screenView.selectedIconResourceName];
132
+ if (selectedImage == nil) {
133
+ RCTLogWarn(@"[RNScreens] Failed to load SF Symbol \"%@\" for selected tab bar item",
134
+ screenView.selectedIconResourceName);
135
+ }
81
136
  } else {
82
- tabBarItem.selectedImage = [UIImage imageNamed:screenView.selectedIconResourceName];
137
+ selectedImage = [UIImage imageNamed:screenView.selectedIconResourceName];
138
+ if (selectedImage == nil) {
139
+ RCTLogWarn(@"[RNScreens] Failed to load xcasset \"%@\" for selected tab bar item",
140
+ screenView.selectedIconResourceName);
141
+ }
83
142
  }
143
+ tabBarItem.selectedImage =
144
+ RNSImageWithSymbolRenderingMode(selectedImage, screenView.selectedIconSymbolRenderingMode);
84
145
  } else if (screenView.systemItem != RNSTabsScreenSystemItemNone) {
85
146
  // Restore default system item icon
86
- UITabBarSystemItem systemItem =
147
+ std::optional<UITabBarSystemItem> systemItem =
87
148
  rnscreens::conversion::RNSTabsScreenSystemItemToUITabBarSystemItem(screenView.systemItem);
88
- tabBarItem.selectedImage = [[UITabBarItem alloc] initWithTabBarSystemItem:systemItem tag:0].selectedImage;
149
+ if (!systemItem) {
150
+ RCTLogError(
151
+ @"[RNScreens] Conversion from tabs screen systemItem to UITabBarSystemItem failed for systemItem [%ld]",
152
+ (long)screenView.systemItem);
153
+ return;
154
+ }
155
+ tabBarItem.selectedImage = [[UITabBarItem alloc] initWithTabBarSystemItem:systemItem.value() tag:0].selectedImage;
89
156
  } else {
90
157
  tabBarItem.selectedImage = nil;
91
158
  }
92
159
  } else if (imageLoader != nil) {
93
- bool isTemplate = screenView.iconType == RNSTabsIconTypeTemplate;
160
+ bool isTemplate = screenView.iconImageRenderingMode == RNSTabsIconImageRenderingModeTemplate;
161
+ bool isSelectedTemplate = screenView.selectedIconImageRenderingMode == RNSTabsIconImageRenderingModeTemplate;
94
162
 
95
163
  // Weak-capture to avoid updating a tab bar item whose internal
96
164
  // view hierarchy has been torn down (iOS 26 UIKit regression:
@@ -110,14 +178,14 @@
110
178
  forScreenView:weakScreenView];
111
179
  }];
112
180
  } else {
113
- tabBarItem.image = nil;
181
+ [self setTabImage:nil forTabBarItem:tabBarItem screenView:screenView];
114
182
  }
115
183
 
116
184
  // Selected icon
117
185
  if (screenView.selectedIconImageSource != nil) {
118
186
  [RNSImageLoadingHelper loadImageFromSource:screenView.selectedIconImageSource
119
187
  withImageLoader:imageLoader
120
- asTemplate:isTemplate
188
+ asTemplate:isSelectedTemplate
121
189
  completionBlock:^(UIImage *image) {
122
190
  [self updateTabBarItem:weakTabBarItem
123
191
  withImage:image
@@ -132,6 +200,22 @@
132
200
  }
133
201
  }
134
202
 
203
+ /// Whether the screen is still managed by a tab bar controller. On the UITab path the controller of
204
+ /// a tab that overflows into More has no parent until the tab is first shown (UIKit parents it
205
+ /// lazily), but its `UITab` is installed - the tab is the liveness check there, not the parent.
206
+ - (BOOL)isScreenControllerAttachedToTabBarController:(nullable RNSTabsScreenViewController *)screenController
207
+ {
208
+ if (screenController == nil) {
209
+ return NO;
210
+ }
211
+ #if RNS_UITAB_API_SDK_AVAILABLE
212
+ if (RNS_UITAB_API_ENABLED) {
213
+ return screenController.tab.tabBarController != nil;
214
+ }
215
+ #endif // RNS_UITAB_API_SDK_AVAILABLE
216
+ return screenController.parentViewController != nil;
217
+ }
218
+
135
219
  - (void)updateTabBarItem:(nullable UITabBarItem *)tabBarItem
136
220
  withImage:(nullable UIImage *)image
137
221
  isSelected:(BOOL)isSelected
@@ -144,16 +228,26 @@
144
228
  return;
145
229
  }
146
230
 
147
- UIViewController *screenParentViewController = [screenView.controller parentViewController];
148
- if (screenParentViewController == nil) {
231
+ if (![self isScreenControllerAttachedToTabBarController:screenView.controller]) {
149
232
  return;
150
233
  }
151
234
 
152
235
  if (isSelected) {
153
236
  tabBarItem.selectedImage = image;
154
237
  } else {
155
- tabBarItem.image = image;
238
+ [self setTabImage:image forTabBarItem:tabBarItem screenView:screenView];
239
+ }
240
+
241
+ UIViewController *screenParentViewController = [screenView.controller parentViewController];
242
+ #if RNS_UITAB_API_SDK_AVAILABLE
243
+ if (RNS_UITAB_API_ENABLED) {
244
+ if (screenParentViewController == nil) {
245
+ // A tab that overflows into More and has not been shown yet - UIKit parents it lazily. Its
246
+ // icon lives in the More list, not in the bar, so there is nothing to lay out.
247
+ return;
248
+ }
156
249
  }
250
+ #endif // RNS_UITAB_API_SDK_AVAILABLE
157
251
 
158
252
  // A layout pass is required because the image might be loaded asynchronously,
159
253
  // after the tab bar has already been attached to the window.
@@ -0,0 +1,16 @@
1
+ #pragma once
2
+
3
+ #import <Foundation/Foundation.h>
4
+ #import "RNSTabsScreenViewController.h"
5
+
6
+ NS_ASSUME_NONNULL_BEGIN
7
+
8
+ @interface RNSTabBarItemCoordinator : NSObject
9
+
10
+ - (void)createTabBarItemsForTabScreenControllers:(nullable NSArray<RNSTabsScreenViewController *> *)tabScreenCtrls;
11
+
12
+ - (void)updateTabBarItemsForTabScreenControllers:(nullable NSArray<RNSTabsScreenViewController *> *)tabScreenCtrls;
13
+
14
+ @end
15
+
16
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,143 @@
1
+ #import "RNSTabBarItemCoordinator.h"
2
+ #import <React/RCTLog.h>
3
+ #import "RNSConversions-Tabs.h"
4
+ #import "RNSDefines.h"
5
+ #import "RNSTabsScreenComponentView.h"
6
+
7
+ @implementation RNSTabBarItemCoordinator
8
+
9
+ /**
10
+ * Creates UITabBarItem instance with set systemItem. Needs to be called before UITab creation for the same
11
+ * viewController.
12
+ */
13
+ - (void)createTabBarItemsForTabScreenControllers:(nullable NSArray<RNSTabsScreenViewController *> *)tabScreenCtrls
14
+ {
15
+ for (RNSTabsScreenViewController *tabScreenCtrl in tabScreenCtrls) {
16
+ RNSTabsScreenComponentView *screenView = tabScreenCtrl.tabScreenComponentView;
17
+ if (screenView == nil) {
18
+ RCTLogWarn(@"[RNScreens] Nullish component view of TabScreen while tab bar item creation!");
19
+ continue;
20
+ }
21
+
22
+ if (screenView.tabBarItemNeedsRecreation) {
23
+ screenView.tabBarItemNeedsRecreation = NO;
24
+ [self createTabBarItemForTabScreenController:tabScreenCtrl];
25
+ }
26
+ }
27
+ }
28
+
29
+ /**
30
+ * Updates the runtime properties of UITabBarItem: title and badge. If used with UITab API, it should be called after
31
+ * the tab is built.
32
+ */
33
+ - (void)updateTabBarItemsForTabScreenControllers:(nullable NSArray<RNSTabsScreenViewController *> *)tabScreenCtrls
34
+ {
35
+ for (RNSTabsScreenViewController *tabScreenCtrl in tabScreenCtrls) {
36
+ RNSTabsScreenComponentView *screenView = tabScreenCtrl.tabScreenComponentView;
37
+ if (screenView == nil) {
38
+ RCTLogWarn(@"[RNScreens] Nullish component view of TabScreen while tab bar item update!");
39
+ continue;
40
+ }
41
+
42
+ if (screenView.tabBarItemNeedsUpdate) {
43
+ screenView.tabBarItemNeedsUpdate = NO;
44
+ [self updateTabBarItemForTabScreenController:tabScreenCtrl];
45
+ }
46
+ }
47
+ }
48
+
49
+ - (void)createTabBarItemForTabScreenController:(nonnull RNSTabsScreenViewController *)tabScreenCtrl
50
+ {
51
+ RNSTabsScreenComponentView *screenView = tabScreenCtrl.tabScreenComponentView;
52
+
53
+ UITabBarItem *tabBarItem = nil;
54
+ if (screenView.systemItem != RNSTabsScreenSystemItemNone) {
55
+ std::optional<UITabBarSystemItem> systemItem =
56
+ rnscreens::conversion::RNSTabsScreenSystemItemToUITabBarSystemItem(screenView.systemItem);
57
+ if (!systemItem) {
58
+ RCTLogError(
59
+ @"[RNScreens] Conversion from tabs screen systemItem to UITabBarSystemItem failed for systemItem [%ld]",
60
+ (long)screenView.systemItem);
61
+ return;
62
+ }
63
+ tabBarItem = [[UITabBarItem alloc] initWithTabBarSystemItem:systemItem.value() tag:0];
64
+ } else {
65
+ tabBarItem = [[UITabBarItem alloc] init];
66
+ }
67
+
68
+ [self applyTabBarItemRepaintWorkaroundForTabScreenController:tabScreenCtrl];
69
+ tabScreenCtrl.tabBarItem = tabBarItem;
70
+ }
71
+
72
+ /**
73
+ * TODO: This is an ugly workaround and I would love to see it replaced.
74
+ * With UITab-managed children (iOS >= 26.1) any change to the systemItem for the first time
75
+ * results in missing icon and wrong title. Assigning a throwaway item first flips the internal logic
76
+ * so that the real assignment that follows paints synchronously.
77
+ * Remove once UIKit internals no longer require it.
78
+ */
79
+ - (void)applyTabBarItemRepaintWorkaroundForTabScreenController:(nonnull RNSTabsScreenViewController *)tabScreenCtrl
80
+ {
81
+ #if RNS_UITAB_API_SDK_AVAILABLE
82
+ if (RNS_UITAB_API_ENABLED) {
83
+ tabScreenCtrl.tabBarItem = [[UITabBarItem alloc] init];
84
+ }
85
+ #endif // RNS_UITAB_API_SDK_AVAILABLE
86
+ }
87
+
88
+ - (void)updateTabBarItemForTabScreenController:(nonnull RNSTabsScreenViewController *)tabScreenCtrl
89
+ {
90
+ RNSTabsScreenComponentView *screenView = tabScreenCtrl.tabScreenComponentView;
91
+
92
+ NSString *evaluatedTitle = screenView.title;
93
+ if (screenView.title == nil && screenView.systemItem != RNSTabsScreenSystemItemNone) {
94
+ // Restore default system item title
95
+ std::optional<UITabBarSystemItem> systemItem =
96
+ rnscreens::conversion::RNSTabsScreenSystemItemToUITabBarSystemItem(screenView.systemItem);
97
+ if (!systemItem) {
98
+ RCTLogError(
99
+ @"[RNScreens] Conversion from tabs screen systemItem to UITabBarSystemItem failed for systemItem [%ld]",
100
+ (long)screenView.systemItem);
101
+ return;
102
+ }
103
+ evaluatedTitle = [[UITabBarItem alloc] initWithTabBarSystemItem:systemItem.value() tag:0].title;
104
+ }
105
+
106
+ [self updateTabBarItemTitle:evaluatedTitle forTabScreenController:tabScreenCtrl];
107
+ [self updateTabBarItemBadge:screenView.badgeValue forTabScreenController:tabScreenCtrl];
108
+ }
109
+
110
+ - (void)updateTabBarItemTitle:(NSString *)newTitle
111
+ forTabScreenController:(nonnull RNSTabsScreenViewController *)tabScreenCtrl
112
+ {
113
+ // Setting controller title updates also controller's tabBarItem.title but only if there
114
+ // is a change to controller title. After creating new tabBarItem, controller title
115
+ // remains the same but tabBarItem.title is nil. For consistency, we always
116
+ // update both.
117
+ if (![tabScreenCtrl.tabBarItem.title isEqualToString:newTitle] || ![tabScreenCtrl.title isEqualToString:newTitle]) {
118
+ tabScreenCtrl.title = newTitle;
119
+ tabScreenCtrl.tabBarItem.title = newTitle;
120
+ #if RNS_UITAB_API_SDK_AVAILABLE
121
+ if (RNS_UITAB_API_ENABLED) {
122
+ // iPad sources the rendered title from the tab, not the item.
123
+ tabScreenCtrl.tab.title = newTitle;
124
+ }
125
+ #endif // RNS_UITAB_API_SDK_AVAILABLE
126
+ }
127
+ }
128
+
129
+ - (void)updateTabBarItemBadge:(NSString *)badgeValue
130
+ forTabScreenController:(nonnull RNSTabsScreenViewController *)tabScreenCtrl
131
+ {
132
+ if (![tabScreenCtrl.tabBarItem.badgeValue isEqualToString:badgeValue]) {
133
+ // The badge must land on both the item (viewController API) and the tab (UITab API) to render.
134
+ tabScreenCtrl.tabBarItem.badgeValue = badgeValue;
135
+ #if RNS_UITAB_API_SDK_AVAILABLE
136
+ if (RNS_UITAB_API_ENABLED) {
137
+ tabScreenCtrl.tab.badgeValue = badgeValue;
138
+ }
139
+ #endif // RNS_UITAB_API_SDK_AVAILABLE
140
+ }
141
+ }
142
+
143
+ @end
@@ -5,7 +5,7 @@
5
5
  #import "RNSTabsHostComponentView.h"
6
6
 
7
7
  #if defined(__cplusplus)
8
- #import <rnscreens/RNSTabsBottomAccessoryComponentDescriptor.h>
8
+ #import <react/renderer/components/rnscreens/RNSTabsBottomAccessoryComponentDescriptor.h>
9
9
  #endif // defined(__cplusplus)
10
10
 
11
11
  NS_ASSUME_NONNULL_BEGIN