@apexnative/navigation 1.0.0-alpha.0 → 1.0.0-alpha.10

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 (574) hide show
  1. package/ApexNavigation.podspec +2 -1
  2. package/CHANGELOG.md +128 -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/SecondaryScreenPresenter.kt +13 -5
  67. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/AppliedTabCalls.kt +49 -0
  68. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsCollapseBehavior.kt +5 -3
  69. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsController.kt +108 -34
  70. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsPresenter.kt +25 -24
  71. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowGeometry.kt +22 -0
  72. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabItems.kt +3 -3
  73. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabsRoom.kt +0 -5
  74. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentPresenter.kt +28 -7
  75. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentViewController.kt +12 -9
  76. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ContentReadiness.kt +2 -2
  77. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/RenderWait.kt +27 -7
  78. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenFrame.kt +1 -1
  79. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenReadiness.kt +103 -56
  80. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenSafeArea.kt +29 -11
  81. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/externalcomponent/ExternalComponentViewController.kt +2 -6
  82. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalAnimations.kt +22 -24
  83. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalCoordinator.kt +109 -21
  84. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalRecord.kt +21 -6
  85. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalSheet.kt +476 -73
  86. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalViews.kt +57 -25
  87. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetBack.kt +42 -0
  88. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetStops.kt +83 -0
  89. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/BackCallbackCheck.kt +50 -0
  90. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/BackCallbackState.kt +49 -14
  91. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/Navigator.kt +71 -12
  92. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/RootCoordinator.kt +37 -11
  93. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/overlay/OverlayCoordinator.kt +10 -8
  94. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/Capabilities.kt +11 -4
  95. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ContainerBackground.kt +3 -3
  96. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ParentController.kt +6 -6
  97. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuController.kt +42 -9
  98. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuMotion.kt +19 -8
  99. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuPresenter.kt +16 -7
  100. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuRules.kt +43 -4
  101. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitPanes.kt +23 -0
  102. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitViewController.kt +77 -17
  103. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/BackPreview.kt +315 -0
  104. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/PreparedFrame.kt +3 -3
  105. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackCommands.kt +30 -20
  106. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackController.kt +216 -18
  107. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackDisplay.kt +26 -1
  108. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackQueue.kt +149 -41
  109. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackTransitions.kt +26 -8
  110. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackViews.kt +115 -6
  111. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabMotion.kt +142 -0
  112. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabPresenter.kt +222 -48
  113. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/ScreenSearch.kt +3 -5
  114. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/StackSearchPresenter.kt +30 -34
  115. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/BarComponents.kt +5 -51
  116. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/BarRowTransition.kt +3 -2
  117. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/ButtonPlaces.kt +11 -5
  118. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/MenuChecks.kt +13 -56
  119. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarPresenter.kt +219 -54
  120. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarVisibility.kt +9 -2
  121. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ScrollEventListener.kt +6 -9
  122. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ViewController.kt +75 -21
  123. package/android/src/main/java/dev/apexnative/navigation/views/animations/AnimationLayer.kt +73 -0
  124. package/android/src/main/java/dev/apexnative/navigation/views/animations/Curves.kt +29 -11
  125. package/android/src/main/java/dev/apexnative/navigation/views/animations/ValueInterpolation.kt +14 -0
  126. package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabs.kt +9 -7
  127. package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabsLayout.kt +61 -2
  128. package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomBottomTabItemView.kt +0 -5
  129. package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomTabRow.kt +72 -10
  130. package/android/src/main/java/dev/apexnative/navigation/views/element/ElementStep.kt +31 -0
  131. package/android/src/main/java/dev/apexnative/navigation/views/element/ElementTransitions.kt +143 -135
  132. package/android/src/main/java/dev/apexnative/navigation/views/element/TargetsWait.kt +13 -5
  133. package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionLayer.kt +37 -112
  134. package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionTargets.kt +9 -6
  135. package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionViews.kt +100 -0
  136. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ElementPictures.kt +112 -4
  137. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/FlightGeometry.kt +346 -36
  138. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMorph.kt +199 -0
  139. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/SharedAnimatorFactory.kt +56 -41
  140. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextMorph.kt +176 -0
  141. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewMorph.kt +108 -0
  142. package/android/src/main/java/dev/apexnative/navigation/views/sidemenu/SideMenuView.kt +12 -3
  143. package/android/src/main/java/dev/apexnative/navigation/views/stack/ScreenEdge.kt +45 -0
  144. package/android/src/main/java/dev/apexnative/navigation/views/stack/StackLayout.kt +140 -1
  145. package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/Fab.kt +14 -10
  146. package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabCopy.kt +85 -0
  147. package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabMenu.kt +13 -0
  148. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TitleBar.kt +5 -17
  149. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TopBar.kt +73 -34
  150. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonComponentCell.kt +6 -6
  151. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonView.kt +113 -0
  152. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarMenu.kt +219 -0
  153. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonBar.kt +125 -178
  154. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonMenus.kt +34 -64
  155. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonRow.kt +216 -0
  156. package/android/src/main/jni/ANNContentHeights.cpp +82 -0
  157. package/android/src/main/res/drawable/apex_navigation_ic_arrow_right.xml +14 -0
  158. package/android/src/main/res/layout/apex_navigation_menu_header.xml +19 -0
  159. package/android/src/main/res/layout/apex_navigation_menu_item.xml +68 -0
  160. package/android/src/main/res/values/styles.xml +1 -1
  161. package/android/src/main/res/values-night/styles.xml +1 -1
  162. package/cli/app.js +1 -1
  163. package/cli/doctor/checks/app.js +77 -14
  164. package/cli/doctor/checks/splash.js +4 -22
  165. package/cli/migrate/native.js +18 -0
  166. package/cli/project.js +10 -2
  167. package/cli/setup/index.js +18 -0
  168. package/cli/setup/source.js +2 -1
  169. package/cli/setup/steps/appDelegate.js +66 -11
  170. package/cli/setup/steps/mainApplication.js +134 -19
  171. package/cli/setup/steps/metro.js +46 -0
  172. package/cli/setup/steps/sceneDelegate.js +108 -0
  173. package/cli/splash/index.js +3 -1
  174. package/cli/upgrade/changelog.js +2 -2
  175. package/docs-md/architecture/native-screens.md +4 -0
  176. package/docs-md/architecture/theme-and-context.md +131 -12
  177. package/docs-md/architecture/transitions.md +58 -12
  178. package/docs-md/containers/modals.md +8 -4
  179. package/docs-md/containers/overlays.md +3 -1
  180. package/docs-md/containers/side-menu.md +19 -2
  181. package/docs-md/containers/tabs.md +5 -1
  182. package/docs-md/flows/bottom-sheets.md +4 -2
  183. package/docs-md/flows/forms-in-a-modal.md +1 -1
  184. package/docs-md/fundamentals/screens-and-props.md +9 -1
  185. package/docs-md/fundamentals/starting-the-app.md +1 -1
  186. package/docs-md/guides/cli.md +4 -3
  187. package/docs-md/guides/deep-links.md +15 -33
  188. package/docs-md/help/glossary.md +4 -4
  189. package/docs-md/help/troubleshooting.md +44 -6
  190. package/docs-md/index.json +57 -1
  191. package/docs-md/migration/from-expo-router.md +1 -1
  192. package/docs-md/migration/from-react-native-navigation.md +9 -3
  193. package/docs-md/migration/from-react-navigation.md +2 -2
  194. package/docs-md/screen-ui/back-and-gestures.md +46 -2
  195. package/docs-md/screen-ui/bar-buttons.md +5 -5
  196. package/docs-md/screen-ui/search.md +1 -1
  197. package/docs-md/screen-ui/system-ui.md +17 -12
  198. package/docs-md/screen-ui/toolbar-and-fab.md +4 -2
  199. package/docs-md/screen-ui/top-bar.md +8 -4
  200. package/docs-md/start/installation.md +21 -3
  201. package/ios/Animations/ANNFrameDriver.h +55 -15
  202. package/ios/Animations/ANNFrameDriver.mm +216 -60
  203. package/ios/Animations/ANNTransitionAnimator.h +26 -5
  204. package/ios/Animations/ANNTransitionAnimator.mm +61 -13
  205. package/ios/Animations/ANNTransitionPlan.h +2 -2
  206. package/ios/Animations/ANNTransitionPlan.mm +10 -0
  207. package/ios/Animations/ANNTransitionWait.mm +6 -7
  208. package/ios/Animations/Elements/ANNElementFinder.h +57 -0
  209. package/ios/Animations/Elements/ANNElementFinder.mm +174 -2
  210. package/ios/Animations/Elements/ANNElementTransition.h +10 -8
  211. package/ios/Animations/Elements/ANNElementTransition.mm +19 -21
  212. package/ios/Animations/Elements/ANNSharedElementFlight.h +16 -11
  213. package/ios/Animations/Elements/ANNSharedElementFlight.mm +308 -69
  214. package/ios/Animations/Interpolators/ANNInterpolate.h +2 -30
  215. package/ios/Animations/Interpolators/ANNTransformParts.h +48 -0
  216. package/ios/Animations/Interpolators/ANNTransformParts.mm +507 -0
  217. package/ios/Animations/Interpolators/ANNViewTracks.h +9 -6
  218. package/ios/Animations/Interpolators/ANNViewTracks.mm +100 -30
  219. package/ios/CLAUDE.md +60 -24
  220. package/ios/CORE.md +44 -34
  221. package/ios/Contract/ANNCommandAnswer.h +13 -5
  222. package/ios/Contract/ANNCommandAnswer.mm +40 -32
  223. package/ios/Contract/ANNCommandContract.h +15 -0
  224. package/ios/Contract/ANNCommandContract.mm +78 -0
  225. package/ios/Contract/ANNCommandRunner.h +10 -9
  226. package/ios/Contract/ANNCommandRunner.mm +22 -28
  227. package/ios/Contract/ANNErrorTexts.h +6 -2
  228. package/ios/Contract/ANNErrorTexts.mm +18 -10
  229. package/ios/Contract/ANNLayoutNode.h +3 -3
  230. package/ios/Contract/ANNLayoutReader.h +3 -3
  231. package/ios/Core/ANNAppDelegate.mm +0 -2
  232. package/ios/Core/ANNAppearanceDispatcher.h +5 -4
  233. package/ios/Core/ANNAppearanceDispatcher.mm +12 -1
  234. package/ios/Core/ANNDeepLinkQueue.h +22 -2
  235. package/ios/Core/ANNDeepLinkQueue.mm +121 -14
  236. package/ios/Core/ANNErrorHandler.h +9 -4
  237. package/ios/Core/ANNErrorHandler.mm +20 -2
  238. package/ios/Core/ANNEventContract.h +246 -0
  239. package/ios/Core/ANNEventContract.mm +225 -0
  240. package/ios/Core/ANNEventEmitter.h +6 -2
  241. package/ios/Core/ANNEventEmitter.mm +117 -80
  242. package/ios/Core/ANNHinge.h +6 -0
  243. package/ios/Core/ANNHinge.mm +15 -4
  244. package/ios/Core/ANNJavaScriptCalls.h +33 -0
  245. package/ios/Core/ANNJavaScriptCalls.mm +52 -0
  246. package/ios/Core/ANNLayoutProtocol.h +5 -5
  247. package/ios/Core/ANNNavigationState.h +7 -5
  248. package/ios/Core/ANNNavigationState.mm +8 -7
  249. package/ios/Core/ANNNodeHelper.h +32 -12
  250. package/ios/Core/ANNNodeHelper.mm +100 -3
  251. package/ios/Core/ANNParking.h +5 -4
  252. package/ios/Core/ANNReloadCoordinator.mm +5 -12
  253. package/ios/Core/ANNRenderWait.h +20 -6
  254. package/ios/Core/ANNRenderWait.mm +143 -56
  255. package/ios/Core/ANNSceneDelegate.mm +25 -15
  256. package/ios/Core/ANNSystemUI.h +3 -2
  257. package/ios/Core/ANNSystemUI.mm +7 -0
  258. package/ios/Core/ANNUtils.h +7 -0
  259. package/ios/Core/ANNUtils.mm +10 -0
  260. package/ios/Core/ApexNavigation+Internal.h +1 -1
  261. package/ios/Core/ApexNavigation.mm +7 -6
  262. package/ios/Core/UIViewController+LayoutProtocol.h +9 -2
  263. package/ios/Core/UIViewController+LayoutProtocol.mm +8 -0
  264. package/ios/Layouts/Arrangement/ANNArrangementState.h +2 -17
  265. package/ios/Layouts/Arrangement/ANNArrangementState.mm +0 -38
  266. package/ios/Layouts/Arrangement/ANNArrangementViewController.mm +10 -8
  267. package/ios/Layouts/Modal/ANNModalCoordinator.h +1 -1
  268. package/ios/Layouts/Modal/ANNModalCoordinator.mm +57 -16
  269. package/ios/Layouts/Modal/ANNModalPresentation.h +8 -5
  270. package/ios/Layouts/Modal/ANNModalPresentation.mm +12 -12
  271. package/ios/Layouts/Modal/ANNSheetPresenter.mm +83 -1
  272. package/ios/Layouts/Overlay/ANNOverlayCoordinator.mm +2 -8
  273. package/ios/Layouts/Root/ANNRootCoordinator.mm +58 -19
  274. package/ios/Layouts/Root/ANNSplashViewController.h +5 -3
  275. package/ios/Layouts/Root/ANNSplashViewController.mm +147 -0
  276. package/ios/Layouts/Screen/ANNComponentPresenter.h +11 -3
  277. package/ios/Layouts/Screen/ANNComponentPresenter.mm +34 -6
  278. package/ios/Layouts/Screen/ANNComponentViewController.h +15 -13
  279. package/ios/Layouts/Screen/ANNComponentViewController.mm +130 -75
  280. package/ios/Layouts/Screen/ANNNativeScreenContext.mm +7 -5
  281. package/ios/Layouts/Screen/ANNPreviewInteraction.h +7 -4
  282. package/ios/Layouts/Screen/ANNPreviewInteraction.mm +72 -10
  283. package/ios/Layouts/Screen/ANNScreenEnvironment.h +63 -0
  284. package/ios/Layouts/Screen/ANNScreenEnvironment.mm +181 -0
  285. package/ios/Layouts/Screen/ANNScreenPlace.h +53 -0
  286. package/ios/Layouts/Screen/ANNScreenPlace.mm +205 -0
  287. package/ios/Layouts/Screen/ANNScreenRegions.h +3 -18
  288. package/ios/Layouts/Screen/ANNScreenRegions.mm +9 -44
  289. package/ios/Layouts/Screen/ANNScreenSafeArea.h +4 -9
  290. package/ios/Layouts/Screen/ANNScreenSafeArea.mm +14 -16
  291. package/ios/Layouts/Screen/ANNScreenSettling.h +32 -0
  292. package/ios/Layouts/Screen/ANNScreenSettling.mm +137 -0
  293. package/ios/Layouts/SideMenu/ANNSideMenuTypes.h +8 -0
  294. package/ios/Layouts/SideMenu/ANNSideMenuViewController.mm +83 -14
  295. package/ios/Layouts/SplitView/ANNSplitViewCommands.h +3 -2
  296. package/ios/Layouts/SplitView/ANNSplitViewCommands.mm +105 -39
  297. package/ios/Layouts/SplitView/ANNSplitViewController.mm +7 -8
  298. package/ios/Layouts/Stack/ANNPreviewPush.h +7 -6
  299. package/ios/Layouts/Stack/ANNPreviewPush.mm +142 -27
  300. package/ios/Layouts/Stack/ANNStackAnimatingDelegate.h +11 -2
  301. package/ios/Layouts/Stack/ANNStackAnimatingDelegate.mm +14 -7
  302. package/ios/Layouts/Stack/ANNStackCommands.mm +1 -0
  303. package/ios/Layouts/Stack/ANNStackController.h +8 -0
  304. package/ios/Layouts/Stack/ANNStackController.mm +184 -16
  305. package/ios/Layouts/Stack/ANNStackQueue.h +5 -2
  306. package/ios/Layouts/Stack/ANNStackQueue.mm +56 -43
  307. package/ios/Layouts/Stack/ANNSwipePopInteraction.h +26 -0
  308. package/ios/Layouts/Stack/ANNSwipePopInteraction.mm +185 -0
  309. package/ios/Layouts/Stack/InteractivePopGestureDelegate.mm +28 -4
  310. package/ios/Layouts/Stack/UINavigationController+ANNCommands.h +4 -2
  311. package/ios/Layouts/Stack/UINavigationController+ANNCommands.mm +2 -3
  312. package/ios/Layouts/Tabs/ANNBottomTabItemBuilder.h +4 -0
  313. package/ios/Layouts/Tabs/ANNBottomTabItemBuilder.mm +11 -0
  314. package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.h +12 -1
  315. package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.mm +23 -0
  316. package/ios/Layouts/Tabs/ANNBottomTabsController.h +3 -0
  317. package/ios/Layouts/Tabs/ANNBottomTabsController.mm +237 -57
  318. package/ios/Layouts/Tabs/ANNBottomTabsCustomRow.mm +8 -3
  319. package/ios/Layouts/Tabs/ANNBottomTabsPresenter.h +6 -2
  320. package/ios/Layouts/Tabs/ANNBottomTabsPresenter.mm +232 -43
  321. package/ios/Layouts/Tabs/ANNTabsDesign.h +6 -5
  322. package/ios/Layouts/Tabs/ANNTabsDesign.mm +9 -1
  323. package/ios/Layouts/Tabs/UITabBar+utils.h +5 -5
  324. package/ios/Layouts/Tabs/UITabBar+utils.mm +32 -13
  325. package/ios/Options/ANNAnimationOptions.h +2 -1
  326. package/ios/Options/ANNAnimationOptions.mm +1 -1
  327. package/ios/Options/ANNBottomTabsOptions.h +2 -0
  328. package/ios/Options/ANNBottomTabsOptions.mm +1 -0
  329. package/ios/Options/ANNOptions.h +25 -0
  330. package/ios/Options/ANNOptions.mm +157 -1
  331. package/ios/Options/ANNOptionsCache.h +7 -6
  332. package/ios/Options/ANNOptionsReader.mm +108 -0
  333. package/ios/Options/ANNSearchBarOptions.h +4 -3
  334. package/ios/Options/ANNSheetOptions.h +4 -1
  335. package/ios/Options/ANNSideMenuOptions.h +2 -0
  336. package/ios/Options/ANNSideMenuOptions.mm +2 -0
  337. package/ios/Options/ANNStackPopAnimationOptions.h +13 -0
  338. package/ios/Options/ANNStackPopAnimationOptions.mm +11 -0
  339. package/ios/Options/ANNUserChoice.h +57 -0
  340. package/ios/Options/ANNUserChoice.mm +44 -0
  341. package/ios/Options/Params/ANNImageSource.h +61 -0
  342. package/ios/Options/Params/ANNImageSource.mm +101 -0
  343. package/ios/Options/Params/ANNOptionImages.h +37 -0
  344. package/ios/Options/Params/ANNOptionImages.mm +284 -0
  345. package/ios/Options/Params/ANNParam.h +15 -0
  346. package/ios/Options/Params/ANNParam.mm +61 -0
  347. package/ios/Options/Params/Color.h +3 -0
  348. package/ios/Options/Params/Color.mm +21 -0
  349. package/ios/Options/Params/ColorParser.h +4 -3
  350. package/ios/Options/Params/ColorParser.mm +22 -4
  351. package/ios/Options/Params/Image.h +15 -2
  352. package/ios/Options/Params/Image.mm +35 -2
  353. package/ios/Options/Params/ImageParser.h +5 -5
  354. package/ios/Options/Params/ImageParser.mm +28 -46
  355. package/ios/Public/ApexNavigation/ANNSceneDelegate.h +3 -0
  356. package/ios/Public/ApexNavigation/ApexNavigation.h +1 -1
  357. package/ios/RECIPES.md +13 -6
  358. package/ios/React/ANNReactView.mm +6 -25
  359. package/ios/React/ANNSafeAreaViewComponentView.mm +28 -17
  360. package/ios/React/ANNSurfaceHostingView.h +14 -0
  361. package/ios/React/ANNSurfaceHostingView.mm +144 -1
  362. package/ios/React/Slots/ANNSlotComponentView.mm +24 -17
  363. package/ios/React/Slots/ANNSlotContainers.h +14 -6
  364. package/ios/React/Slots/ANNSlotContainers.mm +75 -2
  365. package/ios/React/Slots/ANNSlotHost.mm +1 -3
  366. package/ios/React/Slots/ANNSlotScreenView.mm +8 -2
  367. package/ios/TopBar/ANNBackButtonPresenter.mm +6 -5
  368. package/ios/TopBar/ANNBarAppearance.h +2 -1
  369. package/ios/TopBar/ANNBarAppearance.mm +111 -30
  370. package/ios/TopBar/ANNBarBackgroundComponent.mm +16 -0
  371. package/ios/TopBar/ANNBarButtonComponentView.h +4 -4
  372. package/ios/TopBar/ANNBarButtonComponentView.mm +1 -1
  373. package/ios/TopBar/ANNBarButtons.h +14 -8
  374. package/ios/TopBar/ANNBarButtons.mm +397 -80
  375. package/ios/TopBar/ANNIconButtonImage.h +1 -0
  376. package/ios/TopBar/ANNIconButtonImage.mm +34 -1
  377. package/ios/TopBar/ANNLargeTitlePresenter.h +13 -0
  378. package/ios/TopBar/ANNLargeTitlePresenter.mm +50 -7
  379. package/ios/TopBar/ANNMainList.h +3 -0
  380. package/ios/TopBar/ANNMainList.mm +4 -0
  381. package/ios/TopBar/ANNScrollEdgeEffects.h +22 -6
  382. package/ios/TopBar/ANNScrollEdgeEffects.mm +123 -16
  383. package/ios/TopBar/ANNSearchPresenter.mm +172 -21
  384. package/ios/TopBar/ANNSearchResultsViewController.mm +29 -6
  385. package/ios/TopBar/ANNTopBarPresenter.h +8 -2
  386. package/ios/TopBar/ANNTopBarPresenter.mm +155 -33
  387. package/ios/TurboModules/ANNTurboEventEmitter.mm +4 -35
  388. package/ios/TurboModules/ANNTurboModule.mm +104 -33
  389. package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.cpp +20 -0
  390. package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.h +5 -14
  391. package/lib/module/ARCHITECTURE.md +40 -27
  392. package/lib/module/adapters/NativeANNTurboModule.js.map +1 -1
  393. package/lib/module/api/app/AppRegistry.js +14 -2
  394. package/lib/module/api/app/AppRegistry.js.map +1 -1
  395. package/lib/module/api/app/createNavigation.js +190 -66
  396. package/lib/module/api/app/createNavigation.js.map +1 -1
  397. package/lib/module/api/commands/commands.js +54 -6
  398. package/lib/module/api/commands/commands.js.map +1 -1
  399. package/lib/module/api/events/navigationEvents.js +6 -2
  400. package/lib/module/api/events/navigationEvents.js.map +1 -1
  401. package/lib/module/api/hooks/useNavigation.js +8 -3
  402. package/lib/module/api/hooks/useNavigation.js.map +1 -1
  403. package/lib/module/api/hooks/useSafeAreaInsets.js +4 -3
  404. package/lib/module/api/hooks/useSafeAreaInsets.js.map +1 -1
  405. package/lib/module/api/linking/dispatchedLinks.js +23 -0
  406. package/lib/module/api/linking/dispatchedLinks.js.map +1 -0
  407. package/lib/module/api/linking/linking.js +11 -0
  408. package/lib/module/api/linking/linking.js.map +1 -1
  409. package/lib/module/api/navigation.js.map +1 -1
  410. package/lib/module/api/options/OptionsChain.js +2 -2
  411. package/lib/module/api/screens/defineScreen.js +45 -3
  412. package/lib/module/api/screens/defineScreen.js.map +1 -1
  413. package/lib/module/api/screens/nativeScreens.js +31 -6
  414. package/lib/module/api/screens/nativeScreens.js.map +1 -1
  415. package/lib/module/api/screens/registerScreens.js +193 -35
  416. package/lib/module/api/screens/registerScreens.js.map +1 -1
  417. package/lib/module/api/theme/theme.js +5 -0
  418. package/lib/module/api/theme/theme.js.map +1 -1
  419. package/lib/module/engine/commands.js +51 -9
  420. package/lib/module/engine/commands.js.map +1 -1
  421. package/lib/module/engine/layout.js +20 -11
  422. package/lib/module/engine/layout.js.map +1 -1
  423. package/lib/module/engine/nativeScreens.js +9 -0
  424. package/lib/module/engine/nativeScreens.js.map +1 -1
  425. package/lib/module/engine/options.js +49 -15
  426. package/lib/module/engine/options.js.map +1 -1
  427. package/lib/module/engine/optionsChange.js +102 -0
  428. package/lib/module/engine/optionsChange.js.map +1 -0
  429. package/lib/module/engine/places.js +52 -7
  430. package/lib/module/engine/places.js.map +1 -1
  431. package/lib/module/engine/props.js +30 -1
  432. package/lib/module/engine/props.js.map +1 -1
  433. package/lib/module/engine/refresh.js +85 -0
  434. package/lib/module/engine/refresh.js.map +1 -0
  435. package/lib/module/engine/rememberedOptions.js +61 -1
  436. package/lib/module/engine/rememberedOptions.js.map +1 -1
  437. package/lib/module/engine/screens.js +77 -16
  438. package/lib/module/engine/screens.js.map +1 -1
  439. package/lib/module/interfaces/contract/commands.json +101 -0
  440. package/lib/module/interfaces/contract/errors.json +275 -0
  441. package/lib/typescript/adapters/NativeANNTurboModule.d.ts +12 -2
  442. package/lib/typescript/adapters/NativeANNTurboModule.d.ts.map +1 -1
  443. package/lib/typescript/api/app/AppRegistry.d.ts.map +1 -1
  444. package/lib/typescript/api/app/createNavigation.d.ts +8 -3
  445. package/lib/typescript/api/app/createNavigation.d.ts.map +1 -1
  446. package/lib/typescript/api/commands/commands.d.ts.map +1 -1
  447. package/lib/typescript/api/commands/presentation.d.ts +4 -3
  448. package/lib/typescript/api/commands/presentation.d.ts.map +1 -1
  449. package/lib/typescript/api/events/navigationEvents.d.ts +3 -3
  450. package/lib/typescript/api/events/navigationEvents.d.ts.map +1 -1
  451. package/lib/typescript/api/hooks/useNavigation.d.ts +1 -1
  452. package/lib/typescript/api/hooks/useNavigation.d.ts.map +1 -1
  453. package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts +4 -3
  454. package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts.map +1 -1
  455. package/lib/typescript/api/index.d.ts +1 -1
  456. package/lib/typescript/api/index.d.ts.map +1 -1
  457. package/lib/typescript/api/linking/dispatchedLinks.d.ts +7 -0
  458. package/lib/typescript/api/linking/dispatchedLinks.d.ts.map +1 -0
  459. package/lib/typescript/api/linking/linking.d.ts +8 -0
  460. package/lib/typescript/api/linking/linking.d.ts.map +1 -1
  461. package/lib/typescript/api/navigation.d.ts +4 -1
  462. package/lib/typescript/api/navigation.d.ts.map +1 -1
  463. package/lib/typescript/api/options/OptionsChain.d.ts +2 -2
  464. package/lib/typescript/api/screens/defineScreen.d.ts +23 -4
  465. package/lib/typescript/api/screens/defineScreen.d.ts.map +1 -1
  466. package/lib/typescript/api/screens/nativeScreens.d.ts +8 -1
  467. package/lib/typescript/api/screens/nativeScreens.d.ts.map +1 -1
  468. package/lib/typescript/api/screens/registerScreens.d.ts.map +1 -1
  469. package/lib/typescript/api/theme/theme.d.ts +2 -0
  470. package/lib/typescript/api/theme/theme.d.ts.map +1 -1
  471. package/lib/typescript/engine/commands.d.ts +5 -0
  472. package/lib/typescript/engine/commands.d.ts.map +1 -1
  473. package/lib/typescript/engine/layout.d.ts.map +1 -1
  474. package/lib/typescript/engine/nativeScreens.d.ts +5 -0
  475. package/lib/typescript/engine/nativeScreens.d.ts.map +1 -1
  476. package/lib/typescript/engine/options.d.ts +5 -2
  477. package/lib/typescript/engine/options.d.ts.map +1 -1
  478. package/lib/typescript/engine/optionsChange.d.ts +28 -0
  479. package/lib/typescript/engine/optionsChange.d.ts.map +1 -0
  480. package/lib/typescript/engine/places.d.ts +7 -2
  481. package/lib/typescript/engine/places.d.ts.map +1 -1
  482. package/lib/typescript/engine/props.d.ts +8 -1
  483. package/lib/typescript/engine/props.d.ts.map +1 -1
  484. package/lib/typescript/engine/refresh.d.ts +35 -0
  485. package/lib/typescript/engine/refresh.d.ts.map +1 -0
  486. package/lib/typescript/engine/rememberedOptions.d.ts +13 -0
  487. package/lib/typescript/engine/rememberedOptions.d.ts.map +1 -1
  488. package/lib/typescript/engine/screens.d.ts +27 -6
  489. package/lib/typescript/engine/screens.d.ts.map +1 -1
  490. package/lib/typescript/interfaces/ComponentEvents.d.ts +4 -4
  491. package/lib/typescript/interfaces/ComponentEvents.d.ts.map +1 -1
  492. package/lib/typescript/interfaces/Events.d.ts +28 -10
  493. package/lib/typescript/interfaces/Events.d.ts.map +1 -1
  494. package/lib/typescript/interfaces/Options.d.ts +1 -1
  495. package/lib/typescript/interfaces/Options.d.ts.map +1 -1
  496. package/lib/typescript/interfaces/options/animations.d.ts +80 -22
  497. package/lib/typescript/interfaces/options/animations.d.ts.map +1 -1
  498. package/lib/typescript/interfaces/options/bottomTabs.d.ts +21 -7
  499. package/lib/typescript/interfaces/options/bottomTabs.d.ts.map +1 -1
  500. package/lib/typescript/interfaces/options/buttons.d.ts +23 -15
  501. package/lib/typescript/interfaces/options/buttons.d.ts.map +1 -1
  502. package/lib/typescript/interfaces/options/modals.d.ts +34 -26
  503. package/lib/typescript/interfaces/options/modals.d.ts.map +1 -1
  504. package/lib/typescript/interfaces/options/sideMenu.d.ts +23 -6
  505. package/lib/typescript/interfaces/options/sideMenu.d.ts.map +1 -1
  506. package/lib/typescript/interfaces/options/stack.d.ts +17 -3
  507. package/lib/typescript/interfaces/options/stack.d.ts.map +1 -1
  508. package/lib/typescript/interfaces/options/system.d.ts +18 -11
  509. package/lib/typescript/interfaces/options/system.d.ts.map +1 -1
  510. package/lib/typescript/interfaces/options/toolbar.d.ts +2 -2
  511. package/lib/typescript/interfaces/options/topBar.d.ts +68 -38
  512. package/lib/typescript/interfaces/options/topBar.d.ts.map +1 -1
  513. package/metro/acceptPlugin.js +57 -0
  514. package/metro/babelTransformer.js +45 -0
  515. package/metro/index.js +36 -0
  516. package/package.json +4 -25
  517. package/src/ARCHITECTURE.md +40 -27
  518. package/src/adapters/NativeANNTurboModule.ts +12 -2
  519. package/src/api/app/AppRegistry.ts +16 -2
  520. package/src/api/app/createNavigation.ts +203 -69
  521. package/src/api/commands/commands.ts +48 -7
  522. package/src/api/commands/presentation.ts +4 -3
  523. package/src/api/events/navigationEvents.ts +10 -4
  524. package/src/api/hooks/useNavigation.ts +9 -4
  525. package/src/api/hooks/useSafeAreaInsets.ts +4 -3
  526. package/src/api/index.ts +1 -0
  527. package/src/api/linking/dispatchedLinks.ts +18 -0
  528. package/src/api/linking/linking.ts +22 -1
  529. package/src/api/navigation.ts +4 -1
  530. package/src/api/options/OptionsChain.ts +2 -2
  531. package/src/api/screens/defineScreen.ts +49 -5
  532. package/src/api/screens/nativeScreens.ts +40 -4
  533. package/src/api/screens/registerScreens.tsx +185 -42
  534. package/src/api/theme/theme.ts +5 -0
  535. package/src/engine/commands.ts +70 -13
  536. package/src/engine/layout.ts +27 -11
  537. package/src/engine/nativeScreens.ts +10 -1
  538. package/src/engine/options.ts +45 -19
  539. package/src/engine/optionsChange.ts +107 -0
  540. package/src/engine/places.ts +65 -7
  541. package/src/engine/props.ts +30 -1
  542. package/src/engine/refresh.ts +97 -0
  543. package/src/engine/rememberedOptions.ts +74 -1
  544. package/src/engine/screens.tsx +76 -21
  545. package/src/interfaces/ComponentEvents.ts +4 -4
  546. package/src/interfaces/Events.ts +29 -10
  547. package/src/interfaces/Options.ts +1 -0
  548. package/src/interfaces/contract/commands.json +101 -0
  549. package/src/interfaces/contract/errors.json +275 -0
  550. package/src/interfaces/options/animations.ts +81 -22
  551. package/src/interfaces/options/bottomTabs.ts +21 -7
  552. package/src/interfaces/options/buttons.ts +23 -15
  553. package/src/interfaces/options/modals.ts +34 -26
  554. package/src/interfaces/options/sideMenu.ts +24 -6
  555. package/src/interfaces/options/stack.ts +17 -3
  556. package/src/interfaces/options/system.ts +18 -11
  557. package/src/interfaces/options/toolbar.ts +2 -2
  558. package/src/interfaces/options/topBar.ts +68 -38
  559. package/android/src/main/java/dev/apexnative/navigation/react/ArrangementStates.kt +0 -41
  560. package/android/src/main/java/dev/apexnative/navigation/react/ScreenInsets.kt +0 -69
  561. package/android/src/main/java/dev/apexnative/navigation/react/events/NavigationStateReporter.kt +0 -62
  562. package/android/src/main/java/dev/apexnative/navigation/react/events/StateHold.kt +0 -62
  563. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowPlacer.kt +0 -223
  564. package/android/src/main/java/dev/apexnative/navigation/views/element/ElementStub.kt +0 -31
  565. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMatrixAnimator.kt +0 -138
  566. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PlainViewAnimator.kt +0 -88
  567. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PropertyAnimatorCreator.kt +0 -33
  568. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ReactImageAnimator.kt +0 -66
  569. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextChangeAnimator.kt +0 -179
  570. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewChangeAnimator.kt +0 -139
  571. package/ios/Layouts/Screen/ANNScreenInsets.h +0 -30
  572. package/ios/Layouts/Screen/ANNScreenInsets.mm +0 -68
  573. package/ios/Layouts/Tabs/ANNTabsPreloadWindow.h +0 -27
  574. package/ios/Layouts/Tabs/ANNTabsPreloadWindow.mm +0 -55
@@ -29,9 +29,77 @@ export function rememberMergedOptions(id: string, options: Options): void {
29
29
  remembered.set(id, before ? mergeOptions(before, kept) : kept);
30
30
  }
31
31
 
32
+ /** Takes the options at the paths, such as `['topBar', 'subtitle']`, out of those remembered for the node with the id. */
33
+ export function forgetMergedPaths(id: string, paths: readonly string[][]): void {
34
+ const own = ownOptions.get(id);
35
+ if (own) own.options = withoutPaths(own.options, paths);
36
+ const options = remembered.get(id);
37
+ if (options) remembered.set(id, withoutPaths(options, paths));
38
+ }
39
+
40
+ // A copy of the options without the values at the paths.
41
+ function withoutPaths(options: Options, paths: readonly string[][]): Options {
42
+ const kept = structuredCopy(options);
43
+ for (const path of paths) {
44
+ const parent = path
45
+ .slice(0, -1)
46
+ .reduce<Record<string, unknown> | undefined>(
47
+ (group, key) => group?.[key] as Record<string, unknown> | undefined,
48
+ kept
49
+ );
50
+ if (parent) delete parent[path[path.length - 1]!];
51
+ }
52
+ return kept as Options;
53
+ }
54
+
55
+ // A copy of the plain objects of options, the other values shared.
56
+ function structuredCopy(options: Options): Record<string, unknown> {
57
+ return Object.fromEntries(
58
+ Object.entries(options).map(([key, value]) => [
59
+ key,
60
+ isGroup(value) ? structuredCopy(value as Options) : value,
61
+ ])
62
+ );
63
+ }
64
+
65
+ function isGroup(value: unknown): boolean {
66
+ return (
67
+ typeof value === 'object' && value !== null && Object.getPrototypeOf(value) === Object.prototype
68
+ );
69
+ }
70
+
32
71
  /** Forgets the merged options of a node that went; a node of the last root keeps them until another root goes out. */
33
72
  export function forgetMergedOptions(id: string): void {
34
73
  if (!lastRoot?.ids.has(id)) remembered.delete(id);
74
+ ownOptions.delete(id);
75
+ }
76
+
77
+ // The own options of each screen as JavaScript sent them, in development: those it showed with, and every merge and
78
+ // clear since. An edit of a screen's options (Fast Refresh) changes only what still has the old definition's value.
79
+ const ownOptions = new Map<string, { name: string; options: Options }>();
80
+
81
+ /** Notes the own options a screen of the name shows with (development). */
82
+ export function noteOwnOptions(id: string, name: string, options: Options): void {
83
+ if (__DEV__) ownOptions.set(id, { name, options });
84
+ }
85
+
86
+ /** Notes a merge into a screen's own options (development). */
87
+ export function noteMergedOwnOptions(id: string, options: Options): void {
88
+ const noted = __DEV__ ? ownOptions.get(id) : undefined;
89
+ if (noted) noted.options = mergeOptions(noted.options, options);
90
+ }
91
+
92
+ /** The own options of a screen as JavaScript sent them (development); undefined for a screen it didn't note. */
93
+ export function ownOptionsOf(id: string): Options | undefined {
94
+ return ownOptions.get(id)?.options;
95
+ }
96
+
97
+ /**
98
+ * The ids of the screens of the name the native side has, mounted in React or not yet (a tab not selected yet), as
99
+ * development notes them.
100
+ */
101
+ export function notedScreens(name: string): string[] {
102
+ return [...ownOptions].filter(([, noted]) => noted.name === name).map(([id]) => id);
35
103
  }
36
104
 
37
105
  /** The options merged into the node with the id, as remembered; undefined without any. */
@@ -55,12 +123,17 @@ export function rootGoesOut(nodes: LayoutNode[], again: SentRoot | undefined): v
55
123
  const before = lastRoot;
56
124
  lastRoot = { nodes, ids: new Set(nodes.flatMap(idsOf)) };
57
125
  if (!before) return;
126
+ // The screens of the root before go with it, the tabs React never mounted too.
127
+ for (const id of before.ids) if (!lastRoot.ids.has(id)) ownOptions.delete(id);
58
128
  const moved = new Map<string, Options>();
59
129
  if (again === before) {
60
130
  pairNodes(before.nodes, nodes, (old, node) => {
61
131
  const options = remembered.get(old.id);
62
132
  if (!options) return;
63
- node.data.options = mergeNativeOptions(node.data.options ?? {}, toNativeOptions(options));
133
+ node.data.options = mergeNativeOptions(
134
+ node.data.options ?? {},
135
+ toNativeOptions(options, node.id)
136
+ );
64
137
  moved.set(node.id, options);
65
138
  });
66
139
  }
@@ -2,7 +2,7 @@ import React, { type ComponentType, useCallback, useEffect, useSyncExternalStore
2
2
  import { AppRegistry } from 'react-native';
3
3
  import type { Options } from '../interfaces/Options';
4
4
  import { forgetPlace } from './places';
5
- import { forgetProps, propsOf, watchProps } from './props';
5
+ import { forgetProps, isOptionsComponent, propsOf, watchProps } from './props';
6
6
  import { forgetMergedOptions } from './rememberedOptions';
7
7
  import { hasSlot } from './slots';
8
8
  import type { NativeControllerProps } from './nativeScreens';
@@ -52,14 +52,50 @@ export type EngineScreen =
52
52
  /** What the root of a React screen renders: the screen's id, and the props the command gave it. */
53
53
  export type ScreenRootProps = { componentId: string } & Record<string, unknown>;
54
54
 
55
+ /**
56
+ * What React Native gives the root of a React screen: the screen's id, its root tag (none in a slot of the app's one
57
+ * tree), and the props the native side gives that root, a tab cell's `tabIndex`, `selected`, `badge`, `dot` and
58
+ * `dotColor`.
59
+ */
60
+ export type NativeRootProps = { componentId: string; rootTag?: number } & Record<string, unknown>;
61
+
55
62
  const screens = new Map<string, EngineScreen>();
56
- const roots = new Map<string, ComponentType<{ componentId: string; rootTag?: number }>>();
63
+ const roots = new Map<string, ComponentType<NativeRootProps>>();
57
64
  let unmounted: ((screenId: string) => void) | undefined;
58
- // The React root that shows each screen, by its root tag. After a JavaScript reload React Native starts the roots of
59
- // the old screens again in the new runtime, under the ids the new screens get too, and unmounts them once the new ones
60
- // show; their root tags are older, as the native side counts them up for as long as the app runs. A slot of the app's
61
- // one tree has no tag: while the one tree shows a screen with the id, no root of that id lets it go.
62
- const owners = new Map<string, number>();
65
+ // The React roots mounted under each id, by their root tags. One id can have several: after a JavaScript reload React
66
+ // Native starts the roots of the old screens again in the new runtime, under the ids the new screens get too, and
67
+ // unmounts them once the new ones show; a component of the default or a stack's options has one id and a root in the
68
+ // bar of every screen that shows it. The id lets its props go only with the last of them. A slot of the app's one tree
69
+ // has no tag: while the one tree shows a screen with the id, no root of that id lets it go.
70
+ const owners = new Map<string, Set<number>>();
71
+ // The screens that show by their ids: the name, and how many roots or slots of the id are mounted (a component of the
72
+ // options has a root in the bar of every screen that shows it).
73
+ const shown = new Map<string, { name: string; mounts: number }>();
74
+
75
+ /**
76
+ * Notes a screen as shown, a React root or slot of it or the controller of a native screen, until the function it
77
+ * gives is called.
78
+ */
79
+ export function noteShown(componentId: string, name: string): () => void {
80
+ const entry = shown.get(componentId);
81
+ if (entry?.name === name) entry.mounts++;
82
+ else shown.set(componentId, { name, mounts: 1 });
83
+ return () => {
84
+ const current = shown.get(componentId);
85
+ if (current?.name !== name) return;
86
+ if (--current.mounts === 0) shown.delete(componentId);
87
+ };
88
+ }
89
+
90
+ /** The ids of the screens with the name that show now. */
91
+ export function shownScreens(name: string): string[] {
92
+ return [...shown].filter(([, entry]) => entry.name === name).map(([id]) => id);
93
+ }
94
+
95
+ /** Whether a React root of the screen with the id is mounted now (a slot of the app's one tree doesn't count). */
96
+ export function hasRoot(componentId: string): boolean {
97
+ return owners.has(componentId);
98
+ }
63
99
 
64
100
  /** What runs when the root of a screen unmounts: the screen is gone. */
65
101
  export function onScreenUnmounted(listener: (screenId: string) => void): void {
@@ -192,20 +228,29 @@ export function isReactScreen(name: string): boolean {
192
228
  return screen !== undefined && 'component' in screen;
193
229
  }
194
230
 
231
+ /**
232
+ * The props a screen's component renders with: those a command left under its id ([stored]), the props the native side
233
+ * gave its root over them ([root]: a tab cell's state, which the docs promise arrives on top of `passProps`), and its
234
+ * id. The root tag stays with the root.
235
+ */
236
+ export function screenProps(stored: object, root: NativeRootProps): ScreenRootProps {
237
+ const props: ScreenRootProps = { ...stored, ...root, componentId: root.componentId };
238
+ delete props.rootTag;
239
+ return props;
240
+ }
241
+
195
242
  /**
196
243
  * The root a React screen runs in: the screen with the props a command left for it under its id, and the new ones when
197
- * options give its id new props. React Native gives a root only its id (and its own root props, which stay here); the
198
- * slot of the app's one tree renders the same root.
244
+ * options give its id new props, under the props the native side gives the root ([screenProps]). The slot of the app's
245
+ * one tree renders the same root.
199
246
  */
200
- export function screenRoot(
201
- name: string
202
- ): ComponentType<{ componentId: string; rootTag?: number }> | undefined {
247
+ export function screenRoot(name: string): ComponentType<NativeRootProps> | undefined {
203
248
  const screen = screens.get(name);
204
249
  if (!screen || !('component' in screen)) return undefined;
205
250
  let root = roots.get(name);
206
251
  if (!root) {
207
252
  const Screen = screen.component();
208
- root = function ScreenRoot(rootProps: { componentId: string; rootTag?: number }) {
253
+ root = function ScreenRoot(rootProps: NativeRootProps) {
209
254
  // In the app's one tree the slot renders the root, without a tag of its own.
210
255
  const { componentId, rootTag } = rootProps;
211
256
  const watch = useCallback(
@@ -213,24 +258,34 @@ export function screenRoot(
213
258
  [componentId]
214
259
  );
215
260
  const props = useSyncExternalStore(watch, () => propsOf(componentId));
261
+ useEffect(() => noteShown(componentId, name), [componentId]);
216
262
  useEffect(() => {
217
- if (rootTag !== undefined && rootTag > (owners.get(componentId) ?? -1)) {
218
- owners.set(componentId, rootTag);
263
+ if (rootTag !== undefined) {
264
+ const tags = owners.get(componentId) ?? new Set<number>();
265
+ tags.add(rootTag);
266
+ owners.set(componentId, tags);
219
267
  }
220
268
  return () => {
221
- // An old root of the same id leaves the screen alone, and so does any root while the one tree still has a slot
222
- // with the id: a later screen under the id, the restarted root of a screen after a reload into the one tree
223
- // (its slot may mount only once the app's provider lets it), the screen rendering again under the provider.
224
- if (rootTag !== undefined && owners.get(componentId) !== rootTag) return;
269
+ // A root while another root of the id is mounted leaves the screen alone, and so does any root while the one
270
+ // tree still has a slot with the id: a later screen under the id, the restarted root of a screen after a
271
+ // reload into the one tree (its slot may mount only once the app's provider lets it), the screen rendering
272
+ // again under the provider.
273
+ const tags = owners.get(componentId);
274
+ if (rootTag !== undefined && tags) {
275
+ tags.delete(rootTag);
276
+ if (tags.size > 0) return;
277
+ }
225
278
  if (hasSlot(componentId)) return;
226
279
  owners.delete(componentId);
227
- forgetProps(componentId);
280
+ // A component the library named in options keeps its props for the next root under its id (the node shows
281
+ // it again, or another screen shows the same default): they go with the node.
282
+ if (!isOptionsComponent(componentId)) forgetProps(componentId);
228
283
  forgetPlace(componentId);
229
284
  forgetMergedOptions(componentId);
230
285
  unmounted?.(componentId);
231
286
  };
232
287
  }, [componentId, rootTag]);
233
- return <Screen {...props} componentId={componentId} />;
288
+ return <Screen {...screenProps(props, rootProps)} />;
234
289
  };
235
290
  root.displayName = `ScreenRoot(${name})`;
236
291
  roots.set(name, root);
@@ -10,7 +10,7 @@ export type ComponentType =
10
10
 
11
11
  /** The fields every appearance event has. */
12
12
  interface ComponentAppearanceEvent {
13
- /** The id of the component: the screen, or the screen the bar component belongs to. */
13
+ /** The id of the component: of the screen, or the bar component's own id. */
14
14
  componentId: string;
15
15
  /** The name of the component: for a screen, its name without any internal prefix. */
16
16
  componentName: string;
@@ -60,7 +60,7 @@ export interface NavigationButtonPressedEvent {
60
60
  * `ApexNavigation.back`; the hardware back of a modal has `ApexNavigation.hardwareBackButton`.
61
61
  */
62
62
  buttonId: string;
63
- /** (iOS) For a button with `toggle`: its new state, already written into the options of the screen. */
63
+ /** (iOS) For a button with `toggle`: its new state, which the screen keeps. */
64
64
  selected?: boolean;
65
65
  }
66
66
 
@@ -95,8 +95,8 @@ export interface SheetDetentChangedEvent {
95
95
  /** The id of the visible screen of the modal. */
96
96
  componentId: string;
97
97
  /**
98
- * The detent the sheet stopped at: `'medium'`, `'large'`, or a height (points on iOS, dp on Android). `'content'`
99
- * is sent on iOS for a detent that fits the content; Android names such a detent `'medium'`.
98
+ * The detent the sheet stopped at: `'medium'`, `'large'`, `'content'` (the detent that fits the content), or a
99
+ * height (points on iOS, dp on Android).
100
100
  */
101
101
  detent: 'medium' | 'large' | 'content' | number;
102
102
  }
@@ -54,8 +54,12 @@ export interface NavigationStateChangedEvent {
54
54
 
55
55
  /**
56
56
  * A tab was selected by the user: a press on the tab, a pick from the "More" list or a press on "More" that showed a
57
- * tab (iOS). It is sent after the selection, and only when the tab changed; a press on the current tab is reported by
58
- * `BottomTabPressedEvent` alone. Selecting a tab from code sends nothing.
57
+ * tab (iOS). It goes right after the `ComponentDidAppear` of the new tab's screen, before the navigation state and
58
+ * before the tab that was left goes back to its first screen (`popToRootOnBlur`), and only when the tab changed: a
59
+ * press on the selected tab or on a `selectTabOnPress: false` tab is reported by `BottomTabPressedEvent` alone.
60
+ * Selecting a tab from code sends nothing. A switch still running when another press, long press or choice from code
61
+ * comes ends first, with this event, so the events of one press never mix with the next; when that tab's screen
62
+ * hasn't drawn yet, this event goes before its held `ComponentDidAppear`.
59
63
  */
60
64
  export interface BottomTabSelectedEvent {
61
65
  /** The index of the tab that is now selected. */
@@ -67,24 +71,28 @@ export interface BottomTabSelectedEvent {
67
71
  }
68
72
 
69
73
  /**
70
- * A tab was pressed, the selected one too. It is sent before the tab is selected; with `selectTabOnPress: false` it is
71
- * the only thing that happens. A long press sends `BottomTabLongPressedEvent` instead.
74
+ * A tab was pressed, on the bar or on a cell of `bottomTabs.customRow`, the selected one too. It goes first, before
75
+ * anything the press does. Another tab: then the switch's `ComponentWillAppear`, `ComponentDidDisappear` and
76
+ * `ComponentDidAppear`, then `BottomTabSelectedEvent`. The selected tab again (`wasSelected: true`): its stack goes
77
+ * back to its first screen with the events of the user's back (`ScreenPopped`), or, on the first screen, its content
78
+ * scrolls to the top; with `popToRootOnPress: false` nothing follows. With `selectTabOnPress: false` it is the only
79
+ * event and the selection stays. A long press sends `BottomTabLongPressedEvent` instead.
72
80
  */
73
81
  export interface BottomTabPressedEvent {
74
82
  /** The index of the tab that was pressed. */
75
83
  tabIndex: number;
76
84
  /** The id of the tabs. */
77
85
  bottomTabsId: string;
78
- /** The id of the screen the tab shows: the top of its stack. */
86
+ /** The id of the screen the tab shows: the top of its stack, or the tab itself when it is a screen. */
79
87
  screenId?: string;
80
88
  /** Whether the tab was the selected one already; a press on the selected tab scrolls its content to the top. */
81
89
  wasSelected: boolean;
82
90
  }
83
91
 
84
92
  /**
85
- * A tab was pressed and held. The tab is not selected and gets no press event. On iOS it is not sent for the tabs
86
- * that are components (`bottomTab.component`, `bottomTabs.customRow`), for "More", or for the tab strip at the top of an
87
- * iPad. On Android it replaces the tooltip of the tab.
93
+ * A tab was pressed and held, on the bar or on a cell of `bottomTabs.customRow`. The tab is not selected and gets no
94
+ * press event. On iOS it is not sent for "More" or for the tab strip at the top of an iPad. On Android it replaces the
95
+ * tooltip of the tab.
88
96
  */
89
97
  export interface BottomTabLongPressedEvent {
90
98
  /** The index of the tab that was pressed. */
@@ -105,6 +113,16 @@ export interface SplitViewColumnsStackedEvent {
105
113
  stacked: boolean;
106
114
  }
107
115
 
116
+ /**
117
+ * (iOS) A link the app dispatched (`dispatchDeepLinkURL`) that React Native's `Linking` doesn't take from the native
118
+ * side: on React Native 0.88 and newer, in an app whose Info.plist names a scene delegate, it takes only the links a
119
+ * scene opened. JavaScript hands it to `Linking` as a `url` event.
120
+ */
121
+ export interface DeepLinkDispatchedEvent {
122
+ /** The link. */
123
+ url: string;
124
+ }
125
+
108
126
  /**
109
127
  * A screen of the single React tree was destroyed and the slot still belongs to it: JavaScript removes the slot from
110
128
  * its tree. It is not sent for a prepared screen that was never pushed, nor when JavaScript reloads.
@@ -185,11 +203,12 @@ export type HingeState = 'closed' | 'partiallyOpen' | 'fullyOpen' | 'unknown';
185
203
  */
186
204
  export interface HingeChangedEvent {
187
205
  /**
188
- * The state of the hinge. On Android `closed` means the device has no fold, or its angle is below 90 degrees.
206
+ * The state of the hinge. On Android `closed` means the app's window has no fold, or the angle is below 90 degrees,
207
+ * so a device open flat with a window off the fold (split screen) reports `closed`; Android never gives `unknown`.
189
208
  */
190
209
  state?: HingeState;
191
210
  /**
192
- * The angle of the hinge in degrees (on iOS to tenths). Missing when the state is `unknown` and where the system
211
+ * The angle of the hinge in degrees, to tenths. Missing when the state is `unknown` and where the system
193
212
  * gives no angle.
194
213
  */
195
214
  angle?: number;
@@ -107,6 +107,7 @@ export type {
107
107
  ScreenAnimationOptions,
108
108
  SharedElementTransition,
109
109
  StackAnimationOptions,
110
+ StackPopAnimationOptions,
110
111
  StackPushAnimationOptions,
111
112
  TopBarAnimationOptions,
112
113
  ViewAnimationOptions,
@@ -0,0 +1,101 @@
1
+ {
2
+ "description": "Every command with a promise (an async method of src/adapters/NativeANNTurboModule.ts): what it resolves with, whether the navigation state goes before its answer (`state`), and whether `ANN.CommandCompleted` follows the answer (`completed`). scripts/contract.mjs makes ios/Contract/ANNCommandContract.{h,mm} and android/.../react/CommandContract.kt from it, and fails when a command of the spec is missing here or a command here is not in the spec.",
3
+ "commands": [
4
+ {
5
+ "name": "setRoot",
6
+ "resolves": "the id of the root, once the root and the layout's modals and overlays show",
7
+ "state": true,
8
+ "completed": true
9
+ },
10
+ {
11
+ "name": "push",
12
+ "resolves": "the id of the screen that shows; of a pair, the pair's id",
13
+ "state": true,
14
+ "completed": true
15
+ },
16
+ {
17
+ "name": "preparePush",
18
+ "resolves": "the frame `{ width, height, padding }` of the prepared screen, or null; always null on iOS",
19
+ "state": false,
20
+ "completed": false
21
+ },
22
+ {
23
+ "name": "pop",
24
+ "resolves": "the id of the screen that went",
25
+ "state": true,
26
+ "completed": true
27
+ },
28
+ {
29
+ "name": "popTo",
30
+ "resolves": "the id of the screen it went back to",
31
+ "state": true,
32
+ "completed": true
33
+ },
34
+ {
35
+ "name": "popToRoot",
36
+ "resolves": "the id of the first screen of the stack",
37
+ "state": true,
38
+ "completed": true
39
+ },
40
+ {
41
+ "name": "setStackRoot",
42
+ "resolves": "the id of the new top screen",
43
+ "state": true,
44
+ "completed": true
45
+ },
46
+ {
47
+ "name": "showModal",
48
+ "resolves": "the id of the modal's root",
49
+ "state": true,
50
+ "completed": true
51
+ },
52
+ {
53
+ "name": "dismissModal",
54
+ "resolves": "the id of the modal's root",
55
+ "state": true,
56
+ "completed": true
57
+ },
58
+ {
59
+ "name": "dismissAllModals",
60
+ "resolves": "an empty string",
61
+ "state": true,
62
+ "completed": true
63
+ },
64
+ {
65
+ "name": "showOverlay",
66
+ "resolves": "the id of the overlay's root",
67
+ "state": true,
68
+ "completed": true
69
+ },
70
+ {
71
+ "name": "dismissOverlay",
72
+ "resolves": "the id of the overlay's root",
73
+ "state": true,
74
+ "completed": true
75
+ },
76
+ {
77
+ "name": "dismissAllOverlays",
78
+ "resolves": "an empty string",
79
+ "state": true,
80
+ "completed": true
81
+ },
82
+ {
83
+ "name": "showInColumn",
84
+ "resolves": "the id of the screen that shows",
85
+ "state": true,
86
+ "completed": true
87
+ },
88
+ {
89
+ "name": "setColumnShown",
90
+ "resolves": "nothing once the columns stopped moving (`undefined` on iOS, `null` on Android)",
91
+ "state": true,
92
+ "completed": false
93
+ },
94
+ {
95
+ "name": "getLaunchLink",
96
+ "resolves": "the link that launched the app, or null",
97
+ "state": false,
98
+ "completed": false
99
+ }
100
+ ]
101
+ }