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

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 (436) hide show
  1. package/README.md +1 -2
  2. package/RNScreens.podspec +2 -6
  3. package/android/build.gradle +26 -1
  4. package/android/src/fabric/java/com/swmansion/rnscreens/NativeProxy.kt +5 -0
  5. package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +2 -2
  6. package/android/src/main/java/com/swmansion/rnscreens/legacy/Screen.kt +22 -6
  7. package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenStackFragment.kt +39 -10
  8. package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenViewManager.kt +5 -0
  9. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetAppearanceCoordinator.kt → native/coordinator/FormSheetAppearanceCoordinator.kt} +2 -1
  10. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetBehaviorController.kt → native/coordinator/FormSheetBehaviorController.kt} +25 -1
  11. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetDimensionsCoordinator.kt → native/coordinator/FormSheetDimensionsCoordinator.kt} +4 -1
  12. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/coordinator/FormSheetNativeDismissCoordinator.kt +50 -0
  13. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetContainer.kt → native/core/FormSheetContainer.kt} +1 -1
  14. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetDialog.kt → native/core/FormSheetDialog.kt} +24 -1
  15. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetDialogManager.kt → native/core/FormSheetDialogManager.kt} +25 -1
  16. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetContentSizeChangeDelegate.kt → native/interfaces/FormSheetContentSizeChangeDelegate.kt} +1 -1
  17. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetContentSizeChangeProvider.kt → native/interfaces/FormSheetContentSizeChangeProvider.kt} +1 -1
  18. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetDialogEventEmitter.kt → native/interfaces/FormSheetDialogEventEmitter.kt} +3 -1
  19. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetConfig.kt → native/model/FormSheetConfig.kt} +5 -1
  20. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetDetents.kt → native/model/FormSheetDetents.kt} +1 -1
  21. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetAnimatorFactory.kt → native/presentation/FormSheetAnimatorFactory.kt} +1 -1
  22. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetPresentationManager.kt → native/presentation/FormSheetPresentationManager.kt} +3 -12
  23. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetPresentationState.kt → native/presentation/FormSheetPresentationState.kt} +1 -1
  24. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetContentWrapper.kt → react/contentwrapper/FormSheetContentWrapper.kt} +3 -1
  25. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetContentWrapperViewManager.kt → react/contentwrapper/FormSheetContentWrapperViewManager.kt} +1 -1
  26. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetDetentChangedEvent.kt → react/event/FormSheetDetentChangedEvent.kt} +1 -1
  27. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetDidAppearEvent.kt → react/event/FormSheetDidAppearEvent.kt} +1 -1
  28. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetDidDisappearEvent.kt → react/event/FormSheetDidDisappearEvent.kt} +1 -1
  29. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetNativeDismissEvent.kt → react/event/FormSheetNativeDismissEvent.kt} +1 -1
  30. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/react/event/FormSheetNativeDismissPreventedEvent.kt +29 -0
  31. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetSyncFlushEvent.kt → react/event/FormSheetSyncFlushEvent.kt} +1 -1
  32. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetWillAppearEvent.kt → react/event/FormSheetWillAppearEvent.kt} +1 -1
  33. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetWillDisappearEvent.kt → react/event/FormSheetWillDisappearEvent.kt} +1 -1
  34. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetContentView.kt → react/host/FormSheetContentView.kt} +3 -1
  35. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetHost.kt → react/host/FormSheetHost.kt} +6 -1
  36. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetHostEventEmitter.kt → react/host/FormSheetHostEventEmitter.kt} +16 -1
  37. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetHostViewManager.kt → react/host/FormSheetHostViewManager.kt} +11 -2
  38. package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderApplicator.kt +30 -418
  39. package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderCoordinatorLayout.kt +36 -113
  40. package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderFrameSynchronizer.kt +63 -0
  41. package/android/src/main/java/com/swmansion/rnscreens/stack/header/{StackHeaderAppBarLayout.kt → appbar/StackHeaderAppBarLayout.kt} +1 -6
  42. package/android/src/main/java/com/swmansion/rnscreens/stack/header/{StackHeaderAppBarLayoutBehavior.kt → appbar/StackHeaderAppBarLayoutBehavior.kt} +1 -1
  43. package/android/src/main/java/com/swmansion/rnscreens/stack/header/{StackHeaderScrollingViewBehavior.kt → appbar/StackHeaderScrollingViewBehavior.kt} +1 -1
  44. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfig.kt +28 -6
  45. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigViewManager.kt +8 -1
  46. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigurationObserver.kt +1 -1
  47. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigurationProviding.kt +2 -1
  48. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderInvalidationFlags.kt +2 -1
  49. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuApplicator.kt +448 -0
  50. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuMapper.kt +17 -3
  51. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuSelectionController.kt +83 -0
  52. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/{StackHeaderToolbarMenuConfig.kt → model/StackHeaderToolbarMenuConfig.kt} +1 -1
  53. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/{StackHeaderToolbarMenuElementConfig.kt → model/StackHeaderToolbarMenuElementConfig.kt} +1 -1
  54. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/{StackHeaderToolbarMenuGroupConfig.kt → model/StackHeaderToolbarMenuGroupConfig.kt} +1 -1
  55. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/{StackHeaderToolbarMenuGroupMetadata.kt → model/StackHeaderToolbarMenuGroupMetadata.kt} +5 -1
  56. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/{StackHeaderToolbarMenuItemConfig.kt → model/StackHeaderToolbarMenuItemConfig.kt} +1 -1
  57. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/{StackHeaderToolbarMenuItemDefaults.kt → model/StackHeaderToolbarMenuItemDefaults.kt} +1 -1
  58. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/{StackHeaderToolbarMenuItemIconSource.kt → model/StackHeaderToolbarMenuItemIconSource.kt} +1 -1
  59. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/{StackHeaderToolbarMenuItemShowAsAction.kt → model/StackHeaderToolbarMenuItemShowAsAction.kt} +1 -1
  60. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/{StackHeaderToolbarMenuItemType.kt → model/StackHeaderToolbarMenuItemType.kt} +1 -1
  61. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/{StackHeaderToolbarFieldUpdate.kt → update/StackHeaderToolbarFieldUpdate.kt} +1 -1
  62. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/{StackHeaderToolbarMenuElementOptions.kt → update/StackHeaderToolbarMenuElementOptions.kt} +2 -1
  63. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuElementRawUpdate.kt +13 -0
  64. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuElementUpdate.kt +10 -0
  65. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuIconResolver.kt +17 -0
  66. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/{StackHeaderToolbarMenuUpdateQueue.kt → update/StackHeaderToolbarMenuUpdateQueue.kt} +1 -43
  67. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuUpdateQueueDelegate.kt +9 -0
  68. package/android/src/main/java/com/swmansion/rnscreens/stack/screen/StackScreen.kt +1 -0
  69. package/common/cpp/react/renderer/components/rnscreens/legacy/RNSScreenShadowNode.cpp +10 -5
  70. package/ios/RNSEnums.h +0 -2
  71. package/ios/RNSOrientationProviding.h +0 -2
  72. package/ios/RNSReactMountingTransactionObserving.h +15 -0
  73. package/ios/legacy/RNSBarButtonItem.mm +12 -5
  74. package/ios/legacy/RNSScreen.h +8 -1
  75. package/ios/legacy/RNSScreen.mm +39 -17
  76. package/ios/legacy/RNSScreenContentWrapper.mm +9 -0
  77. package/ios/legacy/RNSScreenFooter.mm +2 -0
  78. package/ios/legacy/RNSScreenStack.mm +9 -4
  79. package/ios/modals/form-sheet/RNSFormSheetContentWrapperComponentView.mm +9 -0
  80. package/ios/scroll-to-top-guard/RNSScrollToTopGuard.h +17 -0
  81. package/ios/scroll-to-top-guard/RNSScrollToTopGuard.mm +57 -0
  82. package/ios/scroll-to-top-guard/RNSScrollToTopGuardGestureRecognizer.h +28 -0
  83. package/ios/scroll-to-top-guard/RNSScrollToTopGuardGestureRecognizer.mm +64 -0
  84. package/ios/split/RNSSplitAppearanceApplicator.h +36 -0
  85. package/ios/split/RNSSplitAppearanceApplicator.mm +185 -0
  86. package/ios/split/RNSSplitAppearanceCoordinator.h +26 -0
  87. package/ios/split/RNSSplitAppearanceCoordinator.mm +27 -0
  88. package/ios/split/RNSSplitAppearanceUpdateFlags.h +14 -0
  89. package/ios/split/RNSSplitHostComponentView.mm +1 -1
  90. package/ios/split/RNSSplitHostController.h +86 -0
  91. package/ios/split/RNSSplitHostController.mm +560 -0
  92. package/ios/split/RNSSplitNavigationController.h +31 -0
  93. package/ios/split/RNSSplitNavigationController.mm +44 -0
  94. package/ios/split/RNSSplitNavigationControllerFrameObserver.h +32 -0
  95. package/ios/split/RNSSplitNavigationControllerFrameObserver.mm +80 -0
  96. package/ios/split/RNSSplitNavigationControllerFrameOriginChangeDelegate.h +15 -0
  97. package/ios/split/RNSSplitScreenComponentView.mm +8 -9
  98. package/ios/split/RNSSplitScreenController.h +45 -0
  99. package/ios/split/RNSSplitScreenController.mm +130 -0
  100. package/ios/stack/header/RNSStackHeaderConfigComponentView.h +1 -0
  101. package/ios/stack/header/RNSStackHeaderConfigComponentView.mm +47 -9
  102. package/ios/stack/header/RNSStackHeaderConfigDataProviding.h +3 -0
  103. package/ios/stack/header/RNSStackHeaderMenuCoordinator.h +9 -0
  104. package/ios/stack/header/RNSStackHeaderMenuCoordinator.mm +15 -0
  105. package/ios/stack/header/RNSStackHeaderMenuFinder.h +18 -3
  106. package/ios/stack/header/RNSStackHeaderMenuFinder.mm +21 -3
  107. package/ios/stack/host/RNSStackHostComponentView.mm +3 -1
  108. package/ios/stack/host/RNSStackNavigationController.mm +1 -1
  109. package/ios/stack/screen/RNSStackScreenComponentView.mm +0 -2
  110. package/ios/stack/screen/RNSStackScreenHeaderCoordinator.h +6 -1
  111. package/ios/stack/screen/RNSStackScreenHeaderCoordinator.mm +61 -12
  112. package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryComponentView.mm +3 -0
  113. package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryContentComponentView.mm +4 -1
  114. package/ios/tabs/host/RNSTabBarController.h +5 -12
  115. package/ios/tabs/host/RNSTabBarController.mm +1 -1
  116. package/lib/commonjs/components/scroll-to-top-guard/ScrollToTopGuard.ios.js +25 -0
  117. package/lib/commonjs/components/scroll-to-top-guard/ScrollToTopGuard.ios.js.map +1 -0
  118. package/lib/commonjs/components/scroll-to-top-guard/ScrollToTopGuard.js +24 -0
  119. package/lib/commonjs/components/scroll-to-top-guard/ScrollToTopGuard.js.map +1 -0
  120. package/lib/commonjs/components/scroll-to-top-guard/index.js +13 -0
  121. package/lib/commonjs/components/scroll-to-top-guard/index.js.map +1 -0
  122. package/lib/commonjs/components/stack/header/StackHeaderConfig.ios.js +11 -12
  123. package/lib/commonjs/components/stack/header/StackHeaderConfig.ios.js.map +1 -1
  124. package/lib/commonjs/components/stack/header/ios/StackHeaderItem.ios.js +1 -22
  125. package/lib/commonjs/components/stack/header/ios/StackHeaderItem.ios.js.map +1 -1
  126. package/lib/commonjs/components/stack/header/ios/iconUtils.ios.js +33 -2
  127. package/lib/commonjs/components/stack/header/ios/iconUtils.ios.js.map +1 -1
  128. package/lib/commonjs/components/stack/header/utils.js +6 -9
  129. package/lib/commonjs/components/stack/header/utils.js.map +1 -1
  130. package/lib/commonjs/experimental/index.js +11 -0
  131. package/lib/commonjs/experimental/index.js.map +1 -1
  132. package/lib/commonjs/fabric/ScrollViewMarkerNativeComponent.js.map +1 -1
  133. package/lib/commonjs/fabric/legacy/FullWindowOverlayNativeComponent.js.map +1 -1
  134. package/lib/commonjs/fabric/legacy/ModalScreenNativeComponent.js.map +1 -1
  135. package/lib/commonjs/fabric/legacy/ScreenContainerNativeComponent.js.map +1 -1
  136. package/lib/commonjs/fabric/legacy/ScreenFooterNativeComponent.js.map +1 -1
  137. package/lib/commonjs/fabric/legacy/ScreenNativeComponent.js.map +1 -1
  138. package/lib/commonjs/fabric/legacy/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
  139. package/lib/commonjs/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.js.map +1 -1
  140. package/lib/commonjs/fabric/legacy/ScreenStackNativeComponent.js.map +1 -1
  141. package/lib/commonjs/fabric/legacy/SearchBarNativeComponent.js.map +1 -1
  142. package/lib/commonjs/fabric/modals/form-sheet/FormSheetHostNativeComponent.js.map +1 -1
  143. package/lib/commonjs/fabric/safe-area/SafeAreaViewNativeComponent.js.map +1 -1
  144. package/lib/commonjs/fabric/scroll-to-top-guard/ScrollToTopGuardNativeComponent.js +12 -0
  145. package/lib/commonjs/fabric/scroll-to-top-guard/ScrollToTopGuardNativeComponent.js.map +1 -0
  146. package/lib/commonjs/fabric/split/SplitHostNativeComponent.js.map +1 -1
  147. package/lib/commonjs/fabric/split/SplitScreenNativeComponent.js.map +1 -1
  148. package/lib/commonjs/fabric/stack/StackHeaderConfigAndroidNativeComponent.js.map +1 -1
  149. package/lib/commonjs/fabric/stack/StackHeaderConfigIOSNativeComponent.js.map +1 -1
  150. package/lib/commonjs/fabric/stack/StackHeaderItemIOSNativeComponent.js.map +1 -1
  151. package/lib/commonjs/fabric/stack/StackHeaderItemSpacerIOSNativeComponent.js.map +1 -1
  152. package/lib/commonjs/fabric/stack/StackHeaderSubviewAndroidNativeComponent.js.map +1 -1
  153. package/lib/commonjs/fabric/stack/StackHostNativeComponent.js.map +1 -1
  154. package/lib/commonjs/fabric/stack/StackScreenNativeComponent.js.map +1 -1
  155. package/lib/commonjs/fabric/tabs/TabsBottomAccessoryContentNativeComponent.js.map +1 -1
  156. package/lib/commonjs/fabric/tabs/TabsBottomAccessoryNativeComponent.js.map +1 -1
  157. package/lib/commonjs/fabric/tabs/TabsHostAndroidNativeComponent.js.map +1 -1
  158. package/lib/commonjs/fabric/tabs/TabsHostIOSNativeComponent.js.map +1 -1
  159. package/lib/commonjs/fabric/tabs/TabsScreenAndroidNativeComponent.js.map +1 -1
  160. package/lib/commonjs/fabric/tabs/TabsScreenIOSNativeComponent.js.map +1 -1
  161. package/lib/commonjs/flags.js +22 -1
  162. package/lib/commonjs/flags.js.map +1 -1
  163. package/lib/commonjs/legacy/components/Screen.js +6 -1
  164. package/lib/commonjs/legacy/components/Screen.js.map +1 -1
  165. package/lib/commonjs/legacy/components/ScreenStackHeaderConfig.js +5 -0
  166. package/lib/commonjs/legacy/components/ScreenStackHeaderConfig.js.map +1 -1
  167. package/lib/commonjs/legacy/components/ScreenStackItem.js.map +1 -1
  168. package/lib/commonjs/legacy/components/SearchBar.js +16 -16
  169. package/lib/commonjs/legacy/components/SearchBar.js.map +1 -1
  170. package/lib/commonjs/legacy/components/helpers/prepareHeaderBarButtonItems.js +3 -0
  171. package/lib/commonjs/legacy/components/helpers/prepareHeaderBarButtonItems.js.map +1 -1
  172. package/lib/commonjs/legacy/gesture-handler/fabricUtils.js.map +1 -1
  173. package/lib/commonjs/legacy/useTransitionProgress.js.map +1 -1
  174. package/lib/module/components/scroll-to-top-guard/ScrollToTopGuard.ios.js +20 -0
  175. package/lib/module/components/scroll-to-top-guard/ScrollToTopGuard.ios.js.map +1 -0
  176. package/lib/module/components/scroll-to-top-guard/ScrollToTopGuard.js +18 -0
  177. package/lib/module/components/scroll-to-top-guard/ScrollToTopGuard.js.map +1 -0
  178. package/lib/module/components/scroll-to-top-guard/index.js +2 -0
  179. package/lib/module/components/scroll-to-top-guard/index.js.map +1 -0
  180. package/lib/module/components/stack/header/StackHeaderConfig.ios.js +14 -15
  181. package/lib/module/components/stack/header/StackHeaderConfig.ios.js.map +1 -1
  182. package/lib/module/components/stack/header/ios/StackHeaderItem.ios.js +1 -22
  183. package/lib/module/components/stack/header/ios/StackHeaderItem.ios.js.map +1 -1
  184. package/lib/module/components/stack/header/ios/iconUtils.ios.js +31 -2
  185. package/lib/module/components/stack/header/ios/iconUtils.ios.js.map +1 -1
  186. package/lib/module/components/stack/header/utils.js +5 -8
  187. package/lib/module/components/stack/header/utils.js.map +1 -1
  188. package/lib/module/experimental/index.js +1 -0
  189. package/lib/module/experimental/index.js.map +1 -1
  190. package/lib/module/fabric/ScrollViewMarkerNativeComponent.js.map +1 -1
  191. package/lib/module/fabric/legacy/FullWindowOverlayNativeComponent.js.map +1 -1
  192. package/lib/module/fabric/legacy/ModalScreenNativeComponent.js.map +1 -1
  193. package/lib/module/fabric/legacy/ScreenContainerNativeComponent.js.map +1 -1
  194. package/lib/module/fabric/legacy/ScreenFooterNativeComponent.js.map +1 -1
  195. package/lib/module/fabric/legacy/ScreenNativeComponent.js.map +1 -1
  196. package/lib/module/fabric/legacy/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
  197. package/lib/module/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.js.map +1 -1
  198. package/lib/module/fabric/legacy/ScreenStackNativeComponent.js.map +1 -1
  199. package/lib/module/fabric/legacy/SearchBarNativeComponent.js.map +1 -1
  200. package/lib/module/fabric/modals/form-sheet/FormSheetHostNativeComponent.js.map +1 -1
  201. package/lib/module/fabric/safe-area/SafeAreaViewNativeComponent.js.map +1 -1
  202. package/lib/module/fabric/scroll-to-top-guard/ScrollToTopGuardNativeComponent.js +7 -0
  203. package/lib/module/fabric/scroll-to-top-guard/ScrollToTopGuardNativeComponent.js.map +1 -0
  204. package/lib/module/fabric/split/SplitHostNativeComponent.js.map +1 -1
  205. package/lib/module/fabric/split/SplitScreenNativeComponent.js.map +1 -1
  206. package/lib/module/fabric/stack/StackHeaderConfigAndroidNativeComponent.js.map +1 -1
  207. package/lib/module/fabric/stack/StackHeaderConfigIOSNativeComponent.js.map +1 -1
  208. package/lib/module/fabric/stack/StackHeaderItemIOSNativeComponent.js.map +1 -1
  209. package/lib/module/fabric/stack/StackHeaderItemSpacerIOSNativeComponent.js.map +1 -1
  210. package/lib/module/fabric/stack/StackHeaderSubviewAndroidNativeComponent.js.map +1 -1
  211. package/lib/module/fabric/stack/StackHostNativeComponent.js.map +1 -1
  212. package/lib/module/fabric/stack/StackScreenNativeComponent.js.map +1 -1
  213. package/lib/module/fabric/tabs/TabsBottomAccessoryContentNativeComponent.js.map +1 -1
  214. package/lib/module/fabric/tabs/TabsBottomAccessoryNativeComponent.js.map +1 -1
  215. package/lib/module/fabric/tabs/TabsHostAndroidNativeComponent.js.map +1 -1
  216. package/lib/module/fabric/tabs/TabsHostIOSNativeComponent.js.map +1 -1
  217. package/lib/module/fabric/tabs/TabsScreenAndroidNativeComponent.js.map +1 -1
  218. package/lib/module/fabric/tabs/TabsScreenIOSNativeComponent.js.map +1 -1
  219. package/lib/module/flags.js +22 -1
  220. package/lib/module/flags.js.map +1 -1
  221. package/lib/module/legacy/components/Screen.js +6 -1
  222. package/lib/module/legacy/components/Screen.js.map +1 -1
  223. package/lib/module/legacy/components/ScreenStackHeaderConfig.js +5 -0
  224. package/lib/module/legacy/components/ScreenStackHeaderConfig.js.map +1 -1
  225. package/lib/module/legacy/components/ScreenStackItem.js.map +1 -1
  226. package/lib/module/legacy/components/SearchBar.js +17 -17
  227. package/lib/module/legacy/components/SearchBar.js.map +1 -1
  228. package/lib/module/legacy/components/helpers/prepareHeaderBarButtonItems.js +4 -0
  229. package/lib/module/legacy/components/helpers/prepareHeaderBarButtonItems.js.map +1 -1
  230. package/lib/module/legacy/gesture-handler/fabricUtils.js.map +1 -1
  231. package/lib/module/legacy/useTransitionProgress.js.map +1 -1
  232. package/lib/module/private/hooks/useRenderDebugInfo.js.map +1 -1
  233. package/lib/typescript/components/modals/form-sheet/FormSheet.types.d.ts +2 -2
  234. package/lib/typescript/components/safe-area/SafeAreaView.web.d.ts +5 -2
  235. package/lib/typescript/components/safe-area/SafeAreaView.web.d.ts.map +1 -1
  236. package/lib/typescript/components/scroll-to-top-guard/ScrollToTopGuard.d.ts +15 -0
  237. package/lib/typescript/components/scroll-to-top-guard/ScrollToTopGuard.d.ts.map +1 -0
  238. package/lib/typescript/components/scroll-to-top-guard/ScrollToTopGuard.ios.d.ts +12 -0
  239. package/lib/typescript/components/scroll-to-top-guard/ScrollToTopGuard.ios.d.ts.map +1 -0
  240. package/lib/typescript/components/scroll-to-top-guard/index.d.ts +2 -0
  241. package/lib/typescript/components/scroll-to-top-guard/index.d.ts.map +1 -0
  242. package/lib/typescript/components/stack/header/StackHeaderConfig.android.types.d.ts +24 -0
  243. package/lib/typescript/components/stack/header/StackHeaderConfig.android.types.d.ts.map +1 -1
  244. package/lib/typescript/components/stack/header/StackHeaderConfig.ios.d.ts.map +1 -1
  245. package/lib/typescript/components/stack/header/StackHeaderConfig.ios.types.d.ts +13 -0
  246. package/lib/typescript/components/stack/header/StackHeaderConfig.ios.types.d.ts.map +1 -1
  247. package/lib/typescript/components/stack/header/StackHeaderConfig.web.d.ts +5 -2
  248. package/lib/typescript/components/stack/header/StackHeaderConfig.web.d.ts.map +1 -1
  249. package/lib/typescript/components/stack/header/ios/StackHeaderItem.ios.d.ts.map +1 -1
  250. package/lib/typescript/components/stack/header/ios/iconUtils.ios.d.ts +3 -0
  251. package/lib/typescript/components/stack/header/ios/iconUtils.ios.d.ts.map +1 -1
  252. package/lib/typescript/components/stack/header/utils.d.ts +1 -2
  253. package/lib/typescript/components/stack/header/utils.d.ts.map +1 -1
  254. package/lib/typescript/components/stack/host/StackHost.types.d.ts +2 -2
  255. package/lib/typescript/components/stack/host/StackHost.types.d.ts.map +1 -1
  256. package/lib/typescript/components/stack/host/StackHost.web.d.ts +6 -2
  257. package/lib/typescript/components/stack/host/StackHost.web.d.ts.map +1 -1
  258. package/lib/typescript/components/stack/screen/StackScreen.web.d.ts +5 -2
  259. package/lib/typescript/components/stack/screen/StackScreen.web.d.ts.map +1 -1
  260. package/lib/typescript/components/tabs/host/TabsHost.web.d.ts +5 -2
  261. package/lib/typescript/components/tabs/host/TabsHost.web.d.ts.map +1 -1
  262. package/lib/typescript/components/tabs/screen/TabsScreen.types.d.ts +7 -3
  263. package/lib/typescript/components/tabs/screen/TabsScreen.types.d.ts.map +1 -1
  264. package/lib/typescript/components/tabs/screen/TabsScreen.web.d.ts +5 -2
  265. package/lib/typescript/components/tabs/screen/TabsScreen.web.d.ts.map +1 -1
  266. package/lib/typescript/experimental/index.d.ts +1 -0
  267. package/lib/typescript/experimental/index.d.ts.map +1 -1
  268. package/lib/typescript/fabric/NativeScreensModule.d.ts +1 -1
  269. package/lib/typescript/fabric/ScrollViewMarkerNativeComponent.d.ts +2 -2
  270. package/lib/typescript/fabric/ScrollViewMarkerNativeComponent.d.ts.map +1 -1
  271. package/lib/typescript/fabric/legacy/FullWindowOverlayNativeComponent.d.ts +2 -2
  272. package/lib/typescript/fabric/legacy/FullWindowOverlayNativeComponent.d.ts.map +1 -1
  273. package/lib/typescript/fabric/legacy/ModalScreenNativeComponent.d.ts +3 -2
  274. package/lib/typescript/fabric/legacy/ModalScreenNativeComponent.d.ts.map +1 -1
  275. package/lib/typescript/fabric/legacy/ScreenContainerNativeComponent.d.ts +2 -2
  276. package/lib/typescript/fabric/legacy/ScreenContainerNativeComponent.d.ts.map +1 -1
  277. package/lib/typescript/fabric/legacy/ScreenContentWrapperNativeComponent.d.ts +2 -2
  278. package/lib/typescript/fabric/legacy/ScreenContentWrapperNativeComponent.d.ts.map +1 -1
  279. package/lib/typescript/fabric/legacy/ScreenFooterNativeComponent.d.ts +2 -2
  280. package/lib/typescript/fabric/legacy/ScreenFooterNativeComponent.d.ts.map +1 -1
  281. package/lib/typescript/fabric/legacy/ScreenNativeComponent.d.ts +3 -2
  282. package/lib/typescript/fabric/legacy/ScreenNativeComponent.d.ts.map +1 -1
  283. package/lib/typescript/fabric/legacy/ScreenNavigationContainerNativeComponent.d.ts +2 -2
  284. package/lib/typescript/fabric/legacy/ScreenNavigationContainerNativeComponent.d.ts.map +1 -1
  285. package/lib/typescript/fabric/legacy/ScreenStackHeaderConfigNativeComponent.d.ts +3 -3
  286. package/lib/typescript/fabric/legacy/ScreenStackHeaderConfigNativeComponent.d.ts.map +1 -1
  287. package/lib/typescript/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.d.ts +2 -2
  288. package/lib/typescript/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.d.ts.map +1 -1
  289. package/lib/typescript/fabric/legacy/ScreenStackNativeComponent.d.ts +2 -2
  290. package/lib/typescript/fabric/legacy/ScreenStackNativeComponent.d.ts.map +1 -1
  291. package/lib/typescript/fabric/legacy/SearchBarNativeComponent.d.ts +6 -6
  292. package/lib/typescript/fabric/legacy/SearchBarNativeComponent.d.ts.map +1 -1
  293. package/lib/typescript/fabric/modals/form-sheet/FormSheetContentWrapperNativeComponent.d.ts +2 -2
  294. package/lib/typescript/fabric/modals/form-sheet/FormSheetContentWrapperNativeComponent.d.ts.map +1 -1
  295. package/lib/typescript/fabric/modals/form-sheet/FormSheetHostNativeComponent.d.ts +2 -2
  296. package/lib/typescript/fabric/modals/form-sheet/FormSheetHostNativeComponent.d.ts.map +1 -1
  297. package/lib/typescript/fabric/safe-area/SafeAreaViewNativeComponent.d.ts +2 -2
  298. package/lib/typescript/fabric/safe-area/SafeAreaViewNativeComponent.d.ts.map +1 -1
  299. package/lib/typescript/fabric/scroll-to-top-guard/ScrollToTopGuardNativeComponent.d.ts +6 -0
  300. package/lib/typescript/fabric/scroll-to-top-guard/ScrollToTopGuardNativeComponent.d.ts.map +1 -0
  301. package/lib/typescript/fabric/split/SplitHostNativeComponent.d.ts +1 -1
  302. package/lib/typescript/fabric/split/SplitHostNativeComponent.d.ts.map +1 -1
  303. package/lib/typescript/fabric/split/SplitScreenNativeComponent.d.ts +2 -2
  304. package/lib/typescript/fabric/split/SplitScreenNativeComponent.d.ts.map +1 -1
  305. package/lib/typescript/fabric/stack/StackHeaderConfigAndroidNativeComponent.d.ts +1 -0
  306. package/lib/typescript/fabric/stack/StackHeaderConfigAndroidNativeComponent.d.ts.map +1 -1
  307. package/lib/typescript/fabric/stack/StackHeaderConfigIOSNativeComponent.d.ts +2 -1
  308. package/lib/typescript/fabric/stack/StackHeaderConfigIOSNativeComponent.d.ts.map +1 -1
  309. package/lib/typescript/fabric/stack/StackHeaderItemIOSNativeComponent.d.ts +2 -2
  310. package/lib/typescript/fabric/stack/StackHeaderItemIOSNativeComponent.d.ts.map +1 -1
  311. package/lib/typescript/fabric/stack/StackHeaderItemSpacerIOSNativeComponent.d.ts +2 -2
  312. package/lib/typescript/fabric/stack/StackHeaderItemSpacerIOSNativeComponent.d.ts.map +1 -1
  313. package/lib/typescript/fabric/stack/StackHeaderSubviewAndroidNativeComponent.d.ts +2 -2
  314. package/lib/typescript/fabric/stack/StackHeaderSubviewAndroidNativeComponent.d.ts.map +1 -1
  315. package/lib/typescript/fabric/stack/StackHostNativeComponent.d.ts +2 -2
  316. package/lib/typescript/fabric/stack/StackHostNativeComponent.d.ts.map +1 -1
  317. package/lib/typescript/fabric/stack/StackScreenNativeComponent.d.ts +2 -2
  318. package/lib/typescript/fabric/stack/StackScreenNativeComponent.d.ts.map +1 -1
  319. package/lib/typescript/fabric/tabs/TabsBottomAccessoryContentNativeComponent.d.ts +2 -2
  320. package/lib/typescript/fabric/tabs/TabsBottomAccessoryContentNativeComponent.d.ts.map +1 -1
  321. package/lib/typescript/fabric/tabs/TabsBottomAccessoryNativeComponent.d.ts +2 -2
  322. package/lib/typescript/fabric/tabs/TabsBottomAccessoryNativeComponent.d.ts.map +1 -1
  323. package/lib/typescript/fabric/tabs/TabsHostAndroidNativeComponent.d.ts +2 -2
  324. package/lib/typescript/fabric/tabs/TabsHostAndroidNativeComponent.d.ts.map +1 -1
  325. package/lib/typescript/fabric/tabs/TabsHostIOSNativeComponent.d.ts +2 -2
  326. package/lib/typescript/fabric/tabs/TabsHostIOSNativeComponent.d.ts.map +1 -1
  327. package/lib/typescript/fabric/tabs/TabsScreenAndroidNativeComponent.d.ts +2 -2
  328. package/lib/typescript/fabric/tabs/TabsScreenAndroidNativeComponent.d.ts.map +1 -1
  329. package/lib/typescript/fabric/tabs/TabsScreenIOSNativeComponent.d.ts +2 -2
  330. package/lib/typescript/fabric/tabs/TabsScreenIOSNativeComponent.d.ts.map +1 -1
  331. package/lib/typescript/flags.d.ts +13 -0
  332. package/lib/typescript/flags.d.ts.map +1 -1
  333. package/lib/typescript/legacy/TransitionProgressContext.d.ts +1 -1
  334. package/lib/typescript/legacy/TransitionProgressContext.d.ts.map +1 -1
  335. package/lib/typescript/legacy/components/Screen.d.ts +5 -3
  336. package/lib/typescript/legacy/components/Screen.d.ts.map +1 -1
  337. package/lib/typescript/legacy/components/Screen.web.d.ts +10 -2
  338. package/lib/typescript/legacy/components/Screen.web.d.ts.map +1 -1
  339. package/lib/typescript/legacy/components/ScreenContainer.web.d.ts +5 -2
  340. package/lib/typescript/legacy/components/ScreenContainer.web.d.ts.map +1 -1
  341. package/lib/typescript/legacy/components/ScreenContentWrapper.web.d.ts +5 -2
  342. package/lib/typescript/legacy/components/ScreenContentWrapper.web.d.ts.map +1 -1
  343. package/lib/typescript/legacy/components/ScreenContentWrapper.windows.d.ts +5 -2
  344. package/lib/typescript/legacy/components/ScreenContentWrapper.windows.d.ts.map +1 -1
  345. package/lib/typescript/legacy/components/ScreenFooter.web.d.ts +10 -3
  346. package/lib/typescript/legacy/components/ScreenFooter.web.d.ts.map +1 -1
  347. package/lib/typescript/legacy/components/ScreenFooter.windows.d.ts +10 -3
  348. package/lib/typescript/legacy/components/ScreenFooter.windows.d.ts.map +1 -1
  349. package/lib/typescript/legacy/components/ScreenStack.web.d.ts +5 -2
  350. package/lib/typescript/legacy/components/ScreenStack.web.d.ts.map +1 -1
  351. package/lib/typescript/legacy/components/ScreenStackHeaderConfig.d.ts +3 -1
  352. package/lib/typescript/legacy/components/ScreenStackHeaderConfig.d.ts.map +1 -1
  353. package/lib/typescript/legacy/components/ScreenStackItem.d.ts +3 -2
  354. package/lib/typescript/legacy/components/ScreenStackItem.d.ts.map +1 -1
  355. package/lib/typescript/legacy/components/SearchBar.d.ts +3 -3
  356. package/lib/typescript/legacy/components/SearchBar.d.ts.map +1 -1
  357. package/lib/typescript/legacy/components/SearchBar.web.d.ts +5 -2
  358. package/lib/typescript/legacy/components/SearchBar.web.d.ts.map +1 -1
  359. package/lib/typescript/legacy/components/helpers/prepareHeaderBarButtonItems.d.ts +15 -12
  360. package/lib/typescript/legacy/components/helpers/prepareHeaderBarButtonItems.d.ts.map +1 -1
  361. package/lib/typescript/legacy/gesture-handler/fabricUtils.d.ts +3 -2
  362. package/lib/typescript/legacy/gesture-handler/fabricUtils.d.ts.map +1 -1
  363. package/lib/typescript/legacy/types.d.ts +25 -5
  364. package/lib/typescript/legacy/types.d.ts.map +1 -1
  365. package/lib/typescript/legacy/useTransitionProgress.d.ts +2 -5
  366. package/lib/typescript/legacy/useTransitionProgress.d.ts.map +1 -1
  367. package/lib/typescript/private/hooks/useRenderDebugInfo.d.ts +2 -2
  368. package/lib/typescript/private/hooks/useRenderDebugInfo.d.ts.map +1 -1
  369. package/package.json +17 -17
  370. package/src/components/modals/form-sheet/FormSheet.types.ts +2 -2
  371. package/src/components/scroll-to-top-guard/ScrollToTopGuard.ios.tsx +17 -0
  372. package/src/components/scroll-to-top-guard/ScrollToTopGuard.tsx +18 -0
  373. package/src/components/scroll-to-top-guard/index.ts +1 -0
  374. package/src/components/stack/header/StackHeaderConfig.android.types.ts +24 -0
  375. package/src/components/stack/header/StackHeaderConfig.ios.tsx +32 -22
  376. package/src/components/stack/header/StackHeaderConfig.ios.types.ts +13 -0
  377. package/src/components/stack/header/ios/StackHeaderItem.ios.tsx +1 -23
  378. package/src/components/stack/header/ios/iconUtils.ios.ts +38 -2
  379. package/src/components/stack/header/utils.ts +6 -11
  380. package/src/components/stack/host/StackHost.types.ts +2 -4
  381. package/src/components/tabs/screen/TabsScreen.types.ts +7 -3
  382. package/src/experimental/index.ts +1 -0
  383. package/src/fabric/ScrollViewMarkerNativeComponent.ts +8 -2
  384. package/src/fabric/legacy/FullWindowOverlayNativeComponent.ts +6 -2
  385. package/src/fabric/legacy/ModalScreenNativeComponent.ts +8 -2
  386. package/src/fabric/legacy/ScreenContainerNativeComponent.ts +5 -2
  387. package/src/fabric/legacy/ScreenContentWrapperNativeComponent.ts +2 -2
  388. package/src/fabric/legacy/ScreenFooterNativeComponent.ts +5 -2
  389. package/src/fabric/legacy/ScreenNativeComponent.ts +8 -2
  390. package/src/fabric/legacy/ScreenNavigationContainerNativeComponent.ts +2 -2
  391. package/src/fabric/legacy/ScreenStackHeaderConfigNativeComponent.ts +8 -3
  392. package/src/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.ts +6 -2
  393. package/src/fabric/legacy/ScreenStackNativeComponent.ts +10 -2
  394. package/src/fabric/legacy/SearchBarNativeComponent.ts +10 -7
  395. package/src/fabric/modals/form-sheet/FormSheetContentWrapperNativeComponent.ts +2 -2
  396. package/src/fabric/modals/form-sheet/FormSheetHostNativeComponent.ts +7 -2
  397. package/src/fabric/safe-area/SafeAreaViewNativeComponent.ts +6 -2
  398. package/src/fabric/scroll-to-top-guard/ScrollToTopGuardNativeComponent.ts +10 -0
  399. package/src/fabric/split/SplitHostNativeComponent.ts +5 -2
  400. package/src/fabric/split/SplitScreenNativeComponent.ts +6 -2
  401. package/src/fabric/stack/StackHeaderConfigAndroidNativeComponent.ts +3 -1
  402. package/src/fabric/stack/StackHeaderConfigIOSNativeComponent.ts +7 -2
  403. package/src/fabric/stack/StackHeaderItemIOSNativeComponent.ts +2 -1
  404. package/src/fabric/stack/StackHeaderItemSpacerIOSNativeComponent.ts +6 -2
  405. package/src/fabric/stack/StackHeaderSubviewAndroidNativeComponent.ts +6 -2
  406. package/src/fabric/stack/StackHostNativeComponent.ts +5 -2
  407. package/src/fabric/stack/StackScreenNativeComponent.ts +6 -2
  408. package/src/fabric/tabs/TabsBottomAccessoryContentNativeComponent.ts +6 -2
  409. package/src/fabric/tabs/TabsBottomAccessoryNativeComponent.ts +6 -2
  410. package/src/fabric/tabs/TabsHostAndroidNativeComponent.ts +7 -2
  411. package/src/fabric/tabs/TabsHostIOSNativeComponent.ts +7 -2
  412. package/src/fabric/tabs/TabsScreenAndroidNativeComponent.ts +2 -1
  413. package/src/fabric/tabs/TabsScreenIOSNativeComponent.ts +2 -1
  414. package/src/flags.ts +26 -0
  415. package/src/legacy/TransitionProgressContext.tsx +1 -1
  416. package/src/legacy/components/Screen.tsx +14 -6
  417. package/src/legacy/components/ScreenStackHeaderConfig.tsx +7 -1
  418. package/src/legacy/components/ScreenStackItem.tsx +3 -4
  419. package/src/legacy/components/SearchBar.tsx +34 -44
  420. package/src/legacy/components/helpers/prepareHeaderBarButtonItems.ts +7 -1
  421. package/src/legacy/gesture-handler/fabricUtils.ts +5 -2
  422. package/src/legacy/types.ts +28 -5
  423. package/src/legacy/useTransitionProgress.tsx +4 -2
  424. package/src/private/hooks/useRenderDebugInfo.tsx +2 -2
  425. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/FormSheetNativeDismissCoordinator.kt +0 -25
  426. package/ios/ReactMountingTransactionObserving.swift +0 -7
  427. package/ios/bridging/Swift-Bridging.h +0 -7
  428. package/ios/orientation/RNSOrientationProviding.swift +0 -6
  429. package/ios/orientation/RNSOrientationSwift.swift +0 -14
  430. package/ios/split/RNSSplitAppearanceApplicator.swift +0 -199
  431. package/ios/split/RNSSplitAppearanceCoordinator.swift +0 -26
  432. package/ios/split/RNSSplitAppearanceUpdateFlags.swift +0 -11
  433. package/ios/split/RNSSplitHostController.swift +0 -570
  434. package/ios/split/RNSSplitNavigationController.swift +0 -46
  435. package/ios/split/RNSSplitScreenController.swift +0 -133
  436. package/ios/utils/RNSLog.swift +0 -6
@@ -0,0 +1,448 @@
1
+ package com.swmansion.rnscreens.stack.header.toolbar
2
+
3
+ import android.content.res.ColorStateList
4
+ import android.graphics.drawable.Drawable
5
+ import android.os.Build
6
+ import android.util.Log
7
+ import android.view.Menu
8
+ import android.view.MenuItem
9
+ import androidx.core.view.MenuItemCompat
10
+ import com.google.android.material.appbar.MaterialToolbar
11
+ import com.swmansion.rnscreens.stack.header.getResizedDrawable
12
+ import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuConfig
13
+ import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuElementConfig
14
+ import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuGroupConfig
15
+ import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuGroupMetadata
16
+ import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuItemConfig
17
+ import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuItemType
18
+ import com.swmansion.rnscreens.stack.header.toolbar.update.StackHeaderToolbarFieldUpdate
19
+ import com.swmansion.rnscreens.stack.header.toolbar.update.StackHeaderToolbarMenuElementOptions
20
+ import com.swmansion.rnscreens.stack.header.toolbar.update.valueOrNull
21
+
22
+ /**
23
+ * Builds the toolbar menu from its config and applies in-place element updates
24
+ * (options, checkability, icon tint).
25
+ */
26
+ internal object StackHeaderToolbarMenuApplicator {
27
+ // region Mappings & metadata
28
+
29
+ internal fun generateToolbarMenuItemMappings(menuConfig: StackHeaderToolbarMenuConfig): Pair<Map<String, Int>, Map<Int, String>> {
30
+ val forwardIdMap = mutableMapOf<String, Int>()
31
+ val reverseIdMap = mutableMapOf<Int, String>()
32
+ var counter = 1
33
+ assignElementIds(menuConfig.children, forwardIdMap, reverseIdMap) { counter++ }
34
+ return Pair(forwardIdMap.toMap(), reverseIdMap.toMap())
35
+ }
36
+
37
+ internal fun generateToolbarMenuGroupMappings(menuConfig: StackHeaderToolbarMenuConfig): Map<String, Int> {
38
+ val forwardGroupIdMap = mutableMapOf<String, Int>()
39
+ var counter = 1
40
+ assignGroupIds(menuConfig, forwardGroupIdMap) { counter++ }
41
+ return forwardGroupIdMap.toMap()
42
+ }
43
+
44
+ internal fun computeGroupMetadata(menuConfig: StackHeaderToolbarMenuConfig): StackHeaderToolbarMenuGroupMetadata {
45
+ val itemGroupMap = mutableMapOf<String, String>()
46
+ val groupSingleSelection = mutableMapOf<String, Boolean>()
47
+ val groupMemberItems = mutableMapOf<String, MutableList<String>>()
48
+ collectGroupMetadata(menuConfig, itemGroupMap, groupSingleSelection, groupMemberItems)
49
+ return StackHeaderToolbarMenuGroupMetadata(
50
+ itemGroupMap,
51
+ groupSingleSelection,
52
+ groupMemberItems.mapValues { it.value.toList() },
53
+ )
54
+ }
55
+
56
+ internal fun validateRadioInitialSelection(menuConfig: StackHeaderToolbarMenuConfig) {
57
+ for (group in menuConfig.groups) {
58
+ if (!group.singleSelection) continue
59
+ var count = 0
60
+ for (element in menuConfig.children) {
61
+ if (element.item.groupId == group.groupId && element.item.initialToggleState) {
62
+ count++
63
+ }
64
+ }
65
+ require(count <= 1) {
66
+ "[RNScreens] Radio group '${group.groupId}' has $count items with " +
67
+ "initialToggleState=true. At most 1 is allowed for single-selection groups."
68
+ }
69
+ }
70
+ for (element in menuConfig.children) {
71
+ if (element is StackHeaderToolbarMenuElementConfig.Submenu) {
72
+ validateRadioInitialSelection(element.menu)
73
+ }
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Recursively traverses menu elements and maps user-friendly string item IDs to integers
79
+ * expected by Android.
80
+ *
81
+ * @param elements List of menu elements.
82
+ * @param forwardIdMap Reference to String->Int ID map to which ID entries will be added.
83
+ * @param reverseIdMap Reference to Int->String ID map to which ID entries will be added.
84
+ * @param nextId Function that returns next ID integer. New unique integer should be returned
85
+ * each time the function is called. The function is used to handle recursive
86
+ * element traversal.
87
+ */
88
+ private fun assignElementIds(
89
+ elements: List<StackHeaderToolbarMenuElementConfig>,
90
+ forwardIdMap: MutableMap<String, Int>,
91
+ reverseIdMap: MutableMap<Int, String>,
92
+ nextId: () -> Int,
93
+ ) {
94
+ for (element in elements) {
95
+ require(element.item.id !in forwardIdMap) {
96
+ "[RNScreens] Duplicate toolbar menu item id: '${element.item.id}'. Item IDs must be unique across the entire menu."
97
+ }
98
+ val nativeId = nextId()
99
+ forwardIdMap[element.item.id] = nativeId
100
+ reverseIdMap[nativeId] = element.item.id
101
+ if (element is StackHeaderToolbarMenuElementConfig.Submenu) {
102
+ assignElementIds(element.menu.children, forwardIdMap, reverseIdMap, nextId)
103
+ }
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Recursively traverses menu groups and maps user-friendly string group IDs to integers
109
+ * expected by Android.
110
+ *
111
+ * @param menuConfig Menu whose groups — and those of its submenus — will be mapped.
112
+ * @param forwardMap Reference to String->Int group ID map to which entries will be added.
113
+ * @param nextId Function that returns next ID integer. New unique integer should be returned
114
+ * each time the function is called. The function is used to handle recursive
115
+ * element traversal.
116
+ */
117
+ private fun assignGroupIds(
118
+ menuConfig: StackHeaderToolbarMenuConfig,
119
+ forwardMap: MutableMap<String, Int>,
120
+ nextId: () -> Int,
121
+ ) {
122
+ for (group in menuConfig.groups) {
123
+ require(group.groupId !in forwardMap) {
124
+ "[RNScreens] Duplicate toolbar menu group id: '${group.groupId}'. Group IDs must be unique across the entire menu."
125
+ }
126
+ forwardMap[group.groupId] = nextId()
127
+ }
128
+ for (element in menuConfig.children) {
129
+ if (element is StackHeaderToolbarMenuElementConfig.Submenu) {
130
+ assignGroupIds(element.menu, forwardMap, nextId)
131
+ }
132
+ }
133
+ }
134
+
135
+ private fun collectGroupMetadata(
136
+ config: StackHeaderToolbarMenuConfig,
137
+ itemGroupMap: MutableMap<String, String>,
138
+ groupSingleSelection: MutableMap<String, Boolean>,
139
+ groupMemberItems: MutableMap<String, MutableList<String>>,
140
+ ) {
141
+ val localGroupIds = config.groups.map { it.groupId }.toSet()
142
+ for (group in config.groups) {
143
+ groupSingleSelection[group.groupId] = group.singleSelection
144
+ groupMemberItems.getOrPut(group.groupId) { mutableListOf() }
145
+ }
146
+ for (element in config.children) {
147
+ element.item.groupId?.let { gid ->
148
+ require(gid in localGroupIds) {
149
+ "[RNScreens] Menu item '${element.item.id}' references group '$gid' " +
150
+ "which is not defined at the same menu level. " +
151
+ "Groups cannot span submenus."
152
+ }
153
+ itemGroupMap[element.item.id] = gid
154
+ groupMemberItems[gid]!!.add(element.item.id)
155
+ }
156
+ if (element is StackHeaderToolbarMenuElementConfig.Submenu) {
157
+ collectGroupMetadata(element.menu, itemGroupMap, groupSingleSelection, groupMemberItems)
158
+ }
159
+ }
160
+ }
161
+
162
+ // endregion
163
+
164
+ // region Menu build
165
+
166
+ internal fun rebuildToolbarMenu(
167
+ toolbar: MaterialToolbar,
168
+ menuConfig: StackHeaderToolbarMenuConfig,
169
+ forwardIdMap: Map<String, Int>,
170
+ reverseIdMap: Map<Int, String>,
171
+ forwardGroupIdMap: Map<String, Int>,
172
+ groupDividerEnabled: Boolean,
173
+ onItemClicked: (id: String, menuItem: MenuItem) -> Unit,
174
+ ) {
175
+ toolbar.menu.clear()
176
+ addElements(toolbar, toolbar.menu, menuConfig, forwardIdMap, forwardGroupIdMap)
177
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
178
+ toolbar.menu.setGroupDividerEnabled(groupDividerEnabled)
179
+ }
180
+ toolbar.setOnMenuItemClickListener { menuItem ->
181
+ val stringId = reverseIdMap[menuItem.itemId]
182
+ if (stringId != null) {
183
+ onItemClicked(stringId, menuItem)
184
+ }
185
+ true
186
+ }
187
+ }
188
+
189
+ private fun addElements(
190
+ toolbar: MaterialToolbar,
191
+ menu: Menu,
192
+ menuConfig: StackHeaderToolbarMenuConfig,
193
+ forwardIdMap: Map<String, Int>,
194
+ forwardGroupIdMap: Map<String, Int>,
195
+ ) {
196
+ menuConfig.children.forEachIndexed { index, element ->
197
+ val itemId =
198
+ requireNotNull(forwardIdMap[element.item.id]) {
199
+ "[RNScreens] Invalid forwardIdMap received. Missing item: ${element.item}."
200
+ }
201
+ val groupIntId =
202
+ element.item.groupId
203
+ ?.let { forwardGroupIdMap[it] ?: Menu.NONE }
204
+ ?: Menu.NONE
205
+ when (element) {
206
+ is StackHeaderToolbarMenuElementConfig.MenuItem -> {
207
+ val menuItem = menu.add(groupIntId, itemId, index, null)
208
+ applyMenuElementOptions(toolbar, menuItem, element.item.toOptions())
209
+ applyCheckability(menuItem, element.item)
210
+ }
211
+ is StackHeaderToolbarMenuElementConfig.Submenu -> {
212
+ val subMenu = menu.addSubMenu(groupIntId, itemId, index, null)
213
+ applyMenuElementOptions(toolbar, subMenu.item, element.item.toOptions())
214
+ element.menuTitle?.let { subMenu.setHeaderTitle(it) }
215
+ addElements(toolbar, subMenu, element.menu, forwardIdMap, forwardGroupIdMap)
216
+ }
217
+ }
218
+ }
219
+ configureGroupCheckability(menu, menuConfig.groups, forwardGroupIdMap)
220
+ }
221
+
222
+ private fun configureGroupCheckability(
223
+ menu: Menu,
224
+ groups: List<StackHeaderToolbarMenuGroupConfig>,
225
+ forwardGroupIdMap: Map<String, Int>,
226
+ ) {
227
+ for (group in groups) {
228
+ val groupIntId = forwardGroupIdMap[group.groupId] ?: continue
229
+ menu.setGroupCheckable(groupIntId, true, group.singleSelection)
230
+ }
231
+ }
232
+
233
+ private fun applyCheckability(
234
+ menuItem: MenuItem,
235
+ itemConfig: StackHeaderToolbarMenuItemConfig,
236
+ ) {
237
+ val shouldBeCheckable =
238
+ when (itemConfig.itemType) {
239
+ StackHeaderToolbarMenuItemType.TOGGLE -> {
240
+ require(itemConfig.groupId != null) {
241
+ "[RNScreens] Menu item '${itemConfig.id}' has itemType=TOGGLE but no groupId. " +
242
+ "Toggle items must belong to a group."
243
+ }
244
+ true
245
+ }
246
+ StackHeaderToolbarMenuItemType.AUTOMATIC -> itemConfig.groupId != null
247
+ StackHeaderToolbarMenuItemType.ACTION -> {
248
+ require(itemConfig.groupId == null) {
249
+ "[RNScreens] Menu item '${itemConfig.id}' has itemType=ACTION " +
250
+ "and belongs to a group. Action items cannot belong to groups."
251
+ }
252
+ false
253
+ }
254
+ }
255
+ if (shouldBeCheckable) {
256
+ menuItem.isCheckable = true
257
+ menuItem.isChecked = itemConfig.initialToggleState
258
+ }
259
+ }
260
+
261
+ // endregion
262
+
263
+ // region Element updates
264
+
265
+ internal fun updateToolbarMenuElement(
266
+ toolbar: MaterialToolbar,
267
+ forwardIdMap: Map<String, Int>,
268
+ id: String,
269
+ options: StackHeaderToolbarMenuElementOptions,
270
+ ) {
271
+ val item =
272
+ forwardIdMap[id]?.let { toolbar.menu.findItem(it) } ?: run {
273
+ Log.e(TAG, "[RNScreens] Unable to find menu element with id '$id'.")
274
+ return
275
+ }
276
+ applyMenuElementOptions(toolbar, item, options)
277
+ }
278
+
279
+ private fun applyMenuElementOptions(
280
+ toolbar: MaterialToolbar,
281
+ menuItem: MenuItem,
282
+ options: StackHeaderToolbarMenuElementOptions,
283
+ ) {
284
+ options.title?.let { menuItem.title = it.valueOrNull() }
285
+ options.titleCondensed?.let { menuItem.titleCondensed = it.valueOrNull() }
286
+ options.tooltipText?.let { MenuItemCompat.setTooltipText(menuItem, it.valueOrNull()) }
287
+ options.accessibilityLabel?.let {
288
+ // Setting `null` will restore Android's default (`title` for items
289
+ // in toolbar, `null` otherwise).
290
+ MenuItemCompat.setContentDescription(menuItem, it.valueOrNull())
291
+ }
292
+ options.hidden?.let { menuItem.isVisible = !it }
293
+ options.disabled?.let { menuItem.isEnabled = !it }
294
+ options.showAsAction?.let { menuItem.setShowAsAction(it.toNativeShowAsAction()) }
295
+
296
+ // checked is intentionally not handled here. The coordinator layout manages it in
297
+ // applyGroupItemStateChange because toggling checked state requires group metadata
298
+ // (radio vs checkbox) and may emit onGroupSelectionChanged events.
299
+
300
+ options.icon?.let {
301
+ when (it) {
302
+ StackHeaderToolbarFieldUpdate.Reset -> menuItem.icon = null
303
+ is StackHeaderToolbarFieldUpdate.Set<Drawable> ->
304
+ menuItem.icon = getResizedDrawable(toolbar, it.value)
305
+ }
306
+ }
307
+
308
+ if (options.requiresIconTintColorUpdate || options.icon != null) {
309
+ MenuItemCompat.setIconTintList(menuItem, getResolvedIconTintList(menuItem, options))
310
+ }
311
+
312
+ options.menuTitle?.let { update ->
313
+ val subMenu = menuItem.subMenu
314
+ if (subMenu != null) {
315
+ // In order to match native behavior, we need to clear the header first and then use
316
+ // regular title if menuTitle is not provided. If title is also null, there will be
317
+ // no submenu header at all.
318
+ subMenu.clearHeader()
319
+ subMenu.setHeaderTitle(update.valueOrNull() ?: menuItem.title)
320
+ } else {
321
+ Log.w(TAG, "[RNScreens] menuTitle ignored: target is not a submenu.")
322
+ }
323
+ }
324
+ }
325
+
326
+ private fun StackHeaderToolbarMenuItemConfig.toOptions() =
327
+ StackHeaderToolbarMenuElementOptions(
328
+ title = StackHeaderToolbarFieldUpdate.from(title),
329
+ titleCondensed = StackHeaderToolbarFieldUpdate.from(titleCondensed),
330
+ tooltipText = StackHeaderToolbarFieldUpdate.from(tooltipText),
331
+ accessibilityLabel = StackHeaderToolbarFieldUpdate.from(accessibilityLabel),
332
+ hidden = hidden,
333
+ disabled = disabled,
334
+ showAsAction = showAsAction,
335
+ icon = StackHeaderToolbarFieldUpdate.from(icon),
336
+ iconTintColorNormal = StackHeaderToolbarFieldUpdate.from(iconTintColorNormal),
337
+ iconTintColorPressed = StackHeaderToolbarFieldUpdate.from(iconTintColorPressed),
338
+ iconTintColorFocused = StackHeaderToolbarFieldUpdate.from(iconTintColorFocused),
339
+ iconTintColorDisabled = StackHeaderToolbarFieldUpdate.from(iconTintColorDisabled),
340
+ )
341
+
342
+ // endregion
343
+
344
+ // region Icon tint
345
+
346
+ private fun getResolvedIconTintList(
347
+ menuItem: MenuItem,
348
+ options: StackHeaderToolbarMenuElementOptions,
349
+ ): ColorStateList? {
350
+ val currentTintList = MenuItemCompat.getIconTintList(menuItem)
351
+ // The currently-applied normal (catch-all) color, if any. Used both as the "leave
352
+ // unchanged" value for normal and to dedup read-back overrides: when a normal entry
353
+ // exists every override probe also matches it, so an override equal to the current
354
+ // normal is the catch-all leaking through rather than an explicit override.
355
+ val currentNormal = currentTintList?.resolvedColorOrNull(intArrayOf(android.R.attr.state_enabled))
356
+
357
+ val finalNormal =
358
+ when (val update = options.iconTintColorNormal) {
359
+ StackHeaderToolbarFieldUpdate.Reset -> null
360
+ is StackHeaderToolbarFieldUpdate.Set -> update.value
361
+ null -> currentNormal
362
+ }
363
+
364
+ val finalDisabled =
365
+ when (val update = options.iconTintColorDisabled) {
366
+ StackHeaderToolbarFieldUpdate.Reset -> null
367
+ is StackHeaderToolbarFieldUpdate.Set -> update.value
368
+ null ->
369
+ currentTintList
370
+ ?.resolvedColorOrNull(intArrayOf(-android.R.attr.state_enabled))
371
+ ?.takeIf { it != currentNormal }
372
+ }
373
+
374
+ val finalPressed =
375
+ when (val update = options.iconTintColorPressed) {
376
+ StackHeaderToolbarFieldUpdate.Reset -> null
377
+ is StackHeaderToolbarFieldUpdate.Set -> update.value
378
+ null ->
379
+ currentTintList
380
+ ?.resolvedColorOrNull(intArrayOf(android.R.attr.state_enabled, android.R.attr.state_pressed))
381
+ ?.takeIf { it != currentNormal }
382
+ }
383
+
384
+ val finalFocused =
385
+ when (val update = options.iconTintColorFocused) {
386
+ StackHeaderToolbarFieldUpdate.Reset -> null
387
+ is StackHeaderToolbarFieldUpdate.Set -> update.value
388
+ null ->
389
+ currentTintList
390
+ ?.resolvedColorOrNull(intArrayOf(android.R.attr.state_enabled, android.R.attr.state_focused))
391
+ ?.takeIf { it != currentNormal }
392
+ }
393
+
394
+ val states = mutableListOf<IntArray>()
395
+ val colors = mutableListOf<Int>()
396
+
397
+ finalDisabled?.let {
398
+ states.add(intArrayOf(-android.R.attr.state_enabled))
399
+ colors.add(it)
400
+ }
401
+
402
+ finalPressed?.let {
403
+ states.add(intArrayOf(android.R.attr.state_pressed))
404
+ colors.add(it)
405
+ }
406
+
407
+ finalFocused?.let {
408
+ states.add(intArrayOf(android.R.attr.state_focused))
409
+ colors.add(it)
410
+ }
411
+
412
+ finalNormal?.let {
413
+ states.add(intArrayOf())
414
+ colors.add(it)
415
+ }
416
+
417
+ return if (states.isNotEmpty()) {
418
+ ColorStateList(states.toTypedArray(), colors.toIntArray())
419
+ } else {
420
+ null
421
+ }
422
+ }
423
+
424
+ /**
425
+ * Resolves the color the receiver applies to [stateSet], or `null` when no state spec
426
+ * matches it.
427
+ *
428
+ * `getColorForState` returns the caller-supplied fallback when nothing matches, so we
429
+ * probe twice with two distinct sentinels: equal results mean a real spec matched (the
430
+ * actual color), differing results mean the slot is absent. This is robust for any color
431
+ * value and keeps the read-back stateless — see [getResolvedIconTintList].
432
+ */
433
+ private fun ColorStateList.resolvedColorOrNull(stateSet: IntArray): Int? {
434
+ val a = getColorForState(stateSet, SENTINEL_A)
435
+ val b = getColorForState(stateSet, SENTINEL_B)
436
+ return if (a == b) a else null
437
+ }
438
+
439
+ // endregion
440
+
441
+ private const val TAG = "StackHeaderToolbarMenuApplicator"
442
+
443
+ // Two distinct sentinel fallbacks used to detect whether a ColorStateList actually
444
+ // defines a color for a given state. Their concrete values are irrelevant as long as
445
+ // they differ — see resolvedColorOrNull.
446
+ private const val SENTINEL_A = 0x00000001
447
+ private const val SENTINEL_B = 0x00000002
448
+ }
@@ -11,11 +11,25 @@ import com.swmansion.rnscreens.helpers.readColor
11
11
  import com.swmansion.rnscreens.helpers.readImageUri
12
12
  import com.swmansion.rnscreens.helpers.readOptionalString
13
13
  import com.swmansion.rnscreens.helpers.requireNotNullString
14
+ import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuConfig
15
+ import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuElementConfig
16
+ import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuGroupConfig
17
+ import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuItemConfig
18
+ import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuItemDefaults
19
+ import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuItemIconSource
20
+ import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuItemShowAsAction
21
+ import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuItemType
22
+ import com.swmansion.rnscreens.stack.header.toolbar.update.StackHeaderToolbarFieldUpdate
23
+ import com.swmansion.rnscreens.stack.header.toolbar.update.StackHeaderToolbarMenuElementOptions
14
24
 
25
+ /**
26
+ * Parses React toolbar-menu props (Dynamic / ReadableMap) into the native menu
27
+ * config and element-update models.
28
+ */
15
29
  internal object StackHeaderToolbarMenuMapper {
16
30
  // region Menu prop parsing
17
31
 
18
- fun parseMenu(
32
+ internal fun parseMenu(
19
33
  context: Context,
20
34
  value: Dynamic,
21
35
  ): Pair<StackHeaderToolbarMenuConfig, Map<String, StackHeaderToolbarMenuItemIconSource>> {
@@ -34,7 +48,7 @@ internal object StackHeaderToolbarMenuMapper {
34
48
 
35
49
  // region Menu element command parsing
36
50
 
37
- fun parseMenuElementOptions(
51
+ internal fun parseMenuElementOptions(
38
52
  context: Context,
39
53
  map: ReadableMap,
40
54
  ): StackHeaderToolbarMenuElementOptions =
@@ -63,7 +77,7 @@ internal object StackHeaderToolbarMenuMapper {
63
77
  menuTitle = map.readNullableStringUpdate("menuTitle"),
64
78
  )
65
79
 
66
- fun parseMenuElementIconSource(map: ReadableMap): StackHeaderToolbarMenuItemIconSource? {
80
+ internal fun parseMenuElementIconSource(map: ReadableMap): StackHeaderToolbarMenuItemIconSource? {
67
81
  if (!map.hasKey("drawableIconResourceName") && !map.hasKey("imageIconResource")) {
68
82
  return null
69
83
  }
@@ -0,0 +1,83 @@
1
+ package com.swmansion.rnscreens.stack.header.toolbar
2
+
3
+ import android.util.Log
4
+ import com.google.android.material.appbar.MaterialToolbar
5
+ import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuGroupMetadata
6
+
7
+ /**
8
+ * Owns toolbar-menu selection state (id map + group metadata) and applies
9
+ * group-item checked-state changes.
10
+ */
11
+ internal class StackHeaderToolbarMenuSelectionController {
12
+ internal var forwardIdMap: Map<String, Int> = emptyMap()
13
+ private set
14
+
15
+ private var groupMetadata: StackHeaderToolbarMenuGroupMetadata = StackHeaderToolbarMenuGroupMetadata.EMPTY
16
+
17
+ internal fun setMenuMaps(
18
+ forwardIdMap: Map<String, Int>,
19
+ groupMetadata: StackHeaderToolbarMenuGroupMetadata,
20
+ ) {
21
+ this.forwardIdMap = forwardIdMap
22
+ this.groupMetadata = groupMetadata
23
+ }
24
+
25
+ internal fun clear() {
26
+ forwardIdMap = emptyMap()
27
+ groupMetadata = StackHeaderToolbarMenuGroupMetadata.EMPTY
28
+ }
29
+
30
+ /**
31
+ * Mutates the checked state of [itemId] within its group and returns the id of the group
32
+ * whose selection changed, or `null` when nothing changed (the item is not in a group, an
33
+ * invalid attempt to uncheck a single-selection item, or the item was already in the
34
+ * target state). Does not emit — callers decide when to emit so that batched updates can
35
+ * coalesce into one event per group.
36
+ */
37
+ internal fun applyGroupItemStateChange(
38
+ toolbar: MaterialToolbar,
39
+ itemId: String,
40
+ explicitCheckedValue: Boolean? = null,
41
+ ): String? {
42
+ val groupId = groupMetadata.itemGroupMap[itemId] ?: return null
43
+ val singleSelection = groupMetadata.groupSingleSelection[groupId] ?: return null
44
+ val intId = forwardIdMap[itemId] ?: return null
45
+ val menuItem = toolbar.menu.findItem(intId) ?: return null
46
+
47
+ if (singleSelection && explicitCheckedValue == false) {
48
+ Log.w(
49
+ TAG,
50
+ "[RNScreens] Cannot uncheck item '$itemId' in single-selection group '$groupId'. " +
51
+ "Check a different item instead.",
52
+ )
53
+ return null
54
+ }
55
+
56
+ val newChecked =
57
+ if (singleSelection) {
58
+ true
59
+ } else {
60
+ explicitCheckedValue ?: !menuItem.isChecked
61
+ }
62
+ if (menuItem.isChecked == newChecked) return null
63
+ menuItem.isChecked = newChecked
64
+
65
+ return groupId
66
+ }
67
+
68
+ internal fun collectSelectedIds(
69
+ toolbar: MaterialToolbar,
70
+ groupId: String,
71
+ ): List<String> =
72
+ groupMetadata
73
+ .groupMemberItems[groupId]
74
+ .orEmpty()
75
+ .filter { memberId ->
76
+ val intId = forwardIdMap[memberId] ?: return@filter false
77
+ toolbar.menu.findItem(intId)?.isChecked == true
78
+ }
79
+
80
+ companion object {
81
+ private const val TAG = "StackHeaderToolbarMenuSelectionController"
82
+ }
83
+ }
@@ -1,4 +1,4 @@
1
- package com.swmansion.rnscreens.stack.header.toolbar
1
+ package com.swmansion.rnscreens.stack.header.toolbar.model
2
2
 
3
3
  import android.graphics.drawable.Drawable
4
4
 
@@ -1,4 +1,4 @@
1
- package com.swmansion.rnscreens.stack.header.toolbar
1
+ package com.swmansion.rnscreens.stack.header.toolbar.model
2
2
 
3
3
  internal sealed interface StackHeaderToolbarMenuElementConfig {
4
4
  val item: StackHeaderToolbarMenuItemConfig
@@ -1,4 +1,4 @@
1
- package com.swmansion.rnscreens.stack.header.toolbar
1
+ package com.swmansion.rnscreens.stack.header.toolbar.model
2
2
 
3
3
  internal data class StackHeaderToolbarMenuGroupConfig(
4
4
  val groupId: String,
@@ -1,5 +1,9 @@
1
- package com.swmansion.rnscreens.stack.header.toolbar
1
+ package com.swmansion.rnscreens.stack.header.toolbar.model
2
2
 
3
+ /**
4
+ * Derived group structure for a built menu: item→group, per-group
5
+ * single-selection, and group membership.
6
+ */
3
7
  internal data class StackHeaderToolbarMenuGroupMetadata(
4
8
  val itemGroupMap: Map<String, String>,
5
9
  val groupSingleSelection: Map<String, Boolean>,
@@ -1,4 +1,4 @@
1
- package com.swmansion.rnscreens.stack.header.toolbar
1
+ package com.swmansion.rnscreens.stack.header.toolbar.model
2
2
 
3
3
  import android.graphics.drawable.Drawable
4
4
 
@@ -1,4 +1,4 @@
1
- package com.swmansion.rnscreens.stack.header.toolbar
1
+ package com.swmansion.rnscreens.stack.header.toolbar.model
2
2
 
3
3
  /**
4
4
  * Defaults for toolbar menu item fields.
@@ -1,4 +1,4 @@
1
- package com.swmansion.rnscreens.stack.header.toolbar
1
+ package com.swmansion.rnscreens.stack.header.toolbar.model
2
2
 
3
3
  internal data class StackHeaderToolbarMenuItemIconSource(
4
4
  val drawableIconResourceName: String?,
@@ -1,4 +1,4 @@
1
- package com.swmansion.rnscreens.stack.header.toolbar
1
+ package com.swmansion.rnscreens.stack.header.toolbar.model
2
2
 
3
3
  import android.view.MenuItem.SHOW_AS_ACTION_ALWAYS
4
4
  import android.view.MenuItem.SHOW_AS_ACTION_IF_ROOM
@@ -1,4 +1,4 @@
1
- package com.swmansion.rnscreens.stack.header.toolbar
1
+ package com.swmansion.rnscreens.stack.header.toolbar.model
2
2
 
3
3
  internal enum class StackHeaderToolbarMenuItemType {
4
4
  ACTION,
@@ -1,4 +1,4 @@
1
- package com.swmansion.rnscreens.stack.header.toolbar
1
+ package com.swmansion.rnscreens.stack.header.toolbar.update
2
2
 
3
3
  internal sealed interface StackHeaderToolbarFieldUpdate<out T> {
4
4
  object Reset : StackHeaderToolbarFieldUpdate<Nothing>
@@ -1,6 +1,7 @@
1
- package com.swmansion.rnscreens.stack.header.toolbar
1
+ package com.swmansion.rnscreens.stack.header.toolbar.update
2
2
 
3
3
  import android.graphics.drawable.Drawable
4
+ import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuItemShowAsAction
4
5
 
5
6
  /**
6
7
  * Partial update for a toolbar menu element.
@@ -0,0 +1,13 @@
1
+ package com.swmansion.rnscreens.stack.header.toolbar.update
2
+
3
+ import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuItemIconSource
4
+
5
+ /**
6
+ * A single toolbar menu element update carried by an `updateToolbarMenuElements`
7
+ * view command, before its icon (if any) has been resolved.
8
+ */
9
+ internal data class StackHeaderToolbarMenuElementRawUpdate(
10
+ val id: String,
11
+ val options: StackHeaderToolbarMenuElementOptions,
12
+ val iconSource: StackHeaderToolbarMenuItemIconSource?,
13
+ )