@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
@@ -8,12 +8,12 @@ import androidx.core.view.ViewCompat
8
8
  import androidx.core.view.WindowInsetsCompat
9
9
  import dev.apexnative.navigation.options.DefaultOptions
10
10
  import dev.apexnative.navigation.options.Options
11
- import dev.apexnative.navigation.react.ArrangementStates
12
11
  import dev.apexnative.navigation.react.ReactView
13
- import dev.apexnative.navigation.react.ScreenInsets
12
+ import dev.apexnative.navigation.react.ScreenEnvironment
14
13
  import dev.apexnative.navigation.react.ScreenRegions
15
14
  import dev.apexnative.navigation.react.events.AppearanceDispatcher
16
15
  import dev.apexnative.navigation.react.events.ComponentType
16
+ import dev.apexnative.navigation.react.events.EventEmitter
17
17
  import dev.apexnative.navigation.slots.SlotScreenView
18
18
  import dev.apexnative.navigation.system.SystemUiOwner
19
19
  import dev.apexnative.navigation.viewcontrollers.child.ChildController
@@ -156,7 +156,7 @@ class ComponentViewController(
156
156
  shown = layout.isShown || prepared,
157
157
  layoutPending = !prepared && isLayoutPending(content),
158
158
  topOfStack = parent?.isTopOfStack(this) ?: true,
159
- hasSafeArea = ScreenInsets.padding(id) != null,
159
+ hasSafeArea = ScreenEnvironment.padding(id) != null,
160
160
  )
161
161
  if (!measures) return
162
162
  val windowInsets = ViewCompat.getRootWindowInsets(content) ?: return
@@ -175,10 +175,15 @@ class ComponentViewController(
175
175
  val edges = ScreenSafeArea.paddedEdges(
176
176
  safeAreaEdges = resolveCurrentOptions(DefaultOptions.current).layout.safeAreaEdges,
177
177
  topFree = parent?.leavesTopEdgeFree(this) == true,
178
- bottomFree = parent?.leavesBottomEdgeFree(this) == true,
178
+ largeTitle = parent?.showsLargeTitleOver(this) == true,
179
179
  )
180
- ScreenInsets.update(activity, id, insets, ScreenSafeArea.padding(insets, edges))
181
- ScreenRegions.update(activity, id, Rect(place.left, place.top, place.right, place.bottom), windowInsets)
180
+ // The events of the screen go to the JavaScript it was made for, and to no other.
181
+ val emitter = EventEmitter.of(jsGeneration)
182
+ val padding = ScreenSafeArea.padding(insets, edges)
183
+ val uncovered = ScreenSafeArea.uncovered(insets, padding)
184
+ ScreenEnvironment.setInsets(id, uncovered, padding, ScreenEnvironment.changesOf(emitter))
185
+ val area = Rect(place.left, place.top, place.right, place.bottom)
186
+ ScreenRegions.update(activity, id, area, windowInsets, emitter)
182
187
  }
183
188
 
184
189
  // A layout asked for on the content or on a view around it: it isn't in its place yet.
@@ -241,9 +246,7 @@ class ComponentViewController(
241
246
  }
242
247
  setParentController(null)
243
248
  if (isIdTakenByAnother) return
244
- ScreenInsets.remove(id)
245
- ScreenRegions.remove(id)
246
- ArrangementStates.remove(id)
249
+ ScreenEnvironment.remove(id)
247
250
  ScreenReadiness.remove(id)
248
251
  }
249
252
 
@@ -4,8 +4,8 @@ import dev.apexnative.navigation.viewcontrollers.viewcontroller.ViewController
4
4
 
5
5
  /**
6
6
  * Whether a screen's content rendered, which a command waits for before the screen comes in: a new root (`setRoot`),
7
- * a push with `waitForRender: true`, the new top of a `setStackRoot`. A wait never listens to the readiness store
8
- * itself: the content keeps the one listener of its id and tells every waiter. Main thread only.
7
+ * a push (unless `waitForRender: false`), the new top of a `setStackRoot`. A wait never listens to the readiness store
8
+ * itself: the content keeps its own listener of its id and tells every waiter. Main thread only.
9
9
  */
10
10
  internal interface Readiness {
11
11
  /** The content of [screen] rendered; a screen without content to wait for is ready. */
@@ -16,8 +16,10 @@ import dev.apexnative.navigation.viewcontrollers.viewcontroller.ViewController
16
16
  * without a limit.
17
17
  *
18
18
  * What differs between its users are its values, never its steps: the readiness and the clock (fakes in the unit
19
- * tests), [countsUnknownContent], how a readiness signal is delivered ([deliver]: at once, or posted to the next turn
20
- * of the main loop), and [step], the guard the user runs every later step in (a timer, a signal). Main thread only.
19
+ * tests), [countsUnknownContent], how a readiness signal is delivered ([deliver]: at once, posted to the next turn of
20
+ * the main loop, or behind the calls of JavaScript), whether content ready at once is delivered too
21
+ * ([deliversReadyContent]), and [step], the guard the user runs every later step in (a timer, a signal). Main thread
22
+ * only.
21
23
  */
22
24
  internal class RenderWait(
23
25
  private val readiness: Readiness,
@@ -32,6 +34,12 @@ internal class RenderWait(
32
34
  private val countsUnknownContent: Boolean,
33
35
  /** How a readiness signal reaches the wait: at once by default; posted, when a signal may come inside a layout. */
34
36
  private val deliver: (() -> Unit) -> Unit = { it() },
37
+ /**
38
+ * Content ready when the wait starts (or retakes) still reaches its end through [deliver], within the limit that
39
+ * runs: what [deliver] waits behind (a push's: the calls JavaScript made in the commit of that content) comes
40
+ * first. Off: such content ends the wait at once.
41
+ */
42
+ private val deliversReadyContent: Boolean = false,
35
43
  /** Runs a later step of the wait (a timer, a signal): the user's guards and protection; as it is by default. */
36
44
  private val step: (() -> Unit) -> Unit = { it() },
37
45
  private val onEnd: () -> Unit,
@@ -70,7 +78,8 @@ internal class RenderWait(
70
78
 
71
79
  /**
72
80
  * Starts waiting for [screens], and for the content of [unseen] within its first [UNSEEN_LIMIT_MILLIS]; with all
73
- * of them ready (and their bars' components, when they count within the limit) it ends at once, before it returns.
81
+ * of them ready (and their bars' components, when they count within the limit) it ends at once, before it returns,
82
+ * or through [deliver] with [deliversReadyContent].
74
83
  */
75
84
  fun start(screens: List<ViewController<*>>, unseen: List<ViewController<*>> = emptyList()) {
76
85
  this.screens = screens
@@ -78,15 +87,18 @@ internal class RenderWait(
78
87
  unseenDone = unseen.isEmpty()
79
88
  waiting = true
80
89
  token = Any()
81
- // Content ready at once ends the wait, unless the bar's components count within a limit: it runs for them.
82
- if (contentReady() && !(bar == Bar.WithinLimit && limitMillis != null)) return contentDone()
90
+ // Content ready at once ends the wait, unless the bar's components count within a limit (it runs for them) or
91
+ // the content goes through [deliver] too.
92
+ val ready = contentReady()
93
+ if (ready && !deliversReadyContent && !(bar == Bar.WithinLimit && limitMillis != null)) return contentDone()
94
+ // The timers first: a [deliver] that runs at once may end the wait before this returns.
83
95
  cancelContentTimer = when {
84
96
  limitMillis != null -> scheduler.schedule(limitMillis) { step { atLimit() } }
85
97
  countsUnknownContent -> scheduler.schedule(UNKNOWN_CONTENT_MILLIS) { step { atUnknownContentLimit() } }
86
98
  else -> null
87
99
  }
88
100
  startUnseenLimit()
89
- await()
101
+ if (ready && deliversReadyContent) deliverReady() else await()
90
102
  }
91
103
 
92
104
  /**
@@ -98,7 +110,7 @@ internal class RenderWait(
98
110
  this.screens = screens
99
111
  this.unseen = unseen
100
112
  token = Any()
101
- await()
113
+ if (deliversReadyContent && contentReady()) deliverReady() else await()
102
114
  }
103
115
 
104
116
  /** Ends the wait without [onEnd]: its timers stop, and the signals still to come do nothing. */
@@ -129,6 +141,14 @@ internal class RenderWait(
129
141
  if (contentReady() && cancelBarPhase == null) contentDone()
130
142
  }
131
143
 
144
+ // The content is ready already: it goes once through [deliver] as a signal would, then on as [await] says.
145
+ private fun deliverReady() {
146
+ val token = token
147
+ deliver {
148
+ step { if (waiting && this.token === token) await() }
149
+ }
150
+ }
151
+
132
152
  // The content of every screen ready: on to the bars; else the signals of those not ready.
133
153
  private fun await() {
134
154
  if (contentReady()) return contentDone()
@@ -143,7 +143,7 @@ internal class ScreenFrame(
143
143
  val parent = node.parentController
144
144
  val statusBar = ScreenSafeArea.statusBarRoom(
145
145
  statusBarHeight = statusBarHeight,
146
- hiddenOrDrawBehind = options.statusBar.isHiddenOrDrawBehind,
146
+ hiddenOrDrawBehind = options.statusBar.isHiddenOrDrawBehind(node.isInOverlay),
147
147
  inSheet = node.isInSheet,
148
148
  inSideMenu = node.isInSideMenu,
149
149
  keptAround = parent?.keepsStatusBarRoomOf(node) == true,
@@ -1,93 +1,128 @@
1
1
  package dev.apexnative.navigation.viewcontrollers.component
2
2
 
3
3
  /**
4
- * The readiness of each screen by its id: the safe area view of a screen (`ANNSafeAreaView`) tells it here that it is
5
- * laid out in its place and that the screen's content rendered into it, and asks whether the screen waits for that at
6
- * all. The screen's container listens by the screen's id: no view walks up or down the views to find the other. Main
7
- * thread only.
4
+ * The readiness of each screen by its id: the safe area view of a screen (`ANNSafeAreaView`) tells it here that it
5
+ * has one, that it is laid out in its place and that the screen's content rendered into it, and asks whether the
6
+ * screen waits for that at all. The content of a screen or of a component listens by the id: no view walks up or down
7
+ * the views to find the other. Main thread only.
8
+ *
9
+ * As on iOS (`ANNScreenReadiness`), what a safe area view said is kept: a listener that comes later hears it at once.
10
+ * Several listeners may wait on one id (the roots of a bar component that several screens show with one id), each
11
+ * under a key of its own, which removes it. Each signal carries its source, the React surface of the safe area view
12
+ * that gave it, and a listener hears only the sources it [accepts][Listener.accepts]: React Native never gives a
13
+ * surface's id twice in a process, so the late signal of another root with the same id (a root of the JavaScript that
14
+ * went, a destroyed screen, another live root of a bar component) never makes a new root ready.
8
15
  */
9
16
  object ScreenReadiness {
10
- /** What a screen's container hears from the safe area view of its screen. */
17
+ /** The source of a signal that names none: a listener that accepts every source hears it. */
18
+ const val NO_SOURCE = -1
19
+
20
+ /** What the content of a screen or of a component hears from the safe area view of its id. */
11
21
  interface Listener {
22
+ /**
23
+ * Whether a signal of [source] (the id of the React surface of the safe area view that gave it) is this
24
+ * listener's: by default every one is.
25
+ */
26
+ fun accepts(source: Int): Boolean = true
27
+
12
28
  /** The safe area view is laid out in its place, with a size. */
13
- fun onLaidOut()
29
+ fun onLaidOut() = Unit
14
30
 
15
31
  /** The screen rendered its content into its safe area view, also when it renders nothing (`null`). */
16
32
  fun onContentRendered()
17
33
  }
18
34
 
19
- private val atOnce = HashSet<String>()
20
- private val wrapped = HashSet<String>()
21
- private val laidOut = HashSet<String>()
22
- private val rendered = HashSet<String>()
23
- private val listeners = HashMap<String, Listener>()
35
+ // What the safe area views of one id said: that one exists, and the sources that are laid out and rendered.
36
+ private class Entry {
37
+ var wrapped = false
38
+ val laidOut = HashSet<Int>()
39
+ val rendered = HashSet<Int>()
40
+ }
41
+
42
+ private val entries = HashMap<String, Entry>()
43
+ private val listeners = HashMap<String, LinkedHashMap<Any, Listener>>()
44
+ // The roots that render at once, by id: an id renders at once while one of them lives.
45
+ private val atOnce = HashMap<String, MutableSet<Any>>()
24
46
 
25
47
  /**
26
48
  * Whether the screen [screenId] waits for its safe area view to be laid out before its content renders: every
27
- * screen does, as on iOS, unless the core marked it as one that renders at once ([setRendersAtOnce]) — a React
28
- * component of a bar or a tab item, whose size comes from its content.
49
+ * screen does, as on iOS, unless a root of the id renders at once ([setRendersAtOnce]) — a React component of a
50
+ * bar or a tab item, whose size comes from its content.
29
51
  */
30
- fun waitsForReadiness(screenId: String): Boolean = screenId !in atOnce
52
+ fun waitsForReadiness(screenId: String): Boolean = atOnce[screenId].isNullOrEmpty()
31
53
 
32
- /** The core marks a React root it made as one that renders at once (a component of a bar, a tab item), or not. */
33
- fun setRendersAtOnce(screenId: String, rendersAtOnce: Boolean) {
34
- if (rendersAtOnce) atOnce += screenId else atOnce -= screenId
54
+ /**
55
+ * The root [key] of [screenId] renders at once (a component of a bar, a tab item), or stopped. The id renders at
56
+ * once while a root marks it; when the last one stops, what was said of the id goes too, so a later root with it
57
+ * starts anew.
58
+ */
59
+ fun setRendersAtOnce(screenId: String, key: Any, rendersAtOnce: Boolean) {
60
+ if (rendersAtOnce) {
61
+ atOnce.getOrPut(screenId, ::HashSet).add(key)
62
+ return
63
+ }
64
+ val keys = atOnce[screenId] ?: return
65
+ if (!keys.remove(key) || keys.isNotEmpty()) return
66
+ atOnce.remove(screenId)
67
+ entries.remove(screenId)
35
68
  }
36
69
 
37
70
  /** The screen [screenId] has a safe area view: it is rendered only once that view says so. */
38
71
  fun wrapped(screenId: String) {
39
- wrapped += screenId
72
+ entryOf(screenId).wrapped = true
40
73
  }
41
74
 
42
- /** The safe area view of [screenId] is laid out in its place, with a size. */
43
- fun laidOut(screenId: String) {
44
- if (laidOut.add(screenId)) listeners[screenId]?.onLaidOut()
75
+ /** The safe area view of [screenId], in the React surface [source], is laid out in its place, with a size. */
76
+ fun laidOut(screenId: String, source: Int = NO_SOURCE) {
77
+ val entry = entryOf(screenId)
78
+ entry.wrapped = true
79
+ if (entry.laidOut.add(source)) tell(screenId, source, Listener::onLaidOut)
45
80
  }
46
81
 
47
- /** The screen [screenId] rendered its content into its safe area view. */
48
- fun contentRendered(screenId: String) {
49
- if (rendered.add(screenId)) listeners[screenId]?.onContentRendered()
82
+ /** The screen [screenId] rendered its content into its safe area view, in the React surface [source]. */
83
+ fun contentRendered(screenId: String, source: Int = NO_SOURCE) {
84
+ val entry = entryOf(screenId)
85
+ entry.wrapped = true
86
+ if (entry.rendered.add(source)) tell(screenId, source, Listener::onContentRendered)
50
87
  }
51
88
 
52
89
  /**
53
- * Whether the screen [screenId] rendered its content into its safe area view; null when no safe area view told
54
- * anything of it (a screen without one, of the old API: its container decides by its own content).
90
+ * Whether the screen [screenId] rendered its content into its safe area view, in a source [listener] accepts (any
91
+ * source without one); null when no safe area view told anything of the id (a screen without one, of the old API:
92
+ * its content decides by its own children).
55
93
  */
56
- fun isContentRendered(screenId: String): Boolean? = when (screenId) {
57
- in rendered -> true
58
- in laidOut, in wrapped -> false
59
- else -> null
60
- }
61
-
62
- /** [listener] hears the signals of [screenId] from now on; null stops it. */
63
- fun setListener(screenId: String, listener: Listener?) {
64
- if (listener == null) listeners.remove(screenId) else listeners[screenId] = listener
94
+ fun isContentRendered(screenId: String, listener: Listener? = null): Boolean? {
95
+ val entry = entries[screenId] ?: return null
96
+ return entry.rendered.any { listener?.accepts(it) ?: true }
65
97
  }
66
98
 
67
99
  /**
68
- * [listener] stops hearing [screenId], if it is the one that listens: a later screen with the same id (a `setRoot`
69
- * makes the new root before the old one goes) keeps its own.
100
+ * [listener] hears the signals of [screenId] under [key] (its owner) until [removeListener] with the key: a key
101
+ * has one listener per id, the other keys keep theirs. What the safe area views said before reaches it at once, in
102
+ * order, for the sources it accepts.
70
103
  */
71
- fun removeListener(screenId: String, listener: Listener) {
72
- if (listeners[screenId] === listener) listeners.remove(screenId)
104
+ fun addListener(screenId: String, key: Any, listener: Listener) {
105
+ listeners.getOrPut(screenId, ::LinkedHashMap)[key] = listener
106
+ val entry = entries[screenId] ?: return
107
+ if (entry.laidOut.any(listener::accepts) && isListening(screenId, key, listener)) listener.onLaidOut()
108
+ if (entry.rendered.any(listener::accepts) && isListening(screenId, key, listener)) listener.onContentRendered()
73
109
  }
74
110
 
75
- /**
76
- * A new root takes [screenId] while another with it lives (a component of a bar on two screens): what the other
77
- * rendered isn't the new one's, which waits for its own render. Its mark of rendering at once stays.
78
- */
79
- fun forgetRender(screenId: String) {
80
- laidOut -= screenId
81
- rendered -= screenId
111
+ /** The listener of [key] stops hearing [screenId]; those of other keys (a later root with the id) keep theirs. */
112
+ fun removeListener(screenId: String, key: Any) {
113
+ val keys = listeners[screenId] ?: return
114
+ keys.remove(key)
115
+ if (keys.isEmpty()) listeners.remove(screenId)
82
116
  }
83
117
 
84
- /** The screen is destroyed: what was kept of it goes, so a later screen with the same id starts anew. */
118
+ /**
119
+ * The screen [screenId] owns the id from now on (made), or went while no other node has it (destroyed): what its
120
+ * safe area views said and the marks of rendering at once go, so a later screen with the id starts anew. The
121
+ * listeners stay with their keys, which remove them.
122
+ */
85
123
  fun remove(screenId: String) {
86
- atOnce -= screenId
87
- wrapped -= screenId
88
- laidOut -= screenId
89
- rendered -= screenId
90
- listeners -= screenId
124
+ entries.remove(screenId)
125
+ atOnce.remove(screenId)
91
126
  }
92
127
 
93
128
  /**
@@ -95,10 +130,22 @@ object ScreenReadiness {
95
130
  * "rendered" kept for a screen of the old one would make its new screen with the same id ready at once.
96
131
  */
97
132
  fun reset() {
98
- atOnce.clear()
99
- wrapped.clear()
100
- laidOut.clear()
101
- rendered.clear()
133
+ entries.clear()
102
134
  listeners.clear()
135
+ atOnce.clear()
136
+ }
137
+
138
+ private fun entryOf(screenId: String): Entry = entries.getOrPut(screenId, ::Entry)
139
+
140
+ private fun isListening(screenId: String, key: Any, listener: Listener): Boolean =
141
+ listeners[screenId]?.get(key) === listener
142
+
143
+ // Each listener of the id that accepts the source, as they are now: one that a listener before it removed hears
144
+ // nothing.
145
+ private fun tell(screenId: String, source: Int, signal: (Listener) -> Unit) {
146
+ val now = listeners[screenId]?.entries?.toList() ?: return
147
+ for ((key, listener) in now) {
148
+ if (isListening(screenId, key, listener) && listener.accepts(source)) signal(listener)
149
+ }
103
150
  }
104
151
  }
@@ -1,6 +1,6 @@
1
1
  package dev.apexnative.navigation.viewcontrollers.component
2
2
 
3
- import dev.apexnative.navigation.react.ScreenInsets
3
+ import dev.apexnative.navigation.react.ScreenEnvironment.Insets
4
4
 
5
5
  /**
6
6
  * The arithmetic of a screen's room, safe area and background on Android, without views: the screen nodes read the
@@ -19,6 +19,7 @@ internal object ScreenSafeArea {
19
19
  const val LEFT = "left"
20
20
 
21
21
  private val ALL_EDGES = setOf(TOP, RIGHT, BOTTOM, LEFT)
22
+ private val DEFAULT_EDGES = setOf(TOP, RIGHT, LEFT)
22
23
  private const val OPAQUE = 0xFF
23
24
 
24
25
  /**
@@ -57,10 +58,10 @@ internal object ScreenSafeArea {
57
58
  headerBottom: Int?,
58
59
  tabsTop: Int?,
59
60
  density: Float,
60
- ): ScreenInsets.Insets {
61
+ ): Insets {
61
62
  val coveredAbove = maxOf(system.top, headerBottom ?: 0)
62
63
  val coveredBelow = minOf(windowHeight - system.bottom, tabsTop ?: windowHeight)
63
- return ScreenInsets.Insets(
64
+ return Insets(
64
65
  top = dp((coveredAbove - root.top).coerceAtLeast(0), density),
65
66
  right = dp((root.right - (windowWidth - system.right)).coerceAtLeast(0), density),
66
67
  bottom = dp((root.bottom - coveredBelow).coerceAtLeast(0), density),
@@ -69,26 +70,43 @@ internal object ScreenSafeArea {
69
70
  }
70
71
 
71
72
  /**
72
- * The edges the screen's safe area view keeps its content off: exactly [safeAreaEdges] when the options give them;
73
- * else all four, but the top when the stack's header hides on scroll or a large title shows ([topFree]) and the
74
- * bottom when the tabs hide on scroll ([bottomFree]).
73
+ * The edges the screen's safe area view keeps its content off: exactly [safeAreaEdges] when the options give them,
74
+ * but the top under a large title ([largeTitle]); else the top and the sides, but the top when the stack's header
75
+ * hides on scroll or a large title shows ([topFree]). The bottom is free by default: the content goes down to the
76
+ * bottom, and a list keeps its last rows clear of the navigation bar with `useSafeAreaInsets()`.
75
77
  */
76
- fun paddedEdges(safeAreaEdges: List<String>?, topFree: Boolean, bottomFree: Boolean): Set<String> {
77
- if (safeAreaEdges != null) return safeAreaEdges.filterTo(LinkedHashSet()) { it in ALL_EDGES }
78
- val edges = LinkedHashSet(ALL_EDGES)
78
+ fun paddedEdges(safeAreaEdges: List<String>?, topFree: Boolean, largeTitle: Boolean): Set<String> {
79
+ if (safeAreaEdges != null) {
80
+ val edges = safeAreaEdges.filterTo(LinkedHashSet()) { it in ALL_EDGES }
81
+ // Under a large title the list keeps its first rows clear of the bar itself; a padded top would follow the
82
+ // header as it collapses and move the list with it.
83
+ if (largeTitle) edges -= TOP
84
+ return edges
85
+ }
86
+ val edges = LinkedHashSet(DEFAULT_EDGES)
79
87
  if (topFree) edges -= TOP
80
- if (bottomFree) edges -= BOTTOM
81
88
  return edges
82
89
  }
83
90
 
84
91
  /** The padding of the safe area view: the [insets] on the [edges] it keeps, 0 on the others. */
85
- fun padding(insets: ScreenInsets.Insets, edges: Set<String>): ScreenInsets.Insets = ScreenInsets.Insets(
92
+ fun padding(insets: Insets, edges: Set<String>): Insets = Insets(
86
93
  top = if (TOP in edges) insets.top else 0.0,
87
94
  right = if (RIGHT in edges) insets.right else 0.0,
88
95
  bottom = if (BOTTOM in edges) insets.bottom else 0.0,
89
96
  left = if (LEFT in edges) insets.left else 0.0,
90
97
  )
91
98
 
99
+ /**
100
+ * The insets JavaScript gets (`useSafeAreaInsets`): what of the [insets] still covers the content once the safe
101
+ * area view keeps it off its [padding], 0 on a padded edge.
102
+ */
103
+ fun uncovered(insets: Insets, padding: Insets) = Insets(
104
+ top = (insets.top - padding.top).coerceAtLeast(0.0),
105
+ right = (insets.right - padding.right).coerceAtLeast(0.0),
106
+ bottom = (insets.bottom - padding.bottom).coerceAtLeast(0.0),
107
+ left = (insets.left - padding.left).coerceAtLeast(0.0),
108
+ )
109
+
92
110
  /**
93
111
  * The inner padding of a screen's view: the side system bars ([systemBars]) at the sides; at the bottom the larger
94
112
  * of the navigation bar (none when the screen draws under it) and the keyboard ([imeBottom]; none with
@@ -10,11 +10,9 @@ import dev.apexnative.navigation.layout.LayoutException
10
10
  import dev.apexnative.navigation.nativescreen.NativeScreenContext
11
11
  import dev.apexnative.navigation.options.DefaultOptions
12
12
  import dev.apexnative.navigation.options.Options
13
- import dev.apexnative.navigation.react.ArrangementStates
14
13
  import dev.apexnative.navigation.react.CommandScope
15
14
  import dev.apexnative.navigation.react.ErrorTexts
16
- import dev.apexnative.navigation.react.ScreenInsets
17
- import dev.apexnative.navigation.react.ScreenRegions
15
+ import dev.apexnative.navigation.react.ScreenEnvironment
18
16
  import dev.apexnative.navigation.react.events.AppearanceDispatcher
19
17
  import dev.apexnative.navigation.react.events.ComponentType
20
18
  import dev.apexnative.navigation.react.events.ScreenAppearance
@@ -170,9 +168,7 @@ class ExternalComponentViewController internal constructor(
170
168
  peekView()?.let { (it.parent as? ViewGroup)?.removeView(it) }
171
169
  setParentController(null)
172
170
  if (isIdTakenByAnother) return
173
- ScreenInsets.remove(id)
174
- ScreenRegions.remove(id)
175
- ArrangementStates.remove(id)
171
+ ScreenEnvironment.remove(id)
176
172
  ScreenReadiness.remove(id)
177
173
  if (!notMade) AppearanceDispatcher.nativeScreenReleased(this)
178
174
  }
@@ -1,40 +1,38 @@
1
1
  package dev.apexnative.navigation.viewcontrollers.modal
2
2
 
3
- import kotlin.math.PI
4
- import kotlin.math.cos
3
+ import dev.apexnative.navigation.views.animations.Curves
5
4
 
6
5
  /**
7
- * The default animations of a modal on Android, as values: it comes up from the bottom of the window by the window's
8
- * height (in a split screen or a window, the window's, not the display's) and fades in, [DURATION] with a deceleration
9
- * at the end; it goes down and fades out in the same time, accelerating and decelerating (the system's cosine, not the
10
- * option's `accelerateDecelerate`). A sheet moves only by the Material sheet's own motion. Pure arithmetic.
6
+ * The default animations of a modal over the whole screen on Android, as values: the system's motion of a window that
7
+ * opens over the one below it (`activity_translucent_open_enter` and `activity_translucent_close_exit` of the
8
+ * platform, which Android 16 plays for a translucent activity). The modal comes up from the bottom of the window by the
9
+ * window's height (in a split screen or a window, the window's, not the display's) in [SHOW_DURATION], slowing down at
10
+ * the end; it goes down in [DISMISS_DURATION], speeding up. It doesn't fade: the screen below is seen only around it,
11
+ * as under a translucent activity. A sheet moves only by the Material sheet's own motion. Pure arithmetic.
11
12
  */
12
13
  internal object ModalAnimations {
13
- /** How long the default show and the default dismissal last (ms). */
14
- const val DURATION = 300L
14
+ /** How long the default show lasts (ms): `activity_translucent_open_enter`. */
15
+ const val SHOW_DURATION = 300L
16
+
17
+ /** How long the default dismissal lasts (ms): `activity_translucent_close_exit`. */
18
+ const val DISMISS_DURATION = 250L
19
+
20
+ // `linear_out_slow_in` of the platform: the path (0, 0) (0, 0) (0.2, 1) (1, 1).
21
+ private val linearOutSlowIn = Curves.CubicBezier(0.0, 0.0, 0.2, 1.0)
15
22
 
16
23
  /** How far a modal comes up and goes down: the window's height ([windowHeight]), or the display's while it is 0. */
17
24
  fun distance(windowHeight: Int, displayHeight: Int): Float =
18
25
  (if (windowHeight > 0) windowHeight else displayHeight).toFloat()
19
26
 
20
- /** The curve of the show: a deceleration, 1 − (1 − p)². */
21
- fun decelerate(progress: Float): Float = 1f - (1f - progress) * (1f - progress)
27
+ /** The curve of the show: the platform's `linear_out_slow_in`, fast at first and slow at the end. */
28
+ fun linearOutSlowIn(progress: Float): Float = linearOutSlowIn.getInterpolation(progress)
22
29
 
23
- /** The curve of the dismissal: an acceleration then a deceleration, cos((p + 1)π) / 2 + 0.5. */
24
- fun accelerateDecelerate(progress: Float): Float = (cos((progress + 1) * PI) / 2 + 0.5).toFloat()
30
+ /** The curve of the dismissal: the platform's `accelerate_quad`, p². */
31
+ fun accelerate(progress: Float): Float = progress.coerceIn(0f, 1f).let { it * it }
25
32
 
26
- /** Where a modal is at [progress] (0 … 1, in time) of its show over [distance]: its translation and its alpha. */
27
- fun show(progress: Float, distance: Float): Frame {
28
- val value = decelerate(progress)
29
- return Frame(translationY = distance * (1f - value), alpha = value)
30
- }
33
+ /** Where a modal is at [progress] (0 … 1, in time) of its show over [distance]: its translation. */
34
+ fun show(progress: Float, distance: Float): Float = distance * (1f - linearOutSlowIn(progress))
31
35
 
32
36
  /** Where a modal is at [progress] of its dismissal over [distance], from where it rests. */
33
- fun dismiss(progress: Float, distance: Float): Frame {
34
- val value = accelerateDecelerate(progress)
35
- return Frame(translationY = distance * value, alpha = 1f - value)
36
- }
37
-
38
- /** A modal's place in its animation. */
39
- data class Frame(val translationY: Float, val alpha: Float)
37
+ fun dismiss(progress: Float, distance: Float): Float = distance * accelerate(progress)
40
38
  }