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
@@ -26,13 +26,11 @@ import com.swmansion.rnscreens.common.colorscheme.ColorSchemeProviding
26
26
  import com.swmansion.rnscreens.common.container.Container
27
27
  import com.swmansion.rnscreens.common.container.ContainerItem
28
28
  import com.swmansion.rnscreens.common.container.ParentContainerItemRegistry
29
- import com.swmansion.rnscreens.helpers.FragmentManagerHelper
30
- import com.swmansion.rnscreens.helpers.ViewFinder
29
+ import com.swmansion.rnscreens.ext.createTransactionWithReordering
31
30
  import com.swmansion.rnscreens.helpers.ViewIdGenerator
32
- import com.swmansion.rnscreens.helpers.createTransactionWithReordering
33
31
  import com.swmansion.rnscreens.safearea.EdgeInsets
32
+ import com.swmansion.rnscreens.safearea.OnInterfaceInsetsChangeListener
34
33
  import com.swmansion.rnscreens.safearea.SafeAreaProvider
35
- import com.swmansion.rnscreens.safearea.SafeAreaView
36
34
  import com.swmansion.rnscreens.tabs.appearance.TabsAppearanceCoordinator
37
35
  import com.swmansion.rnscreens.tabs.host.TabsHost
38
36
  import com.swmansion.rnscreens.tabs.host.TabsHostA11yCoordinator
@@ -40,6 +38,7 @@ import com.swmansion.rnscreens.tabs.screen.TabsScreen
40
38
  import com.swmansion.rnscreens.tabs.screen.TabsScreenDelegate
41
39
  import com.swmansion.rnscreens.tabs.screen.TabsScreenFragment
42
40
  import com.swmansion.rnscreens.utils.RNSLog
41
+ import java.lang.ref.WeakReference
43
42
  import kotlin.properties.Delegates
44
43
 
45
44
  /**
@@ -53,6 +52,7 @@ import kotlin.properties.Delegates
53
52
  @SuppressLint("ViewConstructor") // Created only by us. Should never be restored.
54
53
  class TabsContainer internal constructor(
55
54
  private val context: Context,
55
+ private val delegate: WeakReference<TabsContainerDelegate>,
56
56
  ) : FrameLayout(context),
57
57
  Container,
58
58
  ColorSchemeProviding,
@@ -68,9 +68,7 @@ class TabsContainer internal constructor(
68
68
  val selectedTabScreen = this@TabsContainer.selectedTab.tabsScreen
69
69
 
70
70
  if (selectedTabScreen.shouldUseRepeatedTabSelectionPopToRootSpecialEffect) {
71
- val screenStack =
72
- ViewFinder.findScreenStackInFirstDescendantChain(selectedTabScreen)
73
- if (screenStack != null && screenStack.popToRoot()) {
71
+ if (selectedTabScreen.resolveNestedContainer()?.requestPopToRoot() == true) {
74
72
  return true
75
73
  }
76
74
  }
@@ -162,7 +160,7 @@ class TabsContainer internal constructor(
162
160
 
163
161
  private val a11yCoordinator = TabsHostA11yCoordinator(bottomNavigationView, tabsModel)
164
162
 
165
- private var interfaceInsetsChangeListener: SafeAreaView? = null
163
+ private var interfaceInsetsChangeListener: OnInterfaceInsetsChangeListener? = null
166
164
 
167
165
  internal var tabBarHidden: Boolean by Delegates.observable(false) { _, oldValue, newValue ->
168
166
  if (newValue != oldValue) {
@@ -257,9 +255,9 @@ class TabsContainer internal constructor(
257
255
 
258
256
  internal fun setupFragmentManager() {
259
257
  fragmentManager =
260
- checkNotNull(FragmentManagerHelper.findFragmentManagerForView(this)) {
261
- "[RNScreens] Nullish fragment manager - can't run container operations"
262
- }
258
+ checkNotNull(delegate.get()) {
259
+ "[RNScreens] TabsContainer has no delegate to resolve the fragment manager from"
260
+ }.resolveFragmentManager()
263
261
  }
264
262
 
265
263
  internal fun teardownFragmentManager() {
@@ -374,14 +372,14 @@ class TabsContainer internal constructor(
374
372
  }
375
373
  }
376
374
 
377
- override fun setOnInterfaceInsetsChangeListener(listener: SafeAreaView) {
375
+ override fun setOnInterfaceInsetsChangeListener(listener: OnInterfaceInsetsChangeListener) {
378
376
  if (interfaceInsetsChangeListener == null) {
379
377
  bottomNavigationView.addOnLayoutChangeListener(this)
380
378
  }
381
379
  interfaceInsetsChangeListener = listener
382
380
  }
383
381
 
384
- override fun removeOnInterfaceInsetsChangeListener(listener: SafeAreaView) {
382
+ override fun removeOnInterfaceInsetsChangeListener(listener: OnInterfaceInsetsChangeListener) {
385
383
  if (interfaceInsetsChangeListener == listener) {
386
384
  interfaceInsetsChangeListener = null
387
385
  bottomNavigationView.removeOnLayoutChangeListener(this)
@@ -417,11 +415,23 @@ class TabsContainer internal constructor(
417
415
  menuItem,
418
416
  tabsScreen,
419
417
  appearance,
418
+ appearanceCoordinator.resolveIconBoxDp(),
420
419
  )
421
420
  a11yCoordinator.setA11yPropertiesToTabItem(menuItem, tabsScreen)
422
421
  }
423
422
  }
424
423
 
424
+ override fun onItemSizeChange(tabsScreen: TabsScreen) {
425
+ // Icon box is bar-wide, so this must run even when the changed tab is not selected.
426
+ // Skip when detached; reattachment reapplies the full appearance anyway.
427
+ if (isAttachedToWindow) {
428
+ invalidationFlags.isNavigationMenuAppearanceInvalidated = true
429
+ post {
430
+ this.flushPendingUpdates()
431
+ }
432
+ }
433
+ }
434
+
425
435
  override fun getFragmentForTabsScreen(tabsScreen: TabsScreen): TabsScreenFragment? =
426
436
  tabsModel.find {
427
437
  it.tabsScreen ===
@@ -552,6 +562,7 @@ class TabsContainer internal constructor(
552
562
  tabsModel.forEach { fragment ->
553
563
  menu.getOrCreateMenuItemForFragment(fragment)
554
564
  }
565
+ appearanceCoordinator.invalidateRebuiltMenuItems()
555
566
  }
556
567
 
557
568
  private fun updateBottomNavigationViewAppearance() {
@@ -801,6 +812,10 @@ class TabsContainer internal constructor(
801
812
  null
802
813
  }
803
814
 
815
+ // Tabs have no stack of their own - the request goes to the selected tab's nested container.
816
+ override fun requestPopToRoot(): Boolean =
817
+ navState.isNotEmpty() && selectedTab.tabsScreen.resolveNestedContainer()?.requestPopToRoot() == true
818
+
804
819
  // endregion
805
820
 
806
821
  companion object {
@@ -0,0 +1,11 @@
1
+ package com.swmansion.rnscreens.tabs.container
2
+
3
+ import androidx.fragment.app.FragmentManager
4
+
5
+ internal interface TabsContainerDelegate {
6
+ /**
7
+ * Resolves the fragment manager the container should run its operations on. Called every time the container
8
+ * is attached to a window, as the result may differ between attachments.
9
+ */
10
+ fun resolveFragmentManager(): FragmentManager
11
+ }
@@ -4,21 +4,25 @@ import android.annotation.SuppressLint
4
4
  import android.view.ViewTreeObserver
5
5
  import android.widget.FrameLayout
6
6
  import androidx.core.graphics.drawable.toDrawable
7
+ import androidx.fragment.app.FragmentManager
7
8
  import com.facebook.react.bridge.UIManager
8
9
  import com.facebook.react.bridge.UIManagerListener
9
10
  import com.facebook.react.common.annotations.UnstableReactNativeAPI
10
11
  import com.facebook.react.uimanager.ThemedReactContext
11
12
  import com.facebook.react.uimanager.UIManagerHelper
12
13
  import com.swmansion.rnscreens.common.colorscheme.ColorScheme
14
+ import com.swmansion.rnscreens.helpers.FragmentManagerHelper
13
15
  import com.swmansion.rnscreens.helpers.getFabricUIManagerNotNull
14
16
  import com.swmansion.rnscreens.tabs.container.TabsActionOrigin
15
17
  import com.swmansion.rnscreens.tabs.container.TabsContainer
18
+ import com.swmansion.rnscreens.tabs.container.TabsContainerDelegate
16
19
  import com.swmansion.rnscreens.tabs.container.TabsNavigationState
17
20
  import com.swmansion.rnscreens.tabs.container.TabsNavigationStateObserver
18
21
  import com.swmansion.rnscreens.tabs.container.TabsNavigationStateRejectionReason
19
22
  import com.swmansion.rnscreens.tabs.container.TabsNavigationStateUpdateRequest
20
23
  import com.swmansion.rnscreens.tabs.screen.TabsScreen
21
24
  import com.swmansion.rnscreens.utils.RNSLog
25
+ import java.lang.ref.WeakReference
22
26
  import kotlin.properties.Delegates
23
27
 
24
28
  @SuppressLint("ViewConstructor") // Only created by us. Should never be restored
@@ -28,7 +32,8 @@ class TabsHost(
28
32
  ) : FrameLayout(reactContext),
29
33
  TabsNavigationStateObserver,
30
34
  ViewTreeObserver.OnPreDrawListener,
31
- UIManagerListener {
35
+ UIManagerListener,
36
+ TabsContainerDelegate {
32
37
  private val renderedScreens: ArrayList<TabsScreen> = arrayListOf()
33
38
  private var jsNavStateRequest: TabsNavigationStateUpdateRequest? = null
34
39
  private val layoutCoordinator: TabsHostLayoutCoordinator =
@@ -37,7 +42,7 @@ class TabsHost(
37
42
  private var hasFirstLayoutWithInsets: Boolean = false
38
43
 
39
44
  private val container: TabsContainer =
40
- TabsContainer(reactContext).apply {
45
+ TabsContainer(reactContext, WeakReference(this)).apply {
41
46
  layoutParams =
42
47
  LayoutParams(
43
48
  LayoutParams.MATCH_PARENT,
@@ -82,6 +87,11 @@ class TabsHost(
82
87
  super.onDetachedFromWindow()
83
88
  }
84
89
 
90
+ override fun resolveFragmentManager(): FragmentManager =
91
+ checkNotNull(FragmentManagerHelper.findFragmentManagerForView(this)) {
92
+ "[RNScreens] Nullish fragment manager - can't run container operations"
93
+ }
94
+
85
95
  internal fun mountReactSubviewAt(
86
96
  tabsScreen: TabsScreen,
87
97
  index: Int,
@@ -1,7 +1,6 @@
1
1
  package com.swmansion.rnscreens.tabs.screen
2
2
 
3
3
  import android.content.res.Configuration
4
- import android.graphics.drawable.Drawable
5
4
  import android.os.Parcelable
6
5
  import android.util.SparseArray
7
6
  import android.view.ViewGroup
@@ -11,7 +10,6 @@ import com.swmansion.rnscreens.common.FragmentProviding
11
10
  import com.swmansion.rnscreens.common.container.Container
12
11
  import com.swmansion.rnscreens.common.container.ContainerItem
13
12
  import com.swmansion.rnscreens.common.container.ContainerItemSupport
14
- import com.swmansion.rnscreens.helpers.getSystemDrawableResource
15
13
  import com.swmansion.rnscreens.scrollviewmarker.ScrollViewMarker
16
14
  import com.swmansion.rnscreens.scrollviewmarker.ScrollViewSeeking
17
15
  import com.swmansion.rnscreens.tabs.appearance.TabsAppearance
@@ -54,7 +52,11 @@ class TabsScreen(
54
52
 
55
53
  internal var appearance: TabsAppearance? by Delegates.observable(null) { _, oldValue, newValue ->
56
54
  if (oldValue != newValue) {
57
- tabsScreenDelegate.get()?.onAppearanceChanged(this)
55
+ if (invalidateMenuItemSizesIfNeeded(oldValue, newValue)) {
56
+ tabsScreenDelegate.get()?.onItemSizeChange(this)
57
+ } else {
58
+ tabsScreenDelegate.get()?.onAppearanceChanged(this)
59
+ }
58
60
  }
59
61
  }
60
62
 
@@ -80,24 +82,39 @@ class TabsScreen(
80
82
  // endregion
81
83
 
82
84
  // region Icon
83
- var drawableIconResourceName: String? by Delegates.observable(null) { _, oldValue, newValue ->
84
- if (newValue != oldValue) {
85
- icon = getSystemDrawableResource(reactContext, newValue)
86
- }
87
- }
88
85
 
89
- var selectedDrawableIconResourceName: String? by Delegates.observable(null) { _, oldValue, newValue ->
90
- if (newValue != oldValue) {
91
- selectedIcon = getSystemDrawableResource(reactContext, newValue)
92
- }
93
- }
86
+ internal val icon = TabsScreenIcon(reactContext, ::onIconChange)
87
+ internal val selectedIcon = TabsScreenIcon(reactContext, ::onIconChange)
94
88
 
95
- var icon: Drawable? by Delegates.observable(null) { _, oldValue, newValue ->
96
- updateMenuItemAttributesIfNeeded(oldValue, newValue)
89
+ internal var isMenuItemIconInvalidated = true
90
+
91
+ internal var isMenuItemActiveIndicatorInvalidated = true
92
+
93
+ internal var appliedActiveIndicatorWidthPx: Int? = null
94
+
95
+ internal var appliedActiveIndicatorHeightPx: Int? = null
96
+
97
+ internal fun resolveIconsIfNeeded() {
98
+ icon.resolveIfNeeded()
99
+ selectedIcon.resolveIfNeeded()
97
100
  }
98
101
 
99
- var selectedIcon: Drawable? by Delegates.observable(null) { _, oldValue, newValue ->
100
- updateMenuItemAttributesIfNeeded(oldValue, newValue)
102
+ private fun invalidateMenuItemSizesIfNeeded(
103
+ oldValue: TabsAppearance?,
104
+ newValue: TabsAppearance?,
105
+ ): Boolean {
106
+ val isIconSizeChanged = oldValue?.tabBarItemIconSize != newValue?.tabBarItemIconSize
107
+ val isActiveIndicatorSizeChanged =
108
+ oldValue?.tabBarItemActiveIndicatorWidth != newValue?.tabBarItemActiveIndicatorWidth ||
109
+ oldValue?.tabBarItemActiveIndicatorHeight != newValue?.tabBarItemActiveIndicatorHeight
110
+ if (isIconSizeChanged) {
111
+ isMenuItemIconInvalidated = true
112
+ }
113
+ if (isIconSizeChanged || isActiveIndicatorSizeChanged) {
114
+ isMenuItemActiveIndicatorInvalidated = true
115
+ return true
116
+ }
117
+ return false
101
118
  }
102
119
 
103
120
  // endregion
@@ -121,6 +138,8 @@ class TabsScreen(
121
138
  super.onAttachedToWindow()
122
139
  }
123
140
 
141
+ override fun shouldDelayChildPressedState(): Boolean = false
142
+
124
143
  override fun onLayout(
125
144
  changed: Boolean,
126
145
  l: Int,
@@ -150,6 +169,11 @@ class TabsScreen(
150
169
  tabsScreenDelegate.get()?.onMenuItemAttributesChange(this)
151
170
  }
152
171
 
172
+ private fun onIconChange() {
173
+ isMenuItemIconInvalidated = true
174
+ onMenuItemAttributesChange()
175
+ }
176
+
153
177
  internal fun onViewManagerAddEventEmitters() {
154
178
  // When this is called from View Manager the view tag is already set
155
179
  check(id != NO_ID) { "[RNScreens] TabsScreen must have its tag set when registering event emitters" }
@@ -8,6 +8,12 @@ internal interface TabsScreenDelegate {
8
8
 
9
9
  fun onMenuItemAttributesChange(tabsScreen: TabsScreen)
10
10
 
11
+ /**
12
+ * The icon box is bar-wide, so an icon size change requires a whole-bar appearance
13
+ * update regardless of tab selection.
14
+ */
15
+ fun onItemSizeChange(tabsScreen: TabsScreen)
16
+
11
17
  /**
12
18
  * **If a fragment is associated with the tab screen**, notify the delegate that the fragment
13
19
  * got configuration update.
@@ -0,0 +1,82 @@
1
+ package com.swmansion.rnscreens.tabs.screen
2
+
3
+ import android.content.Context
4
+ import android.graphics.drawable.Drawable
5
+ import com.swmansion.rnscreens.helpers.IconResolution
6
+ import com.swmansion.rnscreens.helpers.NoTintDrawable
7
+ import com.swmansion.rnscreens.helpers.PropIconResolver
8
+ import com.swmansion.rnscreens.helpers.resolveImage
9
+ import kotlin.properties.Delegates
10
+
11
+ /**
12
+ * Single icon slot (normal or selected) of a tab bar item. Props stage here and may arrive
13
+ * in any order within a single update batch; resolution runs once per transaction via
14
+ * [resolveIfNeeded]. [onChanged] fires only when the resolved [drawable] actually changes.
15
+ */
16
+ internal class TabsScreenIcon(
17
+ context: Context,
18
+ private val onChanged: () -> Unit,
19
+ ) {
20
+ var drawableResourceName: String? by Delegates.observable(null) { _, oldValue, newValue ->
21
+ if (newValue != oldValue) isInvalidated = true
22
+ }
23
+
24
+ var tinting: TabsScreenIconTinting by Delegates.observable(
25
+ TabsScreenIconTinting.DEFAULT,
26
+ ) { _, oldValue, newValue ->
27
+ if (newValue != oldValue) isInvalidated = true
28
+ }
29
+
30
+ var imageUri: String? by Delegates.observable(null) { _, oldValue, newValue ->
31
+ if (newValue != oldValue) isInvalidated = true
32
+ }
33
+
34
+ // Resolved output; read by the appearance applicator.
35
+ var drawable: Drawable? = null
36
+ private set
37
+
38
+ private var isInvalidated = false
39
+
40
+ // Handles source precedence (drawable name wins over uri), dedup, and stale async image drops.
41
+ private val resolver = createPropIconResolver(context)
42
+
43
+ // Kept unwrapped so a tint-only change re-wraps without reloading.
44
+ private var rawDrawable: Drawable? = null
45
+ private var appliedTinting = TabsScreenIconTinting.DEFAULT
46
+
47
+ fun resolveIfNeeded() {
48
+ if (!isInvalidated) {
49
+ return
50
+ }
51
+ isInvalidated = false
52
+ resolver.resolve(drawableResourceName, imageUri) { result ->
53
+ when (result) {
54
+ IconResolution.Unchanged -> if (tinting != appliedTinting) emit()
55
+ is IconResolution.Resolved -> {
56
+ rawDrawable = result.drawable
57
+ emit()
58
+ }
59
+ }
60
+ }
61
+ }
62
+
63
+ // Tint is read at emit time, so a toggle during an in-flight image load still applies.
64
+ private fun emit() {
65
+ appliedTinting = tinting
66
+ val next =
67
+ rawDrawable?.let {
68
+ if (tinting == TabsScreenIconTinting.ORIGINAL) NoTintDrawable(it) else it
69
+ }
70
+ if (next !== drawable) {
71
+ drawable = next
72
+ onChanged()
73
+ }
74
+ }
75
+
76
+ private companion object {
77
+ fun createPropIconResolver(context: Context) =
78
+ PropIconResolver { name, uri, onComplete ->
79
+ resolveImage(context, name, uri, onComplete)
80
+ }
81
+ }
82
+ }
@@ -0,0 +1,17 @@
1
+ package com.swmansion.rnscreens.tabs.screen
2
+
3
+ internal enum class TabsScreenIconTinting {
4
+ DEFAULT,
5
+ TINTED,
6
+ ORIGINAL,
7
+ ;
8
+
9
+ companion object {
10
+ fun fromString(value: String?): TabsScreenIconTinting =
11
+ when (value) {
12
+ "tinted" -> TINTED
13
+ "original" -> ORIGINAL
14
+ else -> DEFAULT
15
+ }
16
+ }
17
+ }
@@ -8,7 +8,6 @@ import com.facebook.react.uimanager.ViewGroupManager
8
8
  import com.facebook.react.uimanager.ViewManagerDelegate
9
9
  import com.facebook.react.viewmanagers.RNSTabsScreenAndroidManagerDelegate
10
10
  import com.facebook.react.viewmanagers.RNSTabsScreenAndroidManagerInterface
11
- import com.swmansion.rnscreens.helpers.loadImage
12
11
  import com.swmansion.rnscreens.helpers.makeEventRegistrationInfo
13
12
  import com.swmansion.rnscreens.helpers.readOptionalBoolean
14
13
  import com.swmansion.rnscreens.helpers.readOptionalColor
@@ -55,6 +54,11 @@ class TabsScreenViewManager :
55
54
  view.onViewManagerAddEventEmitters()
56
55
  }
57
56
 
57
+ override fun onAfterUpdateTransaction(view: TabsScreen) {
58
+ super.onAfterUpdateTransaction(view)
59
+ view.resolveIconsIfNeeded()
60
+ }
61
+
58
62
  override fun setScreenKey(
59
63
  view: TabsScreen,
60
64
  value: String?,
@@ -125,42 +129,42 @@ class TabsScreenViewManager :
125
129
  view: TabsScreen,
126
130
  value: String?,
127
131
  ) {
128
- view.drawableIconResourceName = value
132
+ view.icon.drawableResourceName = value
129
133
  }
130
134
 
131
135
  override fun setSelectedDrawableIconResourceName(
132
136
  view: TabsScreen,
133
137
  value: String?,
134
138
  ) {
135
- view.selectedDrawableIconResourceName = value
139
+ view.selectedIcon.drawableResourceName = value
140
+ }
141
+
142
+ override fun setIconTinting(
143
+ view: TabsScreen,
144
+ value: String?,
145
+ ) {
146
+ view.icon.tinting = TabsScreenIconTinting.fromString(value)
147
+ }
148
+
149
+ override fun setSelectedIconTinting(
150
+ view: TabsScreen,
151
+ value: String?,
152
+ ) {
153
+ view.selectedIcon.tinting = TabsScreenIconTinting.fromString(value)
136
154
  }
137
155
 
138
156
  override fun setImageIconResource(
139
157
  view: TabsScreen,
140
158
  value: ReadableMap?,
141
159
  ) {
142
- val uri = value?.getString("uri")
143
- if (uri != null) {
144
- loadImage(view.context, uri) { drawable ->
145
- if (drawable != null) {
146
- view.icon = drawable
147
- }
148
- }
149
- }
160
+ view.icon.imageUri = value?.getString("uri")
150
161
  }
151
162
 
152
163
  override fun setSelectedImageIconResource(
153
164
  view: TabsScreen,
154
165
  value: ReadableMap?,
155
166
  ) {
156
- val uri = value?.getString("uri")
157
- if (uri != null) {
158
- loadImage(view.context, uri) { drawable ->
159
- if (drawable != null) {
160
- view.selectedIcon = drawable
161
- }
162
- }
163
- }
167
+ view.selectedIcon.imageUri = value?.getString("uri")
164
168
  }
165
169
 
166
170
  override fun setStandardAppearance(
@@ -187,8 +191,11 @@ class TabsScreenViewManager :
187
191
  selected = if (appearance.hasKey("selected")) parseItemStateAppearance(context, appearance.getMap("selected")) else null,
188
192
  focused = if (appearance.hasKey("focused")) parseItemStateAppearance(context, appearance.getMap("focused")) else null,
189
193
  disabled = if (appearance.hasKey("disabled")) parseItemStateAppearance(context, appearance.getMap("disabled")) else null,
194
+ tabBarItemIconSize = appearance.readOptionalFloat("tabBarItemIconSize"),
190
195
  tabBarItemActiveIndicatorColor = appearance.readOptionalColor(context, "tabBarItemActiveIndicatorColor"),
191
196
  tabBarItemActiveIndicatorEnabled = appearance.readOptionalBoolean("tabBarItemActiveIndicatorEnabled"),
197
+ tabBarItemActiveIndicatorWidth = appearance.readOptionalFloat("tabBarItemActiveIndicatorWidth"),
198
+ tabBarItemActiveIndicatorHeight = appearance.readOptionalFloat("tabBarItemActiveIndicatorHeight"),
192
199
  tabBarItemTitleFontFamily = appearance.readOptionalString("tabBarItemTitleFontFamily"),
193
200
  tabBarItemTitleSmallLabelFontSize = appearance.readOptionalFloat("tabBarItemTitleSmallLabelFontSize"),
194
201
  tabBarItemTitleLargeLabelFontSize = appearance.readOptionalFloat("tabBarItemTitleLargeLabelFontSize"),
@@ -1,13 +1,20 @@
1
1
  package com.swmansion.rnscreens.utils
2
2
 
3
3
  import android.content.Context
4
+ import android.content.res.Resources
4
5
  import android.util.TypedValue
5
6
  import android.view.View
6
- import com.facebook.react.uimanager.PixelUtil
7
+
8
+ /**
9
+ * Density of the device's main display - the value React Native's `PixelUtil` converts with
10
+ * (`DisplayMetricsHolder` screen metrics), read without depending on React Native.
11
+ */
12
+ private val mainDisplayDensity: Float
13
+ get() = Resources.getSystem().displayMetrics.density
7
14
 
8
15
  /**
9
16
  * Converts a pixel value to dp using the given display [density] — not the process-global
10
- * density that [PixelUtil] reads from the device's main display. Fabric mounts views with
17
+ * density of the device's main display. Fabric mounts views with
11
18
  * the per-display density, so state pushed back to the Shadow Tree must be converted with
12
19
  * that same density; the global one mis-scales the frame on any display whose density
13
20
  * differs from the main one (Samsung DeX, freeform multi-window, external monitors). On
@@ -18,12 +25,12 @@ import com.facebook.react.uimanager.PixelUtil
18
25
  * [android.util.DisplayMetrics] that was never populated — which should not happen for a
19
26
  * live view. The `density > 0f` guard exists solely so a degenerate `0` cannot turn the
20
27
  * division into Infinity/NaN and corrupt the pushed state; in that case we fall back to the
21
- * global conversion, which is at least well-defined.
28
+ * main display's density ([mainDisplayDensity]), which is at least well-defined.
22
29
  */
23
30
  internal fun pxToDp(
24
31
  px: Float,
25
32
  density: Float,
26
- ): Float = if (density > 0f) px / density else PixelUtil.toDIPFromPixel(px)
33
+ ): Float = if (density > 0f) px / density else px / mainDisplayDensity
27
34
 
28
35
  /**
29
36
  * Converts a pixel value to dp using the density of the display this [View] is attached to.
@@ -34,13 +41,13 @@ internal fun View.pxToDp(px: Float): Float = pxToDp(px, resources.displayMetrics
34
41
 
35
42
  /**
36
43
  * Converts a dp value to pixels using the given display [density] — not the process-global
37
- * density that [PixelUtil] reads from the device's main display.
44
+ * density of the device's main display.
38
45
  * See [pxToDp] for more context.
39
46
  */
40
47
  internal fun dpToPx(
41
48
  dp: Float,
42
49
  density: Float,
43
- ): Float = if (density > 0f) dp * density else PixelUtil.toPixelFromDIP(dp)
50
+ ): Float = if (density > 0f) dp * density else dp * mainDisplayDensity
44
51
 
45
52
  /**
46
53
  * Converts a dp value to pixels using the density of the display this [View] is attached to.
@@ -52,7 +59,7 @@ internal fun View.dpToPx(dp: Float): Float = dpToPx(dp, resources.displayMetrics
52
59
  /**
53
60
  * Converts an SP value to pixels using the density of the display this [View] is
54
61
  * attached to (including the current font scale). Uses the view's own resources
55
- * rather than the process-global density read by [PixelUtil]. See [pxToDp].
62
+ * rather than the process-global density of the main display. See [pxToDp].
56
63
  */
57
64
  internal fun View.spToPx(sp: Float): Float = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, resources.displayMetrics)
58
65
 
@@ -3,6 +3,10 @@ package com.swmansion.rnscreens.utils
3
3
  import android.util.Log
4
4
  import com.swmansion.rnscreens.BuildConfig
5
5
 
6
+ /**
7
+ * `d`, `i` and `v` are emitted only when `RNS_DEBUG_LOGGING` is enabled;
8
+ * `w`, `e` and `wtf` are always emitted.
9
+ */
6
10
  object RNSLog {
7
11
  private inline fun logIfEnabled(
8
12
  tag: String,
@@ -39,13 +43,17 @@ object RNSLog {
39
43
  fun e(
40
44
  tag: String,
41
45
  msg: String,
42
- ) = logIfEnabled(tag, msg, Log::e)
46
+ ) {
47
+ Log.e(tag, msg)
48
+ }
43
49
 
44
50
  fun e(
45
51
  tag: String,
46
52
  msg: String,
47
53
  tr: Throwable,
48
- ) = logIfEnabled(tag, msg, tr, Log::e)
54
+ ) {
55
+ Log.e(tag, msg, tr)
56
+ }
49
57
 
50
58
  fun i(
51
59
  tag: String,
@@ -72,22 +80,30 @@ object RNSLog {
72
80
  fun w(
73
81
  tag: String,
74
82
  msg: String,
75
- ) = logIfEnabled(tag, msg, Log::w)
83
+ ) {
84
+ Log.w(tag, msg)
85
+ }
76
86
 
77
87
  fun w(
78
88
  tag: String,
79
89
  msg: String,
80
90
  tr: Throwable,
81
- ) = logIfEnabled(tag, msg, tr, Log::w)
91
+ ) {
92
+ Log.w(tag, msg, tr)
93
+ }
82
94
 
83
95
  fun wtf(
84
96
  tag: String,
85
97
  msg: String,
86
- ) = logIfEnabled(tag, msg, Log::wtf)
98
+ ) {
99
+ Log.wtf(tag, msg)
100
+ }
87
101
 
88
102
  fun wtf(
89
103
  tag: String,
90
104
  msg: String,
91
105
  tr: Throwable,
92
- ) = logIfEnabled(tag, msg, tr, Log::wtf)
106
+ ) {
107
+ Log.wtf(tag, msg, tr)
108
+ }
93
109
  }
package/ios/RNSEnums.h CHANGED
@@ -51,11 +51,22 @@ typedef NS_ENUM(NSInteger, RNSBlurEffectStyle) {
51
51
 
52
52
  typedef NS_ENUM(NSInteger, RNSTabsIconType) {
53
53
  RNSTabsIconTypeImage,
54
- RNSTabsIconTypeTemplate,
55
54
  RNSTabsIconTypeSfSymbol,
56
55
  RNSTabsIconTypeXcasset,
57
56
  };
58
57
 
58
+ typedef NS_ENUM(NSInteger, RNSTabsIconImageRenderingMode) {
59
+ RNSTabsIconImageRenderingModeDefault,
60
+ RNSTabsIconImageRenderingModeTemplate,
61
+ RNSTabsIconImageRenderingModeOriginal,
62
+ };
63
+
64
+ typedef NS_ENUM(NSInteger, RNSTabsIconSymbolRenderingMode) {
65
+ RNSTabsIconSymbolRenderingModeDefault,
66
+ RNSTabsIconSymbolRenderingModeMonochrome,
67
+ RNSTabsIconSymbolRenderingModeOriginal,
68
+ };
69
+
59
70
  typedef NS_ENUM(NSInteger, RNSOrientation) {
60
71
  RNSOrientationInherit,
61
72
  RNSOrientationAll,
@@ -84,6 +95,8 @@ typedef NS_ENUM(NSInteger, RNSTabsScreenSystemItem) {
84
95
  RNSTabsScreenSystemItemTopRated
85
96
  };
86
97
 
98
+ typedef NS_ENUM(NSInteger, RNSTabsScreenTabRole) { RNSTabsScreenTabRoleNone, RNSTabsScreenTabRoleSearch };
99
+
87
100
  typedef NS_ENUM(NSInteger, RNSTabsBottomAccessoryEnvironment) {
88
101
  RNSTabsBottomAccessoryEnvironmentRegular,
89
102
  RNSTabsBottomAccessoryEnvironmentInline
@@ -27,6 +27,13 @@
27
27
  asTemplate:(BOOL)isTemplate
28
28
  completionBlock:(void (^_Nonnull)(UIImage *_Nullable image))imageLoadingCompletionBlock;
29
29
 
30
+ /**
31
+ * Loads a symbol image by name: a built-in SF Symbol if one matches, otherwise a custom
32
+ * symbol from the app's asset catalog (custom symbols are semantically SF Symbols, but
33
+ * UIKit only resolves them via `imageNamed:`).
34
+ */
35
+ + (nullable UIImage *)symbolImageNamed:(nonnull NSString *)name;
36
+
30
37
  @end
31
38
 
32
39
  #endif // defined(__cplusplus)