@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
@@ -0,0 +1,108 @@
1
+ // @ts-check
2
+ 'use strict';
3
+
4
+ /** @typedef {import('./types').StepResult} StepResult */
5
+
6
+ const HOW_TO = `Let ANNSceneDelegate take the app's scene: it moves the navigation's window into the scene and passes the
7
+ scene's links to the app delegate. React Native starts in ANNAppDelegate, not here.
8
+
9
+ import ApexNavigation
10
+ import UIKit
11
+
12
+ class SceneDelegate: ANNSceneDelegate {}
13
+
14
+ A scene delegate of the app's own calls ApexNavigation.attach(to:) in scene(_:willConnectTo:options:) instead, as the
15
+ deep links guide shows.`;
16
+
17
+ const SET_UP = `import ApexNavigation
18
+ import UIKit
19
+
20
+ /// ANNSceneDelegate moves the navigation's window into the app's scene and passes the scene's links to the app delegate.
21
+ class SceneDelegate: ANNSceneDelegate {}
22
+ `;
23
+
24
+ // React Native 0.88's template, without its spaces: the scene delegate that makes React Native's factory and starts
25
+ // it in the scene's window.
26
+ const TEMPLATE = `import React
27
+ import React_RCTAppDelegate
28
+ import ReactAppDependencyProvider
29
+ import UIKit
30
+
31
+ class SceneDelegate: RCTDefaultReactNativeFactoryDelegate, UIWindowSceneDelegate {
32
+ var window: UIWindow?
33
+ var reactNativeFactory: RCTReactNativeFactory?
34
+
35
+ func scene(
36
+ _ scene: UIScene,
37
+ willConnectTo session: UISceneSession,
38
+ options connectionOptions: UIScene.ConnectionOptions
39
+ ) {
40
+ guard let windowScene = scene as? UIWindowScene else {
41
+ return
42
+ }
43
+
44
+ dependencyProvider = RCTAppDependencyProvider()
45
+ reactNativeFactory = RCTReactNativeFactory(delegate: self)
46
+ window = UIWindow(windowScene: windowScene)
47
+
48
+ #if DEBUG
49
+ let devMenuConfiguration = RCTDevMenuConfiguration(
50
+ devMenuEnabled: true,
51
+ shakeGestureEnabled: true,
52
+ keyboardShortcutsEnabled: true
53
+ )
54
+ reactNativeFactory?.devMenuConfiguration = devMenuConfiguration
55
+ #endif
56
+
57
+ reactNativeFactory?.startReactNative(
58
+ withModuleName: "",
59
+ in: window,
60
+ connectionOptions: connectionOptions
61
+ )
62
+ }
63
+
64
+ func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
65
+ RCTLinkingManager.scene(scene, openURLContexts: URLContexts)
66
+ }
67
+
68
+ func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
69
+ RCTLinkingManager.scene(scene, continue: userActivity)
70
+ }
71
+
72
+ override func bundleURL() -> URL? {
73
+ #if DEBUG
74
+ RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
75
+ #else
76
+ Bundle.main.url(forResource: "main", withExtension: "jsbundle")
77
+ #endif
78
+ }
79
+ }
80
+ `;
81
+
82
+ /**
83
+ * The text without its spaces and the app's name, to compare with the template.
84
+ * @param {string} text
85
+ */
86
+ function shape(text) {
87
+ return text.replace(/withModuleName:\s*"[^"]*"/, 'withModuleName:""').replace(/\s+/g, '');
88
+ }
89
+
90
+ /**
91
+ * SceneDelegate.swift of React Native 0.88 and newer: the scene delegate becomes an ANNSceneDelegate, since
92
+ * ANNAppDelegate starts React Native and owns the window. Only the template's file changes; one with code of the app's
93
+ * own is changed by hand.
94
+ * @param {string} text
95
+ * @returns {StepResult}
96
+ */
97
+ function planSceneDelegate(text) {
98
+ if (
99
+ /class\s+\w+\s*:\s*ANNSceneDelegate\b/.test(text) ||
100
+ /\bApexNavigation\.attach\s*\(/.test(text)
101
+ )
102
+ return { status: 'done', note: 'already set up' };
103
+ if (shape(text) !== shape(TEMPLATE))
104
+ return { status: 'manual', note: 'changed by hand, see below', howTo: HOW_TO };
105
+ return { status: 'change', next: SET_UP, note: 'ANNSceneDelegate' };
106
+ }
107
+
108
+ module.exports = { planSceneDelegate };
@@ -88,7 +88,9 @@ async function splash({
88
88
  }
89
89
  const plist = project.infoPlist && fs.readFileSync(project.infoPlist, 'utf8');
90
90
  if (plist?.includes('<key>UILaunchScreen</key>')) {
91
- command.warn('Info.plist has UILaunchScreen too: remove it, so that iOS shows the storyboard.');
91
+ command.warn(
92
+ 'Info.plist has UILaunchScreen too: iOS shows it instead of the storyboard; remove it, so that iOS shows the storyboard.'
93
+ );
92
94
  }
93
95
  return command.apply(
94
96
  [
@@ -4,8 +4,8 @@
4
4
  const { compare } = require('./versions');
5
5
 
6
6
  /**
7
- * What changed between two versions, from a CHANGELOG.md as release-it writes it (conventional changelog: a heading
8
- * per version, `## [1.2.0](…) (date)`, and in it `### BREAKING CHANGES`, `### Features`, `### Bug Fixes`).
7
+ * What changed between two versions, from a CHANGELOG.md as release-please writes it (conventional changelog: a
8
+ * heading per version, `## [1.2.0](…) (date)`, and in it `### ⚠ BREAKING CHANGES`, `### Features`, `### Bug Fixes`).
9
9
  * @typedef {{ breaking: { version: string; text: string }[]; notes: { version: string; text: string }[] }} Notes
10
10
  */
11
11
 
@@ -255,6 +255,10 @@ A wrong name or a missing prop is an error of the compiler, not of the app at ru
255
255
  - **Which are left out:** a screen with a required prop that is a function, and one with a prop whose type has no native form (see [Types](#types)). `codegen` names each in a warning. Native code still opens it by its name, `push("Settings", props: [:])`, with its props as a plain dictionary or map.
256
256
  - **After a change** of the screens or their props, run `codegen` again; `doctor` says when the generated code is behind.
257
257
 
258
+ ## Fast Refresh
259
+
260
+ `nativeScreen` returns a component that runs `useProps`. An edit of the hook or of the options applies in place, with the app running. A change of the native name, or adding or removing `useProps`, restarts the app (a reload).
261
+
258
262
  ## UIKit and Android views
259
263
 
260
264
  A screen of UIKit or Android views gets the same `screen`, and follows its props as they change:
@@ -5,7 +5,7 @@ Two things every screen shares: the theme, the colors of the bars and background
5
5
  Every screen of an app shares a look and a few facts: the colors of the bars, the signed-in user, the language. The navigation keeps both for every screen. The **theme** is the colors of the bars, tabs and backgrounds. The **context** is a small object of the app that every screen reads. This page answers:
6
6
 
7
7
  1. [Why the navigation keeps them](#why), and not a React provider.
8
- 2. [The theme](#theme): its colors, dark mode, changing it, Android's own colors.
8
+ 2. [The theme](#theme): its colors, dark mode, changing it, [Android's theme](#android).
9
9
  3. [The context](#context): filling it, reading it, typing it.
10
10
  4. [What goes in the context](#context-roles), and what goes elsewhere.
11
11
 
@@ -37,7 +37,7 @@ export const Navigation = createNavigation({
37
37
 
38
38
  Every top bar and the tab bar are navy with light titles; the buttons, the back arrow and the selected tab are orange.
39
39
 
40
- A color left out keeps the platform's look. On iOS 26 a theme without `bar` keeps the bars on glass. On Android the bars take the colors of the app's Material 3 theme, neutral grays by default (see [Android's colors](#android)).
40
+ A color left out keeps the platform's look. On iOS 26 a theme without `bar` keeps the bars on glass. On Android the bars take the colors of the app's Material 3 theme, neutral grays by default (see [Android's theme](#android)).
41
41
 
42
42
  The theme is the bottom layer of the options of every screen. A screen that needs its own look sets it in its options, and they go over the theme (see [Where a screen gets them](../fundamentals/screen-options#layers)).
43
43
 
@@ -106,9 +106,9 @@ The options of the app and of a screen can be built from the theme: their functi
106
106
 
107
107
  So a color that follows the theme belongs in the theme itself, or in the app's `options`.
108
108
 
109
- ### Android's colors
109
+ ### Android's theme
110
110
 
111
- (Android) The bars, tabs, search, sheets and menus are Material 3 views. What the theme and the options leave out, they take from the app's Android theme, as every Material view of the app does. On an app made from React Native's template, `setup` makes the app's theme inherit `Theme.ApexNavigation`: Material 3 in neutral grays, light and dark, with no tint of its own.
111
+ (Android) The bars, tabs, search, sheets, menus and the floating action button are Material 3 views. What the theme and the options leave out, they take from the app's Android theme, as every Material view of the app does. On an app made from React Native's template, `setup` makes the app's theme inherit `Theme.ApexNavigation`: Material 3 in neutral grays, light and dark, with no tint of its own.
112
112
 
113
113
  An app changes any of these colors in `styles.xml`. A color that differs in dark mode is a color resource with a second value in `values-night`, so the one style serves both modes:
114
114
 
@@ -130,19 +130,138 @@ The selected tab now sits on a peach pill in light mode, and a brown one in dark
130
130
 
131
131
  | Material 3 color | What takes it |
132
132
  | --- | --- |
133
- | `colorSurface` | The top bar. |
134
- | `colorOnSurface` | The title and the back arrow. |
135
- | `colorOnSurfaceVariant` | The subtitle and the "⋮" of the bar. |
136
- | `colorSurfaceContainer`, `colorSurfaceContainerLow`, `colorSurfaceContainerHigh` | The tab bar and the menus of the bar; a sheet; the search field. |
133
+ | `colorSurface` | The top bar, and the menus of the bar while the bar is opaque. |
134
+ | `colorOnSurface` | The title, the large title, the back arrow, the text of the search. |
135
+ | `colorOnSurfaceVariant` | The subtitle and the "⋮" of the bar; the hint of the search. |
136
+ | `colorSurfaceContainer` | The tab bar; the menus of the bar when the bar lets the screen through. |
137
+ | `colorSurfaceContainerLow` | A sheet. |
138
+ | `colorSurfaceContainerHigh` | The search field and its suggestions. |
137
139
  | `colorSecondaryContainer` | The pill of the selected tab, the selected scope of the search. |
138
140
  | `colorPrimaryContainer` | The floating action button. |
139
- | `colorError` | The badges of the tabs. |
141
+ | `colorError` | The badges of the tabs, the destructive items of the bar's menus. |
142
+ | `android:colorBackground` | Behind a screen without `layout.backgroundColor`. It comes from the activity's own theme, Material 3 or not; a screen in a sheet shows the sheet's color. |
140
143
 
141
- The theme's `colors` and a screen's options go over these: `bar` over the top bar and the tab bar, `text` over the titles, `badge` over the badges.
144
+ The theme's `colors` and a screen's options go over these: `bar` over the top bar and the tab bar, `text` over the titles, `badge` over the badges. The menus of the bar take the bar's color and the title's color while the bar is opaque; `topBar.menuBackgroundColor` and `topBar.menuTextColor` set them apart. These two are Android only: iOS draws its menus in the system's colors.
142
145
 
143
146
  - **An app with a Material 3 theme of its own** keeps it, and the navigation takes its colors.
144
- - **An app with a theme that isn't Material 3** keeps it too. The bars, tabs, search and sheets then take `Theme.ApexNavigation` themselves, and follow the app's light or dark mode.
145
- - **An app that is only light** sets it in code: `AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)`.
147
+ - **An app with a theme that isn't Material 3** keeps it too, and the navigation's views take `Theme.ApexNavigation` (see [the next section](#android-other-themes)).
148
+ - **An app that is only light** sets it in code: `AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)`. `Theme.ApexNavigation` follows dark mode, so without it the navigation's views turn dark with the device.
149
+
150
+ #### An app with an AppCompat or MaterialComponents theme
151
+
152
+ Many apps keep a theme of their own, such as `Theme.AppCompat.Light.NoActionBar` or `Theme.MaterialComponents.DayNight.NoActionBar`. `setup` leaves it as it is: it changes only the template's `Theme.AppCompat.DayNight.NoActionBar`.
153
+
154
+ The navigation tells a Material 3 theme by `colorSurfaceContainerHigh`, a role only Material 3 themes have. When the activity's theme has none, each view of the navigation is made in a copy of the app's theme with `Theme.ApexNavigation` **laid over it**. Over it means it wins: the colors, text appearances and shapes it sets replace the app's, so the app's `colorPrimary` and `colorAccent` don't reach the bars, and the bars are neutral gray next to the app's own colors. The app's own views keep its theme.
155
+
156
+ There are two ways to give the bars the app's colors.
157
+
158
+ **Move the theme to Material 3.** The parent becomes `Theme.ApexNavigation`, or `Theme.Material3.DayNight.NoActionBar` for Material's own palette, and the brand colors go to Material 3's roles, the ones in the table above:
159
+
160
+ ```xml
161
+ <!-- Before: parent="Theme.MaterialComponents.DayNight.NoActionBar" -->
162
+ <style name="AppTheme" parent="Theme.ApexNavigation">
163
+ <item name="colorSecondaryContainer">@color/selected_tab</item>
164
+ <item name="colorPrimaryContainer">@color/brand</item>
165
+ </style>
166
+ ```
167
+
168
+ The selected tab and the floating action button take the brand colors. Attributes Material 3 has no role for, such as `colorAccent`, `colorPrimaryDark` or `colorPrimaryVariant`, do nothing in the navigation. The app's own native views change with the theme too: its AppCompat and Material widgets and dialogs take the Material 3 look.
169
+
170
+ **Keep the theme, and color the navigation from JavaScript.** The colors of the [theme](#theme) are options, not Android theme attributes, so they paint the bars with any Android theme:
171
+
172
+ ```ts
173
+ export const Navigation = createNavigation({
174
+ // … screens and root
175
+ theme: {
176
+ colors: {
177
+ primary: '#E76F51',
178
+ bar: '#1E2A44',
179
+ text: '#F3E9D2',
180
+ badge: '#E63946',
181
+ },
182
+ },
183
+ });
184
+ ```
185
+
186
+ The bars, the titles, the buttons, the selected tab and the badges take the brand colors. The rest stays in `Theme.ApexNavigation`'s grays: the pill of the selected tab, a sheet, the search field, the floating action button. The navigation has **no theme attribute or overlay of its own** for them. Two of them have an option of their color: `fab.backgroundColor` and `topBar.searchBar.backgroundColor`; the pill of the selected tab and a sheet have none.
187
+
188
+ The way to recolor them in resources is to replace `Theme.ApexNavigation` itself: a style of the same name in the app wins over the library's when the build merges the resources. It replaces the whole style, so it has Material 3's parent, and it goes in `values` and again in `values-night`, or dark mode keeps the library's grays:
189
+
190
+ ```xml
191
+ <style name="Theme.ApexNavigation"
192
+ parent="Theme.Material3.DayNight.NoActionBar">
193
+ <item name="colorSecondaryContainer">#FCE4D6</item>
194
+ </style>
195
+ ```
196
+
197
+ ```xml
198
+ <style name="Theme.ApexNavigation"
199
+ parent="Theme.Material3.DayNight.NoActionBar">
200
+ <item name="colorSecondaryContainer">#5C3B2E</item>
201
+ </style>
202
+ ```
203
+
204
+ A role the app's style leaves out takes Material 3's own palette, with its violet tint, and not the navigation's grays.
205
+
206
+ #### Fonts and shapes
207
+
208
+ An app with a font of its own sets it in the options, which work with any Android theme. The app's `options` give it to every screen:
209
+
210
+ ```ts
211
+ export const Navigation = createNavigation({
212
+ // … screens and root
213
+ options: {
214
+ topBar: {
215
+ title: { fontFamily: 'Inter', fontWeight: '600' },
216
+ subtitle: { fontFamily: 'Inter' },
217
+ largeTitle: { fontFamily: 'Inter' },
218
+ },
219
+ bottomTab: { fontFamily: 'Inter' },
220
+ },
221
+ });
222
+ ```
223
+
224
+ The family is the name a `Text` style takes: a font in `assets/fonts/` or a `res/font` resource React Native knows. Without options, each text takes its font from the app's theme, or from Material 3's text appearances:
225
+
226
+ | Text | Without options | Options over it |
227
+ | --- | --- | --- |
228
+ | The title and the subtitle | 22 sp and 14 sp, set in code; the theme's `android:fontFamily`, else the system font. | `topBar.title.fontFamily`, `fontSize`, `fontWeight`, `fontStyle`; the same in `topBar.subtitle`. |
229
+ | The large title | 28 sp, set in code; the font as the title. | The same in `topBar.largeTitle`. |
230
+ | A text button of the bar | The theme's `actionMenuTextAppearance`. | `fontFamily`, `fontSize`, `fontWeight`, `fontStyle` of the button. |
231
+ | The labels of the tabs | `textAppearanceLabelMedium`, through Material 3's style of the tab bar. | `bottomTab.fontFamily`, `fontWeight`, `fontStyle`; `fontSize` and `selectedFontSize`. |
232
+ | The items of the bar's menus | `textAppearanceLargePopupMenu`, which Material 3 points to `textAppearanceBodyLarge`; the title of a submenu `textAppearancePopupMenuHeader`. | None. |
233
+ | The text of the search | 16 sp. The field in the bar takes the font as the title; the pill under the title, Material's `SearchBar`, its own `TextAppearance.Material3.SearchBar`. | None. |
234
+ | The scopes of the search | `textAppearanceLabelLarge`. | None. |
235
+
236
+ The shapes come mostly from code, not from `shapeAppearance…` attributes:
237
+
238
+ | Shape | Without options | Option over it |
239
+ | --- | --- | --- |
240
+ | A sheet | 28 dp, the top corners only, set in code. | `modal.sheet.cornerRadius`. |
241
+ | The menus of the bar | The theme's `popupMenuBackground`, a drawable: 4 dp in Material 3. | None. |
242
+ | The search field | A capsule: set in code in the bar, Material's `SearchBar` style under the title; the suggestions 16 dp, set in code. While the search fills the screen, Material's `SearchView` has no corners. | None. |
243
+ | The scopes of the search | `shapeAppearanceCornerSmall`. | None. |
244
+ | The tab bar | Square. | `bottomTabs.cornerRadius`. |
245
+ | The floating action button | `shapeAppearanceCornerLarge`. | None. |
246
+
247
+ An app with a Material 3 theme changes the theme's part in `styles.xml`. These attributes are the app's own: its other views that use them change too.
248
+
249
+ ```xml
250
+ <style name="AppTheme" parent="Theme.ApexNavigation">
251
+ <item name="android:fontFamily">@font/inter</item>
252
+ <item name="textAppearanceLabelMedium">@style/TabLabel</item>
253
+ <item name="popupMenuBackground">@drawable/menu</item>
254
+ </style>
255
+
256
+ <style name="TabLabel" parent="TextAppearance.Material3.LabelMedium">
257
+ <item name="fontFamily">@font/inter</item>
258
+ <item name="android:fontFamily">@font/inter</item>
259
+ </style>
260
+ ```
261
+
262
+ The title, the large title and the labels of the tabs are in Inter, and so is the search field in the bar from Android 8 on: before it, a plain text field can't load a font resource. The menus of the bar take the shape of `menu.xml`, in the bar's color while the bar is opaque.
263
+
264
+ In an app whose theme isn't Material 3, `Theme.ApexNavigation` lies over the app's theme, so the text appearances, `popupMenuBackground` and the shapes are `Theme.ApexNavigation`'s whatever the app's theme says. `Theme.ApexNavigation` doesn't set `android:fontFamily`, so the app's own still reaches the title, the large title and the search field in the bar. For the rest, the options are the way.
146
265
 
147
266
  ## The context
148
267
 
@@ -46,6 +46,8 @@ navigation.showModal('Player', {
46
46
  });
47
47
  ```
48
48
 
49
+ The top bar of a pushed screen goes with the screen on Android and stays in place on iOS: see [the bar in a transition of your own](#custom-bar).
50
+
49
51
  `presentation` of `createNavigation` gives every push or modal of the app its transition: see [Defaults for the whole app](../fundamentals/moving-between-screens#presentation). New roots have presets of their own: see [How a new root comes in](../fundamentals/switching-roots#transitions).
50
52
 
51
53
  ## Transitions out of a view
@@ -78,9 +80,11 @@ navigation.push('Person', {
78
80
  });
79
81
  ```
80
82
 
81
- The avatar of the row moves and grows into the photo of the profile, and the name into its larger title. The views can differ in size and style. `type` and `duration` next to `shared` change how the rest of the screen comes, `'fade'` by default.
83
+ The avatar of the row moves and grows into the photo of the profile, and the name into its larger title. The views can differ in size and style. A pair that isn't found is skipped (the transition waits for it first); one that fails on the way is skipped with a warning in the log. Either way its views show with their screens, and the other pairs move. `type` and `duration` next to `shared` change how the rest of the screen comes, `'fade'` by default.
84
+
85
+ A view turned or scaled by its own `transform`, or by a parent's, flies from where it shows and lands as the other view shows, turning the shorter way. The angle is the one React Native draws, from −180° to 180°: `rotate: '270deg'` turns back a quarter, and no pair spins a full turn; a spin is an animation of the view's own.
82
86
 
83
- Both platforms. (Android) The next screen waits until it is drawn, so its views are there to move into; a `type` other than a fade gives way to a fade.
87
+ What flies is a copy: pictures of the two views, taken as the transition starts, while the views wait hidden in their places. Both platforms. (Android) The next screen waits until it is drawn, so its views are there to take pictures of; an image flies as its own image, from its fit in one view to its fit in the other; a `type` other than a fade gives way to a fade. A skew and a tilt (`skewX`, `rotateX`, …) don't fly: the view flies without them and has them again at the end.
84
88
 
85
89
  ### Zoom
86
90
 
@@ -119,7 +123,7 @@ function Tile({ id, uri }: { id: string; uri: string }) {
119
123
  }
120
124
  ```
121
125
 
122
- The preview goes when the component unmounts. On Android a long press on the view does nothing of the navigation's: the view has no preview.
126
+ The previewed screen renders when the press starts, not when the component mounts ([when the screen renders](/api/transitions/usePreview#time)). The preview goes when the component unmounts. On Android a long press on the view does nothing of the navigation's: the view has no preview.
123
127
 
124
128
  ## Animations of your own
125
129
 
@@ -144,17 +148,60 @@ navigation.push('Details', {
144
148
 
145
149
  Details rises 300 points as it fades in. Each property animates from a value to a value over a time, with a delay and an interpolation if it needs them; the [API](#api) lists every one.
146
150
 
147
- The same goes for `pop`, `showModal`, `dismissModal`, `setStackRoot` and `setRoot`. The swipe back is the exception: (iOS) it always follows the finger with the system's slide, so a custom `pop` plays for the back button and `pop()` only.
151
+ (iOS) Once the move starts, the system draws it on its own, as it draws UIKit's animations: work on the main thread, such as a screen that mounts a long list, doesn't stop it.
152
+
153
+ The same goes for `pop`, `showModal`, `dismissModal`, `setStackRoot` and `setRoot`. The swipe back is the exception: (iOS) by default it follows the finger with the system's slide, so a custom `pop` plays for the back button and `pop()` only. (Android) A pop with an animation of its own shows no preview under the swipe: the screen pops when the swipe ends.
154
+
155
+ ### The swipe back with a pop of your own
156
+
157
+ (iOS) A screen that leaves with a move of its own, such as a card that shrinks away, looks wrong when the swipe back slides it out like any other screen. `interactive` on its pop plays its own move under the finger instead:
158
+
159
+ ```ts
160
+ navigation.push('Details', {
161
+ options: {
162
+ animations: {
163
+ pop: {
164
+ interactive: true,
165
+ content: {
166
+ exit: {
167
+ scaleX: { from: 1, to: 0.8, duration: 400 },
168
+ scaleY: { from: 1, to: 0.8, duration: 400 },
169
+ alpha: { from: 1, to: 0, duration: 400 },
170
+ },
171
+ },
172
+ },
173
+ },
174
+ },
175
+ });
176
+ ```
177
+
178
+ The swipe from the edge now shrinks Details as far as the finger has gone across the screen. The user can stop halfway; letting go past half way, or a flick back, finishes the pop, and letting go before half way, or a flick the other way, grows the screen back. After a quick flick the rest plays faster, never slower. The elements and the shared elements of the pop move with it, so a [shared element](#views) flies home under the finger.
179
+
180
+ - It applies only to a pop with an animation of its own, and `transition` presets get it through `options.animations.pop.interactive`.
181
+ - The swipe moves the time of the animation, not a point: a move with an easing doesn't stay exactly under the finger.
182
+ - On iOS 26 the swipe from the content stays off for a screen with a pop of its own; the swipe from the edge works.
183
+ - The top bar shows the screen under from the start of the swipe, as it does in any move of your own, and comes back if the user gives the swipe up.
184
+ - While the finger is down, the system's animations inside the two screens, such as an activity indicator, hold still.
185
+
186
+ (Android) It doesn't apply: a pop with an animation of its own plays when the back gesture ends.
187
+
188
+ ### The top bar
189
+
190
+ The top bar goes its platform's way in a preset or an animation of your own. (Android) It goes with its screen, as if it were part of it: with `slideUp` the new screen comes up with its bar over the old one and its bar, and on the way back it goes down with its bar, uncovering the bar below. With `fade` or `scale` the bar fades or grows with its screen. (iOS) UIKit keeps the bar in place and changes its title and buttons as the transition starts; only the screens under it move.
191
+
192
+ ### When the user reduces motion
193
+
194
+ The system's setting to reduce motion wins over a move of your own, with nothing to set. (iOS) With Reduce Motion on, the move becomes a fade of the same length: the screen that comes fades in on a push, a modal's show and `setRoot`, and the screen that goes fades out on a pop and a dismissal. No element moves. (Android) With Remove animations on, every animation of the app ends at once: the move jumps to its end, no element moves and the push doesn't wait for one, a side menu opens and closes without its slide, and a sheet shows and closes without it.
148
195
 
149
196
  ## Which to pick
150
197
 
151
198
  | The move | Pick | What it costs |
152
199
  | --- | --- | --- |
153
200
  | Most moves | The platform's | Nothing: it follows the finger and the system. |
154
- | A move that means something else, such as a fading modal | A preset | The swipe back on iOS still slides. |
201
+ | A move that means something else, such as a fading modal | A preset | The swipe back on iOS still slides, unless the pop is [`interactive`](#custom-swipe). |
155
202
  | A view that becomes the next screen | Shared elements, or the zoom on iOS 18+ | A `nativeID` on both views. The zoom shows on iOS 18+ only. |
156
203
  | A look at a screen before opening it | The preview | iOS only. |
157
- | A move no preset has | `options.animations` | Every property spelled out; the swipe back on iOS still slides. |
204
+ | A move no preset has | `options.animations` | Every property spelled out; the swipe back on iOS still slides, unless the pop is [`interactive`](#custom-swipe). |
158
205
 
159
206
  ## Waiting for the content
160
207
 
@@ -162,11 +209,10 @@ A screen can come in before its React content has drawn, or wait for it. Coming
162
209
 
163
210
  | | By default |
164
211
  | --- | --- |
165
- | (iOS) push | Doesn't wait for the content: the screen slides in with its bar, and the content draws as it comes. It waits only for components in the bar. |
166
- | (Android) push | Doesn't wait. With `appProvider` a React screen is rendered before the push starts, so it comes in drawn from the first frame. A screen with a React root of its own comes in at once, and its content draws as it comes; so does a native screen. The components of the bar draw as the screen comes in. |
212
+ | Push | Waits for the screen's first mount, half a second at most, so it comes in drawn, with what it set as it rendered (a title from `useScreenOptions`) already in its bar. A native screen comes in at once. (iOS) The components of the bar wait too, each to its own limit from the start of the wait. (Android) The components of the bar draw as the screen comes in; with `appProvider` the screen is rendered before the push starts ([below](#wait-one-tree)). |
167
213
  | (Android) modal | Waits for the content and the components of the bar, half a second at most, so the screen comes in drawn. |
168
214
 
169
- `waitForRender` of an animation changes it. `true` waits as long as it takes; `false` comes in at once (a push on Android with `appProvider` [still renders the screen first](#wait-one-tree)):
215
+ `waitForRender` of an animation changes it. `true` waits as long as it takes; `false` comes in at once, the content drawing as it comes (a push on Android with `appProvider` [still renders the screen first](#wait-one-tree)):
170
216
 
171
217
  ```ts
172
218
  navigation.push('Details', {
@@ -174,15 +220,15 @@ navigation.push('Details', {
174
220
  });
175
221
  ```
176
222
 
177
- A screen that draws nothing at first doesn't hold its transition back: it comes in empty, with its bar.
223
+ A screen that draws nothing at first holds its transition back half a second at most, then comes in with its bar.
178
224
 
179
225
  ### A push on Android, in one tree
180
226
 
181
- (Android) With `appProvider` a push doesn't wait for the screen, and the screen still comes in drawn: nothing of it mounts during the transition, which would drop frames. It goes in three steps:
227
+ (Android) With `appProvider` the screen comes in drawn without a wait of its own: nothing of it mounts during the transition, which would drop frames. It goes in three steps:
182
228
 
183
229
  1. The native side lays the screen out in its stack, out of sight, and gives React its size and its safe area.
184
230
  2. React renders the screen at that size with its content, at once.
185
- 3. The push starts in the frame in which that content appears; if it doesn't appear, after half a second.
231
+ 3. The push starts right after that content appears, once what the screen set as it rendered (its `useScreenOptions`) is applied; if it doesn't appear, after half a second.
186
232
 
187
233
  So the push starts later by the time React takes to render the screen, as a push in a native app starts once its screen is built. `waitForRender: false` goes the same way here; `true` waits for the content as long as it takes, and for the components of the bar, half a second at most.
188
234
 
@@ -52,8 +52,8 @@ Compose shows with a close button at the leading edge of its top bar. The settin
52
52
 
53
53
  | Setting | What it does |
54
54
  | --- | --- |
55
- | `closeButton` | A close button on the first screen: the system one on iOS, an icon on Android. Needs the stack. |
56
- | `onDismiss` | Called once the modal is gone, whatever closed it: a swipe, a command, a new root. |
55
+ | `closeButton` | A close button on the first screen: the system one on iOS, an icon on Android. Needs the stack. A new first screen from `setStack` or `replace` in the modal's stack gets it too. |
56
+ | `onDismiss` | Called once the modal is gone, whatever closed it: a swipe, a command, a new root. `setStack` and `replace` in the modal's stack replace its first screen and call it too. |
57
57
  | `stack` | `false`: the screen alone, without a stack and its top bar. |
58
58
  | `style`, `sheet`, `popover`, `contentSize` | How it looks: see [How a modal looks](#styles). |
59
59
  | `transition`, `options` | The animation, and the screen's options for this show. |
@@ -70,6 +70,8 @@ navigation.showModal('Compose', { style: 'fullScreen' });
70
70
 
71
71
  Without `style`, a modal is a sheet on (iOS) and covers the whole screen on (Android).
72
72
 
73
+ `'pageSheet'` and `'formSheet'` are sheets on both platforms: on (Android) the Material bottom sheet over the dimmed screen, at the full height under the status bar and at most 640 dp wide. `'fullScreen'` and `'overFullScreen'` come up from the bottom over the whole screen; on Android with the system's motion of a window opening over another, without a fade.
74
+
73
75
  `'overFullScreen'` keeps the screen under the modal in place, so it shows through wherever the modal draws nothing: a dialog of your own, a card over a dimmed app. Give the modal's screen `backgroundColor('transparent')` in its options, so its own background doesn't hide the screen under it.
74
76
 
75
77
  ### A form on iPad
@@ -83,7 +85,7 @@ navigation.showModal('EditProfile', {
83
85
  });
84
86
  ```
85
87
 
86
- On iPhone a form sheet is a sheet, and `contentSize` does nothing.
88
+ On iPhone and on Android a form sheet is a sheet, and `contentSize` does nothing.
87
89
 
88
90
  ### A popover
89
91
 
@@ -95,7 +97,7 @@ navigation.showModal('Filters', {
95
97
  });
96
98
  ```
97
99
 
98
- On iPhone it becomes a sheet, unless `adaptive: false` keeps it a popover. (Android) has no popovers: the modal covers the whole screen, as without `style`.
100
+ On iPhone it becomes a sheet, unless `adaptive: false` keeps it a popover. (Android) has no popovers: the modal is the bottom sheet of `'pageSheet'`.
99
101
 
100
102
  ## Sheets
101
103
 
@@ -124,6 +126,8 @@ navigation.setOptions({
124
126
 
125
127
  On (Android) a sheet is the Material bottom sheet. It stops at half (`'medium'`) and full (`'large'`) height and at heights of its own; `'content'` stops at half.
126
128
 
129
+ (Android) 14+ The back gesture over a sheet shows it sliding down before the user lets go: [the preview of a sheet closing](../screen-ui/back-and-gestures#sheet-preview).
130
+
127
131
  Sheets in a real app, step by step: [Bottom sheets](../flows/bottom-sheets).
128
132
 
129
133
  ## How a modal closes
@@ -24,7 +24,9 @@ This page answers:
24
24
 
25
25
  A push or a modal moves the user somewhere. An overlay doesn't move anyone: it puts a screen **on top of everything**, and the app goes on under it.
26
26
 
27
- An overlay is a screen of `screens` like any other: a component, its props, its options. It shows above the tabs, the bars and the modals; on (iOS) it is in a window of its own. Its background is transparent, so the app shows wherever the overlay draws nothing. What overlays are for:
27
+ An overlay is a screen of `screens` like any other: a component, its props, its options. It shows above the tabs, the bars and the modals; on (iOS) it is in a window of its own. Its background is transparent, so the app shows wherever the overlay draws nothing.
28
+
29
+ An overlay covers the whole window, **the status bar included**: a dialog's dimmed backdrop dims the status bar too, as a system dialog does. Its safe area keeps the top and the sides off the bars, so a toast at the top of the overlay sits below the status bar. On (Android) a status bar with a color of its own (`statusBar.backgroundColor`) stays over the backdrop, and `statusBar.drawBehind: false` starts the overlay below the status bar. What overlays are for:
28
30
 
29
31
  ## Showing and closing
30
32
 
@@ -74,7 +74,7 @@ A tap on the button opens the menu. A button of the options gets the navigation
74
74
 
75
75
  ## A pick in the menu
76
76
 
77
- A menu is a screen without a stack, so **its commands act on the center**, and the menu closes once the center has changed. A pick usually switches the section, so the center starts over with it:
77
+ A menu is a screen without a stack, so **its commands act on the center**, and the menu closes as the center changes: it starts to slide away at the tap, and a push slides in as it goes. The command resolves once both are done. A pick usually switches the section, so the center starts over with it:
78
78
 
79
79
  ```tsx
80
80
  import { Button, View } from 'react-native';
@@ -94,7 +94,7 @@ function Menu() {
94
94
  }
95
95
  ```
96
96
 
97
- A tap on Settings shows Settings in the center, and the menu closes. Which command to use depends on the way back:
97
+ A tap on Settings closes the menu and shows Settings in the center as it goes. Which command to use depends on the way back:
98
98
 
99
99
  | From the menu | The center |
100
100
  | --- | --- |
@@ -108,6 +108,8 @@ A tap on Settings shows Settings in the center, and the menu closes. Which comma
108
108
  | (iOS) | Over the content, which dims: `openMode: 'aboveContent'` of the side, the default. Or under it, with the content moved aside: `'pushContent'`. Then `animation(…)` says how the menu appears: `'parallax'`, `'slide'`, `'slide-and-scale'` or `'door'`. |
109
109
  | (Android) | The drawer of the platform: over the content, which dims. |
110
110
 
111
+ The menu's color is its screen's `layout.backgroundColor`: it fills the whole height of the menu, behind the status bar and the navigation bar, while the menu's content keeps its top and sides clear of them (the bottom goes down to the edge: a list adds `insets.bottom`). A background on the React content stops at the safe area.
112
+
111
113
  `.ios()` keeps the settings that only iOS has apart from the others:
112
114
 
113
115
  ```ts
@@ -122,6 +124,21 @@ On iOS the content moves aside, and the menu comes in under it with a parallax;
122
124
 
123
125
  (iOS) 26: `left({ glass: true })` puts the menu on Liquid Glass. The glass shows where the menu's screen has no background of its own.
124
126
 
127
+ ## When the menus are created
128
+
129
+ The screens of the menus are created with the side menu by default, with their React content. A heavy menu competes
130
+ with the first render of the center. `options({ menusAttachMode })` moves the creation:
131
+
132
+ ```ts
133
+ SideMenu({ left: 'Menu', center: 'Home' }).options({ menusAttachMode: 'onOpen' });
134
+ ```
135
+
136
+ - `'together'` (the default): with the center.
137
+ - `'afterCenter'`: right after the side menu first appears. The menus don't compete with the first render of the center and are ready at the first open.
138
+ - `'onOpen'`: each menu the first time it starts to open, from a swipe, `openMenu`, `visible: true` or `visible` in the layout. Until React draws the menu, it shows its background (`backgroundColor`). A second open reuses it.
139
+
140
+ The trade-off of `'onOpen'`: the first open of a menu doesn't wait for its render and shows its background for a moment, while a menu not opened yet runs no code. A push into the stack of such a menu and `mergeOptions` on its screen wait for the menu, like a tab not yet selected. The screens of the menus get appear events only when the menu opens, in every mode. The mode is read once, when the side menu is created, from its own options, else the default options; `mergeOptions` doesn't change it. With `appProvider` the screens render in the app's React tree at once in every mode, and the mode delays only their native containers. It means the same on iOS and Android.
141
+
125
142
  ## Where the swipe is off
126
143
 
127
144
  A swipe from the edge can clash with the content, such as a map or a carousel. A screen turns it off **while it is on top of the center**, in its options:
@@ -90,6 +90,10 @@ This is the app's `navigation`: its `push` goes to the stack the user sees, now
90
90
 
91
91
  Inbox shows, and Chat comes in over it, in the stack of the Inbox tab.
92
92
 
93
+ On (Android) the content changes with Material's fade through, as in the system's Phone app: the tab that goes fades out, then the new one fades in and grows to its size, in 300 ms; the tab bar stays. On (iOS) the new tab shows at once, as the system's tab bar does.
94
+
95
+ To switch at once on Android too, give `bottomTabs.switchAnimation: 'none'`: to every tabs node in the app's default `options`, to these tabs with `Tabs().options({ switchAnimation: 'none' })`, or to a screen. The tab that is selected decides, by the screen on top of it: a tab whose top screen says `'none'` comes in at once, and leaving it fades as usual. A screen's `setOptions` changes it from the next switch.
96
+
93
97
  ### A press on a tab
94
98
 
95
99
  A second tap on the selected tab is a convention of both platforms: **back to the start of the tab**. The navigation does it without code:
@@ -144,7 +148,7 @@ From a screen of the tab, `setTabBadge(count)` needs no id: it sets the badge of
144
148
 
145
149
  ## When tabs are created
146
150
 
147
- By default every tab is created with the tabs, so a switch shows it at once. `Tabs().lazy()` creates each tab the first time it shows. The app starts faster when its tabs are heavy, and a tab the user never opens costs nothing.
151
+ By default every tab is created with the tabs, so a switch shows it at once. On (iOS) a text input's `autoFocus` in a tab not selected yet does nothing then: focus the field in `useScreenAppear`. `Tabs().lazy()` creates each tab the first time it shows. The app starts faster when its tabs are heavy, and a tab the user never opens costs nothing.
148
152
 
149
153
  ```ts
150
154
  const main = Tabs(/* … */).lazy();
@@ -152,7 +152,7 @@ navigation.showModal('PhotoActions', {
152
152
  });
153
153
  ```
154
154
 
155
- The content is measured after every render, so the sheet follows it when it grows. It needs (iOS) 16; on (Android) the sheet stops at half the height instead, as the Material sheet has no height of its content. A screen that fills its parent (`flex: 1`) has no height of its own, so give the content of this screen its natural height.
155
+ The content is measured after every render, so the sheet follows it when it grows. It needs (iOS) 16. A screen that fills its parent (`flex: 1`) has no height of its own, so give the content of this screen its natural height. The sheet adds the bottom safe area to the height of a `'content'` sheet itself (UIKit on (iOS), the navigation bar on (Android)), so don't add `insets.bottom` to its content: the gap would come twice.
156
156
 
157
157
  ## 8. Close it with a pick
158
158
 
@@ -218,8 +218,10 @@ The sheet is (iOS) UIKit's sheet, and on (Android) the Material bottom sheet. Th
218
218
  | --- | --- | --- |
219
219
  | `'medium'`, `'large'` | Half and full height. | Half height, and full height under the status bar. |
220
220
  | A number | That height, in points. iOS 16+: iOS 15 leaves it out. | That height, in dp. |
221
- | `'content'` | The height of the content. iOS 16+: iOS 15 leaves it out. | Half the height: the Material sheet has no height of its content. |
221
+ | How many stops | Every detent of the list. | Three at most: the lowest, the highest, and one between them (`selectedDetent` when it stands there, else the lowest of the others). |
222
+ | `'content'` | The height of the content. iOS 16+: iOS 15 leaves it out. | The height of the content. |
222
223
  | The screen under it | Shrinks back a little at full height, as UIKit does. | Stays in place. |
224
+ | The keyboard | The sheet rises and stands on it. | The sheet rises and stands on it at every stop, unless the screen in it has `layout.adjustResize: false`. |
223
225
 
224
226
  ## The whole code
225
227
 
@@ -299,7 +299,7 @@ navigation.showModal('EditProfile', {
299
299
  });
300
300
  ```
301
301
 
302
- On iPhone a form sheet is the same sheet as before, and on Android the modal is unchanged.
302
+ On iPhone a form sheet is the same sheet as before. On Android it is the Material bottom sheet, where the modal without a style covered the whole screen.
303
303
 
304
304
  ## The whole code
305
305