@apexnative/navigation 1.0.0-alpha.5 → 1.0.0-alpha.7

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 (358) hide show
  1. package/ApexNavigation.podspec +2 -1
  2. package/CHANGELOG.md +32 -0
  3. package/README.md +1 -1
  4. package/android/CLAUDE.md +31 -20
  5. package/android/CORE.md +12 -8
  6. package/android/consumer-rules.pro +6 -0
  7. package/android/src/main/java/dev/apexnative/navigation/NavigationActivity.kt +36 -5
  8. package/android/src/main/java/dev/apexnative/navigation/options/BottomTabOptions.kt +1 -1
  9. package/android/src/main/java/dev/apexnative/navigation/options/BottomTabsOptions.kt +13 -8
  10. package/android/src/main/java/dev/apexnative/navigation/options/ButtonOptions.kt +1 -1
  11. package/android/src/main/java/dev/apexnative/navigation/options/LargeTitleOptions.kt +1 -1
  12. package/android/src/main/java/dev/apexnative/navigation/options/LayoutAnimation.kt +1 -1
  13. package/android/src/main/java/dev/apexnative/navigation/options/OptionKey.kt +18 -0
  14. package/android/src/main/java/dev/apexnative/navigation/options/OptionPaths.kt +91 -0
  15. package/android/src/main/java/dev/apexnative/navigation/options/SheetOptions.kt +7 -4
  16. package/android/src/main/java/dev/apexnative/navigation/options/TitleOptions.kt +2 -2
  17. package/android/src/main/java/dev/apexnative/navigation/options/TopBarAppearanceOptions.kt +1 -1
  18. package/android/src/main/java/dev/apexnative/navigation/options/TopBarOptions.kt +16 -7
  19. package/android/src/main/java/dev/apexnative/navigation/react/ContentHeights.kt +95 -0
  20. package/android/src/main/java/dev/apexnative/navigation/react/ContentMounts.kt +66 -0
  21. package/android/src/main/java/dev/apexnative/navigation/react/NavigationTurboModule.kt +7 -3
  22. package/android/src/main/java/dev/apexnative/navigation/react/OptionsCommands.kt +41 -3
  23. package/android/src/main/java/dev/apexnative/navigation/react/ReactView.kt +16 -1
  24. package/android/src/main/java/dev/apexnative/navigation/react/ReloadCoordinator.kt +0 -2
  25. package/android/src/main/java/dev/apexnative/navigation/react/ScreenEnvironment.kt +177 -0
  26. package/android/src/main/java/dev/apexnative/navigation/react/ScreenRegions.kt +12 -49
  27. package/android/src/main/java/dev/apexnative/navigation/react/ScrollEvents.kt +49 -128
  28. package/android/src/main/java/dev/apexnative/navigation/safearea/SafeAreaView.kt +6 -6
  29. package/android/src/main/java/dev/apexnative/navigation/slots/SlotScreenView.kt +27 -7
  30. package/android/src/main/java/dev/apexnative/navigation/slots/SlotView.kt +12 -1
  31. package/android/src/main/java/dev/apexnative/navigation/utils/MaterialTheme.kt +5 -6
  32. package/android/src/main/java/dev/apexnative/navigation/utils/SystemAnimations.kt +36 -0
  33. package/android/src/main/java/dev/apexnative/navigation/utils/ViewExtensions.kt +0 -13
  34. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/ArrangementController.kt +9 -7
  35. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsCollapseBehavior.kt +5 -3
  36. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsController.kt +13 -10
  37. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowGeometry.kt +22 -0
  38. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabsRoom.kt +0 -5
  39. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentViewController.kt +7 -8
  40. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenSafeArea.kt +29 -11
  41. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/externalcomponent/ExternalComponentViewController.kt +2 -6
  42. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalCoordinator.kt +20 -2
  43. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalSheet.kt +443 -58
  44. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalViews.kt +33 -5
  45. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetBack.kt +42 -0
  46. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetStops.kt +60 -2
  47. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/Navigator.kt +4 -0
  48. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ParentController.kt +3 -6
  49. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuMotion.kt +8 -2
  50. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/BackPreview.kt +32 -4
  51. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/PreparedFrame.kt +3 -3
  52. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackCommands.kt +2 -2
  53. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackController.kt +50 -7
  54. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackQueue.kt +15 -3
  55. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackViews.kt +10 -4
  56. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabMotion.kt +142 -0
  57. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabPresenter.kt +215 -43
  58. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/StackSearchPresenter.kt +25 -26
  59. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/BarRowTransition.kt +3 -2
  60. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/ButtonPlaces.kt +11 -5
  61. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarPresenter.kt +36 -38
  62. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ScrollEventListener.kt +6 -9
  63. package/android/src/main/java/dev/apexnative/navigation/views/animations/AnimationLayer.kt +73 -0
  64. package/android/src/main/java/dev/apexnative/navigation/views/animations/ValueInterpolation.kt +14 -0
  65. package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabsLayout.kt +61 -2
  66. package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomTabRow.kt +72 -10
  67. package/android/src/main/java/dev/apexnative/navigation/views/element/ElementTransitions.kt +129 -179
  68. package/android/src/main/java/dev/apexnative/navigation/views/element/TargetsWait.kt +8 -1
  69. package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionLayer.kt +37 -112
  70. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ElementPictures.kt +67 -3
  71. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/FlightGeometry.kt +346 -36
  72. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMorph.kt +199 -0
  73. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/SharedAnimatorFactory.kt +55 -42
  74. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextMorph.kt +176 -0
  75. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewMorph.kt +108 -0
  76. package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabCopy.kt +85 -0
  77. package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabMenu.kt +13 -0
  78. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TitleBar.kt +5 -24
  79. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TopBar.kt +51 -34
  80. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonComponentCell.kt +6 -6
  81. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonView.kt +113 -0
  82. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarMenu.kt +219 -0
  83. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonBar.kt +121 -175
  84. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonMenus.kt +34 -64
  85. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonRow.kt +216 -0
  86. package/android/src/main/jni/ANNContentHeights.cpp +82 -0
  87. package/android/src/main/res/drawable/apex_navigation_ic_arrow_right.xml +14 -0
  88. package/android/src/main/res/layout/apex_navigation_menu_header.xml +19 -0
  89. package/android/src/main/res/layout/apex_navigation_menu_item.xml +68 -0
  90. package/android/src/main/res/values/styles.xml +1 -1
  91. package/android/src/main/res/values-night/styles.xml +1 -1
  92. package/cli/doctor/checks/app.js +16 -1
  93. package/cli/project.js +4 -0
  94. package/cli/setup/index.js +5 -0
  95. package/cli/setup/steps/metro.js +46 -0
  96. package/docs-md/architecture/native-screens.md +4 -0
  97. package/docs-md/architecture/theme-and-context.md +131 -12
  98. package/docs-md/architecture/transitions.md +46 -5
  99. package/docs-md/containers/modals.md +2 -0
  100. package/docs-md/containers/overlays.md +1 -1
  101. package/docs-md/containers/side-menu.md +1 -1
  102. package/docs-md/containers/tabs.md +2 -0
  103. package/docs-md/flows/bottom-sheets.md +4 -2
  104. package/docs-md/fundamentals/screens-and-props.md +9 -1
  105. package/docs-md/fundamentals/starting-the-app.md +1 -1
  106. package/docs-md/guides/cli.md +3 -1
  107. package/docs-md/help/glossary.md +2 -2
  108. package/docs-md/help/troubleshooting.md +22 -1
  109. package/docs-md/index.json +41 -1
  110. package/docs-md/migration/from-expo-router.md +1 -1
  111. package/docs-md/migration/from-react-native-navigation.md +1 -1
  112. package/docs-md/migration/from-react-navigation.md +2 -2
  113. package/docs-md/screen-ui/back-and-gestures.md +17 -1
  114. package/docs-md/screen-ui/bar-buttons.md +5 -5
  115. package/docs-md/screen-ui/search.md +1 -1
  116. package/docs-md/screen-ui/system-ui.md +16 -11
  117. package/docs-md/screen-ui/toolbar-and-fab.md +4 -2
  118. package/docs-md/screen-ui/top-bar.md +8 -4
  119. package/docs-md/start/installation.md +16 -1
  120. package/ios/Animations/ANNFrameDriver.h +55 -15
  121. package/ios/Animations/ANNFrameDriver.mm +216 -60
  122. package/ios/Animations/ANNTransitionAnimator.h +26 -5
  123. package/ios/Animations/ANNTransitionAnimator.mm +49 -3
  124. package/ios/Animations/ANNTransitionPlan.h +2 -2
  125. package/ios/Animations/ANNTransitionPlan.mm +10 -0
  126. package/ios/Animations/Elements/ANNElementFinder.h +2 -2
  127. package/ios/Animations/Elements/ANNElementFinder.mm +2 -2
  128. package/ios/Animations/Elements/ANNElementTransition.h +3 -3
  129. package/ios/Animations/Elements/ANNElementTransition.mm +2 -2
  130. package/ios/Animations/Elements/ANNSharedElementFlight.h +3 -3
  131. package/ios/Animations/Elements/ANNSharedElementFlight.mm +249 -45
  132. package/ios/Animations/Interpolators/ANNInterpolate.h +2 -30
  133. package/ios/Animations/Interpolators/ANNTransformParts.h +48 -0
  134. package/ios/Animations/Interpolators/ANNTransformParts.mm +507 -0
  135. package/ios/Animations/Interpolators/ANNViewTracks.h +9 -6
  136. package/ios/Animations/Interpolators/ANNViewTracks.mm +100 -30
  137. package/ios/CLAUDE.md +32 -22
  138. package/ios/CORE.md +25 -21
  139. package/ios/Contract/ANNCommandRunner.h +8 -7
  140. package/ios/Contract/ANNCommandRunner.mm +21 -27
  141. package/ios/Contract/ANNLayoutNode.h +3 -3
  142. package/ios/Contract/ANNLayoutReader.h +3 -3
  143. package/ios/Core/ANNAppDelegate.mm +0 -2
  144. package/ios/Core/ANNDeepLinkQueue.h +6 -5
  145. package/ios/Core/ANNDeepLinkQueue.mm +22 -10
  146. package/ios/Core/ANNJavaScriptCalls.h +11 -12
  147. package/ios/Core/ANNJavaScriptCalls.mm +7 -16
  148. package/ios/Core/ANNReloadCoordinator.mm +4 -8
  149. package/ios/Core/ANNSceneDelegate.mm +2 -2
  150. package/ios/Core/ApexNavigation+Internal.h +1 -1
  151. package/ios/Core/ApexNavigation.mm +6 -2
  152. package/ios/Layouts/Arrangement/ANNArrangementState.h +2 -17
  153. package/ios/Layouts/Arrangement/ANNArrangementState.mm +0 -38
  154. package/ios/Layouts/Arrangement/ANNArrangementViewController.mm +4 -4
  155. package/ios/Layouts/Root/ANNRootCoordinator.mm +45 -15
  156. package/ios/Layouts/Screen/ANNComponentViewController.h +2 -2
  157. package/ios/Layouts/Screen/ANNComponentViewController.mm +13 -23
  158. package/ios/Layouts/Screen/ANNPreviewInteraction.h +7 -4
  159. package/ios/Layouts/Screen/ANNPreviewInteraction.mm +72 -10
  160. package/ios/Layouts/Screen/ANNScreenEnvironment.h +63 -0
  161. package/ios/Layouts/Screen/ANNScreenEnvironment.mm +181 -0
  162. package/ios/Layouts/Screen/ANNScreenRegions.h +3 -18
  163. package/ios/Layouts/Screen/ANNScreenRegions.mm +0 -38
  164. package/ios/Layouts/Screen/ANNScreenSafeArea.h +4 -9
  165. package/ios/Layouts/Screen/ANNScreenSafeArea.mm +14 -16
  166. package/ios/Layouts/Stack/ANNPreviewPush.h +7 -6
  167. package/ios/Layouts/Stack/ANNPreviewPush.mm +57 -5
  168. package/ios/Layouts/Stack/ANNStackAnimatingDelegate.h +11 -2
  169. package/ios/Layouts/Stack/ANNStackAnimatingDelegate.mm +14 -7
  170. package/ios/Layouts/Stack/ANNStackController.h +8 -0
  171. package/ios/Layouts/Stack/ANNStackController.mm +153 -11
  172. package/ios/Layouts/Stack/ANNSwipePopInteraction.h +26 -0
  173. package/ios/Layouts/Stack/ANNSwipePopInteraction.mm +185 -0
  174. package/ios/Layouts/Stack/InteractivePopGestureDelegate.mm +28 -4
  175. package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.h +12 -1
  176. package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.mm +23 -0
  177. package/ios/Layouts/Tabs/ANNBottomTabsController.mm +2 -1
  178. package/ios/Layouts/Tabs/ANNBottomTabsCustomRow.mm +8 -3
  179. package/ios/Layouts/Tabs/ANNBottomTabsPresenter.h +4 -0
  180. package/ios/Layouts/Tabs/ANNBottomTabsPresenter.mm +123 -36
  181. package/ios/Layouts/Tabs/ANNTabsDesign.h +6 -5
  182. package/ios/Layouts/Tabs/ANNTabsDesign.mm +9 -1
  183. package/ios/Layouts/Tabs/UITabBar+utils.h +5 -5
  184. package/ios/Layouts/Tabs/UITabBar+utils.mm +32 -13
  185. package/ios/Options/ANNAnimationOptions.h +2 -1
  186. package/ios/Options/ANNAnimationOptions.mm +1 -1
  187. package/ios/Options/ANNBottomTabsOptions.h +2 -0
  188. package/ios/Options/ANNBottomTabsOptions.mm +1 -0
  189. package/ios/Options/ANNOptions.h +25 -0
  190. package/ios/Options/ANNOptions.mm +157 -1
  191. package/ios/Options/ANNOptionsReader.mm +108 -0
  192. package/ios/Options/ANNStackPopAnimationOptions.h +13 -0
  193. package/ios/Options/ANNStackPopAnimationOptions.mm +11 -0
  194. package/ios/Options/Params/ANNParam.h +15 -0
  195. package/ios/Options/Params/ANNParam.mm +61 -0
  196. package/ios/Options/Params/Color.h +3 -0
  197. package/ios/Options/Params/Color.mm +21 -0
  198. package/ios/Options/Params/ColorParser.h +4 -3
  199. package/ios/Options/Params/ColorParser.mm +22 -4
  200. package/ios/Options/Params/Image.h +4 -0
  201. package/ios/Options/Params/Image.mm +20 -0
  202. package/ios/React/ANNReactView.mm +6 -25
  203. package/ios/React/ANNSafeAreaViewComponentView.mm +26 -15
  204. package/ios/React/ANNSurfaceHostingView.h +14 -0
  205. package/ios/React/ANNSurfaceHostingView.mm +144 -1
  206. package/ios/React/Slots/ANNSlotScreenView.mm +8 -2
  207. package/ios/TopBar/ANNBackButtonPresenter.mm +6 -5
  208. package/ios/TopBar/ANNBarAppearance.h +2 -1
  209. package/ios/TopBar/ANNBarAppearance.mm +111 -30
  210. package/ios/TopBar/ANNBarBackgroundComponent.mm +16 -0
  211. package/ios/TopBar/ANNBarButtonComponentView.h +4 -4
  212. package/ios/TopBar/ANNBarButtonComponentView.mm +1 -1
  213. package/ios/TopBar/ANNBarButtons.h +5 -3
  214. package/ios/TopBar/ANNBarButtons.mm +186 -17
  215. package/ios/TopBar/ANNLargeTitlePresenter.mm +24 -4
  216. package/ios/TopBar/ANNMainList.h +3 -0
  217. package/ios/TopBar/ANNMainList.mm +4 -0
  218. package/ios/TopBar/ANNScrollEdgeEffects.h +22 -6
  219. package/ios/TopBar/ANNScrollEdgeEffects.mm +123 -16
  220. package/ios/TopBar/ANNSearchPresenter.mm +2 -2
  221. package/ios/TopBar/ANNSearchResultsViewController.mm +5 -5
  222. package/ios/TopBar/ANNTopBarPresenter.h +3 -2
  223. package/ios/TopBar/ANNTopBarPresenter.mm +95 -22
  224. package/ios/TurboModules/ANNTurboModule.mm +66 -16
  225. package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.cpp +20 -0
  226. package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.h +5 -14
  227. package/lib/module/ARCHITECTURE.md +17 -7
  228. package/lib/module/adapters/NativeANNTurboModule.js.map +1 -1
  229. package/lib/module/api/app/AppRegistry.js +14 -2
  230. package/lib/module/api/app/AppRegistry.js.map +1 -1
  231. package/lib/module/api/app/createNavigation.js +188 -66
  232. package/lib/module/api/app/createNavigation.js.map +1 -1
  233. package/lib/module/api/events/navigationEvents.js +6 -2
  234. package/lib/module/api/events/navigationEvents.js.map +1 -1
  235. package/lib/module/api/hooks/useSafeAreaInsets.js +4 -3
  236. package/lib/module/api/hooks/useSafeAreaInsets.js.map +1 -1
  237. package/lib/module/api/linking/linking.js +11 -0
  238. package/lib/module/api/linking/linking.js.map +1 -1
  239. package/lib/module/api/options/OptionsChain.js +2 -2
  240. package/lib/module/api/screens/defineScreen.js +45 -3
  241. package/lib/module/api/screens/defineScreen.js.map +1 -1
  242. package/lib/module/api/screens/nativeScreens.js +31 -6
  243. package/lib/module/api/screens/nativeScreens.js.map +1 -1
  244. package/lib/module/api/screens/registerScreens.js +172 -35
  245. package/lib/module/api/screens/registerScreens.js.map +1 -1
  246. package/lib/module/api/theme/theme.js +5 -0
  247. package/lib/module/api/theme/theme.js.map +1 -1
  248. package/lib/module/engine/commands.js +42 -2
  249. package/lib/module/engine/commands.js.map +1 -1
  250. package/lib/module/engine/layout.js +7 -2
  251. package/lib/module/engine/layout.js.map +1 -1
  252. package/lib/module/engine/nativeScreens.js +9 -0
  253. package/lib/module/engine/nativeScreens.js.map +1 -1
  254. package/lib/module/engine/options.js +5 -4
  255. package/lib/module/engine/options.js.map +1 -1
  256. package/lib/module/engine/optionsChange.js +102 -0
  257. package/lib/module/engine/optionsChange.js.map +1 -0
  258. package/lib/module/engine/refresh.js +85 -0
  259. package/lib/module/engine/refresh.js.map +1 -0
  260. package/lib/module/engine/rememberedOptions.js +60 -0
  261. package/lib/module/engine/rememberedOptions.js.map +1 -1
  262. package/lib/module/engine/screens.js +55 -4
  263. package/lib/module/engine/screens.js.map +1 -1
  264. package/lib/typescript/adapters/NativeANNTurboModule.d.ts +7 -0
  265. package/lib/typescript/adapters/NativeANNTurboModule.d.ts.map +1 -1
  266. package/lib/typescript/api/app/AppRegistry.d.ts.map +1 -1
  267. package/lib/typescript/api/app/createNavigation.d.ts +8 -3
  268. package/lib/typescript/api/app/createNavigation.d.ts.map +1 -1
  269. package/lib/typescript/api/events/navigationEvents.d.ts +2 -2
  270. package/lib/typescript/api/events/navigationEvents.d.ts.map +1 -1
  271. package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts +4 -3
  272. package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts.map +1 -1
  273. package/lib/typescript/api/index.d.ts +1 -1
  274. package/lib/typescript/api/index.d.ts.map +1 -1
  275. package/lib/typescript/api/linking/linking.d.ts +8 -0
  276. package/lib/typescript/api/linking/linking.d.ts.map +1 -1
  277. package/lib/typescript/api/options/OptionsChain.d.ts +2 -2
  278. package/lib/typescript/api/screens/defineScreen.d.ts +23 -4
  279. package/lib/typescript/api/screens/defineScreen.d.ts.map +1 -1
  280. package/lib/typescript/api/screens/nativeScreens.d.ts +8 -1
  281. package/lib/typescript/api/screens/nativeScreens.d.ts.map +1 -1
  282. package/lib/typescript/api/screens/registerScreens.d.ts.map +1 -1
  283. package/lib/typescript/api/theme/theme.d.ts +2 -0
  284. package/lib/typescript/api/theme/theme.d.ts.map +1 -1
  285. package/lib/typescript/engine/commands.d.ts +5 -0
  286. package/lib/typescript/engine/commands.d.ts.map +1 -1
  287. package/lib/typescript/engine/layout.d.ts.map +1 -1
  288. package/lib/typescript/engine/nativeScreens.d.ts +5 -0
  289. package/lib/typescript/engine/nativeScreens.d.ts.map +1 -1
  290. package/lib/typescript/engine/optionsChange.d.ts +28 -0
  291. package/lib/typescript/engine/optionsChange.d.ts.map +1 -0
  292. package/lib/typescript/engine/refresh.d.ts +35 -0
  293. package/lib/typescript/engine/refresh.d.ts.map +1 -0
  294. package/lib/typescript/engine/rememberedOptions.d.ts +13 -0
  295. package/lib/typescript/engine/rememberedOptions.d.ts.map +1 -1
  296. package/lib/typescript/engine/screens.d.ts +27 -6
  297. package/lib/typescript/engine/screens.d.ts.map +1 -1
  298. package/lib/typescript/interfaces/ComponentEvents.d.ts +2 -2
  299. package/lib/typescript/interfaces/options/animations.d.ts +44 -14
  300. package/lib/typescript/interfaces/options/animations.d.ts.map +1 -1
  301. package/lib/typescript/interfaces/options/bottomTabs.d.ts +19 -6
  302. package/lib/typescript/interfaces/options/bottomTabs.d.ts.map +1 -1
  303. package/lib/typescript/interfaces/options/buttons.d.ts +10 -10
  304. package/lib/typescript/interfaces/options/modals.d.ts +6 -7
  305. package/lib/typescript/interfaces/options/modals.d.ts.map +1 -1
  306. package/lib/typescript/interfaces/options/stack.d.ts +8 -3
  307. package/lib/typescript/interfaces/options/stack.d.ts.map +1 -1
  308. package/lib/typescript/interfaces/options/system.d.ts +8 -5
  309. package/lib/typescript/interfaces/options/system.d.ts.map +1 -1
  310. package/lib/typescript/interfaces/options/toolbar.d.ts +2 -2
  311. package/lib/typescript/interfaces/options/topBar.d.ts +46 -29
  312. package/lib/typescript/interfaces/options/topBar.d.ts.map +1 -1
  313. package/metro/acceptPlugin.js +57 -0
  314. package/metro/babelTransformer.js +45 -0
  315. package/metro/index.js +36 -0
  316. package/package.json +3 -1
  317. package/src/ARCHITECTURE.md +17 -7
  318. package/src/adapters/NativeANNTurboModule.ts +7 -0
  319. package/src/api/app/AppRegistry.ts +16 -2
  320. package/src/api/app/createNavigation.ts +201 -69
  321. package/src/api/events/navigationEvents.ts +9 -3
  322. package/src/api/hooks/useSafeAreaInsets.ts +4 -3
  323. package/src/api/index.ts +1 -0
  324. package/src/api/linking/linking.ts +22 -1
  325. package/src/api/options/OptionsChain.ts +2 -2
  326. package/src/api/screens/defineScreen.ts +49 -5
  327. package/src/api/screens/nativeScreens.ts +40 -4
  328. package/src/api/screens/registerScreens.tsx +170 -42
  329. package/src/api/theme/theme.ts +5 -0
  330. package/src/engine/commands.ts +51 -6
  331. package/src/engine/layout.ts +11 -2
  332. package/src/engine/nativeScreens.ts +10 -1
  333. package/src/engine/options.ts +6 -8
  334. package/src/engine/optionsChange.ts +107 -0
  335. package/src/engine/refresh.ts +97 -0
  336. package/src/engine/rememberedOptions.ts +70 -0
  337. package/src/engine/screens.tsx +53 -8
  338. package/src/interfaces/ComponentEvents.ts +2 -2
  339. package/src/interfaces/options/animations.ts +44 -14
  340. package/src/interfaces/options/bottomTabs.ts +19 -6
  341. package/src/interfaces/options/buttons.ts +10 -10
  342. package/src/interfaces/options/modals.ts +6 -7
  343. package/src/interfaces/options/stack.ts +8 -3
  344. package/src/interfaces/options/system.ts +8 -5
  345. package/src/interfaces/options/toolbar.ts +2 -2
  346. package/src/interfaces/options/topBar.ts +46 -29
  347. package/android/src/main/java/dev/apexnative/navigation/react/ArrangementStates.kt +0 -42
  348. package/android/src/main/java/dev/apexnative/navigation/react/ScreenInsets.kt +0 -70
  349. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowPlacer.kt +0 -223
  350. package/android/src/main/java/dev/apexnative/navigation/views/element/ElementStub.kt +0 -31
  351. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMatrixAnimator.kt +0 -136
  352. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PlainViewAnimator.kt +0 -86
  353. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PropertyAnimatorCreator.kt +0 -33
  354. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ReactImageAnimator.kt +0 -64
  355. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextChangeAnimator.kt +0 -177
  356. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewChangeAnimator.kt +0 -137
  357. package/ios/Layouts/Screen/ANNScreenInsets.h +0 -30
  358. package/ios/Layouts/Screen/ANNScreenInsets.mm +0 -70
@@ -2,149 +2,78 @@ package dev.apexnative.navigation.views.element
2
2
 
3
3
  import android.animation.Animator
4
4
  import android.animation.AnimatorListenerAdapter
5
- import android.graphics.Rect
6
5
  import android.os.Build
7
6
  import android.util.Log
8
7
  import android.view.View
9
8
  import android.view.ViewGroup
10
- import com.facebook.react.views.view.ReactViewGroup
11
9
  import dev.apexnative.navigation.options.ElementTransitionOptions
12
10
  import dev.apexnative.navigation.options.LayoutAnimation
13
11
  import dev.apexnative.navigation.options.SharedElementTransitionOptions
14
12
  import dev.apexnative.navigation.react.events.AppearanceDispatcher
15
13
  import dev.apexnative.navigation.utils.DevelopmentLog
16
14
  import dev.apexnative.navigation.utils.NavigationLog
15
+ import dev.apexnative.navigation.utils.SystemAnimations
17
16
  import dev.apexnative.navigation.viewcontrollers.viewcontroller.ViewController
17
+ import dev.apexnative.navigation.views.animations.AnimationLayer
18
18
  import dev.apexnative.navigation.views.animations.SideAnimator
19
19
  import dev.apexnative.navigation.views.element.animators.SharedAnimatorFactory
20
+ import java.util.Collections
21
+ import java.util.WeakHashMap
20
22
 
21
23
  /**
22
- * The elements of one transition: the element transitions and the targets of the shared elements found by their
23
- * `nativeID` (depth first, the first match) in the whole view of the screen each side shows — an element in the screen
24
- * that goes first, then in the one that comes; a pair's `fromId` in the screen that goes, its `toId` in the one that
25
- * comes; each screen is walked once for all of them ([TransitionViews]). What isn't found, what is in another
26
- * transition's layer and an image that isn't loaded is skipped; so is an element whose start fails ([elementStep]):
27
- * it goes back at once and the rest plays. Each view found moves into a [TransitionLayer] at its place on the screen,
28
- * in the order its hierarchy draws it, and an [ElementStub] takes its index in its parent. A pair's `from` stays where
29
- * it is, hidden while its copy flies. [finish] puts every view back at its index with its layout, its pivot and the
30
- * values of its properties read before — unless React removed its stub meanwhile: then it is gone for good —, shows
31
- * the `from`s again and takes the layer away. Main thread only.
24
+ * The elements of one transition: the element transitions and the shared pairs found by their `nativeID` (depth first,
25
+ * the first match) in the whole view of the screen each side shows — an element in the screen that goes first, then in
26
+ * the one that comes; a pair's `fromId` in the screen that goes, its `toId` in the one that comes; each screen is
27
+ * walked once for all of them ([TransitionViews]). What isn't found, what another transition plays now and an image
28
+ * that isn't loaded is skipped; so is an element whose start fails ([elementStep]): it gets its values back at once and
29
+ * the rest plays. No view leaves its parent, as on iOS. An element plays where it is, in its screen: its properties
30
+ * animate about its center and it moves with its screen. A pair flies as a copy drawn in a [TransitionLayer] over the
31
+ * screens, the copies in the order their targets are drawn; its `to` is hidden from the start, its `from` from the
32
+ * start of its flight. [finish] gives every element the values of its properties read before, shows the pairs' views
33
+ * again and takes the layer away. Main thread only.
32
34
  */
33
- internal class ElementTransition private constructor(private val layer: TransitionLayer) {
34
- // A view in the layer: where it came from and what it was.
35
- private class Moved(
36
- val view: View,
37
- val stub: ElementStub,
38
- val params: ViewGroup.LayoutParams,
39
- val frame: Rect,
40
- val values: FloatArray,
41
- val pivotSet: Boolean,
42
- // Where its parent's origin is in the layer: what `x` and `y` are counted from.
43
- val originX: Int,
44
- val originY: Int,
45
- )
35
+ internal class ElementTransition private constructor(
36
+ private val layer: TransitionLayer?,
37
+ // The views of the screens, as far as the parents that cut a pair's views count.
38
+ private val fromRoot: View?,
39
+ private val toRoot: View?,
40
+ ) {
41
+ // An element playing where it is: what it was.
42
+ private class InPlace(val view: View, val values: FloatArray, val pivotSet: Boolean)
46
43
 
47
- private val moved = ArrayList<Moved>()
48
- private val hidden = ArrayList<Pair<View, Float>>()
44
+ private val inPlace = ArrayList<InPlace>()
45
+ private val taken = ArrayList<View>()
46
+ // The views of the pairs hidden while their copies fly, with the alpha each had.
47
+ private val hidden = LinkedHashMap<View, Float>()
49
48
  private var finished = false
50
49
 
51
50
  /** The animators of the elements and of the shared elements, each with its own time. */
52
51
  val animators = ArrayList<Animator>()
53
52
 
54
- /** Every view back, the `from`s seen, the layer gone; at the end of the transition and at any stop. Once. */
53
+ /**
54
+ * Every element's values back, the pairs' views seen, the layer gone; at the end of the transition and at any stop.
55
+ * Once.
56
+ */
55
57
  fun finish() {
56
58
  if (finished) return
57
59
  finished = true
58
- for ((view, alpha) in hidden) view.alpha = alpha
60
+ for ((view, alpha) in hidden) show(view, alpha)
59
61
  hidden.clear()
60
- // Each view goes back on its own: one that can't (its parent gone wrong) doesn't keep the others in the layer.
61
- for (item in moved.asReversed()) {
62
+ // Each element on its own: one that can't get its values back doesn't keep the others from theirs.
63
+ for (item in inPlace.asReversed()) {
62
64
  try {
63
- giveBack(item)
65
+ restore(item.view, item.values, item.pivotSet)
64
66
  } catch (e: RuntimeException) {
65
- Log.w(NavigationLog.TAG, "[ApexNavigation] An element of a transition couldn't go back", e)
67
+ Log.w(NavigationLog.TAG, "[ApexNavigation] An element of a transition couldn't get its values back", e)
66
68
  }
67
69
  }
68
- moved.clear()
69
- layer.detach()
70
+ inPlace.clear()
71
+ playing -= taken.toSet()
72
+ taken.clear()
73
+ layer?.detach()
70
74
  }
71
75
 
72
- private fun moveIntoLayer(view: View): Moved? {
73
- val parent = view.parent as? ViewGroup ?: return null
74
- // A parent that clips its subviews keeps its own list of children, which a stub swapped in would leave
75
- // behind: its element stays where it is.
76
- if ((parent as? ReactViewGroup)?.removeClippedSubviews == true) return null
77
- val index = parent.indexOfChild(view)
78
- if (index < 0) return null
79
- val onScreen = IntArray(2)
80
- parent.getLocationOnScreen(onScreen)
81
- val origin = layer.originOnScreen
82
- val originX = onScreen[0] - parent.scrollX - origin.x
83
- val originY = onScreen[1] - parent.scrollY - origin.y
84
- val frame = Rect(view.left, view.top, view.right, view.bottom)
85
- val params = view.layoutParams ?: ViewGroup.LayoutParams(view.width, view.height)
86
- val pivotSet = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && view.isPivotSet
87
- val values = floatArrayOf(
88
- view.alpha, view.translationX, view.translationY, view.scaleX, view.scaleY, view.rotation,
89
- view.rotationX, view.rotationY, view.pivotX, view.pivotY,
90
- )
91
- val stub = ElementStub(view.context, view)
92
- try {
93
- parent.removeViewAt(index)
94
- parent.addView(stub, index, params)
95
- stub.layout(frame.left, frame.top, frame.right, frame.bottom)
96
- val left = originX + frame.left
97
- val top = originY + frame.top
98
- layer.put(view, left, top, frame.width(), frame.height())
99
- } catch (e: RuntimeException) {
100
- putBack(view, stub, parent, index, params, frame)
101
- throw e
102
- }
103
- // Scale and rotations turn about the center.
104
- view.pivotX = frame.width() / 2f
105
- view.pivotY = frame.height() / 2f
106
- return Moved(view, stub, params, frame, values, pivotSet, originX, originY).also { moved += it }
107
- }
108
-
109
- // A move that failed half way undone: the view back at its index in its parent, the stub gone.
110
- private fun putBack(
111
- view: View,
112
- stub: ElementStub,
113
- parent: ViewGroup,
114
- index: Int,
115
- params: ViewGroup.LayoutParams,
116
- frame: Rect,
117
- ) {
118
- if (view.parent === layer) layer.removeView(view)
119
- val stubIndex = parent.indexOfChild(stub)
120
- if (stubIndex >= 0) parent.removeViewAt(stubIndex)
121
- if (view.parent == null) {
122
- parent.addView(view, index.coerceAtMost(parent.childCount), params)
123
- view.layout(frame.left, frame.top, frame.right, frame.bottom)
124
- }
125
- }
126
-
127
- private fun giveBack(item: Moved) {
128
- val view = item.view
129
- // A commit of Fabric meanwhile laid it out in its parent's coordinates: the newest such frame holds.
130
- val reactFrame = if (view.parent === layer) layer.frameFromReact(view) else null
131
- if (view.parent === layer) layer.removeView(view)
132
- restore(view, item)
133
- val parent = item.stub.parent as? ViewGroup ?: return
134
- val index = parent.indexOfChild(item.stub)
135
- if (index < 0) return
136
- parent.removeViewAt(index)
137
- parent.addView(view, index, item.params)
138
- val frame = reactFrame ?: item.frame
139
- view.measure(
140
- View.MeasureSpec.makeMeasureSpec(frame.width(), View.MeasureSpec.EXACTLY),
141
- View.MeasureSpec.makeMeasureSpec(frame.height(), View.MeasureSpec.EXACTLY),
142
- )
143
- view.layout(frame.left, frame.top, frame.right, frame.bottom)
144
- }
145
-
146
- private fun restore(view: View, item: Moved) {
147
- val values = item.values
76
+ private fun restore(view: View, values: FloatArray, pivotSet: Boolean) {
148
77
  view.alpha = values[ALPHA]
149
78
  view.translationX = values[TRANSLATION_X]
150
79
  view.translationY = values[TRANSLATION_Y]
@@ -153,7 +82,7 @@ internal class ElementTransition private constructor(private val layer: Transiti
153
82
  view.rotation = values[ROTATION]
154
83
  view.rotationX = values[ROTATION_X]
155
84
  view.rotationY = values[ROTATION_Y]
156
- if (!item.pivotSet && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
85
+ if (!pivotSet && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
157
86
  view.resetPivot()
158
87
  } else {
159
88
  view.pivotX = values[PIVOT_X]
@@ -161,47 +90,74 @@ internal class ElementTransition private constructor(private val layer: Transiti
161
90
  }
162
91
  }
163
92
 
164
- private fun addElement(options: ElementTransitionOptions, item: Moved) {
165
- val base = SideAnimator.Base(xOffset = item.originX.toFloat(), yOffset = item.originY.toFloat())
166
- SideAnimator.build(item.view, options, base)?.let(animators::add)
93
+ // An element with views in it fades through a hardware layer only where its alpha would draw it into an offscreen
94
+ // buffer at every frame (AnimationLayer: its rendering overlaps). React's views overlap only with
95
+ // `needsOffscreenAlphaCompositing`, so most elements fade without one and nothing they draw outside their bounds (a
96
+ // box shadow) is clipped. A view without children fades its own drawing at no extra cost. Scale and rotations turn
97
+ // about the element's center; `x` and `y` are its place in its own parent.
98
+ private fun addElement(options: ElementTransitionOptions, view: View) {
99
+ inPlace += InPlace(view, valuesOf(view), pivotSetOf(view))
100
+ view.pivotX = view.width / 2f
101
+ view.pivotY = view.height / 2f
102
+ val animator = SideAnimator.build(view, options, SideAnimator.Base()) ?: return
103
+ if (view is ViewGroup) AnimationLayer.during(view, animator)
104
+ animators += animator
105
+ }
106
+
107
+ // An element whose start failed gets its values back now.
108
+ private fun giveValuesBack(view: View) {
109
+ val item = inPlace.lastOrNull { it.view === view } ?: return
110
+ inPlace -= item
111
+ try {
112
+ restore(view, item.values, item.pivotSet)
113
+ } catch (e: RuntimeException) {
114
+ Log.w(NavigationLog.TAG, "[ApexNavigation] An element of a transition couldn't get its values back", e)
115
+ }
167
116
  }
168
117
 
169
- // The pair's flight: `to` hidden until it starts, `from` hidden from its start; false when it doesn't fly.
118
+ // The pair's flight: `to` hidden from now, `from` from its start, both seen again when it stops or its copy can't
119
+ // be drawn. Nothing changes when it doesn't fly.
170
120
  private fun addPair(
171
121
  options: SharedElementTransitionOptions,
172
122
  from: View,
173
- item: Moved,
174
- toParent: View?,
123
+ to: View,
124
+ name: String,
175
125
  fallbackDuration: Long,
176
- ): Boolean {
177
- val to = item.view
126
+ ) {
127
+ val layer = layer ?: return
178
128
  val flight = SharedAnimatorFactory.create(
179
- from, to, toParent, layer, options, fallbackDuration, DevelopmentLog::warn,
180
- ) ?: return false
181
- val alpha = item.values[ALPHA]
129
+ from, to, fromRoot, toRoot, layer, options, fallbackDuration, DevelopmentLog::warn,
130
+ ) ?: return
182
131
  val fromAlpha = from.alpha
183
- to.alpha = 0f
184
- hidden += from to fromAlpha
132
+ val seenAgain = {
133
+ flight.picture.shown = false
134
+ hidden.remove(from)?.let { show(from, it) }
135
+ hidden.remove(to)?.let { show(to, it) }
136
+ layer.invalidate()
137
+ }
138
+ flight.picture.onFailed = { e ->
139
+ elementSkipped(name, e.toString())
140
+ seenAgain()
141
+ }
185
142
  flight.animator.addListener(object : AnimatorListenerAdapter() {
186
143
  private var stopped = false
187
144
 
188
145
  override fun onAnimationStart(animation: Animator) {
189
- if (stopped) return
146
+ if (stopped || finished) return
147
+ hidden[from] = fromAlpha
190
148
  from.alpha = 0f
191
- if (!flight.drawsPictures) to.alpha = alpha
192
149
  }
193
150
 
194
- // A flight whose start or frame failed stops (`MoveAnimator`), maybe inside its own start: `from` shows
195
- // again in its screen, and a `to` that moves itself in its place, as at any stop (a flight of pictures
196
- // shows its `to` at its end).
151
+ // A flight whose start or frame failed stops (`MoveAnimator`), maybe inside its own start.
197
152
  override fun onAnimationCancel(animation: Animator) {
198
153
  stopped = true
199
- from.alpha = fromAlpha
200
- if (!flight.drawsPictures) to.alpha = alpha
154
+ seenAgain()
201
155
  }
202
156
  })
157
+ layer.add(flight.picture)
158
+ hidden[to] = to.alpha
159
+ to.alpha = 0f
203
160
  animators += flight.animator
204
- return true
205
161
  }
206
162
 
207
163
  companion object {
@@ -216,10 +172,26 @@ internal class ElementTransition private constructor(private val layer: Transiti
216
172
  private const val PIVOT_X = 8
217
173
  private const val PIVOT_Y = 9
218
174
 
175
+ // The views the transitions that run now play: another transition leaves them alone.
176
+ private val playing: MutableSet<View> = Collections.newSetFromMap(WeakHashMap())
177
+
178
+ private fun valuesOf(view: View) = floatArrayOf(
179
+ view.alpha, view.translationX, view.translationY, view.scaleX, view.scaleY, view.rotation,
180
+ view.rotationX, view.rotationY, view.pivotX, view.pivotY,
181
+ )
182
+
183
+ private fun pivotSetOf(view: View) = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && view.isPivotSet
184
+
185
+ // A view hidden for a flight shows again with its alpha, unless React gave it another one meanwhile. React
186
+ // writes the same alpha: an opacity it commits during the flight shows the view beside its copy until the end.
187
+ private fun show(view: View, alpha: Float) {
188
+ if (view.alpha == 0f) view.alpha = alpha
189
+ }
190
+
219
191
  /**
220
- * The elements of [animation] from [from] to [to], moved into a layer that joins [host] at [layerIndex] (its
221
- * top without one); none when none of them is found. A shared element without a duration takes
222
- * [fallbackDuration], the screen's fade.
192
+ * The elements of [animation] from [from] to [to]; the copies of the pairs in a layer that joins [host] at
193
+ * [layerIndex] (its top without one). None when none of them is found or the system's animations are off. A
194
+ * shared element without a duration takes [fallbackDuration], the screen's fade.
223
195
  */
224
196
  fun start(
225
197
  animation: LayoutAnimation,
@@ -229,6 +201,7 @@ internal class ElementTransition private constructor(private val layer: Transiti
229
201
  layerIndex: Int?,
230
202
  fallbackDuration: Long,
231
203
  ): ElementTransition? {
204
+ if (SystemAnimations.areOff(host.context)) return null
232
205
  val fromView = from?.let { AppearanceDispatcher.visibleNode(it).peekView() }
233
206
  val toView = AppearanceDispatcher.visibleNode(to).peekView()
234
207
  val transitions = animation.elementTransitions.transitions
@@ -238,27 +211,28 @@ internal class ElementTransition private constructor(private val layer: Transiti
238
211
  val elements = ArrayList<Pair<ElementTransitionOptions, View>>()
239
212
  for (element in transitions) {
240
213
  if (element.id.isEmpty()) continue
241
- val view = found(views.leaving(element.id)) ?: found(views.arriving(element.id)) ?: continue
242
- if (TransitionLayer.holds(view) || !taken.add(view)) continue
214
+ val view = views.leaving(element.id) ?: views.arriving(element.id) ?: continue
215
+ if (view in playing || !taken.add(view)) continue
243
216
  elements += element to view
244
217
  }
245
218
  val pairs = ArrayList<Triple<SharedElementTransitionOptions, View, View>>()
246
219
  for (pair in shared) {
247
220
  val fromId = pair.fromId.get(null) ?: continue
248
221
  val toId = pair.toId.get(null) ?: continue
249
- val source = found(views.leaving(fromId)) ?: continue
250
- val target = found(views.arriving(toId)) ?: continue
251
- if (source === target || TransitionLayer.holds(source) || TransitionLayer.holds(target)) continue
222
+ val source = views.leaving(fromId) ?: continue
223
+ val target = views.arriving(toId) ?: continue
224
+ if (source === target || source in playing || target in playing) continue
252
225
  if (target in taken || source in taken) continue
253
226
  if (!loaded(source, fromId) || !loaded(target, toId)) continue
227
+ taken += source
254
228
  taken += target
255
229
  pairs += Triple(pair, source, target)
256
230
  }
257
231
  if (elements.isEmpty() && pairs.isEmpty()) return null
258
- val layer = TransitionLayer(host.context)
259
- val transition = ElementTransition(layer)
232
+ val layer = if (pairs.isEmpty()) null else TransitionLayer(host.context)
233
+ val transition = ElementTransition(layer, fromView, toView)
260
234
  try {
261
- layer.attachTo(host, layerIndex ?: host.childCount)
235
+ layer?.attachTo(host, layerIndex ?: host.childCount)
262
236
  transition.fill(host, elements, pairs, fallbackDuration)
263
237
  } catch (e: RuntimeException) {
264
238
  transition.finish()
@@ -268,8 +242,8 @@ internal class ElementTransition private constructor(private val layer: Transiti
268
242
  }
269
243
 
270
244
  /**
271
- * [start], and when that fails, a line in the log and none: the screens play without their elements; every view
272
- * moved is back already.
245
+ * [start], and when that fails, a line in the log and none: the screens play without their elements; every
246
+ * element has its values back already.
273
247
  */
274
248
  fun startOrLog(
275
249
  animation: LayoutAnimation,
@@ -285,8 +259,6 @@ internal class ElementTransition private constructor(private val layer: Transiti
285
259
  null
286
260
  }
287
261
 
288
- private fun found(view: View?): View? = view?.takeUnless { it is ElementStub }
289
-
290
262
  // An image not loaded drops out of the transition; its wait logged it already, else it is logged now.
291
263
  private fun loaded(view: View, id: String): Boolean {
292
264
  if (ImageLoads.isLoaded(view)) return true
@@ -295,45 +267,23 @@ internal class ElementTransition private constructor(private val layer: Transiti
295
267
  }
296
268
  }
297
269
 
298
- // The views into the layer in the order they are drawn, then their animators; a pair that doesn't fly goes back at
299
- // once. Each element's steps run on their own ([elementStep]): one that fails goes back, the others play.
270
+ // The elements' animators where they are, then the pairs' flights, their copies in the order their targets are
271
+ // drawn. Each element's steps run on their own ([elementStep]): one that fails is left as it was, the others play.
300
272
  private fun fill(
301
273
  host: ViewGroup,
302
274
  elements: List<Pair<ElementTransitionOptions, View>>,
303
275
  pairs: List<Triple<SharedElementTransitionOptions, View, View>>,
304
276
  fallbackDuration: Long,
305
277
  ) {
306
- val names = HashMap<View, String>()
307
- for ((options, view) in elements) names[view] = elementName(options.id)
308
- for ((options, _, target) in pairs) names[target] = pairName(options.fromId.get(""), options.toId.get(""))
309
- val views = elements.map { it.second } + pairs.map { it.third }
310
- val parents = views.associateWith { it.parent as? View }
311
- val placed = HashMap<View, Moved>()
312
- for (view in DrawOrder.sorted(views, host) { it }) {
313
- var item: Moved? = null
314
- if (elementStep(names.getValue(view)) { item = moveIntoLayer(view) }) item?.let { placed[view] = it }
315
- }
278
+ for ((_, view) in elements) taken += view
279
+ for ((_, source, target) in pairs) taken += listOf(source, target)
280
+ playing += taken
316
281
  for ((options, view) in elements) {
317
- val item = placed[view] ?: continue
318
- if (!elementStep(names.getValue(view)) { addElement(options, item) }) goBack(item)
319
- }
320
- for ((options, source, target) in pairs) {
321
- val item = placed[target] ?: continue
322
- var flies = false
323
- elementStep(names.getValue(target)) {
324
- flies = addPair(options, source, item, parents[target], fallbackDuration)
325
- }
326
- if (!flies) goBack(item)
282
+ if (!elementStep(elementName(options.id)) { addElement(options, view) }) giveValuesBack(view)
327
283
  }
328
- }
329
-
330
- // An element that doesn't play leaves the layer now; one that can't go back is logged, the others go on.
331
- private fun goBack(item: Moved) {
332
- moved -= item
333
- try {
334
- giveBack(item)
335
- } catch (e: RuntimeException) {
336
- Log.w(NavigationLog.TAG, "[ApexNavigation] An element of a transition couldn't go back", e)
284
+ for ((options, source, target) in DrawOrder.sorted(pairs, host) { it.third }) {
285
+ val name = pairName(options.fromId.get(""), options.toId.get(""))
286
+ elementStep(name) { addPair(options, source, target, name, fallbackDuration) }
337
287
  }
338
288
  }
339
289
  }
@@ -7,6 +7,7 @@ import dev.apexnative.navigation.options.LayoutAnimation
7
7
  import dev.apexnative.navigation.react.events.AppearanceDispatcher
8
8
  import dev.apexnative.navigation.utils.DevelopmentLog
9
9
  import dev.apexnative.navigation.utils.NavigationLog
10
+ import dev.apexnative.navigation.utils.SystemAnimations
10
11
  import dev.apexnative.navigation.viewcontrollers.viewcontroller.ViewController
11
12
  import kotlinx.coroutines.CancellationException
12
13
  import kotlinx.coroutines.CoroutineScope
@@ -17,7 +18,8 @@ import kotlinx.coroutines.launch
17
18
  /**
18
19
  * The wait of a forward transition with elements for its targets: the module's frames (`awaitTransitionTargets`, 0.5 s
19
20
  * at most, then one frame more), then the images of the shared elements found ([ImageWait], 1 s at most each). It ends
20
- * early when the screen that goes is destroyed. A failure in it is logged and the transition starts. Main thread only.
21
+ * early when the screen that goes is destroyed, and doesn't wait with the system's animations off. A failure in it is
22
+ * logged and the transition starts. Main thread only.
21
23
  */
22
24
  internal object TargetsWait {
23
25
  // The waits run on the main thread's frames; each is cancelled on its own.
@@ -31,6 +33,11 @@ internal object TargetsWait {
31
33
  waiting: () -> Boolean,
32
34
  done: () -> Unit,
33
35
  ): () -> Unit {
36
+ // With the system's animations off no element moves ([ElementTransition.start]): nothing to wait for.
37
+ if (SystemAnimations.areOff(to.peekView()?.context)) {
38
+ guarded { done() }
39
+ return NOTHING
40
+ }
34
41
  var stopped = false
35
42
  var stopImages: () -> Unit = NOTHING
36
43
  val still = { !stopped && waiting() && from?.isDestroyed != true }