@apexnative/navigation 1.0.0-alpha.1 → 1.0.0-alpha.11

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 (581) hide show
  1. package/ApexNavigation.podspec +2 -1
  2. package/CHANGELOG.md +132 -0
  3. package/README.md +147 -51
  4. package/android/CLAUDE.md +78 -25
  5. package/android/CORE.md +49 -25
  6. package/android/RECIPES.md +13 -6
  7. package/android/consumer-rules.pro +6 -0
  8. package/android/src/main/java/dev/apexnative/navigation/NavigationActivity.kt +85 -10
  9. package/android/src/main/java/dev/apexnative/navigation/NavigationApplication.kt +34 -13
  10. package/android/src/main/java/dev/apexnative/navigation/layout/LayoutChecks.kt +5 -1
  11. package/android/src/main/java/dev/apexnative/navigation/layout/LayoutNode.kt +6 -2
  12. package/android/src/main/java/dev/apexnative/navigation/nativescreen/NativeScreenContext.kt +2 -2
  13. package/android/src/main/java/dev/apexnative/navigation/options/AnimationsOptions.kt +2 -2
  14. package/android/src/main/java/dev/apexnative/navigation/options/BottomTabOptions.kt +1 -1
  15. package/android/src/main/java/dev/apexnative/navigation/options/BottomTabsOptions.kt +13 -8
  16. package/android/src/main/java/dev/apexnative/navigation/options/ButtonMenuOptions.kt +2 -2
  17. package/android/src/main/java/dev/apexnative/navigation/options/ButtonOptions.kt +3 -3
  18. package/android/src/main/java/dev/apexnative/navigation/options/HardwareBackButtonOptions.kt +9 -1
  19. package/android/src/main/java/dev/apexnative/navigation/options/LargeTitleOptions.kt +1 -1
  20. package/android/src/main/java/dev/apexnative/navigation/options/LayoutAnimation.kt +1 -1
  21. package/android/src/main/java/dev/apexnative/navigation/options/OptionKey.kt +18 -0
  22. package/android/src/main/java/dev/apexnative/navigation/options/OptionPaths.kt +91 -0
  23. package/android/src/main/java/dev/apexnative/navigation/options/OptionsCache.kt +8 -4
  24. package/android/src/main/java/dev/apexnative/navigation/options/SheetOptions.kt +7 -4
  25. package/android/src/main/java/dev/apexnative/navigation/options/SideMenuOptions.kt +6 -1
  26. package/android/src/main/java/dev/apexnative/navigation/options/StackAnimationOptions.kt +40 -2
  27. package/android/src/main/java/dev/apexnative/navigation/options/StatusBarOptions.kt +7 -3
  28. package/android/src/main/java/dev/apexnative/navigation/options/TitleOptions.kt +2 -2
  29. package/android/src/main/java/dev/apexnative/navigation/options/TopBarAppearanceOptions.kt +1 -1
  30. package/android/src/main/java/dev/apexnative/navigation/options/TopBarOptions.kt +16 -7
  31. package/android/src/main/java/dev/apexnative/navigation/options/UserChoices.kt +159 -0
  32. package/android/src/main/java/dev/apexnative/navigation/react/CommandAnswer.kt +29 -36
  33. package/android/src/main/java/dev/apexnative/navigation/react/CommandContract.kt +59 -0
  34. package/android/src/main/java/dev/apexnative/navigation/react/ContentHeights.kt +95 -0
  35. package/android/src/main/java/dev/apexnative/navigation/react/ContentMounts.kt +66 -0
  36. package/android/src/main/java/dev/apexnative/navigation/react/ErrorTexts.kt +75 -60
  37. package/android/src/main/java/dev/apexnative/navigation/react/Hinge.kt +35 -23
  38. package/android/src/main/java/dev/apexnative/navigation/react/NavigationTurboModule.kt +12 -7
  39. package/android/src/main/java/dev/apexnative/navigation/react/OptionsCommands.kt +42 -4
  40. package/android/src/main/java/dev/apexnative/navigation/react/PendingCalls.kt +48 -0
  41. package/android/src/main/java/dev/apexnative/navigation/react/ReactView.kt +54 -20
  42. package/android/src/main/java/dev/apexnative/navigation/react/ReloadCoordinator.kt +7 -6
  43. package/android/src/main/java/dev/apexnative/navigation/react/ScreenEnvironment.kt +177 -0
  44. package/android/src/main/java/dev/apexnative/navigation/react/ScreenRegions.kt +19 -50
  45. package/android/src/main/java/dev/apexnative/navigation/react/ScrollEvents.kt +49 -128
  46. package/android/src/main/java/dev/apexnative/navigation/react/events/AppearanceDispatcher.kt +50 -81
  47. package/android/src/main/java/dev/apexnative/navigation/react/events/EventContract.kt +226 -0
  48. package/android/src/main/java/dev/apexnative/navigation/react/events/EventEmitter.kt +135 -94
  49. package/android/src/main/java/dev/apexnative/navigation/react/events/NavigationState.kt +154 -0
  50. package/android/src/main/java/dev/apexnative/navigation/react/events/ScreenAppearance.kt +0 -6
  51. package/android/src/main/java/dev/apexnative/navigation/safearea/SafeAreaView.kt +12 -10
  52. package/android/src/main/java/dev/apexnative/navigation/slots/SlotContainers.kt +10 -7
  53. package/android/src/main/java/dev/apexnative/navigation/slots/SlotScreenView.kt +39 -19
  54. package/android/src/main/java/dev/apexnative/navigation/slots/SlotView.kt +16 -4
  55. package/android/src/main/java/dev/apexnative/navigation/slots/SlotViews.kt +40 -0
  56. package/android/src/main/java/dev/apexnative/navigation/utils/ImageKey.kt +66 -0
  57. package/android/src/main/java/dev/apexnative/navigation/utils/ImageLoader.kt +7 -89
  58. package/android/src/main/java/dev/apexnative/navigation/utils/ImageRequests.kt +76 -0
  59. package/android/src/main/java/dev/apexnative/navigation/utils/MaterialTheme.kt +5 -6
  60. package/android/src/main/java/dev/apexnative/navigation/utils/OptionImages.kt +262 -0
  61. package/android/src/main/java/dev/apexnative/navigation/utils/SystemAnimations.kt +36 -0
  62. package/android/src/main/java/dev/apexnative/navigation/utils/UiUtils.kt +3 -3
  63. package/android/src/main/java/dev/apexnative/navigation/utils/ViewController.kt +3 -1
  64. package/android/src/main/java/dev/apexnative/navigation/utils/ViewExtensions.kt +0 -13
  65. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/ArrangementController.kt +10 -7
  66. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/ArrangementDefinition.kt +9 -3
  67. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/ArrangementPlanner.kt +20 -15
  68. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/SecondaryScreenPresenter.kt +13 -5
  69. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/AppliedTabCalls.kt +49 -0
  70. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsCollapseBehavior.kt +5 -3
  71. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsController.kt +108 -34
  72. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsPresenter.kt +25 -24
  73. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowGeometry.kt +22 -0
  74. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabItems.kt +3 -3
  75. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabsRoom.kt +0 -5
  76. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentPresenter.kt +28 -7
  77. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentViewController.kt +12 -9
  78. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ContentReadiness.kt +2 -2
  79. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/RenderWait.kt +27 -7
  80. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenFrame.kt +1 -1
  81. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenReadiness.kt +103 -56
  82. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenSafeArea.kt +29 -11
  83. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/externalcomponent/ExternalComponentViewController.kt +2 -6
  84. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalAnimations.kt +22 -24
  85. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalCoordinator.kt +109 -21
  86. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalRecord.kt +21 -6
  87. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalSheet.kt +476 -73
  88. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalViews.kt +57 -25
  89. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetBack.kt +42 -0
  90. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetStops.kt +83 -0
  91. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/BackCallbackCheck.kt +50 -0
  92. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/BackCallbackState.kt +49 -14
  93. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/Navigator.kt +71 -12
  94. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/RootCoordinator.kt +37 -11
  95. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/overlay/OverlayCoordinator.kt +10 -8
  96. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/Capabilities.kt +11 -4
  97. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ContainerBackground.kt +3 -3
  98. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ParentController.kt +6 -6
  99. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuController.kt +42 -9
  100. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuMotion.kt +19 -8
  101. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuPresenter.kt +16 -7
  102. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuRules.kt +43 -4
  103. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitPanes.kt +23 -0
  104. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitViewController.kt +77 -17
  105. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/BackPreview.kt +315 -0
  106. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/PreparedFrame.kt +3 -3
  107. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackCommands.kt +30 -20
  108. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackController.kt +216 -18
  109. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackDisplay.kt +26 -1
  110. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackQueue.kt +149 -41
  111. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackTransitions.kt +26 -8
  112. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackViews.kt +115 -6
  113. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabMotion.kt +142 -0
  114. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabPresenter.kt +222 -48
  115. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/ScreenSearch.kt +3 -5
  116. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/StackSearchPresenter.kt +30 -34
  117. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/BarComponents.kt +5 -51
  118. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/BarRowTransition.kt +3 -2
  119. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/ButtonPlaces.kt +11 -5
  120. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/MenuChecks.kt +13 -56
  121. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarPresenter.kt +219 -54
  122. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarVisibility.kt +9 -2
  123. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ScrollEventListener.kt +6 -9
  124. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ViewController.kt +75 -21
  125. package/android/src/main/java/dev/apexnative/navigation/views/animations/AnimationLayer.kt +73 -0
  126. package/android/src/main/java/dev/apexnative/navigation/views/animations/Curves.kt +29 -11
  127. package/android/src/main/java/dev/apexnative/navigation/views/animations/ValueInterpolation.kt +14 -0
  128. package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabs.kt +9 -7
  129. package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabsLayout.kt +61 -2
  130. package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomBottomTabItemView.kt +0 -5
  131. package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomTabRow.kt +72 -10
  132. package/android/src/main/java/dev/apexnative/navigation/views/element/ElementStep.kt +31 -0
  133. package/android/src/main/java/dev/apexnative/navigation/views/element/ElementTransitions.kt +143 -135
  134. package/android/src/main/java/dev/apexnative/navigation/views/element/TargetsWait.kt +13 -5
  135. package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionLayer.kt +37 -112
  136. package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionTargets.kt +9 -6
  137. package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionViews.kt +100 -0
  138. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ElementPictures.kt +112 -4
  139. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/FlightGeometry.kt +346 -36
  140. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMorph.kt +199 -0
  141. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/SharedAnimatorFactory.kt +56 -41
  142. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextMorph.kt +176 -0
  143. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewMorph.kt +108 -0
  144. package/android/src/main/java/dev/apexnative/navigation/views/sidemenu/SideMenuView.kt +12 -3
  145. package/android/src/main/java/dev/apexnative/navigation/views/stack/ScreenEdge.kt +45 -0
  146. package/android/src/main/java/dev/apexnative/navigation/views/stack/StackLayout.kt +140 -1
  147. package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/Fab.kt +14 -10
  148. package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabCopy.kt +85 -0
  149. package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabMenu.kt +13 -0
  150. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TitleBar.kt +5 -17
  151. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TopBar.kt +73 -34
  152. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonComponentCell.kt +6 -6
  153. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonView.kt +113 -0
  154. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarMenu.kt +219 -0
  155. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonBar.kt +125 -178
  156. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonMenus.kt +34 -64
  157. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonRow.kt +216 -0
  158. package/android/src/main/jni/ANNContentHeights.cpp +82 -0
  159. package/android/src/main/res/drawable/apex_navigation_ic_arrow_right.xml +14 -0
  160. package/android/src/main/res/layout/apex_navigation_menu_header.xml +19 -0
  161. package/android/src/main/res/layout/apex_navigation_menu_item.xml +68 -0
  162. package/android/src/main/res/values/styles.xml +1 -1
  163. package/android/src/main/res/values-night/styles.xml +1 -1
  164. package/cli/app.js +1 -1
  165. package/cli/doctor/checks/app.js +77 -14
  166. package/cli/doctor/checks/splash.js +4 -22
  167. package/cli/migrate/native.js +18 -0
  168. package/cli/project.js +10 -2
  169. package/cli/setup/index.js +18 -0
  170. package/cli/setup/source.js +2 -1
  171. package/cli/setup/steps/appDelegate.js +66 -11
  172. package/cli/setup/steps/mainApplication.js +134 -19
  173. package/cli/setup/steps/metro.js +46 -0
  174. package/cli/setup/steps/sceneDelegate.js +108 -0
  175. package/cli/splash/index.js +3 -1
  176. package/docs-md/architecture/native-screens.md +4 -0
  177. package/docs-md/architecture/theme-and-context.md +131 -12
  178. package/docs-md/architecture/transitions.md +58 -12
  179. package/docs-md/containers/arrangement.md +17 -1
  180. package/docs-md/containers/modals.md +8 -4
  181. package/docs-md/containers/overlays.md +3 -1
  182. package/docs-md/containers/side-menu.md +19 -2
  183. package/docs-md/containers/tabs.md +5 -1
  184. package/docs-md/flows/bottom-sheets.md +4 -2
  185. package/docs-md/flows/forms-in-a-modal.md +1 -1
  186. package/docs-md/fundamentals/screens-and-props.md +9 -1
  187. package/docs-md/fundamentals/starting-the-app.md +1 -1
  188. package/docs-md/guides/cli.md +4 -3
  189. package/docs-md/guides/deep-links.md +15 -33
  190. package/docs-md/help/glossary.md +4 -4
  191. package/docs-md/help/troubleshooting.md +44 -6
  192. package/docs-md/index.json +61 -1
  193. package/docs-md/migration/from-expo-router.md +1 -1
  194. package/docs-md/migration/from-react-native-navigation.md +9 -3
  195. package/docs-md/migration/from-react-navigation.md +2 -2
  196. package/docs-md/screen-ui/back-and-gestures.md +46 -2
  197. package/docs-md/screen-ui/bar-buttons.md +5 -5
  198. package/docs-md/screen-ui/search.md +1 -1
  199. package/docs-md/screen-ui/system-ui.md +17 -12
  200. package/docs-md/screen-ui/toolbar-and-fab.md +4 -2
  201. package/docs-md/screen-ui/top-bar.md +8 -4
  202. package/docs-md/start/installation.md +21 -3
  203. package/ios/Animations/ANNFrameDriver.h +55 -15
  204. package/ios/Animations/ANNFrameDriver.mm +216 -60
  205. package/ios/Animations/ANNTransitionAnimator.h +26 -5
  206. package/ios/Animations/ANNTransitionAnimator.mm +61 -13
  207. package/ios/Animations/ANNTransitionPlan.h +2 -2
  208. package/ios/Animations/ANNTransitionPlan.mm +10 -0
  209. package/ios/Animations/ANNTransitionWait.mm +6 -7
  210. package/ios/Animations/Elements/ANNElementFinder.h +57 -0
  211. package/ios/Animations/Elements/ANNElementFinder.mm +174 -2
  212. package/ios/Animations/Elements/ANNElementTransition.h +10 -8
  213. package/ios/Animations/Elements/ANNElementTransition.mm +19 -21
  214. package/ios/Animations/Elements/ANNSharedElementFlight.h +16 -11
  215. package/ios/Animations/Elements/ANNSharedElementFlight.mm +308 -69
  216. package/ios/Animations/Interpolators/ANNInterpolate.h +2 -30
  217. package/ios/Animations/Interpolators/ANNTransformParts.h +48 -0
  218. package/ios/Animations/Interpolators/ANNTransformParts.mm +507 -0
  219. package/ios/Animations/Interpolators/ANNViewTracks.h +9 -6
  220. package/ios/Animations/Interpolators/ANNViewTracks.mm +100 -30
  221. package/ios/CLAUDE.md +60 -24
  222. package/ios/CORE.md +44 -34
  223. package/ios/Contract/ANNCommandAnswer.h +13 -5
  224. package/ios/Contract/ANNCommandAnswer.mm +40 -32
  225. package/ios/Contract/ANNCommandContract.h +15 -0
  226. package/ios/Contract/ANNCommandContract.mm +78 -0
  227. package/ios/Contract/ANNCommandRunner.h +10 -9
  228. package/ios/Contract/ANNCommandRunner.mm +22 -28
  229. package/ios/Contract/ANNErrorTexts.h +6 -2
  230. package/ios/Contract/ANNErrorTexts.mm +18 -10
  231. package/ios/Contract/ANNLayoutNode.h +3 -3
  232. package/ios/Contract/ANNLayoutReader.h +3 -3
  233. package/ios/Core/ANNAppDelegate.mm +0 -2
  234. package/ios/Core/ANNAppearanceDispatcher.h +5 -4
  235. package/ios/Core/ANNAppearanceDispatcher.mm +12 -1
  236. package/ios/Core/ANNDeepLinkQueue.h +22 -2
  237. package/ios/Core/ANNDeepLinkQueue.mm +121 -14
  238. package/ios/Core/ANNErrorHandler.h +9 -4
  239. package/ios/Core/ANNErrorHandler.mm +20 -2
  240. package/ios/Core/ANNEventContract.h +246 -0
  241. package/ios/Core/ANNEventContract.mm +225 -0
  242. package/ios/Core/ANNEventEmitter.h +6 -2
  243. package/ios/Core/ANNEventEmitter.mm +117 -80
  244. package/ios/Core/ANNHinge.h +6 -0
  245. package/ios/Core/ANNHinge.mm +15 -4
  246. package/ios/Core/ANNJavaScriptCalls.h +33 -0
  247. package/ios/Core/ANNJavaScriptCalls.mm +52 -0
  248. package/ios/Core/ANNLayoutProtocol.h +5 -5
  249. package/ios/Core/ANNNavigationState.h +7 -5
  250. package/ios/Core/ANNNavigationState.mm +8 -7
  251. package/ios/Core/ANNNodeHelper.h +32 -12
  252. package/ios/Core/ANNNodeHelper.mm +100 -3
  253. package/ios/Core/ANNParking.h +5 -4
  254. package/ios/Core/ANNReloadCoordinator.mm +5 -12
  255. package/ios/Core/ANNRenderWait.h +20 -6
  256. package/ios/Core/ANNRenderWait.mm +143 -56
  257. package/ios/Core/ANNSceneDelegate.mm +25 -15
  258. package/ios/Core/ANNSystemUI.h +3 -2
  259. package/ios/Core/ANNSystemUI.mm +7 -0
  260. package/ios/Core/ANNUtils.h +7 -0
  261. package/ios/Core/ANNUtils.mm +10 -0
  262. package/ios/Core/ApexNavigation+Internal.h +1 -1
  263. package/ios/Core/ApexNavigation.mm +7 -6
  264. package/ios/Core/UIViewController+LayoutProtocol.h +9 -2
  265. package/ios/Core/UIViewController+LayoutProtocol.mm +8 -0
  266. package/ios/Layouts/Arrangement/ANNArrangementState.h +2 -17
  267. package/ios/Layouts/Arrangement/ANNArrangementState.mm +0 -38
  268. package/ios/Layouts/Arrangement/ANNArrangementViewController.mm +195 -21
  269. package/ios/Layouts/Modal/ANNModalCoordinator.h +1 -1
  270. package/ios/Layouts/Modal/ANNModalCoordinator.mm +57 -16
  271. package/ios/Layouts/Modal/ANNModalPresentation.h +8 -5
  272. package/ios/Layouts/Modal/ANNModalPresentation.mm +12 -12
  273. package/ios/Layouts/Modal/ANNSheetPresenter.mm +83 -1
  274. package/ios/Layouts/Overlay/ANNOverlayCoordinator.mm +2 -8
  275. package/ios/Layouts/Root/ANNRootCoordinator.mm +58 -19
  276. package/ios/Layouts/Root/ANNSplashViewController.h +5 -3
  277. package/ios/Layouts/Root/ANNSplashViewController.mm +147 -0
  278. package/ios/Layouts/Screen/ANNComponentPresenter.h +11 -3
  279. package/ios/Layouts/Screen/ANNComponentPresenter.mm +34 -6
  280. package/ios/Layouts/Screen/ANNComponentViewController.h +15 -13
  281. package/ios/Layouts/Screen/ANNComponentViewController.mm +130 -75
  282. package/ios/Layouts/Screen/ANNNativeScreenContext.mm +7 -5
  283. package/ios/Layouts/Screen/ANNPreviewInteraction.h +7 -4
  284. package/ios/Layouts/Screen/ANNPreviewInteraction.mm +72 -10
  285. package/ios/Layouts/Screen/ANNScreenEnvironment.h +63 -0
  286. package/ios/Layouts/Screen/ANNScreenEnvironment.mm +181 -0
  287. package/ios/Layouts/Screen/ANNScreenPlace.h +53 -0
  288. package/ios/Layouts/Screen/ANNScreenPlace.mm +205 -0
  289. package/ios/Layouts/Screen/ANNScreenRegions.h +3 -18
  290. package/ios/Layouts/Screen/ANNScreenRegions.mm +9 -44
  291. package/ios/Layouts/Screen/ANNScreenSafeArea.h +4 -9
  292. package/ios/Layouts/Screen/ANNScreenSafeArea.mm +14 -16
  293. package/ios/Layouts/Screen/ANNScreenSettling.h +34 -0
  294. package/ios/Layouts/Screen/ANNScreenSettling.mm +171 -0
  295. package/ios/Layouts/SideMenu/ANNSideMenuTypes.h +8 -0
  296. package/ios/Layouts/SideMenu/ANNSideMenuViewController.mm +83 -14
  297. package/ios/Layouts/SplitView/ANNSplitViewCommands.h +3 -2
  298. package/ios/Layouts/SplitView/ANNSplitViewCommands.mm +105 -39
  299. package/ios/Layouts/SplitView/ANNSplitViewController.mm +7 -8
  300. package/ios/Layouts/Stack/ANNPreviewPush.h +7 -6
  301. package/ios/Layouts/Stack/ANNPreviewPush.mm +142 -27
  302. package/ios/Layouts/Stack/ANNStackAnimatingDelegate.h +11 -2
  303. package/ios/Layouts/Stack/ANNStackAnimatingDelegate.mm +14 -7
  304. package/ios/Layouts/Stack/ANNStackCommands.mm +1 -0
  305. package/ios/Layouts/Stack/ANNStackController.h +8 -0
  306. package/ios/Layouts/Stack/ANNStackController.mm +184 -16
  307. package/ios/Layouts/Stack/ANNStackQueue.h +5 -2
  308. package/ios/Layouts/Stack/ANNStackQueue.mm +56 -43
  309. package/ios/Layouts/Stack/ANNSwipePopInteraction.h +26 -0
  310. package/ios/Layouts/Stack/ANNSwipePopInteraction.mm +185 -0
  311. package/ios/Layouts/Stack/InteractivePopGestureDelegate.mm +28 -4
  312. package/ios/Layouts/Stack/UINavigationController+ANNCommands.h +4 -2
  313. package/ios/Layouts/Stack/UINavigationController+ANNCommands.mm +2 -3
  314. package/ios/Layouts/Tabs/ANNBottomTabItemBuilder.h +4 -0
  315. package/ios/Layouts/Tabs/ANNBottomTabItemBuilder.mm +11 -0
  316. package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.h +12 -1
  317. package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.mm +23 -0
  318. package/ios/Layouts/Tabs/ANNBottomTabsController.h +3 -0
  319. package/ios/Layouts/Tabs/ANNBottomTabsController.mm +237 -57
  320. package/ios/Layouts/Tabs/ANNBottomTabsCustomRow.mm +8 -3
  321. package/ios/Layouts/Tabs/ANNBottomTabsPresenter.h +6 -2
  322. package/ios/Layouts/Tabs/ANNBottomTabsPresenter.mm +232 -43
  323. package/ios/Layouts/Tabs/ANNTabsDesign.h +6 -5
  324. package/ios/Layouts/Tabs/ANNTabsDesign.mm +9 -1
  325. package/ios/Layouts/Tabs/UITabBar+utils.h +5 -5
  326. package/ios/Layouts/Tabs/UITabBar+utils.mm +32 -13
  327. package/ios/Options/ANNAnimationOptions.h +2 -1
  328. package/ios/Options/ANNAnimationOptions.mm +1 -1
  329. package/ios/Options/ANNBottomTabsOptions.h +2 -0
  330. package/ios/Options/ANNBottomTabsOptions.mm +1 -0
  331. package/ios/Options/ANNOptions.h +25 -0
  332. package/ios/Options/ANNOptions.mm +157 -1
  333. package/ios/Options/ANNOptionsCache.h +7 -6
  334. package/ios/Options/ANNOptionsReader.mm +108 -0
  335. package/ios/Options/ANNSearchBarOptions.h +4 -3
  336. package/ios/Options/ANNSheetOptions.h +4 -1
  337. package/ios/Options/ANNSideMenuOptions.h +2 -0
  338. package/ios/Options/ANNSideMenuOptions.mm +2 -0
  339. package/ios/Options/ANNStackPopAnimationOptions.h +13 -0
  340. package/ios/Options/ANNStackPopAnimationOptions.mm +11 -0
  341. package/ios/Options/ANNUserChoice.h +57 -0
  342. package/ios/Options/ANNUserChoice.mm +44 -0
  343. package/ios/Options/Params/ANNImageSource.h +61 -0
  344. package/ios/Options/Params/ANNImageSource.mm +101 -0
  345. package/ios/Options/Params/ANNOptionImages.h +37 -0
  346. package/ios/Options/Params/ANNOptionImages.mm +284 -0
  347. package/ios/Options/Params/ANNParam.h +15 -0
  348. package/ios/Options/Params/ANNParam.mm +61 -0
  349. package/ios/Options/Params/Color.h +3 -0
  350. package/ios/Options/Params/Color.mm +21 -0
  351. package/ios/Options/Params/ColorParser.h +4 -3
  352. package/ios/Options/Params/ColorParser.mm +22 -4
  353. package/ios/Options/Params/Image.h +15 -2
  354. package/ios/Options/Params/Image.mm +35 -2
  355. package/ios/Options/Params/ImageParser.h +5 -5
  356. package/ios/Options/Params/ImageParser.mm +28 -46
  357. package/ios/Public/ApexNavigation/ANNSceneDelegate.h +3 -0
  358. package/ios/Public/ApexNavigation/ApexNavigation.h +1 -1
  359. package/ios/RECIPES.md +13 -6
  360. package/ios/React/ANNReactView.mm +6 -25
  361. package/ios/React/ANNSafeAreaViewComponentView.mm +28 -17
  362. package/ios/React/ANNSurfaceHostingView.h +14 -0
  363. package/ios/React/ANNSurfaceHostingView.mm +144 -1
  364. package/ios/React/Slots/ANNSlotComponentView.mm +24 -17
  365. package/ios/React/Slots/ANNSlotContainers.h +14 -6
  366. package/ios/React/Slots/ANNSlotContainers.mm +75 -2
  367. package/ios/React/Slots/ANNSlotHost.mm +1 -3
  368. package/ios/React/Slots/ANNSlotScreenView.mm +8 -2
  369. package/ios/TopBar/ANNBackButtonPresenter.mm +6 -5
  370. package/ios/TopBar/ANNBarAppearance.h +2 -1
  371. package/ios/TopBar/ANNBarAppearance.mm +111 -30
  372. package/ios/TopBar/ANNBarBackgroundComponent.mm +16 -0
  373. package/ios/TopBar/ANNBarButtonComponentView.h +4 -4
  374. package/ios/TopBar/ANNBarButtonComponentView.mm +1 -1
  375. package/ios/TopBar/ANNBarButtons.h +14 -8
  376. package/ios/TopBar/ANNBarButtons.mm +397 -80
  377. package/ios/TopBar/ANNIconButtonImage.h +1 -0
  378. package/ios/TopBar/ANNIconButtonImage.mm +34 -1
  379. package/ios/TopBar/ANNLargeTitlePresenter.h +13 -0
  380. package/ios/TopBar/ANNLargeTitlePresenter.mm +50 -7
  381. package/ios/TopBar/ANNMainList.h +3 -0
  382. package/ios/TopBar/ANNMainList.mm +4 -0
  383. package/ios/TopBar/ANNScrollEdgeEffects.h +22 -6
  384. package/ios/TopBar/ANNScrollEdgeEffects.mm +123 -16
  385. package/ios/TopBar/ANNSearchPresenter.mm +172 -21
  386. package/ios/TopBar/ANNSearchResultsViewController.mm +29 -6
  387. package/ios/TopBar/ANNTopBarPresenter.h +8 -2
  388. package/ios/TopBar/ANNTopBarPresenter.mm +155 -33
  389. package/ios/TurboModules/ANNTurboEventEmitter.mm +4 -35
  390. package/ios/TurboModules/ANNTurboModule.mm +104 -33
  391. package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.cpp +20 -0
  392. package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.h +5 -14
  393. package/lib/module/ARCHITECTURE.md +40 -27
  394. package/lib/module/adapters/NativeANNTurboModule.js.map +1 -1
  395. package/lib/module/api/app/AppRegistry.js +14 -2
  396. package/lib/module/api/app/AppRegistry.js.map +1 -1
  397. package/lib/module/api/app/createNavigation.js +190 -66
  398. package/lib/module/api/app/createNavigation.js.map +1 -1
  399. package/lib/module/api/commands/commands.js +54 -6
  400. package/lib/module/api/commands/commands.js.map +1 -1
  401. package/lib/module/api/events/navigationEvents.js +6 -2
  402. package/lib/module/api/events/navigationEvents.js.map +1 -1
  403. package/lib/module/api/hooks/useNavigation.js +8 -3
  404. package/lib/module/api/hooks/useNavigation.js.map +1 -1
  405. package/lib/module/api/hooks/useSafeAreaInsets.js +4 -3
  406. package/lib/module/api/hooks/useSafeAreaInsets.js.map +1 -1
  407. package/lib/module/api/linking/dispatchedLinks.js +23 -0
  408. package/lib/module/api/linking/dispatchedLinks.js.map +1 -0
  409. package/lib/module/api/linking/linking.js +11 -0
  410. package/lib/module/api/linking/linking.js.map +1 -1
  411. package/lib/module/api/navigation.js.map +1 -1
  412. package/lib/module/api/options/OptionsChain.js +2 -2
  413. package/lib/module/api/screens/arrangement.js +5 -2
  414. package/lib/module/api/screens/arrangement.js.map +1 -1
  415. package/lib/module/api/screens/defineScreen.js +45 -3
  416. package/lib/module/api/screens/defineScreen.js.map +1 -1
  417. package/lib/module/api/screens/nativeScreens.js +31 -6
  418. package/lib/module/api/screens/nativeScreens.js.map +1 -1
  419. package/lib/module/api/screens/registerScreens.js +193 -35
  420. package/lib/module/api/screens/registerScreens.js.map +1 -1
  421. package/lib/module/api/theme/theme.js +5 -0
  422. package/lib/module/api/theme/theme.js.map +1 -1
  423. package/lib/module/engine/commands.js +51 -9
  424. package/lib/module/engine/commands.js.map +1 -1
  425. package/lib/module/engine/layout.js +20 -11
  426. package/lib/module/engine/layout.js.map +1 -1
  427. package/lib/module/engine/nativeScreens.js +9 -0
  428. package/lib/module/engine/nativeScreens.js.map +1 -1
  429. package/lib/module/engine/options.js +49 -15
  430. package/lib/module/engine/options.js.map +1 -1
  431. package/lib/module/engine/optionsChange.js +102 -0
  432. package/lib/module/engine/optionsChange.js.map +1 -0
  433. package/lib/module/engine/places.js +52 -7
  434. package/lib/module/engine/places.js.map +1 -1
  435. package/lib/module/engine/props.js +30 -1
  436. package/lib/module/engine/props.js.map +1 -1
  437. package/lib/module/engine/refresh.js +85 -0
  438. package/lib/module/engine/refresh.js.map +1 -0
  439. package/lib/module/engine/rememberedOptions.js +61 -1
  440. package/lib/module/engine/rememberedOptions.js.map +1 -1
  441. package/lib/module/engine/screens.js +77 -16
  442. package/lib/module/engine/screens.js.map +1 -1
  443. package/lib/module/interfaces/contract/commands.json +101 -0
  444. package/lib/module/interfaces/contract/errors.json +275 -0
  445. package/lib/typescript/adapters/NativeANNTurboModule.d.ts +12 -2
  446. package/lib/typescript/adapters/NativeANNTurboModule.d.ts.map +1 -1
  447. package/lib/typescript/api/app/AppRegistry.d.ts.map +1 -1
  448. package/lib/typescript/api/app/createNavigation.d.ts +8 -3
  449. package/lib/typescript/api/app/createNavigation.d.ts.map +1 -1
  450. package/lib/typescript/api/commands/commands.d.ts.map +1 -1
  451. package/lib/typescript/api/commands/presentation.d.ts +4 -3
  452. package/lib/typescript/api/commands/presentation.d.ts.map +1 -1
  453. package/lib/typescript/api/events/navigationEvents.d.ts +3 -3
  454. package/lib/typescript/api/events/navigationEvents.d.ts.map +1 -1
  455. package/lib/typescript/api/hooks/useNavigation.d.ts +1 -1
  456. package/lib/typescript/api/hooks/useNavigation.d.ts.map +1 -1
  457. package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts +4 -3
  458. package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts.map +1 -1
  459. package/lib/typescript/api/index.d.ts +1 -1
  460. package/lib/typescript/api/index.d.ts.map +1 -1
  461. package/lib/typescript/api/linking/dispatchedLinks.d.ts +7 -0
  462. package/lib/typescript/api/linking/dispatchedLinks.d.ts.map +1 -0
  463. package/lib/typescript/api/linking/linking.d.ts +8 -0
  464. package/lib/typescript/api/linking/linking.d.ts.map +1 -1
  465. package/lib/typescript/api/navigation.d.ts +4 -1
  466. package/lib/typescript/api/navigation.d.ts.map +1 -1
  467. package/lib/typescript/api/options/OptionsChain.d.ts +2 -2
  468. package/lib/typescript/api/screens/arrangement.d.ts +12 -2
  469. package/lib/typescript/api/screens/arrangement.d.ts.map +1 -1
  470. package/lib/typescript/api/screens/defineScreen.d.ts +23 -4
  471. package/lib/typescript/api/screens/defineScreen.d.ts.map +1 -1
  472. package/lib/typescript/api/screens/nativeScreens.d.ts +8 -1
  473. package/lib/typescript/api/screens/nativeScreens.d.ts.map +1 -1
  474. package/lib/typescript/api/screens/registerScreens.d.ts.map +1 -1
  475. package/lib/typescript/api/theme/theme.d.ts +2 -0
  476. package/lib/typescript/api/theme/theme.d.ts.map +1 -1
  477. package/lib/typescript/engine/commands.d.ts +5 -0
  478. package/lib/typescript/engine/commands.d.ts.map +1 -1
  479. package/lib/typescript/engine/layout.d.ts.map +1 -1
  480. package/lib/typescript/engine/nativeScreens.d.ts +5 -0
  481. package/lib/typescript/engine/nativeScreens.d.ts.map +1 -1
  482. package/lib/typescript/engine/options.d.ts +5 -2
  483. package/lib/typescript/engine/options.d.ts.map +1 -1
  484. package/lib/typescript/engine/optionsChange.d.ts +28 -0
  485. package/lib/typescript/engine/optionsChange.d.ts.map +1 -0
  486. package/lib/typescript/engine/places.d.ts +7 -2
  487. package/lib/typescript/engine/places.d.ts.map +1 -1
  488. package/lib/typescript/engine/props.d.ts +8 -1
  489. package/lib/typescript/engine/props.d.ts.map +1 -1
  490. package/lib/typescript/engine/refresh.d.ts +35 -0
  491. package/lib/typescript/engine/refresh.d.ts.map +1 -0
  492. package/lib/typescript/engine/rememberedOptions.d.ts +13 -0
  493. package/lib/typescript/engine/rememberedOptions.d.ts.map +1 -1
  494. package/lib/typescript/engine/screens.d.ts +27 -6
  495. package/lib/typescript/engine/screens.d.ts.map +1 -1
  496. package/lib/typescript/interfaces/ComponentEvents.d.ts +4 -4
  497. package/lib/typescript/interfaces/ComponentEvents.d.ts.map +1 -1
  498. package/lib/typescript/interfaces/Events.d.ts +28 -10
  499. package/lib/typescript/interfaces/Events.d.ts.map +1 -1
  500. package/lib/typescript/interfaces/Options.d.ts +1 -1
  501. package/lib/typescript/interfaces/Options.d.ts.map +1 -1
  502. package/lib/typescript/interfaces/options/animations.d.ts +80 -22
  503. package/lib/typescript/interfaces/options/animations.d.ts.map +1 -1
  504. package/lib/typescript/interfaces/options/bottomTabs.d.ts +21 -7
  505. package/lib/typescript/interfaces/options/bottomTabs.d.ts.map +1 -1
  506. package/lib/typescript/interfaces/options/buttons.d.ts +23 -15
  507. package/lib/typescript/interfaces/options/buttons.d.ts.map +1 -1
  508. package/lib/typescript/interfaces/options/modals.d.ts +34 -26
  509. package/lib/typescript/interfaces/options/modals.d.ts.map +1 -1
  510. package/lib/typescript/interfaces/options/sideMenu.d.ts +23 -6
  511. package/lib/typescript/interfaces/options/sideMenu.d.ts.map +1 -1
  512. package/lib/typescript/interfaces/options/stack.d.ts +17 -3
  513. package/lib/typescript/interfaces/options/stack.d.ts.map +1 -1
  514. package/lib/typescript/interfaces/options/system.d.ts +18 -11
  515. package/lib/typescript/interfaces/options/system.d.ts.map +1 -1
  516. package/lib/typescript/interfaces/options/toolbar.d.ts +2 -2
  517. package/lib/typescript/interfaces/options/topBar.d.ts +68 -38
  518. package/lib/typescript/interfaces/options/topBar.d.ts.map +1 -1
  519. package/metro/acceptPlugin.js +57 -0
  520. package/metro/babelTransformer.js +45 -0
  521. package/metro/index.js +36 -0
  522. package/package.json +3 -1
  523. package/src/ARCHITECTURE.md +40 -27
  524. package/src/adapters/NativeANNTurboModule.ts +12 -2
  525. package/src/api/app/AppRegistry.ts +16 -2
  526. package/src/api/app/createNavigation.ts +203 -69
  527. package/src/api/commands/commands.ts +48 -7
  528. package/src/api/commands/presentation.ts +4 -3
  529. package/src/api/events/navigationEvents.ts +10 -4
  530. package/src/api/hooks/useNavigation.ts +9 -4
  531. package/src/api/hooks/useSafeAreaInsets.ts +4 -3
  532. package/src/api/index.ts +1 -0
  533. package/src/api/linking/dispatchedLinks.ts +18 -0
  534. package/src/api/linking/linking.ts +22 -1
  535. package/src/api/navigation.ts +4 -1
  536. package/src/api/options/OptionsChain.ts +2 -2
  537. package/src/api/screens/arrangement.ts +17 -4
  538. package/src/api/screens/defineScreen.ts +49 -5
  539. package/src/api/screens/nativeScreens.ts +40 -4
  540. package/src/api/screens/registerScreens.tsx +185 -42
  541. package/src/api/theme/theme.ts +5 -0
  542. package/src/engine/commands.ts +70 -13
  543. package/src/engine/layout.ts +27 -11
  544. package/src/engine/nativeScreens.ts +10 -1
  545. package/src/engine/options.ts +45 -19
  546. package/src/engine/optionsChange.ts +107 -0
  547. package/src/engine/places.ts +65 -7
  548. package/src/engine/props.ts +30 -1
  549. package/src/engine/refresh.ts +97 -0
  550. package/src/engine/rememberedOptions.ts +74 -1
  551. package/src/engine/screens.tsx +76 -21
  552. package/src/interfaces/ComponentEvents.ts +4 -4
  553. package/src/interfaces/Events.ts +29 -10
  554. package/src/interfaces/Options.ts +1 -0
  555. package/src/interfaces/contract/commands.json +101 -0
  556. package/src/interfaces/contract/errors.json +275 -0
  557. package/src/interfaces/options/animations.ts +81 -22
  558. package/src/interfaces/options/bottomTabs.ts +21 -7
  559. package/src/interfaces/options/buttons.ts +23 -15
  560. package/src/interfaces/options/modals.ts +34 -26
  561. package/src/interfaces/options/sideMenu.ts +24 -6
  562. package/src/interfaces/options/stack.ts +17 -3
  563. package/src/interfaces/options/system.ts +18 -11
  564. package/src/interfaces/options/toolbar.ts +2 -2
  565. package/src/interfaces/options/topBar.ts +68 -38
  566. package/android/src/main/java/dev/apexnative/navigation/react/ArrangementStates.kt +0 -41
  567. package/android/src/main/java/dev/apexnative/navigation/react/ScreenInsets.kt +0 -69
  568. package/android/src/main/java/dev/apexnative/navigation/react/events/NavigationStateReporter.kt +0 -62
  569. package/android/src/main/java/dev/apexnative/navigation/react/events/StateHold.kt +0 -62
  570. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowPlacer.kt +0 -223
  571. package/android/src/main/java/dev/apexnative/navigation/views/element/ElementStub.kt +0 -31
  572. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMatrixAnimator.kt +0 -138
  573. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PlainViewAnimator.kt +0 -88
  574. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PropertyAnimatorCreator.kt +0 -33
  575. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ReactImageAnimator.kt +0 -66
  576. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextChangeAnimator.kt +0 -179
  577. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewChangeAnimator.kt +0 -139
  578. package/ios/Layouts/Screen/ANNScreenInsets.h +0 -30
  579. package/ios/Layouts/Screen/ANNScreenInsets.mm +0 -68
  580. package/ios/Layouts/Tabs/ANNTabsPreloadWindow.h +0 -27
  581. package/ios/Layouts/Tabs/ANNTabsPreloadWindow.mm +0 -55
@@ -1,9 +1,16 @@
1
1
  package dev.apexnative.navigation.viewcontrollers.stack.fab
2
2
 
3
+ import android.animation.Animator
4
+ import android.animation.AnimatorListenerAdapter
5
+ import android.animation.AnimatorSet
6
+ import android.animation.ObjectAnimator
7
+ import android.animation.PropertyValuesHolder
3
8
  import android.app.Activity
4
9
  import android.view.Gravity
5
10
  import android.view.View
6
11
  import android.view.ViewGroup
12
+ import android.view.animation.AccelerateDecelerateInterpolator
13
+ import android.view.animation.LinearInterpolator
7
14
  import androidx.coordinatorlayout.widget.CoordinatorLayout
8
15
  import androidx.core.view.WindowInsetsCompat
9
16
  import dev.apexnative.navigation.options.FabOptions
@@ -11,16 +18,20 @@ import dev.apexnative.navigation.react.events.AppearanceDispatcher
11
18
  import dev.apexnative.navigation.utils.TestIds
12
19
  import dev.apexnative.navigation.viewcontrollers.viewcontroller.ScrollEventListener
13
20
  import dev.apexnative.navigation.viewcontrollers.viewcontroller.ViewController
21
+ import dev.apexnative.navigation.views.animations.FadeThrough
22
+ import dev.apexnative.navigation.views.animations.SystemTransition
14
23
  import dev.apexnative.navigation.views.stack.StackLayout
15
24
  import dev.apexnative.navigation.views.stack.fab.Fab
25
+ import dev.apexnative.navigation.views.stack.fab.FabCopy
16
26
  import dev.apexnative.navigation.views.stack.fab.FabMenu
17
27
 
18
28
  /**
19
29
  * The FAB of one stack (`fab.*`), over the module's `Fab` and `FabMenu`: one FAB or one menu at a time, from the
20
30
  * resolved `fab` of the screen on top (its options over the stack's, its parents' and the defaults). It follows the top
21
- * at the end of each transition and the merges of `fab` into it; a press sends `ANN.NavigationButtonPressed` with the
22
- * screen whose options showed it, an action with its own id. Its views are children of the stack's view, over the
23
- * screens and the bar. Main thread only.
31
+ * from the start of each transition, going with the screens by [FabMotion], and the merges of `fab` into it; a press
32
+ * sends `ANN.NavigationButtonPressed` with the screen whose options showed it, an action with its own id. Its views are
33
+ * children of the stack's view, over the screens and the bar; a FAB that leaves goes as a copy ([FabCopy]). Main
34
+ * thread only.
24
35
  */
25
36
  internal class FabPresenter(
26
37
  private val activity: Activity,
@@ -38,38 +49,75 @@ internal class FabPresenter(
38
49
  var source: ViewController<*>? = null
39
50
  private set
40
51
 
52
+ // The ride of the FAB that shows as it arrives; none at rest.
53
+ private var ride: Animator? = null
54
+ // The copies of the FABs that leave, each with its ride.
55
+ private val copies = LinkedHashMap<FabCopy, Animator>()
56
+
57
+ // The top's FAB while a back gesture's preview shows the screen under the top with its own: out of the stack, as
58
+ // it was (hidden by the scroll, say).
59
+ private class Aside(
60
+ val fab: Fab?,
61
+ val menu: FabMenu?,
62
+ val shownId: String?,
63
+ var source: ViewController<*>?,
64
+ val alignStart: Boolean,
65
+ )
66
+
67
+ private var aside: Aside? = null
68
+
41
69
  private val view: View?
42
70
  get() = menu ?: fab
43
71
 
72
+ /** The view of the FAB or of its menu that shows; none. */
73
+ val shownView: View?
74
+ get() = view
75
+
44
76
  /**
45
- * The screen on top became [source], with its resolved [options]: the same id updates the FAB that shows and grows
46
- * it again, another id replaces it, none takes it away; the scroll of [scroll] hides it with `hideOnScroll`.
47
- * Nothing when [source] already shows it.
77
+ * The screen on top became [source], with its resolved [options], in a transition that goes by [move]: the same id
78
+ * updates the FAB that shows, where it stays as it is, another id replaces it, none takes it away — the new FAB
79
+ * arrives and a copy of the old one leaves by [move]; the scroll of [scroll] hides it with `hideOnScroll`. An open
80
+ * menu closes. The copies of an older transition go, and with [FabMotion.Move.AtOnce] a FAB still riding comes to
81
+ * rest. Nothing when [source] already shows it.
48
82
  */
49
- fun showFor(layout: StackLayout, source: ViewController<*>?, options: FabOptions, scroll: ScrollEventListener?) {
83
+ fun showFor(
84
+ layout: StackLayout,
85
+ source: ViewController<*>?,
86
+ options: FabOptions,
87
+ scroll: ScrollEventListener?,
88
+ move: FabMotion.Move = FabMotion.Move.Swap,
89
+ ) {
90
+ // At once, what still moves comes to rest, also when the top stays (a failed push).
91
+ if (move == FabMotion.Move.AtOnce) {
92
+ dropCopies()
93
+ stopRide(rest = true)
94
+ }
50
95
  if (source === this.source && this.layout === layout) return
51
96
  this.layout = layout
52
- disableCollapse()
97
+ dropCopies()
53
98
  this.source = source
54
99
  when (FabPlan.step(shownId, menu != null, options)) {
55
100
  FabPlan.Step.None -> Unit
56
- FabPlan.Step.Remove -> remove()
57
- FabPlan.Step.Create -> create(layout, options, scroll)
101
+ FabPlan.Step.Remove -> leave(layout, move)
102
+ FabPlan.Step.Create -> {
103
+ create(layout, options, scroll)
104
+ arrive(move)
105
+ }
58
106
  FabPlan.Step.Replace -> {
59
- remove()
107
+ leave(layout, move)
60
108
  create(layout, options, scroll)
109
+ arrive(move)
61
110
  }
62
111
  FabPlan.Step.Update -> {
112
+ disableCollapse()
113
+ menu?.close()
63
114
  apply(options, scroll)
64
115
  // A new top whose options don't hide it shows it, even where the screen before hid it.
65
116
  if (!options.visible.isFalse) {
66
117
  fab?.show()
67
118
  menu?.show()
68
119
  }
69
- view?.let {
70
- it.bringToFront()
71
- grow(it)
72
- }
120
+ view?.bringToFront()
73
121
  }
74
122
  }
75
123
  }
@@ -83,11 +131,15 @@ internal class FabPresenter(
83
131
  this.source = source
84
132
  when (FabPlan.step(shownId, menu != null, options)) {
85
133
  FabPlan.Step.None -> Unit
86
- FabPlan.Step.Remove -> remove()
87
- FabPlan.Step.Create -> create(layout, options, scroll)
134
+ FabPlan.Step.Remove -> leave(layout, FabMotion.Move.Swap)
135
+ FabPlan.Step.Create -> {
136
+ create(layout, options, scroll)
137
+ arrive(FabMotion.Move.Swap)
138
+ }
88
139
  FabPlan.Step.Replace -> {
89
- remove()
140
+ leave(layout, FabMotion.Move.Swap)
90
141
  create(layout, options, scroll)
142
+ arrive(FabMotion.Move.Swap)
91
143
  }
92
144
  FabPlan.Step.Update -> apply(options, scroll)
93
145
  }
@@ -130,13 +182,57 @@ internal class FabPresenter(
130
182
  view.layoutParams = params
131
183
  }
132
184
 
185
+ /**
186
+ * A back gesture's preview shows the screen under the top: the FAB that shows goes aside, out of the stack but as it
187
+ * is, its menu closing, until [bringBack] or [dropAside]; the screen's own FAB shows next ([showFor]).
188
+ */
189
+ fun setAside() {
190
+ if (aside != null) return
191
+ dropCopies()
192
+ stopRide(rest = true)
193
+ menu?.close()
194
+ view?.let { (it.parent as? ViewGroup)?.removeView(it) }
195
+ aside = Aside(fab, menu, shownId, source, alignStart)
196
+ fab = null
197
+ menu = null
198
+ shownId = null
199
+ source = null
200
+ }
201
+
202
+ /** The gesture was cancelled: the FAB the preview showed goes, and the one set aside is back as it was. */
203
+ fun bringBack() {
204
+ val kept = aside ?: return
205
+ aside = null
206
+ val layout = layout ?: return discard(kept)
207
+ leave(layout, FabMotion.Move.AtOnce)
208
+ fab = kept.fab
209
+ menu = kept.menu
210
+ shownId = kept.shownId
211
+ source = kept.source
212
+ alignStart = kept.alignStart
213
+ view?.let { layout.addOverAll(it, it.layoutParams as? CoordinatorLayout.LayoutParams ?: params()) }
214
+ place()
215
+ }
216
+
217
+ /** The gesture was released: the FAB set aside goes with the top that leaves. */
218
+ fun dropAside() {
219
+ val kept = aside ?: return
220
+ aside = null
221
+ discard(kept)
222
+ }
223
+
133
224
  /** [node] was destroyed: a FAB it showed sends nothing more. */
134
225
  fun forget(node: ViewController<*>) {
135
226
  if (source === node) source = null
227
+ aside?.let { if (it.source === node) it.source = null }
136
228
  }
137
229
 
138
- /** The stack goes: the FAB and its menu go at once, the scrim first. */
230
+ /** The stack goes: the FAB and its menu go at once, the scrim first, and the copies that leave. */
139
231
  fun destroy() {
232
+ aside?.let(::discard)
233
+ aside = null
234
+ dropCopies()
235
+ stopRide(rest = false)
140
236
  disableCollapse()
141
237
  menu?.let {
142
238
  it.removeScrim()
@@ -153,7 +249,7 @@ internal class FabPresenter(
153
249
  private fun create(layout: StackLayout, options: FabOptions, scroll: ScrollEventListener?) {
154
250
  val id = FabPlan.idOf(options) ?: return
155
251
  shownId = id
156
- val params = CoordinatorLayout.LayoutParams(WRAP, WRAP)
252
+ val params = params()
157
253
  if (FabPlan.isMenu(options)) {
158
254
  val menu = FabMenu(activity, id)
159
255
  this.menu = menu
@@ -164,7 +260,6 @@ internal class FabPresenter(
164
260
  layout.addOverAll(fab, params)
165
261
  }
166
262
  apply(options, scroll)
167
- view?.let(::grow)
168
263
  }
169
264
 
170
265
  // Every option of the FAB that shows; the collapse before the visibility, which `disableCollapse` would undo.
@@ -172,19 +267,20 @@ internal class FabPresenter(
172
267
  alignStart = options.alignHorizontally.get("right") == "left"
173
268
  val source = source
174
269
  fab?.let { fab ->
175
- applyButton(fab, options)
270
+ applyButton(fab, options, mayWait = fab.drawable != null || options.visible.isFalse)
176
271
  TestIds.apply(fab, options.testID.takeIf { it.hasValue() }?.get())
177
272
  val id = shownId.orEmpty()
178
273
  fab.setOnClickListener { press(source, id) }
179
274
  }
180
275
  menu?.let { menu ->
181
- applyButton(menu.main, options)
276
+ applyButton(menu.main, options, mayWait = menu.main.drawable != null || options.visible.isFalse)
182
277
  TestIds.apply(menu.main, options.testID.takeIf { it.hasValue() }?.get())
183
278
  menu.scrimColor = options.scrimColor.get(activity, null)
184
279
  menu.setActions(options.actions.orEmpty().map { action ->
185
280
  val actionId = action.id.get("")
186
281
  Fab(activity, actionId).also { button ->
187
- applyButton(button, action)
282
+ // The actions show only while the menu is open.
283
+ applyButton(button, action, mayWait = !menu.isOpen)
188
284
  TestIds.apply(button, action.testID.takeIf { it.hasValue() }?.get())
189
285
  button.setOnClickListener {
190
286
  press(source, actionId)
@@ -205,9 +301,10 @@ internal class FabPresenter(
205
301
  place()
206
302
  }
207
303
 
208
- private fun applyButton(button: Fab, options: FabOptions) {
304
+ // [mayWait]: the button can take its icon when it is ready (it shows one, or it stays hidden), see [Fab.applyIcon].
305
+ private fun applyButton(button: Fab, options: FabOptions, mayWait: Boolean) {
209
306
  val icon = options.icon.takeIf { it.hasValue() }?.get()?.ifEmpty { null }
210
- if (icon != null) button.applyIcon(icon, options.iconColor)
307
+ if (icon != null) button.applyIcon(icon, options.iconColor, mayWait)
211
308
  applyColors(button, options)
212
309
  button.setMini(options.size.get("regular") == "mini")
213
310
  }
@@ -233,43 +330,120 @@ internal class FabPresenter(
233
330
  menu?.disableCollapse()
234
331
  }
235
332
 
236
- // The FAB that shows goes: a button shrinks to 0 in 200 ms; a menu goes at once, its scrim first.
237
- private fun remove() {
333
+ // The FAB that shows goes with its screen: a copy of it leaves by [move] while the button, or the menu, goes from the
334
+ // stack at once; an open menu closes, its scrim fading out by itself. At once nothing leaves, the scrim neither.
335
+ private fun leave(layout: StackLayout, move: FabMotion.Move) {
336
+ val view = view ?: return
337
+ val departure = FabMotion.departure(move, isRtl(layout))
338
+ val copy = departure?.let { FabCopy.of((view as? FabMenu)?.main ?: view, view, layout) }
339
+ stopRide(rest = false)
340
+ disableCollapse()
238
341
  menu?.let {
239
- it.removeScrim()
342
+ if (departure != null) it.closeToLeave() else it.removeScrim()
240
343
  (it.parent as? ViewGroup)?.removeView(it)
241
344
  }
242
- fab?.let { fab ->
243
- fab.animate().cancel()
244
- if (!fab.isAttachedToWindow) {
245
- (fab.parent as? ViewGroup)?.removeView(fab)
246
- } else {
247
- fab.animate().scaleX(0f).scaleY(0f).setDuration(ANIMATION_MILLIS)
248
- .withEndAction { (fab.parent as? ViewGroup)?.removeView(fab) }.start()
249
- }
250
- }
345
+ fab?.let { (it.parent as? ViewGroup)?.removeView(it) }
251
346
  menu = null
252
347
  fab = null
253
348
  shownId = null
349
+ if (copy == null) return
350
+ copies[copy] = play(copy, departure, fromCurrent = true) { copies.remove(copy)?.let { removeCopy(copy) } }
351
+ }
352
+
353
+ // The new FAB arrives with its screen by [move]; one its options hide (`visible: false`) has nothing to show.
354
+ private fun arrive(move: FabMotion.Move) {
355
+ val view = view ?: return
356
+ if (((view as? FabMenu)?.main ?: view).visibility != View.VISIBLE) return
357
+ val arrival = FabMotion.arrival(move, layout?.let(::isRtl) ?: false) ?: return
358
+ ride = play(view, arrival, fromCurrent = false) { animator -> if (ride === animator) ride = null }
359
+ }
360
+
361
+ // A ride stops where it is; [rest]: the FAB is in its place again, opaque and whole.
362
+ private fun stopRide(rest: Boolean) {
363
+ val running = ride ?: return
364
+ ride = null
365
+ running.cancel()
366
+ if (!rest) return
367
+ view?.apply {
368
+ translationX = 0f
369
+ alpha = 1f
370
+ scaleX = 1f
371
+ scaleY = 1f
372
+ }
373
+ }
374
+
375
+ // The copies of an older transition go at once.
376
+ private fun dropCopies() {
377
+ if (copies.isEmpty()) return
378
+ val dropped = copies.toList()
379
+ copies.clear()
380
+ dropped.forEach { (copy, animator) ->
381
+ animator.cancel()
382
+ removeCopy(copy)
383
+ }
254
384
  }
255
385
 
256
- // It comes to the top and grows from 60 % in 200 ms.
257
- private fun grow(view: View) {
258
- val target = (view as? FabMenu)?.main ?: view
259
- target.animate().cancel()
260
- target.scaleX = GROW_FROM
261
- target.scaleY = GROW_FROM
262
- target.animate().scaleX(1f).scaleY(1f).setDuration(ANIMATION_MILLIS).start()
386
+ private fun removeCopy(copy: FabCopy) {
387
+ (copy.parent as? ViewGroup)?.removeView(copy)
263
388
  }
264
389
 
390
+ // Plays [ride] on [view], from its start values or [fromCurrent] from where the view is; [end] at its end or stop.
391
+ private fun play(view: View, ride: FabMotion.Ride, fromCurrent: Boolean, end: (Animator) -> Unit): Animator {
392
+ val density = activity.resources.displayMetrics.density
393
+ if (!fromCurrent) {
394
+ view.translationX = ride.fromX * density
395
+ view.alpha = ride.fromAlpha
396
+ view.scaleX = ride.fromScale
397
+ view.scaleY = ride.fromScale
398
+ }
399
+ val move = ObjectAnimator.ofPropertyValuesHolder(
400
+ view,
401
+ PropertyValuesHolder.ofFloat(View.TRANSLATION_X, ride.toX * density),
402
+ PropertyValuesHolder.ofFloat(View.SCALE_X, ride.toScale),
403
+ PropertyValuesHolder.ofFloat(View.SCALE_Y, ride.toScale),
404
+ ).apply {
405
+ duration = ride.duration
406
+ interpolator = when (ride.curve) {
407
+ FabMotion.Curve.System -> SystemTransition.CURVE
408
+ FabMotion.Curve.FadeThrough -> FadeThrough.CURVE
409
+ FabMotion.Curve.Material -> AccelerateDecelerateInterpolator()
410
+ }
411
+ }
412
+ val animator = AnimatorSet()
413
+ if (ride.alphaDuration > 0) {
414
+ val fade = ObjectAnimator.ofFloat(view, View.ALPHA, ride.toAlpha).apply {
415
+ startDelay = ride.alphaDelay
416
+ duration = ride.alphaDuration
417
+ interpolator = LinearInterpolator()
418
+ }
419
+ animator.playTogether(move, fade)
420
+ } else {
421
+ animator.play(move)
422
+ }
423
+ animator.addListener(object : AnimatorListenerAdapter() {
424
+ override fun onAnimationEnd(animation: Animator) = end(animation)
425
+ })
426
+ animator.start()
427
+ return animator
428
+ }
429
+
430
+ // A FAB set aside that won't come back: it follows no scroll, its scrim goes.
431
+ private fun discard(kept: Aside) {
432
+ kept.fab?.disableCollapse()
433
+ kept.menu?.disableCollapse()
434
+ kept.menu?.removeScrim()
435
+ }
436
+
437
+ private fun params() = CoordinatorLayout.LayoutParams(WRAP, WRAP)
438
+
439
+ private fun isRtl(layout: StackLayout): Boolean = layout.layoutDirection == View.LAYOUT_DIRECTION_RTL
440
+
265
441
  companion object {
266
442
  private const val WRAP = ViewGroup.LayoutParams.WRAP_CONTENT
267
- private const val ANIMATION_MILLIS = 200L
268
- private const val GROW_FROM = 0.6f
269
443
 
270
444
  /**
271
445
  * A press on the FAB, or on an action of its menu, of [source] (EVT-NavigationButtonPressed): nothing once
272
- * [source] is destroyed — its FAB still fades for 200 ms.
446
+ * [source] is destroyed.
273
447
  */
274
448
  fun press(source: ViewController<*>?, buttonId: String) {
275
449
  if (source == null || source.isDestroyed) return
@@ -36,6 +36,8 @@ import dev.apexnative.navigation.views.stack.topbar.search.SuggestionList
36
36
  class ScreenSearch(
37
37
  private val host: Host,
38
38
  private val screenId: String,
39
+ /** The sender of the JavaScript the screen was made for: silent once it went. */
40
+ private val emitter: EventEmitter,
39
41
  private val context: Context,
40
42
  private val loadIcon: (String) -> Drawable?,
41
43
  /** A scope the user picks goes into the screen's options, so it stays when they apply again. */
@@ -45,7 +47,6 @@ class ScreenSearch(
45
47
  /** The search changed what the bar shows (open or closed, its text): shown again if it is the shown one. */
46
48
  fun refresh(search: ScreenSearch)
47
49
  fun isShown(search: ScreenSearch): Boolean
48
- fun emitter(): EventEmitter?
49
50
  fun keyboard(view: View, show: Boolean)
50
51
  /** The stack's view: a search view goes over it. */
51
52
  fun stackView(): ViewGroup?
@@ -402,7 +403,7 @@ class ScreenSearch(
402
403
 
403
404
  // A pick sends searchSuggestionPicked with the suggestion's id; the text stays.
404
405
  private fun pickSuggestion(suggestionId: String) {
405
- host.emitter()?.emitSearchSuggestionPicked(screenId, suggestionId)
406
+ emitter.emitSearchSuggestionPicked(screenId, suggestionId)
406
407
  setSuggestions(emptyList())
407
408
  }
408
409
 
@@ -426,18 +427,15 @@ class ScreenSearch(
426
427
  private fun sendUpdate(
427
428
  focused: Boolean = isActive && (panel?.searchView?.editText ?: searchField.editText).hasFocus(),
428
429
  ) {
429
- val emitter = host.emitter() ?: return
430
430
  eventTargets().forEach { emitter.emitSearchBarUpdated(it, text, focused, scope()) }
431
431
  }
432
432
 
433
433
  private fun sendCancel() {
434
- val emitter = host.emitter() ?: return
435
434
  eventTargets().forEach { emitter.emitSearchBarCancelPressed(it) }
436
435
  sendUpdate()
437
436
  }
438
437
 
439
438
  private fun sendSubmit() {
440
- val emitter = host.emitter() ?: return
441
439
  eventTargets().forEach { emitter.emitSearchBarSubmitted(it, text, scope()) }
442
440
  }
443
441
 
@@ -3,8 +3,6 @@ package dev.apexnative.navigation.viewcontrollers.stack.search
3
3
  import android.app.Activity
4
4
  import android.content.Context
5
5
  import android.graphics.drawable.Drawable
6
- import android.view.Menu
7
- import android.view.MenuItem
8
6
  import android.view.View
9
7
  import android.view.ViewGroup
10
8
  import androidx.appcompat.R as AppCompatR
@@ -12,17 +10,17 @@ import androidx.appcompat.content.res.AppCompatResources
12
10
  import androidx.coordinatorlayout.widget.CoordinatorLayout
13
11
  import androidx.core.view.WindowCompat
14
12
  import androidx.core.view.WindowInsetsCompat
15
- import com.facebook.react.ReactApplication
16
13
  import dev.apexnative.navigation.options.SearchBarOptions
17
- import dev.apexnative.navigation.options.params.Text
18
14
  import dev.apexnative.navigation.options.params.ThemeColour
19
15
  import dev.apexnative.navigation.react.events.EventEmitter
16
+ import dev.apexnative.navigation.utils.TestIds
20
17
  import dev.apexnative.navigation.utils.dp
21
18
  import dev.apexnative.navigation.viewcontrollers.parent.OptionsScreen
22
19
  import dev.apexnative.navigation.viewcontrollers.viewcontroller.ViewController
23
20
  import dev.apexnative.navigation.views.stack.topbar.TopBar
24
21
  import dev.apexnative.navigation.views.stack.topbar.TopBarDefaults
25
22
  import dev.apexnative.navigation.views.stack.topbar.search.SearchStyle
23
+ import dev.apexnative.navigation.views.stack.topbar.titlebar.BarButtonView
26
24
 
27
25
  /**
28
26
  * The search of the screens of a stack (`topBar.searchBar`): each screen has its own while it is in the stack, and the
@@ -40,6 +38,7 @@ class StackSearchPresenter(
40
38
  private var suggestions: View? = null
41
39
  private var wasActive = false
42
40
  private var onActiveChanged: Runnable? = null
41
+ private var magnifier: BarButtonView? = null
43
42
 
44
43
  /** The search of the screen on top opened or closed: the bar's hideOnScroll stops or goes on. */
45
44
  fun setOnActiveChanged(listener: Runnable?) {
@@ -51,6 +50,7 @@ class StackSearchPresenter(
51
50
 
52
51
  fun bindTopBar(topBar: TopBar) {
53
52
  this.topBar = topBar
53
+ magnifier = null
54
54
  // The suggestions hang from the bar: they follow its height as the search opens and its scopes show.
55
55
  topBar.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ -> topBar.post { positionSuggestions(topBar) } }
56
56
  }
@@ -93,28 +93,29 @@ class StackSearchPresenter(
93
93
  return true
94
94
  }
95
95
 
96
- /** After the right buttons change: the magnifier of an integrated search goes back among them, last. */
96
+ /**
97
+ * After the right buttons change: the magnifier of an integrated search stands after them, before "⋮", as a button
98
+ * of the bar, with the id `<topBar.searchBar.testID>.button`.
99
+ */
97
100
  fun applyMagnifier() {
98
101
  val bar = topBar ?: return
99
- val menu = bar.rightButtonBar.menu
100
- val item = menu.findItem(MAGNIFIER_ID)
101
- if (shown?.showsMagnifier != true) {
102
- if (item != null) menu.removeItem(MAGNIFIER_ID)
102
+ val row = bar.rightButtonBar
103
+ val search = shown
104
+ if (search?.showsMagnifier != true) {
105
+ row.setTrailing(null)
103
106
  return
104
107
  }
105
- if (item != null) return
106
- val context = styleContext()
107
- val label = context.getString(AppCompatR.string.abc_searchview_description_search)
108
- menu.add(Menu.NONE, MAGNIFIER_ID, MAGNIFIER_ORDER, label).apply {
109
- icon = AppCompatResources.getDrawable(context, AppCompatR.drawable.abc_ic_search_api_material)?.mutate()?.also {
110
- it.setTint(TopBarDefaults.overflowIconColor(context))
111
- }
112
- setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)
113
- setOnMenuItemClickListener {
114
- shown?.activate()
115
- true
116
- }
108
+ val button = magnifier ?: BarButtonView(row.context).also { button ->
109
+ val context = styleContext()
110
+ val icon = AppCompatResources.getDrawable(context, AppCompatR.drawable.abc_ic_search_api_material)?.mutate()
111
+ icon?.setTint(TopBarDefaults.overflowIconColor(context))
112
+ val label = context.getString(AppCompatR.string.abc_searchview_description_search)
113
+ button.show(label, icon, null, true)
114
+ button.setOnClickListener { shown?.activate() }
115
+ magnifier = button
117
116
  }
117
+ TestIds.apply(button, search.options.testID.get(null)?.let { "$it.button" })
118
+ row.setTrailing(button)
118
119
  }
119
120
 
120
121
  override fun refresh(search: ScreenSearch) {
@@ -134,13 +135,12 @@ class StackSearchPresenter(
134
135
  fun onConfigurationChanged(tint: ThemeColour) {
135
136
  shown?.takeTint(tint)
136
137
  searches.values.forEach { it.restyle() }
137
- topBar?.rightButtonBar?.menu?.removeItem(MAGNIFIER_ID)
138
+ // The magnifier is made again in the new mode's colors.
139
+ magnifier = null
140
+ topBar?.rightButtonBar?.setTrailing(null)
138
141
  refresh()
139
142
  }
140
143
 
141
- override fun emitter(): EventEmitter? =
142
- (activity.application as? ReactApplication)?.reactHost?.currentReactContext?.let { EventEmitter(it) }
143
-
144
144
  override fun keyboard(view: View, show: Boolean) {
145
145
  val controller = WindowCompat.getInsetsController(activity.window, view)
146
146
  if (show) controller.show(WindowInsetsCompat.Type.ime()) else controller.hide(WindowInsetsCompat.Type.ime())
@@ -148,10 +148,12 @@ class StackSearchPresenter(
148
148
 
149
149
  private fun searchOf(screen: ViewController<*>): ScreenSearch =
150
150
  searches.getOrPut(screen.view) {
151
- // The search of a pair of screens is its primary's: its events name that screen, which keeps the scope.
151
+ // The search of a pair of screens is its primary's: its events name that screen, which keeps the scope in
152
+ // its user layer, where a merge that sends the same options again doesn't take it away.
152
153
  val owner = (screen as? OptionsScreen)?.optionsScreen ?: screen
153
- ScreenSearch(this, owner.id, styleContext(), loadIcon) { scope ->
154
- owner.changeOptions { it.topBar.searchBar.selectedScope = Text(scope) }
154
+ // Its events go to the JavaScript the screen was made for, and to no other.
155
+ ScreenSearch(this, owner.id, EventEmitter.of(owner.jsGeneration), styleContext(), loadIcon) { scope ->
156
+ owner.changeChoices { it.pickScope(scope) }
155
157
  }
156
158
  }
157
159
 
@@ -234,10 +236,4 @@ class StackSearchPresenter(
234
236
  lp.topMargin = top
235
237
  card.layoutParams = lp
236
238
  }
237
-
238
- private companion object {
239
- val MAGNIFIER_ID = View.generateViewId()
240
- // The highest a menu order goes: after the screen's own buttons.
241
- const val MAGNIFIER_ORDER = 0xFFFF
242
- }
243
239
  }
@@ -5,7 +5,6 @@ import dev.apexnative.navigation.options.Options
5
5
  import dev.apexnative.navigation.options.TitleComponentOptions
6
6
  import dev.apexnative.navigation.options.TopBarBackgroundComponentOptions
7
7
  import dev.apexnative.navigation.options.params.Text
8
- import dev.apexnative.navigation.viewcontrollers.component.ScreenReadiness
9
8
  import dev.apexnative.navigation.viewcontrollers.viewcontroller.IReactView
10
9
  import dev.apexnative.navigation.viewcontrollers.viewcontroller.ViewController
11
10
 
@@ -15,7 +14,8 @@ import dev.apexnative.navigation.viewcontrollers.viewcontroller.ViewController
15
14
  * same root, never made again; another replaces it, and the old one stops at once. A background with the same `name`
16
15
  * and `componentId` on several screens is one root, shared; it stops when no screen of the stack names it any more. The
17
16
  * roots go with their screen ([screenDestroyed]) or the stack ([destroyAll]). Each root renders at once, without
18
- * waiting for its layout: [makeRoot] marks its id so before its surface starts. Main thread only.
17
+ * waiting for its layout: [makeRoot] makes it so (`ReactView`'s `rendersAtOnce`), and each answers by its own render
18
+ * when several live roots show one id (`ScreenReadiness`). Main thread only.
19
19
  */
20
20
  internal class BarComponents(private val makeRoot: (componentId: String, name: String) -> IReactView) {
21
21
  /** A root of the bar: what it renders, and its content. */
@@ -151,18 +151,10 @@ internal class BarComponents(private val makeRoot: (componentId: String, name: S
151
151
  backgrounds.remove(key)?.let(::stop)
152
152
  }
153
153
 
154
- // Made first, counted after: the maker asks whether another root with the id lives.
155
- private fun make(key: Key): Root {
156
- val root = Root(key.name, key.componentId, makeRoot(key.componentId, key.name))
157
- LiveIds.add(key.componentId)
158
- return root
159
- }
154
+ private fun make(key: Key): Root = Root(key.name, key.componentId, makeRoot(key.componentId, key.name))
160
155
 
161
- // Stops a root once; what the readiness store kept of its id goes unless another live root holds the id.
162
- private fun stop(root: Root) {
163
- root.view.destroy()
164
- if (LiveIds.remove(root.componentId)) ScreenReadiness.remove(root.componentId)
165
- }
156
+ // Stops a root once; its content takes its mark of rendering at once with it.
157
+ private fun stop(root: Root) = root.view.destroy()
166
158
 
167
159
  private fun keyOf(name: Text, componentId: Text, id: Text): Key? {
168
160
  val componentName = name.get(null)?.takeIf { it.isNotEmpty() } ?: return null
@@ -170,42 +162,4 @@ internal class BarComponents(private val makeRoot: (componentId: String, name: S
170
162
  ?: return null
171
163
  return Key(componentName, rootId)
172
164
  }
173
-
174
- companion object {
175
- /** Whether a bar root with [id] is alive now, in any stack. */
176
- fun isLive(id: String): Boolean = LiveIds.has(id)
177
-
178
- /**
179
- * Another root that renders at once lives with [id] (a cell of the tabs' custom row): it counts as the bar's
180
- * roots do, so a root that stops clears the id's readiness only when it was the last one with it.
181
- */
182
- internal fun rootMade(id: String) = LiveIds.add(id)
183
-
184
- /** A root of [rootMade] stopped; true when no live root has [id] any more. */
185
- internal fun rootStopped(id: String): Boolean = LiveIds.remove(id)
186
-
187
- /** The JavaScript went (a reload): no id counts as held by a live root any more, as `ScreenReadiness.reset`. */
188
- fun reset() = LiveIds.clear()
189
- }
190
-
191
- // The ids of the bar roots alive now, in every stack: a root that stops clears its id's readiness only when it was
192
- // the last one with it.
193
- private object LiveIds {
194
- private val counts = HashMap<String, Int>()
195
-
196
- fun has(id: String): Boolean = (counts[id] ?: 0) > 0
197
-
198
- fun clear() = counts.clear()
199
-
200
- fun add(id: String) {
201
- counts[id] = (counts[id] ?: 0) + 1
202
- }
203
-
204
- // True when no root with the id is left.
205
- fun remove(id: String): Boolean {
206
- val count = (counts[id] ?: return true) - 1
207
- if (count <= 0) counts.remove(id) else counts[id] = count
208
- return count <= 0
209
- }
210
- }
211
165
  }