react-native-screens 5.0.0-alpha.3 → 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 (337) hide show
  1. package/README.md +0 -4
  2. package/android/build.gradle +1 -0
  3. package/android/consumer-rules.pro +3 -0
  4. package/android/src/fabric/java/com/swmansion/rnscreens/legacy/FabricEnabledHeaderConfigViewGroup.kt +2 -0
  5. package/android/src/fabric/java/com/swmansion/rnscreens/legacy/FabricEnabledHeaderSubviewViewGroup.kt +2 -0
  6. package/android/src/fabric/java/com/swmansion/rnscreens/legacy/FabricEnabledViewGroup.kt +18 -3
  7. package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +2 -2
  8. package/android/src/main/java/com/swmansion/rnscreens/ScreensModule.kt +7 -3
  9. package/android/src/main/java/com/swmansion/rnscreens/common/colorscheme/ColorSchemeCoordinator.kt +11 -1
  10. package/android/src/main/java/com/swmansion/rnscreens/common/container/Container.kt +9 -0
  11. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/coordinator/FormSheetAppearanceCoordinator.kt +2 -2
  12. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/coordinator/FormSheetBehaviorController.kt +2 -2
  13. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/coordinator/FormSheetDimensionsCoordinator.kt +6 -6
  14. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/coordinator/FormSheetKeyboardCoordinator.kt +1 -1
  15. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/coordinator/FormSheetNativeDismissCoordinator.kt +2 -2
  16. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native/core → core/modals/formsheet/dialog}/FormSheetAvailableHeightProvider.kt +1 -1
  17. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native/core → core/modals/formsheet/dialog}/FormSheetContainer.kt +1 -1
  18. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native/core → core/modals/formsheet/dialog}/FormSheetDialog.kt +1 -1
  19. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native/core → core/modals/formsheet/dialog}/FormSheetDialogManager.kt +26 -8
  20. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/interfaces/FormSheetContentSizeChangeDelegate.kt +1 -1
  21. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/interfaces/FormSheetContentSizeChangeProvider.kt +1 -1
  22. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/interfaces/FormSheetDialogEventEmitter.kt +1 -1
  23. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/model/FormSheetConfig.kt +1 -1
  24. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/model/FormSheetDetents.kt +1 -1
  25. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/presentation/FormSheetAnimatorFactory.kt +1 -1
  26. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/presentation/FormSheetDimmingManager.kt +6 -18
  27. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/presentation/FormSheetDismissalOrigin.kt +1 -1
  28. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/presentation/FormSheetPresentation.kt +10 -10
  29. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/presentation/FormSheetPresentationManager.kt +1 -1
  30. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/presentation/FormSheetPresentationState.kt +1 -1
  31. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/presentation/FormSheetStackRegistry.kt +1 -1
  32. package/android/src/main/java/com/swmansion/rnscreens/ext/FragmentManagerExt.kt +6 -0
  33. package/android/src/main/java/com/swmansion/rnscreens/helpers/FragmentManagerHelper.kt +0 -3
  34. package/android/src/main/java/com/swmansion/rnscreens/helpers/NoTintDrawable.kt +31 -0
  35. package/android/src/main/java/com/swmansion/rnscreens/helpers/ViewFinder.kt +0 -17
  36. package/android/src/main/java/com/swmansion/rnscreens/legacy/Screen.kt +29 -2
  37. package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenContainer.kt +35 -3
  38. package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenStack.kt +13 -0
  39. package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenStackHeaderConfig.kt +7 -1
  40. package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenStackHeaderSubviewManager.kt +7 -0
  41. package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenStackViewManager.kt +6 -0
  42. package/android/src/main/java/com/swmansion/rnscreens/legacy/bottomsheet/DimmingView.kt +2 -0
  43. package/android/src/main/java/com/swmansion/rnscreens/legacy/stack/views/ScreensCoordinatorLayout.kt +2 -0
  44. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/contentwrapper/FormSheetContentWrapper.kt +3 -3
  45. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/contentwrapper/FormSheetContentWrapperViewManager.kt +1 -1
  46. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetDetentChangedEvent.kt +1 -1
  47. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetDidAppearEvent.kt +1 -1
  48. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetDidDisappearEvent.kt +1 -1
  49. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetDismissEvent.kt +1 -1
  50. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetNativeDismissEvent.kt +1 -1
  51. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetNativeDismissPreventedEvent.kt +1 -1
  52. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetSyncFlushEvent.kt +1 -1
  53. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetWillAppearEvent.kt +1 -1
  54. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetWillDisappearEvent.kt +1 -1
  55. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/host/FormSheetContentView.kt +3 -3
  56. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/host/FormSheetHost.kt +5 -3
  57. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/host/FormSheetHostEventEmitter.kt +11 -11
  58. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/host/FormSheetHostViewManager.kt +10 -10
  59. package/android/src/main/java/com/swmansion/rnscreens/safearea/OnInterfaceInsetsChangeListener.kt +15 -0
  60. package/android/src/main/java/com/swmansion/rnscreens/safearea/SafeAreaProvider.kt +8 -8
  61. package/android/src/main/java/com/swmansion/rnscreens/safearea/SafeAreaView.kt +3 -2
  62. package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderApplicator.kt +0 -52
  63. package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderCoordinatorLayout.kt +112 -59
  64. package/android/src/main/java/com/swmansion/rnscreens/stack/header/appbar/StackHeaderAppBarLayout.kt +1 -1
  65. package/android/src/main/java/com/swmansion/rnscreens/stack/header/appbar/StackHeaderToolbar.kt +74 -0
  66. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfig.kt +4 -73
  67. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigurationObserver.kt +5 -2
  68. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigurationProviding.kt +0 -6
  69. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderInvalidationFlags.kt +3 -7
  70. package/android/src/main/java/com/swmansion/rnscreens/stack/host/FragmentOperation.kt +1 -0
  71. package/android/src/main/java/com/swmansion/rnscreens/stack/host/FragmentOperationExecutor.kt +2 -1
  72. package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackContainer.kt +57 -19
  73. package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackContainerDelegate.kt +7 -0
  74. package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackContainerUpdateCoordinator.kt +5 -3
  75. package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackHost.kt +14 -5
  76. package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackUpdateBatchStateProviding.kt +10 -0
  77. package/android/src/main/java/com/swmansion/rnscreens/stack/screen/PreventNativeDismissCallback.kt +2 -2
  78. package/android/src/main/java/com/swmansion/rnscreens/stack/screen/StackScreenFragment.kt +33 -12
  79. package/android/src/main/java/com/swmansion/rnscreens/tabs/appearance/TabsAppearanceApplicator.kt +106 -10
  80. package/android/src/main/java/com/swmansion/rnscreens/tabs/appearance/TabsAppearanceCoordinator.kt +44 -3
  81. package/android/src/main/java/com/swmansion/rnscreens/tabs/appearance/TabsAppearanceModel.kt +3 -0
  82. package/android/src/main/java/com/swmansion/rnscreens/tabs/container/CustomBottomNavigationView.kt +21 -1
  83. package/android/src/main/java/com/swmansion/rnscreens/tabs/container/TabsContainer.kt +28 -13
  84. package/android/src/main/java/com/swmansion/rnscreens/tabs/container/TabsContainerDelegate.kt +11 -0
  85. package/android/src/main/java/com/swmansion/rnscreens/tabs/host/TabsHost.kt +12 -2
  86. package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreen.kt +41 -17
  87. package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreenDelegate.kt +6 -0
  88. package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreenIcon.kt +82 -0
  89. package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreenIconTinting.kt +17 -0
  90. package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreenViewManager.kt +26 -19
  91. package/android/src/main/java/com/swmansion/rnscreens/utils/DimensionUtils.kt +14 -7
  92. package/android/src/main/java/com/swmansion/rnscreens/utils/RNSLog.kt +22 -6
  93. package/ios/RNSEnums.h +14 -1
  94. package/ios/helpers/image/RNSImageLoadingHelper.h +7 -0
  95. package/ios/helpers/image/RNSImageLoadingHelper.mm +9 -0
  96. package/ios/legacy/RNSBarButtonItem.mm +15 -0
  97. package/ios/legacy/RNSConvert.h +6 -0
  98. package/ios/legacy/RNSConvert.mm +17 -0
  99. package/ios/legacy/RNSNavigationBar.h +31 -0
  100. package/ios/legacy/RNSNavigationBar.mm +15 -0
  101. package/ios/legacy/RNSScreen.mm +122 -12
  102. package/ios/legacy/RNSScreenContentWrapper.mm +4 -1
  103. package/ios/legacy/RNSScreenStack.mm +202 -15
  104. package/ios/legacy/RNSScreenStackHeaderConfig.h +30 -0
  105. package/ios/legacy/RNSScreenStackHeaderConfig.mm +70 -17
  106. package/ios/legacy/RNSScreenStackHeaderSubview.mm +33 -0
  107. package/ios/safe-area/RNSSafeAreaViewComponentView.mm +1 -12
  108. package/ios/stack/conversion/RNSConversions-Stack.h +30 -0
  109. package/ios/stack/conversion/RNSConversions-Stack.mm +79 -0
  110. package/ios/stack/header/RNSHeaderItemVisibilityPriority.h +9 -0
  111. package/ios/stack/header/RNSStackHeaderConfigComponentView.h +4 -0
  112. package/ios/stack/header/RNSStackHeaderConfigComponentView.mm +40 -6
  113. package/ios/stack/header/RNSStackHeaderConfigDataProviding.h +5 -0
  114. package/ios/stack/header/RNSStackHeaderContentFactory.mm +3 -0
  115. package/ios/stack/header/RNSStackHeaderItemComponentView.h +9 -2
  116. package/ios/stack/header/RNSStackHeaderItemComponentView.mm +57 -3
  117. package/ios/stack/header/RNSStackHeaderItemDataProviding.h +5 -0
  118. package/ios/stack/header/RNSStackHeaderMenuCoordinator.h +13 -0
  119. package/ios/stack/header/RNSStackHeaderMenuCoordinator.mm +24 -0
  120. package/ios/stack/header/RNSStackHeaderMenuFinder.h +8 -1
  121. package/ios/stack/header/RNSStackHeaderMenuFinder.mm +26 -9
  122. package/ios/stack/screen/RNSStackScreenComponentView.h +2 -1
  123. package/ios/stack/screen/RNSStackScreenComponentView.mm +23 -0
  124. package/ios/stack/screen/RNSStackScreenHeaderCoordinator.mm +81 -8
  125. package/ios/tabs/RNSTabBarAppearanceCoordinator.mm +79 -16
  126. package/ios/tabs/RNSTabBarItemCoordinator.h +16 -0
  127. package/ios/tabs/RNSTabBarItemCoordinator.mm +143 -0
  128. package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryWrapperView.h +24 -0
  129. package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryWrapperView.mm +22 -0
  130. package/ios/tabs/conversion/RNSConversions-Tabs.h +22 -0
  131. package/ios/tabs/conversion/RNSConversions-Tabs.mm +97 -3
  132. package/ios/tabs/host/RNSTabBarController.h +16 -0
  133. package/ios/tabs/host/RNSTabBarController.mm +516 -107
  134. package/ios/tabs/host/RNSTabsHostComponentView.h +2 -0
  135. package/ios/tabs/host/RNSTabsHostComponentView.mm +32 -2
  136. package/ios/tabs/screen/RNSTabsScreenComponentView.h +21 -0
  137. package/ios/tabs/screen/RNSTabsScreenComponentView.mm +54 -69
  138. package/ios/tabs/screen/RNSTabsScreenViewController.mm +1 -0
  139. package/ios/utils/RNSDefines.h +12 -7
  140. package/lib/commonjs/components/stack/header/StackHeaderConfig.android.js +3 -2
  141. package/lib/commonjs/components/stack/header/StackHeaderConfig.android.js.map +1 -1
  142. package/lib/commonjs/components/stack/header/StackHeaderConfig.ios.js +8 -3
  143. package/lib/commonjs/components/stack/header/StackHeaderConfig.ios.js.map +1 -1
  144. package/lib/commonjs/components/stack/header/StackHeaderConfig.js +17 -0
  145. package/lib/commonjs/components/stack/header/StackHeaderConfig.js.map +1 -0
  146. package/lib/commonjs/components/stack/header/ios/StackHeaderItem.ios.js +4 -1
  147. package/lib/commonjs/components/stack/header/ios/StackHeaderItem.ios.js.map +1 -1
  148. package/lib/commonjs/components/stack/host/StackHost.js +8 -1
  149. package/lib/commonjs/components/stack/host/StackHost.js.map +1 -1
  150. package/lib/commonjs/components/stack/host/StackHost.web.js +0 -2
  151. package/lib/commonjs/components/stack/host/StackHost.web.js.map +1 -1
  152. package/lib/commonjs/components/stack/index.js.map +1 -1
  153. package/lib/commonjs/components/tabs/host/TabsHost.ios.js +2 -0
  154. package/lib/commonjs/components/tabs/host/TabsHost.ios.js.map +1 -1
  155. package/lib/commonjs/components/tabs/host/{TabsHost.web.js → TabsHost.js} +1 -1
  156. package/lib/commonjs/components/tabs/host/TabsHost.js.map +1 -0
  157. package/lib/commonjs/components/tabs/index.js.map +1 -1
  158. package/lib/commonjs/components/tabs/screen/TabsScreen.android.js +3 -1
  159. package/lib/commonjs/components/tabs/screen/TabsScreen.android.js.map +1 -1
  160. package/lib/commonjs/components/tabs/screen/TabsScreen.ios.js +10 -1
  161. package/lib/commonjs/components/tabs/screen/TabsScreen.ios.js.map +1 -1
  162. package/lib/commonjs/components/tabs/screen/{TabsScreen.web.js → TabsScreen.js} +1 -1
  163. package/lib/commonjs/components/tabs/screen/TabsScreen.js.map +1 -0
  164. package/lib/commonjs/components/{stack/header/StackHeaderConfig.d.js → tabs/screen/TabsScreenIcon.types.js} +1 -1
  165. package/lib/commonjs/components/{stack/header/StackHeaderConfig.d.js.map → tabs/screen/TabsScreenIcon.types.js.map} +1 -1
  166. package/lib/commonjs/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.js.map +1 -1
  167. package/lib/commonjs/fabric/legacy/ScreenStackNativeComponent.js.map +1 -1
  168. package/lib/commonjs/fabric/stack/StackHeaderConfigIOSNativeComponent.js.map +1 -1
  169. package/lib/commonjs/fabric/stack/StackHeaderItemIOSNativeComponent.js.map +1 -1
  170. package/lib/commonjs/fabric/tabs/TabsHostIOSNativeComponent.js.map +1 -1
  171. package/lib/commonjs/fabric/tabs/TabsScreenAndroidNativeComponent.js.map +1 -1
  172. package/lib/commonjs/fabric/tabs/TabsScreenIOSNativeComponent.js +1 -1
  173. package/lib/commonjs/fabric/tabs/TabsScreenIOSNativeComponent.js.map +1 -1
  174. package/lib/commonjs/legacy/components/ScreenStackItem.js +31 -11
  175. package/lib/commonjs/legacy/components/ScreenStackItem.js.map +1 -1
  176. package/lib/module/components/stack/header/StackHeaderConfig.android.js +4 -3
  177. package/lib/module/components/stack/header/StackHeaderConfig.android.js.map +1 -1
  178. package/lib/module/components/stack/header/StackHeaderConfig.ios.js +9 -4
  179. package/lib/module/components/stack/header/StackHeaderConfig.ios.js.map +1 -1
  180. package/lib/module/components/stack/header/StackHeaderConfig.js +10 -0
  181. package/lib/module/components/stack/header/StackHeaderConfig.js.map +1 -0
  182. package/lib/module/components/stack/header/ios/StackHeaderItem.ios.js +4 -1
  183. package/lib/module/components/stack/header/ios/StackHeaderItem.ios.js.map +1 -1
  184. package/lib/module/components/stack/host/StackHost.js +9 -2
  185. package/lib/module/components/stack/host/StackHost.js.map +1 -1
  186. package/lib/module/components/stack/host/StackHost.web.js +0 -3
  187. package/lib/module/components/stack/host/StackHost.web.js.map +1 -1
  188. package/lib/module/components/stack/index.js.map +1 -1
  189. package/lib/module/components/tabs/host/TabsHost.ios.js +2 -0
  190. package/lib/module/components/tabs/host/TabsHost.ios.js.map +1 -1
  191. package/{src/components/tabs/host/TabsHost.web.tsx → lib/module/components/tabs/host/TabsHost.js} +1 -2
  192. package/lib/module/components/tabs/host/TabsHost.js.map +1 -0
  193. package/lib/module/components/tabs/index.js.map +1 -1
  194. package/lib/module/components/tabs/screen/TabsScreen.android.js +3 -1
  195. package/lib/module/components/tabs/screen/TabsScreen.android.js.map +1 -1
  196. package/lib/module/components/tabs/screen/TabsScreen.ios.js +10 -1
  197. package/lib/module/components/tabs/screen/TabsScreen.ios.js.map +1 -1
  198. package/{src/components/tabs/screen/TabsScreen.web.tsx → lib/module/components/tabs/screen/TabsScreen.js} +1 -2
  199. package/lib/module/components/tabs/screen/TabsScreen.js.map +1 -0
  200. package/lib/module/components/tabs/screen/TabsScreenIcon.types.js +2 -0
  201. package/lib/module/components/{stack/header/StackHeaderConfig.d.js.map → tabs/screen/TabsScreenIcon.types.js.map} +1 -1
  202. package/lib/module/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.js.map +1 -1
  203. package/lib/module/fabric/legacy/ScreenStackNativeComponent.js.map +1 -1
  204. package/lib/module/fabric/stack/StackHeaderConfigIOSNativeComponent.js.map +1 -1
  205. package/lib/module/fabric/stack/StackHeaderItemIOSNativeComponent.js.map +1 -1
  206. package/lib/module/fabric/tabs/TabsHostIOSNativeComponent.js.map +1 -1
  207. package/lib/module/fabric/tabs/TabsScreenAndroidNativeComponent.js.map +1 -1
  208. package/lib/module/fabric/tabs/TabsScreenIOSNativeComponent.js +1 -1
  209. package/lib/module/fabric/tabs/TabsScreenIOSNativeComponent.js.map +1 -1
  210. package/lib/module/legacy/components/ScreenStackItem.js +31 -11
  211. package/lib/module/legacy/components/ScreenStackItem.js.map +1 -1
  212. package/lib/typescript/components/stack/header/StackHeaderConfig.android.d.ts +6 -3
  213. package/lib/typescript/components/stack/header/StackHeaderConfig.android.d.ts.map +1 -1
  214. package/lib/typescript/components/stack/header/StackHeaderConfig.android.types.d.ts +4 -3
  215. package/lib/typescript/components/stack/header/StackHeaderConfig.android.types.d.ts.map +1 -1
  216. package/lib/typescript/components/stack/header/StackHeaderConfig.d.ts +8 -0
  217. package/lib/typescript/components/stack/header/StackHeaderConfig.d.ts.map +1 -0
  218. package/lib/typescript/components/stack/header/StackHeaderConfig.ios.d.ts +6 -3
  219. package/lib/typescript/components/stack/header/StackHeaderConfig.ios.d.ts.map +1 -1
  220. package/lib/typescript/components/stack/header/StackHeaderConfig.ios.types.d.ts +137 -2
  221. package/lib/typescript/components/stack/header/StackHeaderConfig.ios.types.d.ts.map +1 -1
  222. package/lib/typescript/components/stack/header/StackHeaderConfig.types.d.ts +2 -0
  223. package/lib/typescript/components/stack/header/StackHeaderConfig.types.d.ts.map +1 -1
  224. package/lib/typescript/components/stack/header/ios/StackHeaderItem.ios.d.ts.map +1 -1
  225. package/lib/typescript/components/stack/header/ios/StackHeaderItem.ios.types.d.ts +5 -0
  226. package/lib/typescript/components/stack/header/ios/StackHeaderItem.ios.types.d.ts.map +1 -1
  227. package/lib/typescript/components/stack/host/StackHost.d.ts.map +1 -1
  228. package/lib/typescript/components/stack/host/StackHost.types.d.ts +24 -1
  229. package/lib/typescript/components/stack/host/StackHost.types.d.ts.map +1 -1
  230. package/lib/typescript/components/stack/host/StackHost.web.d.ts +1 -3
  231. package/lib/typescript/components/stack/host/StackHost.web.d.ts.map +1 -1
  232. package/lib/typescript/components/stack/index.d.ts +4 -3
  233. package/lib/typescript/components/stack/index.d.ts.map +1 -1
  234. package/lib/typescript/components/tabs/host/TabsHost.d.ts +5 -0
  235. package/lib/typescript/components/tabs/host/TabsHost.d.ts.map +1 -0
  236. package/lib/typescript/components/tabs/host/TabsHost.ios.d.ts.map +1 -1
  237. package/lib/typescript/components/tabs/host/TabsHost.ios.types.d.ts +56 -0
  238. package/lib/typescript/components/tabs/host/TabsHost.ios.types.d.ts.map +1 -1
  239. package/lib/typescript/components/tabs/index.d.ts +4 -6
  240. package/lib/typescript/components/tabs/index.d.ts.map +1 -1
  241. package/lib/typescript/components/tabs/screen/TabsScreen.android.d.ts.map +1 -1
  242. package/lib/typescript/components/tabs/screen/TabsScreen.android.types.d.ts +42 -7
  243. package/lib/typescript/components/tabs/screen/TabsScreen.android.types.d.ts.map +1 -1
  244. package/lib/typescript/components/tabs/screen/TabsScreen.d.ts +5 -0
  245. package/lib/typescript/components/tabs/screen/TabsScreen.d.ts.map +1 -0
  246. package/lib/typescript/components/tabs/screen/TabsScreen.ios.d.ts.map +1 -1
  247. package/lib/typescript/components/tabs/screen/TabsScreen.ios.types.d.ts +78 -13
  248. package/lib/typescript/components/tabs/screen/TabsScreen.ios.types.d.ts.map +1 -1
  249. package/lib/typescript/components/tabs/screen/TabsScreenIcon.types.d.ts +91 -0
  250. package/lib/typescript/components/tabs/screen/TabsScreenIcon.types.d.ts.map +1 -0
  251. package/lib/typescript/components/tabs/screen/index.d.ts +1 -0
  252. package/lib/typescript/components/tabs/screen/index.d.ts.map +1 -1
  253. package/lib/typescript/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.d.ts +2 -0
  254. package/lib/typescript/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.d.ts.map +1 -1
  255. package/lib/typescript/fabric/legacy/ScreenStackNativeComponent.d.ts +1 -0
  256. package/lib/typescript/fabric/legacy/ScreenStackNativeComponent.d.ts.map +1 -1
  257. package/lib/typescript/fabric/stack/StackHeaderConfigIOSNativeComponent.d.ts +4 -0
  258. package/lib/typescript/fabric/stack/StackHeaderConfigIOSNativeComponent.d.ts.map +1 -1
  259. package/lib/typescript/fabric/stack/StackHeaderItemIOSNativeComponent.d.ts +6 -0
  260. package/lib/typescript/fabric/stack/StackHeaderItemIOSNativeComponent.d.ts.map +1 -1
  261. package/lib/typescript/fabric/tabs/TabsHostIOSNativeComponent.d.ts +3 -0
  262. package/lib/typescript/fabric/tabs/TabsHostIOSNativeComponent.d.ts.map +1 -1
  263. package/lib/typescript/fabric/tabs/TabsScreenAndroidNativeComponent.d.ts +6 -0
  264. package/lib/typescript/fabric/tabs/TabsScreenAndroidNativeComponent.d.ts.map +1 -1
  265. package/lib/typescript/fabric/tabs/TabsScreenIOSNativeComponent.d.ts +10 -1
  266. package/lib/typescript/fabric/tabs/TabsScreenIOSNativeComponent.d.ts.map +1 -1
  267. package/lib/typescript/legacy/components/ScreenStackItem.d.ts +25 -0
  268. package/lib/typescript/legacy/components/ScreenStackItem.d.ts.map +1 -1
  269. package/lib/typescript/legacy/components/helpers/prepareHeaderBarButtonItems.d.ts +4 -0
  270. package/lib/typescript/legacy/components/helpers/prepareHeaderBarButtonItems.d.ts.map +1 -1
  271. package/lib/typescript/legacy/types.d.ts +30 -0
  272. package/lib/typescript/legacy/types.d.ts.map +1 -1
  273. package/package.json +4 -2
  274. package/src/components/stack/header/StackHeaderConfig.android.tsx +6 -20
  275. package/src/components/stack/header/StackHeaderConfig.android.types.ts +4 -3
  276. package/src/components/stack/header/StackHeaderConfig.ios.tsx +10 -16
  277. package/src/components/stack/header/StackHeaderConfig.ios.types.ts +148 -2
  278. package/src/components/stack/header/StackHeaderConfig.tsx +12 -0
  279. package/src/components/stack/header/StackHeaderConfig.types.ts +2 -0
  280. package/src/components/stack/header/ios/StackHeaderItem.ios.tsx +9 -1
  281. package/src/components/stack/header/ios/StackHeaderItem.ios.types.ts +5 -0
  282. package/src/components/stack/host/StackHost.tsx +10 -3
  283. package/src/components/stack/host/StackHost.types.ts +25 -1
  284. package/src/components/stack/host/StackHost.web.tsx +1 -4
  285. package/src/components/stack/index.ts +9 -1
  286. package/src/components/tabs/host/TabsHost.ios.tsx +2 -0
  287. package/src/components/tabs/host/TabsHost.ios.types.ts +60 -0
  288. package/src/components/tabs/host/TabsHost.tsx +7 -0
  289. package/src/components/tabs/index.ts +9 -0
  290. package/src/components/tabs/screen/TabsScreen.android.tsx +8 -3
  291. package/src/components/tabs/screen/TabsScreen.android.types.ts +42 -7
  292. package/src/components/tabs/screen/TabsScreen.ios.tsx +22 -5
  293. package/src/components/tabs/screen/TabsScreen.ios.types.ts +79 -17
  294. package/src/components/tabs/screen/TabsScreen.tsx +7 -0
  295. package/src/components/tabs/screen/TabsScreenIcon.types.ts +117 -0
  296. package/src/components/tabs/screen/index.ts +1 -0
  297. package/src/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.ts +6 -0
  298. package/src/fabric/legacy/ScreenStackNativeComponent.ts +2 -0
  299. package/src/fabric/stack/StackHeaderConfigIOSNativeComponent.ts +11 -0
  300. package/src/fabric/stack/StackHeaderItemIOSNativeComponent.ts +11 -0
  301. package/src/fabric/tabs/TabsHostIOSNativeComponent.ts +7 -0
  302. package/src/fabric/tabs/TabsScreenAndroidNativeComponent.ts +9 -0
  303. package/src/fabric/tabs/TabsScreenIOSNativeComponent.ts +20 -2
  304. package/src/legacy/components/ScreenStackItem.tsx +59 -12
  305. package/src/legacy/types.ts +31 -0
  306. package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenModalFragment.kt +0 -281
  307. package/android/src/main/java/com/swmansion/rnscreens/legacy/bottomsheet/BottomSheetDialogRootView.kt +0 -104
  308. package/android/src/main/java/com/swmansion/rnscreens/legacy/bottomsheet/BottomSheetDialogScreen.kt +0 -26
  309. package/lib/commonjs/components/stack/header/StackHeaderConfig.web.js +0 -10
  310. package/lib/commonjs/components/stack/header/StackHeaderConfig.web.js.map +0 -1
  311. package/lib/commonjs/components/tabs/host/TabsHost.d.js +0 -2
  312. package/lib/commonjs/components/tabs/host/TabsHost.d.js.map +0 -1
  313. package/lib/commonjs/components/tabs/host/TabsHost.web.js.map +0 -1
  314. package/lib/commonjs/components/tabs/screen/TabsScreen.d.js +0 -2
  315. package/lib/commonjs/components/tabs/screen/TabsScreen.d.js.map +0 -1
  316. package/lib/commonjs/components/tabs/screen/TabsScreen.web.js.map +0 -1
  317. package/lib/module/components/stack/header/StackHeaderConfig.d.js +0 -2
  318. package/lib/module/components/stack/header/StackHeaderConfig.web.js +0 -4
  319. package/lib/module/components/stack/header/StackHeaderConfig.web.js.map +0 -1
  320. package/lib/module/components/tabs/host/TabsHost.d.js +0 -2
  321. package/lib/module/components/tabs/host/TabsHost.d.js.map +0 -1
  322. package/lib/module/components/tabs/host/TabsHost.web.js +0 -4
  323. package/lib/module/components/tabs/host/TabsHost.web.js.map +0 -1
  324. package/lib/module/components/tabs/screen/TabsScreen.d.js +0 -2
  325. package/lib/module/components/tabs/screen/TabsScreen.d.js.map +0 -1
  326. package/lib/module/components/tabs/screen/TabsScreen.web.js +0 -4
  327. package/lib/module/components/tabs/screen/TabsScreen.web.js.map +0 -1
  328. package/lib/typescript/components/stack/header/StackHeaderConfig.web.d.ts +0 -7
  329. package/lib/typescript/components/stack/header/StackHeaderConfig.web.d.ts.map +0 -1
  330. package/lib/typescript/components/tabs/host/TabsHost.web.d.ts +0 -7
  331. package/lib/typescript/components/tabs/host/TabsHost.web.d.ts.map +0 -1
  332. package/lib/typescript/components/tabs/screen/TabsScreen.web.d.ts +0 -7
  333. package/lib/typescript/components/tabs/screen/TabsScreen.web.d.ts.map +0 -1
  334. package/src/components/stack/header/StackHeaderConfig.d.ts +0 -22
  335. package/src/components/stack/header/StackHeaderConfig.web.tsx +0 -5
  336. package/src/components/tabs/host/TabsHost.d.ts +0 -12
  337. package/src/components/tabs/screen/TabsScreen.d.ts +0 -12
@@ -49,10 +49,14 @@ namespace react = facebook::react;
49
49
  [self setTitleProp:nil];
50
50
  [self setIconProp:nil];
51
51
  [self setMenuProp:nil];
52
+ [self setMenuRepresentationProp:nil];
52
53
  _placement = RNSHeaderItemPlacementTrailing;
53
54
  _didSetHeaderItemPlacement = NO;
55
+ _style = UIBarButtonItemStylePlain;
56
+ _disabled = NO;
54
57
  _respondsToOnPress = NO;
55
58
  _hidesSharedBackground = NO;
59
+ _visibilityPriority = RNSHeaderItemVisibilityPriorityStandard;
56
60
  }
57
61
 
58
62
  - (void)setTitleProp:(NSString *)titleProp
@@ -73,6 +77,12 @@ namespace react = facebook::react;
73
77
  _menu = menuProp;
74
78
  }
75
79
 
80
+ - (void)setMenuRepresentationProp:(RNSStackHeaderMenuData *)menuRepresentationProp
81
+ {
82
+ _menuRepresentationProp = menuRepresentationProp;
83
+ _menuRepresentation = menuRepresentationProp;
84
+ }
85
+
76
86
  - (void)emitOnPress
77
87
  {
78
88
  [_headerItemEventEmitter emitOnPress];
@@ -81,11 +91,22 @@ namespace react = facebook::react;
81
91
  - (void)updateMenuElementWithId:(NSString *)elementId
82
92
  withElement:(id<RNSStackHeaderMenuElement>)newElement
83
93
  parentMenu:(nullable RNSStackHeaderMenuData *)parentMenu
94
+ inMenuRepresentation:(BOOL)inMenuRepresentation
84
95
  {
85
- if (parentMenu == nil) {
86
- _menu = (RNSStackHeaderMenuData *)newElement;
96
+ if (inMenuRepresentation) {
97
+ if (parentMenu == nil) {
98
+ _menuRepresentation = (RNSStackHeaderMenuData *)newElement;
99
+ } else {
100
+ _menuRepresentation = [RNSStackHeaderMenuCoordinator menu:_menuRepresentation
101
+ replacingChildWithId:elementId
102
+ withElement:newElement];
103
+ }
87
104
  } else {
88
- _menu = [RNSStackHeaderMenuCoordinator menu:_menu replacingChildWithId:elementId withElement:newElement];
105
+ if (parentMenu == nil) {
106
+ _menu = (RNSStackHeaderMenuData *)newElement;
107
+ } else {
108
+ _menu = [RNSStackHeaderMenuCoordinator menu:_menu replacingChildWithId:elementId withElement:newElement];
109
+ }
89
110
  }
90
111
  [_invalidationDelegate headerItemMenuDidUpdateFromCommandWithId:_itemId];
91
112
  }
@@ -217,6 +238,25 @@ RNS_IGNORE_SUPER_CALL_END
217
238
  menuDidChange = YES;
218
239
  }
219
240
 
241
+ if (oldItemProps.menuRepresentation != newItemProps.menuRepresentation) {
242
+ [self setMenuRepresentationProp:[RNSStackHeaderMenuMapper
243
+ menuFromDictionary:rnscreens::conversion::RNSConvertFollyDynamicToId(
244
+ newItemProps.menuRepresentation)]];
245
+ // menu representation is applied together with the menu & shares its toggle state tracker,
246
+ // so it follows the same invalidation path
247
+ menuDidChange = YES;
248
+ }
249
+
250
+ if (oldItemProps.variant != newItemProps.variant) {
251
+ _style = rnscreens::conversion::UIBarButtonItemStyleFromReactRNSStackHeaderItemIOSVariant(newItemProps.variant);
252
+ needsUpdate = YES;
253
+ }
254
+
255
+ if (oldItemProps.disabled != newItemProps.disabled) {
256
+ _disabled = newItemProps.disabled;
257
+ needsUpdate = YES;
258
+ }
259
+
220
260
  if (oldItemProps.respondsToOnPress != newItemProps.respondsToOnPress) {
221
261
  _respondsToOnPress = newItemProps.respondsToOnPress;
222
262
  needsUpdate = YES;
@@ -227,6 +267,20 @@ RNS_IGNORE_SUPER_CALL_END
227
267
  needsUpdate = YES;
228
268
  }
229
269
 
270
+ if (oldItemProps.visibilityPriority != newItemProps.visibilityPriority) {
271
+ _visibilityPriority =
272
+ rnscreens::conversion::RNSHeaderItemVisibilityPriorityFromReactRNSStackHeaderItemIOSVisibilityPriority(
273
+ newItemProps.visibilityPriority);
274
+ // tvOS and visionOS are excluded on purpose: `visibilityPriority` exists there, but the only
275
+ // supported value is `standard`, which is already the default.
276
+ #if RNS_IPHONE_OS_VERSION_AVAILABLE(27_0) && !TARGET_OS_TV && !TARGET_OS_VISION
277
+ // The item is rebuilt only on iOS 27+, where the priority is actually applied.
278
+ if (@available(iOS 27.0, *)) {
279
+ needsUpdate = YES;
280
+ }
281
+ #endif // RNS_IPHONE_OS_VERSION_AVAILABLE(27_0) && !TARGET_OS_TV && !TARGET_OS_VISION
282
+ }
283
+
230
284
  [super updateProps:props oldProps:oldProps];
231
285
 
232
286
  if (needsUpdate) {
@@ -3,6 +3,7 @@
3
3
  #import <UIKit/UIKit.h>
4
4
 
5
5
  #import "RNSHeaderItemPlacement.h"
6
+ #import "RNSHeaderItemVisibilityPriority.h"
6
7
  #import "RNSStackHeaderIconData.h"
7
8
  #import "RNSStackHeaderMenuData.h"
8
9
 
@@ -16,9 +17,13 @@ NS_ASSUME_NONNULL_BEGIN
16
17
  @property (nonatomic, readonly, nullable) NSString *title;
17
18
  @property (nonatomic, readonly, nullable) RNSStackHeaderIconData *icon;
18
19
  @property (nonatomic, readonly, nullable) RNSStackHeaderMenuData *menu;
20
+ @property (nonatomic, readonly, nullable) RNSStackHeaderMenuData *menuRepresentation;
19
21
  @property (nonatomic, readonly, nullable) UIView *customView;
22
+ @property (nonatomic, readonly) UIBarButtonItemStyle style;
23
+ @property (nonatomic, readonly) BOOL disabled;
20
24
  @property (nonatomic, readonly) BOOL respondsToOnPress;
21
25
  @property (nonatomic, readonly) BOOL hidesSharedBackground;
26
+ @property (nonatomic, readonly) RNSHeaderItemVisibilityPriority visibilityPriority;
22
27
 
23
28
  @end
24
29
 
@@ -25,6 +25,19 @@ NS_ASSUME_NONNULL_BEGIN
25
25
  withImageLoader:(id<RNSImageLoading>)imageLoader
26
26
  menuInvalidatedCallback:(nullable void (^)(void))onMenuInvalidated;
27
27
 
28
+ /**
29
+ * Applies menu representation to the item - a menu element substituting the item
30
+ * when it is displayed in a menu (e.g. the navigation bar overflow menu).
31
+ * Passing nil `data` clears the representation. Works like regular `applyMenu`.
32
+ * No-op below iOS 16 and on tvOS, where `UIBarButtonItem.menuRepresentation` is unavailable.
33
+ */
34
+ + (void)applyMenuRepresentation:(nullable RNSStackHeaderMenuData *)data
35
+ toBarButtonItem:(UIBarButtonItem *)item
36
+ withHeaderEventsDelegate:(id<RNSStackHeaderEventsDelegate>)delegate
37
+ stateTracker:(RNSStackHeaderMenuToggleStateTracker *)tracker
38
+ withImageLoader:(id<RNSImageLoading>)imageLoader
39
+ menuInvalidatedCallback:(nullable void (^)(void))onMenuInvalidated;
40
+
28
41
  /**
29
42
  * Collects IDs of all toggle items in a single selection hierarchy rooted at the given menu.
30
43
  */
@@ -26,6 +26,30 @@
26
26
  #endif // !TARGET_OS_TV || __TV_OS_VERSION_MAX_ALLOWED >= 170000
27
27
  }
28
28
 
29
+ + (void)applyMenuRepresentation:(nullable RNSStackHeaderMenuData *)data
30
+ toBarButtonItem:(UIBarButtonItem *)item
31
+ withHeaderEventsDelegate:(id<RNSStackHeaderEventsDelegate>)delegate
32
+ stateTracker:(RNSStackHeaderMenuToggleStateTracker *)tracker
33
+ withImageLoader:(id<RNSImageLoading>)imageLoader
34
+ menuInvalidatedCallback:(nullable void (^)(void))onMenuInvalidated
35
+ {
36
+ #if RNS_IPHONE_OS_VERSION_AVAILABLE(16_0) && !TARGET_OS_TV
37
+ if (@available(iOS 16.0, *)) {
38
+ if (data == nil) {
39
+ item.menuRepresentation = nil;
40
+ return;
41
+ }
42
+ item.menuRepresentation = [self buildMenuFromData:data
43
+ withHeaderEventsDelegate:delegate
44
+ stateTracker:tracker
45
+ singleSelectionRoot:nil
46
+ initialSingleSelectionStateClaimed:NULL
47
+ withImageLoader:imageLoader
48
+ menuInvalidatedCallback:onMenuInvalidated];
49
+ }
50
+ #endif // RNS_IPHONE_OS_VERSION_AVAILABLE(16_0) && !TARGET_OS_TV
51
+ }
52
+
29
53
  + (UIMenu *)buildMenuFromData:(RNSStackHeaderMenuData *)data
30
54
  withHeaderEventsDelegate:(id<RNSStackHeaderEventsDelegate>)delegate
31
55
  stateTracker:(RNSStackHeaderMenuToggleStateTracker *)tracker
@@ -41,11 +41,18 @@ typedef NS_ENUM(NSInteger, RNSMenuElementPosition) {
41
41
  */
42
42
  @property (nonatomic, copy, readonly, nullable) NSString *trackerItemId;
43
43
 
44
+ /**
45
+ * Whether the element was found in the header item's menuRepresentation tree
46
+ * rather than its menu tree.
47
+ */
48
+ @property (nonatomic, readonly) BOOL inMenuRepresentation;
49
+
44
50
  - (instancetype)initWithSearchResult:(RNSStackHeaderMenuElementSearchResult *)searchResult
45
51
  position:(RNSMenuElementPosition)position
46
52
  headerItem:(nullable id<RNSStackHeaderItemDataProviding>)headerItem
47
53
  rootMenu:(nullable RNSStackHeaderMenuData *)rootMenu
48
- trackerItemId:(nullable NSString *)trackerItemId;
54
+ trackerItemId:(nullable NSString *)trackerItemId
55
+ inMenuRepresentation:(BOOL)inMenuRepresentation;
49
56
 
50
57
  @end
51
58
 
@@ -25,6 +25,7 @@
25
25
  headerItem:(nullable id<RNSStackHeaderItemDataProviding>)headerItem
26
26
  rootMenu:(nullable RNSStackHeaderMenuData *)rootMenu
27
27
  trackerItemId:(nullable NSString *)trackerItemId
28
+ inMenuRepresentation:(BOOL)inMenuRepresentation
28
29
  {
29
30
  if (self = [super init]) {
30
31
  _searchResult = searchResult;
@@ -32,6 +33,7 @@
32
33
  _headerItem = headerItem;
33
34
  _rootMenu = rootMenu;
34
35
  _trackerItemId = [trackerItemId copy];
36
+ _inMenuRepresentation = inMenuRepresentation;
35
37
  }
36
38
  return self;
37
39
  }
@@ -47,16 +49,30 @@
47
49
  titleMenu:(nullable RNSStackHeaderMenuData *)titleMenu
48
50
  {
49
51
  for (id<RNSStackHeaderItemDataProviding> item in items) {
50
- if (item.menu == nil || item.itemId == nil) {
52
+ if (item.itemId == nil) {
51
53
  continue;
52
54
  }
53
- RNSStackHeaderMenuElementSearchResult *result = [self findElementWithId:elementId inMenu:item.menu];
54
- if (result != nil) {
55
- return [[RNSMenuElementLocator alloc] initWithSearchResult:result
56
- position:RNSMenuElementPositionItem
57
- headerItem:item
58
- rootMenu:item.menu
59
- trackerItemId:item.itemId];
55
+ if (item.menu != nil) {
56
+ RNSStackHeaderMenuElementSearchResult *result = [self findElementWithId:elementId inMenu:item.menu];
57
+ if (result != nil) {
58
+ return [[RNSMenuElementLocator alloc] initWithSearchResult:result
59
+ position:RNSMenuElementPositionItem
60
+ headerItem:item
61
+ rootMenu:item.menu
62
+ trackerItemId:item.itemId
63
+ inMenuRepresentation:NO];
64
+ }
65
+ }
66
+ if (item.menuRepresentation != nil) {
67
+ RNSStackHeaderMenuElementSearchResult *result = [self findElementWithId:elementId inMenu:item.menuRepresentation];
68
+ if (result != nil) {
69
+ return [[RNSMenuElementLocator alloc] initWithSearchResult:result
70
+ position:RNSMenuElementPositionItem
71
+ headerItem:item
72
+ rootMenu:item.menuRepresentation
73
+ trackerItemId:item.itemId
74
+ inMenuRepresentation:YES];
75
+ }
60
76
  }
61
77
  }
62
78
 
@@ -67,7 +83,8 @@
67
83
  position:RNSMenuElementPositionTitle
68
84
  headerItem:nil
69
85
  rootMenu:titleMenu
70
- trackerItemId:RNSTitleMenuTrackerItemId];
86
+ trackerItemId:RNSTitleMenuTrackerItemId
87
+ inMenuRepresentation:NO];
71
88
  }
72
89
  }
73
90
 
@@ -1,6 +1,7 @@
1
1
  #pragma once
2
2
 
3
3
  #import "RNSReactBaseView.h"
4
+ #import "RNSSafeAreaProviding.h"
4
5
  #import "RNSStackScreenComponentEventEmitter.h"
5
6
 
6
7
  NS_ASSUME_NONNULL_BEGIN
@@ -14,7 +15,7 @@ typedef NS_ENUM(int, RNSStackScreenActivityMode) {
14
15
  RNSStackScreenActivityModeAttached = 1,
15
16
  };
16
17
 
17
- @interface RNSStackScreenComponentView : RNSReactBaseView
18
+ @interface RNSStackScreenComponentView : RNSReactBaseView <RNSSafeAreaProviding>
18
19
 
19
20
  @property (nonatomic, weak, readwrite, nullable) RNSStackHostComponentView *stackHost;
20
21
  @property (nonatomic, weak, readonly, nullable) RNSStackHeaderConfigComponentView *headerConfig;
@@ -8,6 +8,7 @@
8
8
  #import <react/renderer/components/rnscreens/RNSStackScreenComponentDescriptor.h>
9
9
 
10
10
  #import "RNSConversions-Stack.h"
11
+ #import "RNSSafeAreaViewNotifications.h"
11
12
  #import "RNSScrollViewMarkerComponentView.h"
12
13
  #import "RNSScrollViewSeeking.h"
13
14
  #import "RNSStackHeaderConfigComponentView.h"
@@ -107,6 +108,28 @@ namespace react = facebook::react;
107
108
  return _reactEventEmitter;
108
109
  }
109
110
 
111
+ #pragma mark - RNSSafeAreaProviding
112
+
113
+ - (UIEdgeInsets)providerSafeAreaInsets
114
+ {
115
+ return self.safeAreaInsets;
116
+ }
117
+
118
+ - (void)dispatchSafeAreaDidChangeNotification
119
+ {
120
+ [NSNotificationCenter.defaultCenter postNotificationName:RNSSafeAreaDidChange object:self userInfo:nil];
121
+ }
122
+
123
+ #pragma mark - RNSSafeAreaProviding related methods
124
+
125
+ // TODO: register for UIKeyboard notifications
126
+
127
+ - (void)safeAreaInsetsDidChange
128
+ {
129
+ [super safeAreaInsetsDidChange];
130
+ [self dispatchSafeAreaDidChangeNotification];
131
+ }
132
+
110
133
  #pragma mark - RCTComponentViewProtocol
111
134
 
112
135
  - (void)updateProps:(const facebook::react::Props::Shared &)props
@@ -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"
@@ -336,6 +337,12 @@
336
337
  }
337
338
  #endif // RNS_IPHONE_OS_VERSION_AVAILABLE(26_0)
338
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
+
339
346
  #if !TARGET_OS_TV
340
347
  navItem.prompt = nil;
341
348
  navItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeNever;
@@ -371,19 +378,52 @@
371
378
 
372
379
  if (item.menu == nil) {
373
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) {
374
414
  return;
375
415
  }
376
416
 
377
417
  RNSStackHeaderMenuToggleStateTracker *tracker = [_trackerRegistry trackerForItemId:itemId];
378
418
  __weak auto weakSelf = self;
379
- [RNSStackHeaderMenuCoordinator applyMenu:item.menu
380
- toBarButtonItem:barButtonItem
381
- withHeaderEventsDelegate:_eventsDelegate
382
- stateTracker:tracker
383
- withImageLoader:_imageLoader
384
- menuInvalidatedCallback:^{
385
- [weakSelf reapplyMenuForItemWithId:itemId];
386
- }];
419
+ [RNSStackHeaderMenuCoordinator applyMenuRepresentation:item.menuRepresentation
420
+ toBarButtonItem:barButtonItem
421
+ withHeaderEventsDelegate:_eventsDelegate
422
+ stateTracker:tracker
423
+ withImageLoader:_imageLoader
424
+ menuInvalidatedCallback:^{
425
+ [weakSelf reapplyMenuRepresentationForItemWithId:itemId];
426
+ }];
387
427
  }
388
428
 
389
429
  - (nullable id<RNSStackHeaderItemDataProviding>)findItemWithId:(NSString *)itemId
@@ -448,6 +488,15 @@
448
488
  }
449
489
  #endif // RNS_IPHONE_OS_VERSION_AVAILABLE(26_0)
450
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
+
451
500
  #if !TARGET_OS_TV
452
501
  navItem.largeTitleDisplayMode = _configDataProvider.largeTitleEnabled ? UINavigationItemLargeTitleDisplayModeAlways
453
502
  : UINavigationItemLargeTitleDisplayModeNever;
@@ -553,6 +602,16 @@
553
602
  }
554
603
  #endif // RNS_IPHONE_OS_VERSION_AVAILABLE(26_0)
555
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
+
556
615
  if (item.menu != nil && item.itemId != nil) {
557
616
  RNSStackHeaderMenuToggleStateTracker *tracker = [_trackerRegistry trackerForItemId:item.itemId];
558
617
  __weak auto weakSelf = self;
@@ -567,6 +626,20 @@
567
626
  }];
568
627
  }
569
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
+
570
643
  if (item.itemId != nil) {
571
644
  _barButtonItemsByItemId[item.itemId] = barButtonItem;
572
645
  }
@@ -4,11 +4,26 @@
4
4
  #import <React/RCTLog.h>
5
5
  #import "RCTConvert+RNSTabs.h"
6
6
  #import "RNSConversions-Tabs.h"
7
+ #import "RNSDefines.h"
7
8
  #import "RNSImageLoadingHelper.h"
8
9
  #import "RNSTabBarController.h"
9
10
  #import "RNSTabsHostComponentView.h"
10
11
  #import "RNSTabsScreenViewController.h"
11
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
+
12
27
  @implementation RNSTabBarAppearanceCoordinator
13
28
 
14
29
  - (void)updateAppearanceOfTabBar:(nullable UITabBar *)tabBar
@@ -56,25 +71,43 @@
56
71
  withImageLoader:imageLoader];
57
72
  }
58
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
+
59
90
  - (void)setIconsForTabBarItem:(UITabBarItem *)tabBarItem
60
91
  fromScreenView:(RNSTabsScreenComponentView *)screenView
61
92
  withImageLoader:(RCTImageLoader *_Nullable)imageLoader
62
93
  {
63
94
  if (screenView.iconType == RNSTabsIconTypeSfSymbol || screenView.iconType == RNSTabsIconTypeXcasset) {
64
95
  if (screenView.iconResourceName != nil) {
96
+ UIImage *image;
65
97
  if (screenView.iconType == RNSTabsIconTypeSfSymbol) {
66
- UIImage *image = [UIImage systemImageNamed:screenView.iconResourceName];
98
+ image = [RNSImageLoadingHelper symbolImageNamed:screenView.iconResourceName];
67
99
  if (image == nil) {
68
100
  RCTLogWarn(@"[RNScreens] Failed to load SF Symbol \"%@\" for tab bar item", screenView.iconResourceName);
69
101
  }
70
- tabBarItem.image = image;
71
102
  } else {
72
- UIImage *image = [UIImage imageNamed:screenView.iconResourceName];
103
+ image = [UIImage imageNamed:screenView.iconResourceName];
73
104
  if (image == nil) {
74
105
  RCTLogWarn(@"[RNScreens] Failed to load xcasset \"%@\" for tab bar item", screenView.iconResourceName);
75
106
  }
76
- tabBarItem.image = image;
77
107
  }
108
+ [self setTabImage:RNSImageWithSymbolRenderingMode(image, screenView.iconSymbolRenderingMode)
109
+ forTabBarItem:tabBarItem
110
+ screenView:screenView];
78
111
  } else if (screenView.systemItem != RNSTabsScreenSystemItemNone) {
79
112
  // Restore default system item icon
80
113
  std::optional<UITabBarSystemItem> systemItem =
@@ -85,27 +118,30 @@
85
118
  (long)screenView.systemItem);
86
119
  return;
87
120
  }
88
- tabBarItem.image = [[UITabBarItem alloc] initWithTabBarSystemItem:systemItem.value() tag:0].image;
121
+ UIImage *_Nullable systemItemImage =
122
+ [[UITabBarItem alloc] initWithTabBarSystemItem:systemItem.value() tag:0].image;
123
+ [self setTabImage:systemItemImage forTabBarItem:tabBarItem screenView:screenView];
89
124
  } else {
90
- tabBarItem.image = nil;
125
+ [self setTabImage:nil forTabBarItem:tabBarItem screenView:screenView];
91
126
  }
92
127
 
93
128
  if (screenView.selectedIconResourceName != nil) {
129
+ UIImage *selectedImage;
94
130
  if (screenView.iconType == RNSTabsIconTypeSfSymbol) {
95
- UIImage *selectedImage = [UIImage systemImageNamed:screenView.selectedIconResourceName];
131
+ selectedImage = [RNSImageLoadingHelper symbolImageNamed:screenView.selectedIconResourceName];
96
132
  if (selectedImage == nil) {
97
133
  RCTLogWarn(@"[RNScreens] Failed to load SF Symbol \"%@\" for selected tab bar item",
98
134
  screenView.selectedIconResourceName);
99
135
  }
100
- tabBarItem.selectedImage = selectedImage;
101
136
  } else {
102
- UIImage *selectedImage = [UIImage imageNamed:screenView.selectedIconResourceName];
137
+ selectedImage = [UIImage imageNamed:screenView.selectedIconResourceName];
103
138
  if (selectedImage == nil) {
104
139
  RCTLogWarn(@"[RNScreens] Failed to load xcasset \"%@\" for selected tab bar item",
105
140
  screenView.selectedIconResourceName);
106
141
  }
107
- tabBarItem.selectedImage = selectedImage;
108
142
  }
143
+ tabBarItem.selectedImage =
144
+ RNSImageWithSymbolRenderingMode(selectedImage, screenView.selectedIconSymbolRenderingMode);
109
145
  } else if (screenView.systemItem != RNSTabsScreenSystemItemNone) {
110
146
  // Restore default system item icon
111
147
  std::optional<UITabBarSystemItem> systemItem =
@@ -121,7 +157,8 @@
121
157
  tabBarItem.selectedImage = nil;
122
158
  }
123
159
  } else if (imageLoader != nil) {
124
- bool isTemplate = screenView.iconType == RNSTabsIconTypeTemplate;
160
+ bool isTemplate = screenView.iconImageRenderingMode == RNSTabsIconImageRenderingModeTemplate;
161
+ bool isSelectedTemplate = screenView.selectedIconImageRenderingMode == RNSTabsIconImageRenderingModeTemplate;
125
162
 
126
163
  // Weak-capture to avoid updating a tab bar item whose internal
127
164
  // view hierarchy has been torn down (iOS 26 UIKit regression:
@@ -141,14 +178,14 @@
141
178
  forScreenView:weakScreenView];
142
179
  }];
143
180
  } else {
144
- tabBarItem.image = nil;
181
+ [self setTabImage:nil forTabBarItem:tabBarItem screenView:screenView];
145
182
  }
146
183
 
147
184
  // Selected icon
148
185
  if (screenView.selectedIconImageSource != nil) {
149
186
  [RNSImageLoadingHelper loadImageFromSource:screenView.selectedIconImageSource
150
187
  withImageLoader:imageLoader
151
- asTemplate:isTemplate
188
+ asTemplate:isSelectedTemplate
152
189
  completionBlock:^(UIImage *image) {
153
190
  [self updateTabBarItem:weakTabBarItem
154
191
  withImage:image
@@ -163,6 +200,22 @@
163
200
  }
164
201
  }
165
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
+
166
219
  - (void)updateTabBarItem:(nullable UITabBarItem *)tabBarItem
167
220
  withImage:(nullable UIImage *)image
168
221
  isSelected:(BOOL)isSelected
@@ -175,16 +228,26 @@
175
228
  return;
176
229
  }
177
230
 
178
- UIViewController *screenParentViewController = [screenView.controller parentViewController];
179
- if (screenParentViewController == nil) {
231
+ if (![self isScreenControllerAttachedToTabBarController:screenView.controller]) {
180
232
  return;
181
233
  }
182
234
 
183
235
  if (isSelected) {
184
236
  tabBarItem.selectedImage = image;
185
237
  } else {
186
- 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
+ }
187
249
  }
250
+ #endif // RNS_UITAB_API_SDK_AVAILABLE
188
251
 
189
252
  // A layout pass is required because the image might be loaded asynchronously,
190
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