@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
@@ -6,32 +6,39 @@ import React, {
6
6
  lazy,
7
7
  type ReactNode,
8
8
  Suspense,
9
- useEffect,
10
9
  useMemo,
11
10
  useState,
12
11
  } from 'react';
13
- import { Platform, StyleSheet } from 'react-native';
12
+ import { DevSettings, Platform, StyleSheet } from 'react-native';
14
13
  import ANNTurboModule from '../../adapters/NativeANNTurboModule';
15
14
  import type { NativeControllerProps } from '../../engine/nativeScreens';
16
15
  import { isButtonRoot } from '../../engine/props';
17
16
  import {
18
17
  checkArrangements,
19
- type EngineArrangement,
20
18
  onScreenUnmounted,
21
19
  registerScreen as registerEngineScreen,
22
20
  type ScreenRootProps,
21
+ shownScreens,
23
22
  } from '../../engine/screens';
24
23
  import { screenUnmounted } from '../events/screenLifecycle';
25
24
  import { mergeOptions } from '../../engine/mergeOptions';
26
25
  import { preparedPadding } from '../../engine/slots';
27
- import { buildScreenOptions, type ScreenDefinition, type ScreenOptionsInput } from './defineScreen';
28
- import { isNativeScreen, type NativeScreen } from './nativeScreens';
26
+ import { clearOptions, mergeOptions as sendMergeOptions } from '../../engine/commands';
27
+ import { changeOverOwn, optionsChange } from '../../engine/optionsChange';
28
+ import { notedScreens, ownOptionsOf } from '../../engine/rememberedOptions';
29
+ import { openNativeScreens } from '../../engine/nativeScreens';
30
+ import { placeOf } from '../../engine/places';
31
+ import { propsOf } from '../../engine/props';
32
+ import { familyOf, newestType, onRedefined } from '../../engine/refresh';
29
33
  import {
30
- type Arrangement,
31
- isArrangement,
32
- type ScreenArrangement,
33
- toEngineArrangement,
34
- } from './arrangement';
34
+ buildScreenOptions,
35
+ definitionOf,
36
+ ownDefinitionOf,
37
+ type ScreenDefinition,
38
+ type ScreenOptionsInput,
39
+ } from './defineScreen';
40
+ import { isNativeScreen, type NativeScreen, type NativeScreenHookProps } from './nativeScreens';
41
+ import { type Arrangement, isArrangement, toEngineArrangement } from './arrangement';
35
42
  import { type ErrorFallbackProps, ScreenBoundary } from './ScreenBoundary';
36
43
  import ANNSafeAreaView from '../safeArea/ANNSafeAreaViewNativeComponent';
37
44
 
@@ -98,6 +105,125 @@ export interface ScreenSet {
98
105
  // The root of a screen tells when it unmounts: what the screen left behind goes.
99
106
  onScreenUnmounted(screenUnmounted);
100
107
 
108
+ // The screens of defineScreen by name, in development: what `screens` gives (a lazy screen's module once loaded) and
109
+ // the options of its group.
110
+ const editable = new Map<
111
+ string,
112
+ { screen: () => unknown; groupOptions: ScreenOptionsInput<object> | undefined }
113
+ >();
114
+
115
+ onRedefined(applyEdit);
116
+
117
+ // Fast Refresh ran the module of a screen again: the screens of it that show take what the edit changed in their
118
+ // options, as a command would have shown them. The family's newest is still the version before the edit here, as React
119
+ // Refresh moves it on only after the update.
120
+ function applyEdit(next: object) {
121
+ const family = familyOf(next);
122
+ const edited = ownDefinitionOf(next) ?? (isNativeScreen(next) ? next : undefined);
123
+ if (!family || !edited) return;
124
+ for (const [name, { screen, groupOptions }] of editable) {
125
+ const current = screen();
126
+ if (current === undefined || familyOf(current) !== family) continue;
127
+ const native = isNativeScreen(current);
128
+ const before = native ? newestType(current) : definitionOf(current);
129
+ // The screen as it was registered: its own module running, nothing edited yet.
130
+ if (before === edited) continue;
131
+ // What a native screen is made of goes to the native side when it is registered and shown: a change of it starts
132
+ // the app again.
133
+ if (native && isNativeScreen(edited) && madeOtherwise(newestType(current), edited)) {
134
+ DevSettings.reload('[navigation] A native screen changed its name or its useProps');
135
+ return;
136
+ }
137
+ applyChange(
138
+ name,
139
+ native,
140
+ { group: groupOptions, definition: before },
141
+ { group: groupOptions, definition: edited }
142
+ );
143
+ }
144
+ }
145
+
146
+ /** The options a screen is shown with: those of its group, and those of its definition over them. */
147
+ interface ShownOptions {
148
+ group: ScreenOptionsInput<object> | undefined;
149
+ definition: { options?: ScreenOptionsInput<any> } | undefined;
150
+ }
151
+
152
+ // What an edit changed in a screen's options goes to every screen of it the native side has, a screen React hasn't
153
+ // mounted yet too (a tab not selected yet), as a command would have shown it; only where the screen still has what
154
+ // the definition before gave.
155
+ function applyChange(name: string, native: boolean, before: ShownOptions, after: ShownOptions) {
156
+ const shown = native
157
+ ? openNativeScreens(name)
158
+ : [...new Set([...shownScreens(name), ...notedScreens(name).filter(isPlaced)])].map((id) => ({
159
+ id,
160
+ props: propsOf(id),
161
+ }));
162
+ for (const { id, props } of shown) {
163
+ const options = ({ group, definition }: ShownOptions) =>
164
+ mergeOptions(
165
+ buildScreenOptions(group, props),
166
+ buildScreenOptions(definition?.options, props)
167
+ );
168
+ const shownWith = options(before);
169
+ const change = optionsChange(shownWith, options(after));
170
+ const { merge, removed } = changeOverOwn(change, shownWith, ownOptionsOf(id) ?? shownWith);
171
+ if (removed.length > 0) clearOptions(id, removed);
172
+ if (merge) sendMergeOptions(id, merge);
173
+ }
174
+ }
175
+
176
+ // The screens map registered again (Fast Refresh ran the module of the app): a screen written in the map itself, a
177
+ // definition no module exports, has no family to tell its edit, so its definition before and after are compared here.
178
+ // The options of its group too: a group is written in the app's module, and an edit of them leaves the screen as it was.
179
+ function applyRegisteredAgain(
180
+ name: string,
181
+ entry: unknown,
182
+ group: ScreenOptionsInput<object> | undefined
183
+ ) {
184
+ const previous = editable.get(name);
185
+ const before = previous?.screen();
186
+ if (before === undefined) return;
187
+ if (before === entry) {
188
+ if (previous!.groupOptions === group) return;
189
+ const native = isNativeScreen(entry);
190
+ const definition = native ? newestType(entry) : definitionOf(entry);
191
+ applyChange(name, native, { group: previous!.groupOptions, definition }, { group, definition });
192
+ return;
193
+ }
194
+ if (isNativeScreen(before) && isNativeScreen(entry)) {
195
+ if (madeOtherwise(newestType(before), entry)) {
196
+ DevSettings.reload('[navigation] A native screen changed its name or its useProps');
197
+ return;
198
+ }
199
+ applyChange(
200
+ name,
201
+ true,
202
+ { group: previous!.groupOptions, definition: newestType(before) },
203
+ { group, definition: entry }
204
+ );
205
+ return;
206
+ }
207
+ const was = definitionOf(before);
208
+ const now = definitionOf(entry);
209
+ if (!was && !now && previous!.groupOptions === group) return;
210
+ applyChange(
211
+ name,
212
+ false,
213
+ { group: previous!.groupOptions, definition: was },
214
+ { group, definition: now }
215
+ );
216
+ }
217
+
218
+ // A screen the engine knows the place of: one whose command failed after its layout was built has none.
219
+ function isPlaced(id: string): boolean {
220
+ return placeOf(id) !== undefined;
221
+ }
222
+
223
+ function madeOtherwise(before: NativeScreen<any>, after: NativeScreen<any>): boolean {
224
+ return before.nativeName !== after.nativeName || !before.useProps !== !after.useProps;
225
+ }
226
+
101
227
  export function registerScreens(sets: ScreenSet[], wrapper: ScreenWrapper = {}) {
102
228
  // The screens of every set are in one namespace: a command names a screen without its group.
103
229
  const sources = new Map<string, string>();
@@ -131,21 +257,38 @@ function registerScreen(
131
257
  return;
132
258
  }
133
259
  if (isNativeScreen(entry)) {
260
+ // Read on every show, the newest after Fast Refresh, as for a screen of defineScreen.
261
+ const screen = () => newestType(entry);
262
+ if (__DEV__) {
263
+ applyRegisteredAgain(name, entry, groupOptions);
264
+ editable.set(name, { screen: () => entry, groupOptions });
265
+ }
134
266
  registerEngineScreen(name, {
135
267
  nativeName: entry.nativeName,
136
268
  options: (props) =>
137
269
  mergeOptions(
138
270
  buildScreenOptions(groupOptions, props),
139
- buildScreenOptions(entry.options, props)
271
+ buildScreenOptions(screen().options, props)
140
272
  ),
141
- controller: entry.useProps && wrapNativeScreen(name, entry.useProps, wrapper),
142
- arrangement: pairOf(name, entry.arrangement),
273
+ controller: entry.useProps && wrapNativeScreen(name, entry, wrapper),
274
+ arrangement: () => {
275
+ const arrangement = screen().arrangement;
276
+ return arrangement && toEngineArrangement(name, arrangement);
277
+ },
143
278
  });
144
279
  return;
145
280
  }
146
281
  // React.memo and forwardRef components are objects, so the kind of entry is told by its keys.
147
282
  if (isObject(entry) && 'load' in entry) {
148
283
  const screen = lazyScreen(entry.load);
284
+ if (__DEV__) {
285
+ // A lazy screen registered again loads its module on its next show: until then the one loaded before stands for
286
+ // it, so the screens of it that show take an edit of their group's options, and of their module, as before.
287
+ const before = editable.get(name)?.screen();
288
+ const loaded = () => screen.loaded() ?? before;
289
+ applyRegisteredAgain(name, loaded(), groupOptions);
290
+ editable.set(name, { screen: loaded, groupOptions });
291
+ }
149
292
  registerEngineScreen(name, {
150
293
  component: () => wrapScreen(name, screen.component, wrapper),
151
294
  // A command loads the screen before it reads its options.
@@ -164,32 +307,34 @@ function registerScreen(
164
307
  });
165
308
  return;
166
309
  }
167
- const definition = toDefinition(entry);
310
+ // Read on every show: after Fast Refresh a screen of defineScreen gives its new options, key and pair.
311
+ const definition = () => toDefinition(entry);
312
+ if (__DEV__) {
313
+ applyRegisteredAgain(name, entry, groupOptions);
314
+ editable.set(name, { screen: () => entry, groupOptions });
315
+ }
168
316
  registerEngineScreen(name, {
169
- component: () => wrapScreen(name, definition.component, wrapper),
317
+ component: () => wrapScreen(name, definition().component, wrapper),
170
318
  options: (props) =>
171
319
  mergeOptions(
172
320
  buildScreenOptions(groupOptions, props),
173
- buildScreenOptions(definition.options, props)
321
+ buildScreenOptions(definition().options, props)
174
322
  ),
175
- key: definition.key && ((props) => definition.key!(props)),
323
+ key: (props) => definition().key?.(props),
176
324
  ownRoot,
177
- arrangement: pairOf(name, definition.arrangement),
325
+ arrangement: () => {
326
+ const arrangement = definition().arrangement;
327
+ return arrangement && toEngineArrangement(name, arrangement);
328
+ },
178
329
  });
179
330
  }
180
331
 
181
- // The pair of a screen whose `arrangement` is known at registration: checked and filled in once.
182
- function pairOf(
183
- name: string,
184
- arrangement: ScreenArrangement<any> | undefined
185
- ): (() => EngineArrangement) | undefined {
186
- if (!arrangement) return undefined;
187
- const pair = toEngineArrangement(name, arrangement);
188
- return () => pair;
189
- }
190
-
191
332
  function toDefinition(value: ScreenComponent | ScreenDefinition): ScreenDefinition {
192
- return isObject(value) && 'component' in value ? value : { component: value };
333
+ // A screen of defineScreen renders as itself: React Refresh knows it by its module's export, and the version of the
334
+ // newest definition renders in its place.
335
+ const defined = definitionOf(value);
336
+ if (defined) return { ...defined, component: value as ScreenComponent };
337
+ return isObject(value) && 'component' in value ? value : { component: value as ScreenComponent };
193
338
  }
194
339
 
195
340
  /**
@@ -198,15 +343,17 @@ function toDefinition(value: ScreenComponent | ScreenDefinition): ScreenDefiniti
198
343
  * screen) waits for it in Suspense.
199
344
  */
200
345
  function lazyScreen(loadModule: () => ScreenModule | PromiseLike<ScreenModule>) {
201
- let definition: ScreenDefinition | undefined;
346
+ // The screen the module gives; its definition is read from it each time, the newest after Fast Refresh.
347
+ let loaded: ScreenComponent | ScreenDefinition | undefined;
202
348
  let loading: Promise<void> | undefined;
349
+ const definition = () => (loaded ? toDefinition(loaded) : undefined);
203
350
  const load = (): Promise<void> | undefined => {
204
- if (definition) return undefined;
351
+ if (loaded) return undefined;
205
352
  if (!loading) {
206
353
  loading = Promise.resolve()
207
354
  .then(loadModule)
208
355
  .then((module) => {
209
- definition = toDefinition(unwrapModule(module));
356
+ loaded = unwrapModule(module);
210
357
  });
211
358
  loading.catch(() => {
212
359
  loading = undefined;
@@ -216,14 +363,14 @@ function lazyScreen(loadModule: () => ScreenModule | PromiseLike<ScreenModule>)
216
363
  };
217
364
  const Loaded = lazy(async () => {
218
365
  await load();
219
- return { default: definition!.component };
366
+ return { default: definition()!.component };
220
367
  });
221
368
  function LazyScreen(props: object) {
222
369
  // The same component for the life of the view, so that the load doesn't mount it again.
223
- const [Screen] = useState(() => definition?.component ?? Loaded);
370
+ const [Screen] = useState(() => definition()?.component ?? Loaded);
224
371
  return <Screen {...props} />;
225
372
  }
226
- return { load, definition: () => definition, component: LazyScreen };
373
+ return { load, definition, loaded: () => loaded, component: LazyScreen };
227
374
  }
228
375
 
229
376
  function unwrapModule(loaded: ScreenModule): ScreenComponent | ScreenDefinition {
@@ -297,15 +444,11 @@ function wrapScreen(name: string, Screen: ScreenComponent, wrapper: ScreenWrappe
297
444
  */
298
445
  function wrapNativeScreen(
299
446
  name: string,
300
- useProps: (props: object) => object,
447
+ entry: NativeScreen<any>,
301
448
  { provider: Provider, onError }: ScreenWrapper
302
449
  ): ComponentType<NativeControllerProps> {
303
- function Hook({ props, onProps }: Pick<NativeControllerProps, 'props' | 'onProps'>) {
304
- const result = useProps(props);
305
- // After each render React committed, so the native side never shows what the app did not.
306
- useEffect(() => onProps(result));
307
- return null;
308
- }
450
+ // The screen's own component runs the hook: Fast Refresh puts a new version of it in place.
451
+ const Hook = entry as unknown as ComponentType<NativeScreenHookProps<object>>;
309
452
  function NativeScreenProps({
310
453
  componentId,
311
454
  props,
@@ -135,6 +135,11 @@ export function setTheme(next: NavigationTheme) {
135
135
  listeners.forEach((listener) => listener());
136
136
  }
137
137
 
138
+ /** The direction of the app now: the config's, or the one `setDirection` gave since. */
139
+ export function getDirection(): NavigationDirection | undefined {
140
+ return direction;
141
+ }
142
+
138
143
  /** Changes the direction of the app: the bars, the transitions and the swipe back follow at once. */
139
144
  export function setDirection(next: NavigationDirection) {
140
145
  direction = next;
@@ -9,15 +9,17 @@ import { whenNativeScreensReady } from './nativeScreens';
9
9
  import { commands as native } from './native';
10
10
  import { toNativeOptions } from './options';
11
11
  import { dropReactRenderMeasures } from './reactMeasures';
12
- import { columnOf, forgetPlace, notePlaces, placeOf, stackOfColumn } from './places';
12
+ import { columnOf, forgetPlace, layoutsOf, notePlaces, placeOf, stackOfColumn } from './places';
13
13
  import { forgetProps } from './props';
14
14
  import {
15
15
  forgetMergedOptions,
16
+ forgetMergedPaths,
17
+ noteMergedOwnOptions,
16
18
  rememberMergedOptions,
17
19
  rootGoesOut,
18
20
  sentRoot,
19
21
  } from './rememberedOptions';
20
- import { afterLoading } from './screens';
22
+ import { afterLoading, hasRoot, isReactScreen } from './screens';
21
23
  import { holdSlot, isSlotName, removeSlots, showSlot, type SlotFrame } from './slots';
22
24
  import { forgetTabsScreen, showScreensFrom } from './tabs';
23
25
 
@@ -122,7 +124,7 @@ export function setRoot(root: LayoutRoot): Promise<string> {
122
124
 
123
125
  export function setDefaultOptions(options: Options): void {
124
126
  rememberDefaultOptions(options);
125
- native.setDefaultOptions(toNativeOptions(options));
127
+ native.setDefaultOptions(toNativeOptions(options, 'defaultOptions'));
126
128
  }
127
129
 
128
130
  // The show commands that wait in JS, by number: for lazy screens to load, for the first props of native screens, for a
@@ -141,9 +143,10 @@ const preparedScreens = new Set<string>();
141
143
  * engine remembers them by the node's id, so the root set again for a new launch of the native side shows them too.
142
144
  */
143
145
  export function mergeOptions(componentId: string, options: Options): void {
144
- const nativeOptions = toNativeOptions(options);
146
+ const nativeOptions = toNativeOptions(options, componentId);
145
147
  const send = () => {
146
148
  rememberMergedOptions(componentId, options);
149
+ noteMergedOwnOptions(componentId, options);
147
150
  native.mergeOptions(componentId, nativeOptions);
148
151
  };
149
152
  const prepared =
@@ -152,6 +155,24 @@ export function mergeOptions(componentId: string, options: Options): void {
152
155
  else heldMerges.push({ id: componentId, after: shows, send });
153
156
  }
154
157
 
158
+ /**
159
+ * Takes the options at the paths, such as `['topBar', 'subtitle']`, out of the own options of a node, so it shows what
160
+ * the layouts around it and the defaults give there (Fast Refresh, development). It waits for the shows as a merge does.
161
+ */
162
+ export function clearOptions(componentId: string, paths: readonly string[][]): void {
163
+ const send = () => {
164
+ forgetMergedPaths(componentId, paths);
165
+ native.clearOptions(
166
+ componentId,
167
+ paths.map((path) => path.join('.'))
168
+ );
169
+ };
170
+ const prepared =
171
+ preparedScreens.has(componentId) && !heldMerges.some(({ id }) => id === componentId);
172
+ if (waitingShows.size === 0 || prepared) send();
173
+ else heldMerges.push({ id: componentId, after: shows, send });
174
+ }
175
+
155
176
  // Runs a show command; the function `run` gets lets the mergeOptions made after the show go, once it went out. It is
156
177
  // called again when the command ends, so a command that fails before it goes out lets them go too.
157
178
  function show<Result>(run: (goneOut: () => void) => Promise<Result>): Promise<Result> {
@@ -225,19 +246,44 @@ export function push(
225
246
  from?.stack ?? null,
226
247
  (from?.index ?? 0) + 1,
227
248
  from?.menu,
228
- from?.layer
249
+ from?.layer,
250
+ layoutsOf(componentId)
229
251
  );
230
252
  return whenNativeScreensReady([node], () =>
231
- sendPush(commandId, componentId, node, prepares, wanted, goneOut).then((shownId) => {
232
- // A screen with a key went back to the one with the same key: the new screen never shows.
233
- if (shownId !== node.id) forgetNeverShown(node.id);
234
- return shownId;
235
- })
253
+ sendPush(commandId, componentId, node, prepares, wanted, goneOut).then(
254
+ (shownId) => {
255
+ // A screen with a key went back to the one with the same key: the new screen never shows.
256
+ if (shownId !== node.id) forgetNeverShown(node.id);
257
+ return shownId;
258
+ },
259
+ (error: unknown) => {
260
+ if (rendersAtPress(node)) forgetUnmountedPreview(node.id);
261
+ throw error;
262
+ }
263
+ )
236
264
  );
237
265
  })
238
266
  );
239
267
  }
240
268
 
269
+ // A preview's React screen with a root of its own renders only once the view is pressed (iOS): one whose preview went
270
+ // before that never mounts. A screen of the one tree mounts with its slot, a native screen has no root.
271
+ function rendersAtPress(node: LayoutNode): boolean {
272
+ return node.data.options?.preview?.nativeID !== undefined && isReactScreen(node.data.name ?? '');
273
+ }
274
+
275
+ // A root started at a press that came just before the preview went can reach JavaScript after its push failed: without
276
+ // its props it would render the screen with none. Its notes go after this time, when no root of it has mounted by
277
+ // then; one that has clears them as it unmounts.
278
+ const PREVIEW_FORGET_DELAY = 1000;
279
+
280
+ function forgetUnmountedPreview(screenId: string): void {
281
+ if (hasRoot(screenId)) return;
282
+ setTimeout(() => {
283
+ if (!hasRoot(screenId)) forgetNeverShown(screenId);
284
+ }, PREVIEW_FORGET_DELAY);
285
+ }
286
+
241
287
  // Everything a push noted for a screen that never mounts, which an unmount would clear.
242
288
  function forgetNeverShown(screenId: string): void {
243
289
  forgetProps(screenId);
@@ -363,7 +409,8 @@ export function setStackRoot(componentId: string, children: Layout[]): Promise<s
363
409
  from?.stack ?? null,
364
410
  index,
365
411
  from?.menu,
366
- from?.layer
412
+ from?.layer,
413
+ layoutsOf(componentId)
367
414
  )
368
415
  );
369
416
  return whenNativeScreensReady(nodes, () =>
@@ -383,7 +430,17 @@ export function showInColumn(componentId: string, column: string, layout: Layout
383
430
  showScreensFrom(componentId, node);
384
431
  const from = placeOf(componentId);
385
432
  const at = columnPlace(componentId, column);
386
- notePlaces(node, from?.container ?? 'root', at.stack, at.index, from?.menu, from?.layer);
433
+ // In the split view of the screen it comes from, and in the column's stack.
434
+ const within = at.stack ? [...layoutsOf(componentId), at.stack] : layoutsOf(componentId);
435
+ notePlaces(
436
+ node,
437
+ from?.container ?? 'root',
438
+ at.stack,
439
+ at.index,
440
+ from?.menu,
441
+ from?.layer,
442
+ within
443
+ );
387
444
  return whenNativeScreensReady([node], () =>
388
445
  inOrder(() =>
389
446
  sendShow(goneOut, () => native.showInColumn(commandId, componentId, column, node))
@@ -431,7 +488,7 @@ export function dismissModal(componentId: string, options?: Options): Promise<st
431
488
  dropReactRenderMeasures();
432
489
  const commandId = nextId('dismissModal');
433
490
  return inOrder(() =>
434
- native.dismissModal(commandId, componentId, options && toNativeOptions(options))
491
+ native.dismissModal(commandId, componentId, options && toNativeOptions(options, componentId))
435
492
  );
436
493
  }
437
494
 
@@ -14,6 +14,7 @@ import { nextId } from './ids';
14
14
  import { showNativeScreen } from './nativeScreens';
15
15
  import { toNativeOptions } from './options';
16
16
  import { setProps } from './props';
17
+ import { noteOwnOptions } from './rememberedOptions';
17
18
  import { getStartInfo } from './native';
18
19
  import { noteAlone } from './places';
19
20
  import {
@@ -103,6 +104,13 @@ function screen(component: LayoutComponent, inPair = false, keyed = !inPair): La
103
104
  if (nativeName) {
104
105
  // A native screen: its props go to the native side as data, its own options over those of the show.
105
106
  const options = takeButtonHandlers(id, component.options ?? {});
107
+ if (__DEV__) {
108
+ noteOwnOptions(
109
+ id,
110
+ name,
111
+ mergeOptions(screenOptions(name, props ?? {}), component.options ?? {})
112
+ );
113
+ }
106
114
  const node = external({
107
115
  id,
108
116
  name: nativeName,
@@ -113,8 +121,9 @@ function screen(component: LayoutComponent, inPair = false, keyed = !inPair): La
113
121
  }
114
122
  // The screen's own options under those of the show (a command has them there already: merging again changes
115
123
  // nothing).
116
- const own = screenOptions(name, props ?? {});
117
- const options = takeButtonHandlers(id, mergeOptions(own, component.options ?? {}));
124
+ const own = mergeOptions(screenOptions(name, props ?? {}), component.options ?? {});
125
+ noteOwnOptions(id, name, own);
126
+ const options = takeButtonHandlers(id, own);
118
127
  const key = keyed ? screenKey(name, props ?? {}) : undefined;
119
128
  setProps(id, props);
120
129
  return {
@@ -122,7 +131,7 @@ function screen(component: LayoutComponent, inPair = false, keyed = !inPair): La
122
131
  type: 'Component',
123
132
  data: {
124
133
  name: rendersInSlot(name) ? slotName(id, name) : name,
125
- options: toNativeOptions(options),
134
+ options: toNativeOptions(options, id),
126
135
  ...(key !== undefined && { key }),
127
136
  },
128
137
  children: [],
@@ -167,12 +176,13 @@ function arrangement(
167
176
  }
168
177
 
169
178
  function external(component: ExternalComponent): LayoutNode {
179
+ const id = component.id || nextId('ExternalComponent');
170
180
  return {
171
- id: component.id || nextId('ExternalComponent'),
181
+ id,
172
182
  type: 'ExternalComponent',
173
183
  data: {
174
184
  name: String(component.name),
175
- options: toNativeOptions(component.options),
185
+ options: toNativeOptions(component.options, id),
176
186
  passProps: component.passProps,
177
187
  },
178
188
  children: [],
@@ -185,10 +195,11 @@ function parent(
185
195
  options: Options | undefined,
186
196
  children: Layout[] = []
187
197
  ): LayoutNode {
198
+ const nodeId = id || nextId(type);
188
199
  return {
189
- id: id || nextId(type),
200
+ id: nodeId,
190
201
  type,
191
- data: { options: toNativeOptions(options) },
202
+ data: { options: toNativeOptions(options, nodeId) },
192
203
  children: children.map(toNativeLayout),
193
204
  };
194
205
  }
@@ -213,10 +224,11 @@ function sideMenu(menu: LayoutSideMenu): LayoutNode {
213
224
  data: {},
214
225
  children: [toNativeLayout(content)],
215
226
  });
227
+ const id = menu.id || nextId('SideMenuRoot');
216
228
  return {
217
- id: menu.id || nextId('SideMenuRoot'),
229
+ id,
218
230
  type: 'SideMenuRoot',
219
- data: { options: toNativeOptions(menu.options) },
231
+ data: { options: toNativeOptions(menu.options, id) },
220
232
  children: [
221
233
  ...(menu.left ? [side('SideMenuLeft', menu.left)] : []),
222
234
  side('SideMenuCenter', menu.center),
@@ -238,10 +250,14 @@ function splitView(split: LayoutSplitView): LayoutNode {
238
250
  ] as [string, Layout | undefined][]
239
251
  ).filter((column): column is [string, Layout] => column[1] !== undefined);
240
252
  const present = split.master && split.detail ? columns : [];
253
+ const id = split.id || nextId('SplitView');
241
254
  return {
242
- id: split.id || nextId('SplitView'),
255
+ id,
243
256
  type: 'SplitView',
244
- data: { options: toNativeOptions(split.options), columns: present.map(([column]) => column) },
257
+ data: {
258
+ options: toNativeOptions(split.options, id),
259
+ columns: present.map(([column]) => column),
260
+ },
245
261
  children: present.map(([, content]) => toNativeLayout(content)),
246
262
  };
247
263
  }
@@ -38,6 +38,8 @@ interface NativeProps {
38
38
  interface OpenScreen {
39
39
  id: string;
40
40
  name: string;
41
+ /** The props the command gave, as they are. */
42
+ given: object;
41
43
  props: NativeProps;
42
44
  /** The data the native side has, and the names of the functions; none before the command sends the screen. */
43
45
  sent?: { data: Map<string, string>; functions: string };
@@ -78,7 +80,7 @@ export const nativeScreenHooks = {
78
80
  * screen with `useProps` starts its hook, and its props go in once the hook has returned (`whenNativeScreensReady`).
79
81
  */
80
82
  export function showNativeScreen(node: LayoutNode, name: string, props: object): void {
81
- const screen: OpenScreen = { id: node.id, name, props: toNativeProps(props) };
83
+ const screen: OpenScreen = { id: node.id, name, given: props, props: toNativeProps(props) };
82
84
  const Controller = nativeScreenController(name);
83
85
  if (Controller) {
84
86
  screen.first = deferred();
@@ -135,6 +137,13 @@ export function callNativeScreenFunction(id: string, name: string, args: unknown
135
137
  return fn(...args);
136
138
  }
137
139
 
140
+ /** The native screens with the name that are open, each with the props its command gave. */
141
+ export function openNativeScreens(name: string): { id: string; props: object }[] {
142
+ return [...screens.values()]
143
+ .filter((screen) => screen.name === name)
144
+ .map((screen) => ({ id: screen.id, props: screen.given }));
145
+ }
146
+
138
147
  /** The native screen with the id, for the navigation of its calls. */
139
148
  export function nativeScreenInfo(id: string): { id: string; name: string } | undefined {
140
149
  const screen = screens.get(id);