@apexnative/navigation 0.0.0-stage → 1.0.0-alpha.0

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 (1372) hide show
  1. package/ApexNavigation.podspec +42 -0
  2. package/LICENSE +21 -0
  3. package/README.md +76 -2
  4. package/android/CLAUDE.md +183 -0
  5. package/android/CORE.md +219 -0
  6. package/android/MATERIAL_SYMBOLS_LICENSE.txt +205 -0
  7. package/android/RECIPES.md +39 -0
  8. package/android/build.gradle +108 -0
  9. package/android/consumer-rules.pro +2 -0
  10. package/android/src/main/AndroidManifest.xml +9 -0
  11. package/android/src/main/java/dev/apexnative/navigation/EdgeToEdgeDecision.kt +25 -0
  12. package/android/src/main/java/dev/apexnative/navigation/NavigationActivity.kt +339 -0
  13. package/android/src/main/java/dev/apexnative/navigation/NavigationApplication.kt +90 -0
  14. package/android/src/main/java/dev/apexnative/navigation/NavigationPackage.kt +37 -0
  15. package/android/src/main/java/dev/apexnative/navigation/customrow/BottomTabsCustomRowOptions.kt +85 -0
  16. package/android/src/main/java/dev/apexnative/navigation/layout/LayoutChecks.kt +51 -0
  17. package/android/src/main/java/dev/apexnative/navigation/layout/LayoutException.kt +7 -0
  18. package/android/src/main/java/dev/apexnative/navigation/layout/LayoutNode.kt +118 -0
  19. package/android/src/main/java/dev/apexnative/navigation/layout/LayoutReader.kt +274 -0
  20. package/android/src/main/java/dev/apexnative/navigation/layout/LayoutType.kt +35 -0
  21. package/android/src/main/java/dev/apexnative/navigation/nativescreen/NativeScreenCalls.kt +61 -0
  22. package/android/src/main/java/dev/apexnative/navigation/nativescreen/NativeScreenContext.kt +84 -0
  23. package/android/src/main/java/dev/apexnative/navigation/nativescreen/NativeScreenCreator.kt +17 -0
  24. package/android/src/main/java/dev/apexnative/navigation/options/AnimationsOptions.kt +54 -0
  25. package/android/src/main/java/dev/apexnative/navigation/options/BottomTabOptions.kt +238 -0
  26. package/android/src/main/java/dev/apexnative/navigation/options/BottomTabsOptions.kt +244 -0
  27. package/android/src/main/java/dev/apexnative/navigation/options/ButtonMenuOptions.kt +70 -0
  28. package/android/src/main/java/dev/apexnative/navigation/options/ButtonOptions.kt +296 -0
  29. package/android/src/main/java/dev/apexnative/navigation/options/ComponentOptions.kt +141 -0
  30. package/android/src/main/java/dev/apexnative/navigation/options/DefaultOptions.kt +21 -0
  31. package/android/src/main/java/dev/apexnative/navigation/options/FabOptions.kt +97 -0
  32. package/android/src/main/java/dev/apexnative/navigation/options/FontOptions.kt +47 -0
  33. package/android/src/main/java/dev/apexnative/navigation/options/HardwareBackButtonOptions.kt +49 -0
  34. package/android/src/main/java/dev/apexnative/navigation/options/InterpolationOptions.kt +203 -0
  35. package/android/src/main/java/dev/apexnative/navigation/options/KeyCommandOptions.kt +49 -0
  36. package/android/src/main/java/dev/apexnative/navigation/options/LargeTitleOptions.kt +78 -0
  37. package/android/src/main/java/dev/apexnative/navigation/options/LayoutAnimation.kt +157 -0
  38. package/android/src/main/java/dev/apexnative/navigation/options/LayoutOptions.kt +94 -0
  39. package/android/src/main/java/dev/apexnative/navigation/options/ModalOptions.kt +87 -0
  40. package/android/src/main/java/dev/apexnative/navigation/options/ModalPlacementOptions.kt +90 -0
  41. package/android/src/main/java/dev/apexnative/navigation/options/NavigationBarOptions.kt +44 -0
  42. package/android/src/main/java/dev/apexnative/navigation/options/Options.kt +167 -0
  43. package/android/src/main/java/dev/apexnative/navigation/options/OptionsCache.kt +21 -0
  44. package/android/src/main/java/dev/apexnative/navigation/options/OptionsReader.kt +133 -0
  45. package/android/src/main/java/dev/apexnative/navigation/options/PreviewOptions.kt +97 -0
  46. package/android/src/main/java/dev/apexnative/navigation/options/ReadableMaps.kt +70 -0
  47. package/android/src/main/java/dev/apexnative/navigation/options/ScrollEdgeEffectOptions.kt +98 -0
  48. package/android/src/main/java/dev/apexnative/navigation/options/SearchBarOptions.kt +151 -0
  49. package/android/src/main/java/dev/apexnative/navigation/options/SharedElementTransitionOptions.kt +57 -0
  50. package/android/src/main/java/dev/apexnative/navigation/options/SheetOptions.kt +108 -0
  51. package/android/src/main/java/dev/apexnative/navigation/options/SideMenuOptions.kt +130 -0
  52. package/android/src/main/java/dev/apexnative/navigation/options/SplitViewGroupOptions.kt +190 -0
  53. package/android/src/main/java/dev/apexnative/navigation/options/SplitViewOptions.kt +28 -0
  54. package/android/src/main/java/dev/apexnative/navigation/options/StackAnimationOptions.kt +270 -0
  55. package/android/src/main/java/dev/apexnative/navigation/options/StatusBarOptions.kt +75 -0
  56. package/android/src/main/java/dev/apexnative/navigation/options/TitleOptions.kt +167 -0
  57. package/android/src/main/java/dev/apexnative/navigation/options/ToolbarOptions.kt +60 -0
  58. package/android/src/main/java/dev/apexnative/navigation/options/TopBarAppearanceOptions.kt +223 -0
  59. package/android/src/main/java/dev/apexnative/navigation/options/TopBarOptions.kt +381 -0
  60. package/android/src/main/java/dev/apexnative/navigation/options/ViewAnimationOptions.kt +225 -0
  61. package/android/src/main/java/dev/apexnative/navigation/options/WindowOptions.kt +36 -0
  62. package/android/src/main/java/dev/apexnative/navigation/options/params/Bool.kt +23 -0
  63. package/android/src/main/java/dev/apexnative/navigation/options/params/Fraction.kt +12 -0
  64. package/android/src/main/java/dev/apexnative/navigation/options/params/LayoutDirection.kt +26 -0
  65. package/android/src/main/java/dev/apexnative/navigation/options/params/Param.kt +24 -0
  66. package/android/src/main/java/dev/apexnative/navigation/options/params/Text.kt +24 -0
  67. package/android/src/main/java/dev/apexnative/navigation/options/params/ThemeColour.kt +259 -0
  68. package/android/src/main/java/dev/apexnative/navigation/options/params/Variant.kt +36 -0
  69. package/android/src/main/java/dev/apexnative/navigation/options/parsers/BoolParser.kt +15 -0
  70. package/android/src/main/java/dev/apexnative/navigation/options/parsers/FontParser.kt +28 -0
  71. package/android/src/main/java/dev/apexnative/navigation/options/parsers/FractionParser.kt +24 -0
  72. package/android/src/main/java/dev/apexnative/navigation/options/parsers/IconParser.kt +48 -0
  73. package/android/src/main/java/dev/apexnative/navigation/options/parsers/StringListParser.kt +27 -0
  74. package/android/src/main/java/dev/apexnative/navigation/options/parsers/TextParser.kt +32 -0
  75. package/android/src/main/java/dev/apexnative/navigation/options/parsers/TypefaceLoader.kt +42 -0
  76. package/android/src/main/java/dev/apexnative/navigation/options/parsers/VariantParser.kt +34 -0
  77. package/android/src/main/java/dev/apexnative/navigation/react/ArrangementStates.kt +41 -0
  78. package/android/src/main/java/dev/apexnative/navigation/react/CommandAnswer.kt +111 -0
  79. package/android/src/main/java/dev/apexnative/navigation/react/CommandListener.kt +27 -0
  80. package/android/src/main/java/dev/apexnative/navigation/react/CommandRunner.kt +131 -0
  81. package/android/src/main/java/dev/apexnative/navigation/react/DeveloperReload.kt +69 -0
  82. package/android/src/main/java/dev/apexnative/navigation/react/ErrorTexts.kt +123 -0
  83. package/android/src/main/java/dev/apexnative/navigation/react/Hinge.kt +154 -0
  84. package/android/src/main/java/dev/apexnative/navigation/react/LaunchLink.kt +37 -0
  85. package/android/src/main/java/dev/apexnative/navigation/react/NavigationTurboModule.kt +311 -0
  86. package/android/src/main/java/dev/apexnative/navigation/react/OptionsCommands.kt +89 -0
  87. package/android/src/main/java/dev/apexnative/navigation/react/ReactGateway.kt +67 -0
  88. package/android/src/main/java/dev/apexnative/navigation/react/ReactView.kt +197 -0
  89. package/android/src/main/java/dev/apexnative/navigation/react/ReadableJson.kt +60 -0
  90. package/android/src/main/java/dev/apexnative/navigation/react/ReloadCoordinator.kt +130 -0
  91. package/android/src/main/java/dev/apexnative/navigation/react/ScreenInsets.kt +69 -0
  92. package/android/src/main/java/dev/apexnative/navigation/react/ScreenRegions.kt +87 -0
  93. package/android/src/main/java/dev/apexnative/navigation/react/ScrollEvents.kt +160 -0
  94. package/android/src/main/java/dev/apexnative/navigation/react/StartInfo.kt +44 -0
  95. package/android/src/main/java/dev/apexnative/navigation/react/events/AppearanceDispatcher.kt +507 -0
  96. package/android/src/main/java/dev/apexnative/navigation/react/events/ComponentType.kt +13 -0
  97. package/android/src/main/java/dev/apexnative/navigation/react/events/EventEmitter.kt +199 -0
  98. package/android/src/main/java/dev/apexnative/navigation/react/events/NavigationStateReporter.kt +62 -0
  99. package/android/src/main/java/dev/apexnative/navigation/react/events/ScreenAppearance.kt +87 -0
  100. package/android/src/main/java/dev/apexnative/navigation/react/events/StateHold.kt +62 -0
  101. package/android/src/main/java/dev/apexnative/navigation/safearea/SafeAreaReadyEvent.kt +16 -0
  102. package/android/src/main/java/dev/apexnative/navigation/safearea/SafeAreaView.kt +140 -0
  103. package/android/src/main/java/dev/apexnative/navigation/safearea/SafeAreaViewManager.kt +45 -0
  104. package/android/src/main/java/dev/apexnative/navigation/slots/SlotContainers.kt +44 -0
  105. package/android/src/main/java/dev/apexnative/navigation/slots/SlotHost.kt +91 -0
  106. package/android/src/main/java/dev/apexnative/navigation/slots/SlotScreenView.kt +158 -0
  107. package/android/src/main/java/dev/apexnative/navigation/slots/SlotView.kt +141 -0
  108. package/android/src/main/java/dev/apexnative/navigation/slots/SlotViewManager.kt +50 -0
  109. package/android/src/main/java/dev/apexnative/navigation/splash/SplashHold.kt +67 -0
  110. package/android/src/main/java/dev/apexnative/navigation/splash/SplashTheme.kt +81 -0
  111. package/android/src/main/java/dev/apexnative/navigation/splash/SplashView.kt +77 -0
  112. package/android/src/main/java/dev/apexnative/navigation/system/AppDirection.kt +92 -0
  113. package/android/src/main/java/dev/apexnative/navigation/system/SystemUiLayers.kt +126 -0
  114. package/android/src/main/java/dev/apexnative/navigation/system/SystemUiOwner.kt +229 -0
  115. package/android/src/main/java/dev/apexnative/navigation/system/SystemUiRules.kt +302 -0
  116. package/android/src/main/java/dev/apexnative/navigation/system/SystemUiState.kt +58 -0
  117. package/android/src/main/java/dev/apexnative/navigation/system/SystemUiWindow.kt +405 -0
  118. package/android/src/main/java/dev/apexnative/navigation/utils/ColorUtils.kt +22 -0
  119. package/android/src/main/java/dev/apexnative/navigation/utils/DevelopmentLog.kt +45 -0
  120. package/android/src/main/java/dev/apexnative/navigation/utils/DimensionExtensions.kt +16 -0
  121. package/android/src/main/java/dev/apexnative/navigation/utils/ImageLoader.kt +112 -0
  122. package/android/src/main/java/dev/apexnative/navigation/utils/MaterialTheme.kt +148 -0
  123. package/android/src/main/java/dev/apexnative/navigation/utils/NavigationLog.kt +6 -0
  124. package/android/src/main/java/dev/apexnative/navigation/utils/ScrollToTop.kt +33 -0
  125. package/android/src/main/java/dev/apexnative/navigation/utils/SystemUiUtils.kt +41 -0
  126. package/android/src/main/java/dev/apexnative/navigation/utils/TestIds.kt +89 -0
  127. package/android/src/main/java/dev/apexnative/navigation/utils/TextViewUtils.kt +10 -0
  128. package/android/src/main/java/dev/apexnative/navigation/utils/UiThread.kt +31 -0
  129. package/android/src/main/java/dev/apexnative/navigation/utils/UiUtils.kt +43 -0
  130. package/android/src/main/java/dev/apexnative/navigation/utils/ViewController.kt +124 -0
  131. package/android/src/main/java/dev/apexnative/navigation/utils/ViewExtensions.kt +41 -0
  132. package/android/src/main/java/dev/apexnative/navigation/utils/ViewUtils.kt +15 -0
  133. package/android/src/main/java/dev/apexnative/navigation/utils/WindowFolds.kt +107 -0
  134. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/ArrangementController.kt +258 -0
  135. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/ArrangementDefinition.kt +57 -0
  136. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/ArrangementLayout.kt +225 -0
  137. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/ArrangementPlanner.kt +120 -0
  138. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/SecondaryScreenPresenter.kt +31 -0
  139. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsCollapseBehavior.kt +54 -0
  140. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsController.kt +664 -0
  141. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsPresenter.kt +367 -0
  142. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowGeometry.kt +81 -0
  143. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowPlacer.kt +223 -0
  144. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabBarLook.kt +74 -0
  145. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabBarMotion.kt +83 -0
  146. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabCellState.kt +27 -0
  147. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabHistory.kt +38 -0
  148. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabItems.kt +172 -0
  149. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabSelection.kt +65 -0
  150. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabsAttach.kt +42 -0
  151. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabsRoom.kt +72 -0
  152. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/child/ChildController.kt +45 -0
  153. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/child/ChildControllersRegistry.kt +29 -0
  154. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentPresenter.kt +90 -0
  155. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentViewController.kt +254 -0
  156. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ContentReadiness.kt +65 -0
  157. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/RenderWait.kt +231 -0
  158. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/RestPlace.kt +28 -0
  159. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenContentFactory.kt +28 -0
  160. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenFocus.kt +22 -0
  161. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenFrame.kt +154 -0
  162. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenReadiness.kt +104 -0
  163. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenSafeArea.kt +148 -0
  164. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/externalcomponent/ExternalComponentCreator.kt +18 -0
  165. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/externalcomponent/ExternalComponentViewController.kt +187 -0
  166. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/externalcomponent/NativeScreens.kt +25 -0
  167. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalAnimations.kt +40 -0
  168. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalContainer.kt +20 -0
  169. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalCoordinator.kt +1269 -0
  170. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalRecord.kt +186 -0
  171. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalSheet.kt +342 -0
  172. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalViews.kt +398 -0
  173. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetContainer.kt +67 -0
  174. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/BackCallbackState.kt +78 -0
  175. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/FirstRootDraw.kt +58 -0
  176. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/LayoutFactory.kt +203 -0
  177. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/Navigator.kt +562 -0
  178. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/Navigators.kt +53 -0
  179. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/RootCoordinator.kt +514 -0
  180. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/WaitingLayer.kt +18 -0
  181. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/overlay/OverlayContainer.kt +33 -0
  182. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/overlay/OverlayCoordinator.kt +383 -0
  183. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/overlay/OverlayTouches.kt +44 -0
  184. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/overlay/OverlayViews.kt +117 -0
  185. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/Capabilities.kt +62 -0
  186. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ContainerBackground.kt +43 -0
  187. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ParentController.kt +218 -0
  188. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ShownChildren.kt +82 -0
  189. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuController.kt +283 -0
  190. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuMotion.kt +276 -0
  191. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuPresenter.kt +92 -0
  192. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuRules.kt +107 -0
  193. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitPanes.kt +59 -0
  194. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitViewController.kt +509 -0
  195. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitViewLayout.kt +61 -0
  196. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitViewPresenter.kt +25 -0
  197. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/PreparedFrame.kt +19 -0
  198. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/PreparedPushes.kt +114 -0
  199. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackCommands.kt +387 -0
  200. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackController.kt +635 -0
  201. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackDisplay.kt +167 -0
  202. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackPresenter.kt +24 -0
  203. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackQueue.kt +1274 -0
  204. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackTransitions.kt +82 -0
  205. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackViews.kt +222 -0
  206. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabPlacement.kt +47 -0
  207. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabPlan.kt +44 -0
  208. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabPresenter.kt +279 -0
  209. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/ScreenSearch.kt +450 -0
  210. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/SearchPanel.kt +176 -0
  211. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/StackSearchPresenter.kt +243 -0
  212. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/BarComponents.kt +211 -0
  213. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/BarRowTransition.kt +122 -0
  214. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/ButtonCells.kt +30 -0
  215. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/ButtonPlaces.kt +65 -0
  216. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/LargeTitleCollapse.kt +71 -0
  217. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/MenuChecks.kt +72 -0
  218. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarCollapseBehavior.kt +104 -0
  219. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarPresenter.kt +1085 -0
  220. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarRoom.kt +95 -0
  221. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarVisibility.kt +122 -0
  222. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/IReactView.kt +89 -0
  223. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/Presenter.kt +51 -0
  224. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ScrollEventListener.kt +194 -0
  225. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ViewController.kt +320 -0
  226. package/android/src/main/java/dev/apexnative/navigation/views/animations/AnimationRules.kt +141 -0
  227. package/android/src/main/java/dev/apexnative/navigation/views/animations/Curves.kt +193 -0
  228. package/android/src/main/java/dev/apexnative/navigation/views/animations/FadeThrough.kt +57 -0
  229. package/android/src/main/java/dev/apexnative/navigation/views/animations/SideAnimator.kt +143 -0
  230. package/android/src/main/java/dev/apexnative/navigation/views/animations/SystemTransition.kt +26 -0
  231. package/android/src/main/java/dev/apexnative/navigation/views/animations/ValueInterpolation.kt +93 -0
  232. package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabItem.kt +13 -0
  233. package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabs.kt +550 -0
  234. package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabsContainer.kt +135 -0
  235. package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabsLayout.kt +89 -0
  236. package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomBottomTabItemView.kt +91 -0
  237. package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomTabRow.kt +165 -0
  238. package/android/src/main/java/dev/apexnative/navigation/views/component/ComponentLayout.kt +89 -0
  239. package/android/src/main/java/dev/apexnative/navigation/views/component/Renderable.kt +6 -0
  240. package/android/src/main/java/dev/apexnative/navigation/views/element/DrawOrder.kt +44 -0
  241. package/android/src/main/java/dev/apexnative/navigation/views/element/ElementStub.kt +31 -0
  242. package/android/src/main/java/dev/apexnative/navigation/views/element/ElementTransitions.kt +281 -0
  243. package/android/src/main/java/dev/apexnative/navigation/views/element/ImageLoads.kt +103 -0
  244. package/android/src/main/java/dev/apexnative/navigation/views/element/TargetsWait.kt +112 -0
  245. package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionLayer.kt +152 -0
  246. package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionTargets.kt +53 -0
  247. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ElementPictures.kt +46 -0
  248. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/FlightGeometry.kt +53 -0
  249. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMatrixAnimator.kt +138 -0
  250. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PlainViewAnimator.kt +88 -0
  251. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PropertyAnimatorCreator.kt +33 -0
  252. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ReactImageAnimator.kt +66 -0
  253. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/SharedAnimatorFactory.kt +70 -0
  254. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextChangeAnimator.kt +179 -0
  255. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewChangeAnimator.kt +139 -0
  256. package/android/src/main/java/dev/apexnative/navigation/views/externalcomponent/ExternalComponentLayout.kt +44 -0
  257. package/android/src/main/java/dev/apexnative/navigation/views/sidemenu/SideMenuView.kt +183 -0
  258. package/android/src/main/java/dev/apexnative/navigation/views/stack/StackLayout.kt +137 -0
  259. package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/Fab.kt +125 -0
  260. package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabAnimator.kt +8 -0
  261. package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabCollapseBehaviour.kt +34 -0
  262. package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabMenu.kt +133 -0
  263. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/LargeTitleView.kt +45 -0
  264. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TitleBar.kt +211 -0
  265. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TopBar.kt +407 -0
  266. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TopBarDefaults.kt +35 -0
  267. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/search/ScopeRow.kt +82 -0
  268. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/search/SearchField.kt +130 -0
  269. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/search/SearchStyle.kt +29 -0
  270. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/search/SuggestionList.kt +77 -0
  271. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonComponentCell.kt +80 -0
  272. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonBar.kt +334 -0
  273. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonMenus.kt +106 -0
  274. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/IconBackgroundDrawable.kt +93 -0
  275. package/android/src/main/jni/ApexNavigationSpec.h +18 -0
  276. package/android/src/main/jni/CMakeLists.txt +33 -0
  277. package/android/src/main/res/color/apex_navigation_highlight_inverse.xml +5 -0
  278. package/android/src/main/res/color/apex_navigation_text_primary.xml +6 -0
  279. package/android/src/main/res/color/apex_navigation_text_primary_inverse.xml +6 -0
  280. package/android/src/main/res/color/apex_navigation_text_secondary.xml +6 -0
  281. package/android/src/main/res/color/apex_navigation_text_secondary_inverse.xml +6 -0
  282. package/android/src/main/res/drawable/apex_navigation_ic_arrow_back.xml +13 -0
  283. package/android/src/main/res/drawable/apex_navigation_ic_close.xml +12 -0
  284. package/android/src/main/res/drawable/ic_fab_add_24dp.xml +12 -0
  285. package/android/src/main/res/values/attrs.xml +13 -0
  286. package/android/src/main/res/values/dimens.xml +5 -0
  287. package/android/src/main/res/values/dimens_splash.xml +9 -0
  288. package/android/src/main/res/values/ids.xml +12 -0
  289. package/android/src/main/res/values/styles.xml +18 -0
  290. package/android/src/main/res/values/themes.xml +75 -0
  291. package/android/src/main/res/values-night/styles.xml +6 -0
  292. package/android/src/main/res/values-night/themes.xml +67 -0
  293. package/cli/app.js +113 -0
  294. package/cli/changes.js +235 -0
  295. package/cli/codegen/commands.js +356 -0
  296. package/cli/codegen/index.js +211 -0
  297. package/cli/codegen/kotlin.js +396 -0
  298. package/cli/codegen/names.js +99 -0
  299. package/cli/codegen/read.js +602 -0
  300. package/cli/codegen/swift.js +342 -0
  301. package/cli/config.js +78 -0
  302. package/cli/diff.js +139 -0
  303. package/cli/doctor/checks/android.js +217 -0
  304. package/cli/doctor/checks/app.js +305 -0
  305. package/cli/doctor/checks/conflicts.js +42 -0
  306. package/cli/doctor/checks/devices.js +98 -0
  307. package/cli/doctor/checks/icons.js +69 -0
  308. package/cli/doctor/checks/ios.js +187 -0
  309. package/cli/doctor/checks/navigation.js +285 -0
  310. package/cli/doctor/checks/splash.js +102 -0
  311. package/cli/doctor/fix.js +66 -0
  312. package/cli/doctor/index.js +136 -0
  313. package/cli/doctor/types.js +30 -0
  314. package/cli/exec.js +34 -0
  315. package/cli/gradle.js +142 -0
  316. package/cli/icons/android.js +173 -0
  317. package/cli/icons/images.js +202 -0
  318. package/cli/icons/index.js +97 -0
  319. package/cli/icons/ios.js +113 -0
  320. package/cli/icons/settings.js +116 -0
  321. package/cli/images.js +67 -0
  322. package/cli/index.js +307 -0
  323. package/cli/info/index.js +290 -0
  324. package/cli/init/index.js +426 -0
  325. package/cli/init/packageManager.js +48 -0
  326. package/cli/init/starter.js +440 -0
  327. package/cli/links/files.js +109 -0
  328. package/cli/links/identity.js +75 -0
  329. package/cli/links/index.js +532 -0
  330. package/cli/links/native.js +396 -0
  331. package/cli/links/open.js +120 -0
  332. package/cli/links/prefixes.js +89 -0
  333. package/cli/mcp/appMap.js +128 -0
  334. package/cli/mcp/docs.js +175 -0
  335. package/cli/mcp/index.js +153 -0
  336. package/cli/mcp/markdown.js +210 -0
  337. package/cli/mcp/protocol.js +151 -0
  338. package/cli/mcp/tools.js +389 -0
  339. package/cli/migrate/entry.js +451 -0
  340. package/cli/migrate/index.js +305 -0
  341. package/cli/migrate/native.js +250 -0
  342. package/cli/migrate/report.js +238 -0
  343. package/cli/pods.js +56 -0
  344. package/cli/project.js +189 -0
  345. package/cli/screen/index.js +383 -0
  346. package/cli/screen/templates/compose.js +46 -0
  347. package/cli/screen/templates/native.js +40 -0
  348. package/cli/screen/templates/react.js +47 -0
  349. package/cli/screen/templates/swiftui.js +30 -0
  350. package/cli/screen/templates/uikit.js +48 -0
  351. package/cli/screen/templates/views.js +46 -0
  352. package/cli/setup/index.js +240 -0
  353. package/cli/setup/source.js +58 -0
  354. package/cli/setup/steps/app.js +76 -0
  355. package/cli/setup/steps/appDelegate.js +98 -0
  356. package/cli/setup/steps/entry.js +68 -0
  357. package/cli/setup/steps/env.js +245 -0
  358. package/cli/setup/steps/infoPlist.js +39 -0
  359. package/cli/setup/steps/mainActivity.js +60 -0
  360. package/cli/setup/steps/mainApplication.js +58 -0
  361. package/cli/setup/steps/manifest.js +38 -0
  362. package/cli/setup/steps/styles.js +29 -0
  363. package/cli/setup/steps/types.js +14 -0
  364. package/cli/splash/android.js +239 -0
  365. package/cli/splash/files.js +50 -0
  366. package/cli/splash/images.js +117 -0
  367. package/cli/splash/index.js +109 -0
  368. package/cli/splash/ios.js +349 -0
  369. package/cli/splash/settings.js +143 -0
  370. package/cli/typescript.js +473 -0
  371. package/cli/ui.js +268 -0
  372. package/cli/upgrade/changelog.js +45 -0
  373. package/cli/upgrade/index.js +347 -0
  374. package/cli/upgrade/versions.js +105 -0
  375. package/cli/workspace.js +60 -0
  376. package/cli/xcode/pbxproj.js +327 -0
  377. package/docs-md/architecture/errors-and-loading.md +138 -0
  378. package/docs-md/architecture/native-screens.md +290 -0
  379. package/docs-md/architecture/one-tree.md +164 -0
  380. package/docs-md/architecture/theme-and-context.md +368 -0
  381. package/docs-md/architecture/transitions.md +191 -0
  382. package/docs-md/containers/arrangement.md +320 -0
  383. package/docs-md/containers/modals.md +195 -0
  384. package/docs-md/containers/overlays.md +109 -0
  385. package/docs-md/containers/side-menu.md +138 -0
  386. package/docs-md/containers/split-view.md +155 -0
  387. package/docs-md/containers/stack.md +156 -0
  388. package/docs-md/containers/tabs.md +187 -0
  389. package/docs-md/flows/a-search-screen.md +311 -0
  390. package/docs-md/flows/an-app-with-tabs.md +380 -0
  391. package/docs-md/flows/bottom-sheets.md +326 -0
  392. package/docs-md/flows/forms-in-a-modal.md +420 -0
  393. package/docs-md/flows/list-and-details.md +428 -0
  394. package/docs-md/flows/onboarding.md +454 -0
  395. package/docs-md/flows/sign-in-and-sign-out.md +693 -0
  396. package/docs-md/fundamentals/lifecycle-and-events.md +224 -0
  397. package/docs-md/fundamentals/moving-between-screens.md +267 -0
  398. package/docs-md/fundamentals/screen-options.md +197 -0
  399. package/docs-md/fundamentals/screens-and-props.md +314 -0
  400. package/docs-md/fundamentals/starting-the-app.md +317 -0
  401. package/docs-md/fundamentals/switching-roots.md +166 -0
  402. package/docs-md/guides/analytics.md +377 -0
  403. package/docs-md/guides/app-context.md +554 -0
  404. package/docs-md/guides/building-a-screen.md +350 -0
  405. package/docs-md/guides/cli.md +421 -0
  406. package/docs-md/guides/data-fetching.md +492 -0
  407. package/docs-md/guides/deep-links.md +694 -0
  408. package/docs-md/guides/error-reporting.md +290 -0
  409. package/docs-md/guides/gestures-and-animations.md +381 -0
  410. package/docs-md/guides/notifications.md +548 -0
  411. package/docs-md/guides/overview.md +65 -0
  412. package/docs-md/guides/right-to-left.md +273 -0
  413. package/docs-md/guides/splash-screen.md +30 -0
  414. package/docs-md/guides/state-management.md +1050 -0
  415. package/docs-md/guides/testing.md +293 -0
  416. package/docs-md/help/glossary.md +433 -0
  417. package/docs-md/help/troubleshooting.md +709 -0
  418. package/docs-md/index.json +4205 -0
  419. package/docs-md/migration/from-expo-router.md +446 -0
  420. package/docs-md/migration/from-react-native-navigation.md +789 -0
  421. package/docs-md/migration/from-react-navigation.md +628 -0
  422. package/docs-md/screen-ui/back-and-gestures.md +178 -0
  423. package/docs-md/screen-ui/bar-buttons.md +312 -0
  424. package/docs-md/screen-ui/search.md +181 -0
  425. package/docs-md/screen-ui/system-ui.md +337 -0
  426. package/docs-md/screen-ui/toolbar-and-fab.md +146 -0
  427. package/docs-md/screen-ui/top-bar.md +247 -0
  428. package/docs-md/start/installation.md +233 -0
  429. package/docs-md/start/introduction.md +46 -0
  430. package/docs-md/start/quick-start.md +124 -0
  431. package/ios/Animations/ANNAnimationRules.h +72 -0
  432. package/ios/Animations/ANNAnimationRules.mm +122 -0
  433. package/ios/Animations/ANNFrameDriver.h +46 -0
  434. package/ios/Animations/ANNFrameDriver.mm +126 -0
  435. package/ios/Animations/ANNTransitionAnimator.h +34 -0
  436. package/ios/Animations/ANNTransitionAnimator.mm +293 -0
  437. package/ios/Animations/ANNTransitionPlan.h +115 -0
  438. package/ios/Animations/ANNTransitionPlan.mm +130 -0
  439. package/ios/Animations/ANNTransitionWait.h +29 -0
  440. package/ios/Animations/ANNTransitionWait.mm +135 -0
  441. package/ios/Animations/Elements/ANNElementFinder.h +26 -0
  442. package/ios/Animations/Elements/ANNElementFinder.mm +37 -0
  443. package/ios/Animations/Elements/ANNElementTransition.h +30 -0
  444. package/ios/Animations/Elements/ANNElementTransition.mm +75 -0
  445. package/ios/Animations/Elements/ANNSharedElementFlight.h +42 -0
  446. package/ios/Animations/Elements/ANNSharedElementFlight.mm +340 -0
  447. package/ios/Animations/Elements/ANNZoomAnchor.h +33 -0
  448. package/ios/Animations/Elements/ANNZoomAnchor.mm +133 -0
  449. package/ios/Animations/Interpolators/ANNCurve.h +61 -0
  450. package/ios/Animations/Interpolators/ANNCurve.mm +301 -0
  451. package/ios/Animations/Interpolators/ANNInterpolate.h +69 -0
  452. package/ios/Animations/Interpolators/ANNTrack.h +52 -0
  453. package/ios/Animations/Interpolators/ANNTrack.mm +77 -0
  454. package/ios/Animations/Interpolators/ANNViewTracks.h +57 -0
  455. package/ios/Animations/Interpolators/ANNViewTracks.mm +261 -0
  456. package/ios/ApexNavigation-prefix.h +6 -0
  457. package/ios/CLAUDE.md +151 -0
  458. package/ios/CORE.md +177 -0
  459. package/ios/Contract/ANNCommandAnswer.h +38 -0
  460. package/ios/Contract/ANNCommandAnswer.mm +99 -0
  461. package/ios/Contract/ANNCommandRunner.h +42 -0
  462. package/ios/Contract/ANNCommandRunner.mm +89 -0
  463. package/ios/Contract/ANNErrorTexts.h +86 -0
  464. package/ios/Contract/ANNErrorTexts.mm +230 -0
  465. package/ios/Contract/ANNLayoutNode.h +64 -0
  466. package/ios/Contract/ANNLayoutNode.mm +153 -0
  467. package/ios/Contract/ANNLayoutReader.h +34 -0
  468. package/ios/Contract/ANNLayoutReader.mm +282 -0
  469. package/ios/Contract/ANNLayoutRoot.h +26 -0
  470. package/ios/Contract/ANNLayoutRoot.mm +21 -0
  471. package/ios/Contract/ANNLayoutTreeOptions.h +22 -0
  472. package/ios/Contract/ANNLayoutTreeOptions.mm +32 -0
  473. package/ios/Contract/ANNLayoutType.h +44 -0
  474. package/ios/Contract/ANNLayoutValidator.h +23 -0
  475. package/ios/Contract/ANNLayoutValidator.mm +28 -0
  476. package/ios/Core/ANNAppDelegate.mm +122 -0
  477. package/ios/Core/ANNAppDirection.h +43 -0
  478. package/ios/Core/ANNAppDirection.mm +194 -0
  479. package/ios/Core/ANNAppearanceDispatcher.h +117 -0
  480. package/ios/Core/ANNAppearanceDispatcher.mm +433 -0
  481. package/ios/Core/ANNAssert.h +7 -0
  482. package/ios/Core/ANNDeepLinkQueue.h +35 -0
  483. package/ios/Core/ANNDeepLinkQueue.mm +136 -0
  484. package/ios/Core/ANNErrorHandler.h +17 -0
  485. package/ios/Core/ANNErrorHandler.mm +14 -0
  486. package/ios/Core/ANNEventEmitter.h +174 -0
  487. package/ios/Core/ANNEventEmitter.mm +337 -0
  488. package/ios/Core/ANNHinge.h +26 -0
  489. package/ios/Core/ANNHinge.mm +116 -0
  490. package/ios/Core/ANNKeyCommands.h +12 -0
  491. package/ios/Core/ANNKeyCommands.mm +74 -0
  492. package/ios/Core/ANNLayoutInfo.h +18 -0
  493. package/ios/Core/ANNLayoutInfo.mm +13 -0
  494. package/ios/Core/ANNLayoutProtocol.h +155 -0
  495. package/ios/Core/ANNNavigationState.h +38 -0
  496. package/ios/Core/ANNNavigationState.mm +127 -0
  497. package/ios/Core/ANNNodeHelper.h +114 -0
  498. package/ios/Core/ANNNodeHelper.mm +260 -0
  499. package/ios/Core/ANNNodePresenter.h +86 -0
  500. package/ios/Core/ANNNodePresenter.mm +92 -0
  501. package/ios/Core/ANNNodeRegistry.h +30 -0
  502. package/ios/Core/ANNNodeRegistry.mm +48 -0
  503. package/ios/Core/ANNOptionsRepaint.h +19 -0
  504. package/ios/Core/ANNOptionsRepaint.mm +59 -0
  505. package/ios/Core/ANNParking.h +34 -0
  506. package/ios/Core/ANNParking.mm +117 -0
  507. package/ios/Core/ANNPendingLayers.h +31 -0
  508. package/ios/Core/ANNPendingLayers.mm +57 -0
  509. package/ios/Core/ANNReloadCoordinator.h +26 -0
  510. package/ios/Core/ANNReloadCoordinator.mm +211 -0
  511. package/ios/Core/ANNRenderWait.h +105 -0
  512. package/ios/Core/ANNRenderWait.mm +496 -0
  513. package/ios/Core/ANNSceneDelegate.mm +92 -0
  514. package/ios/Core/ANNScreenAppearance+Internal.h +29 -0
  515. package/ios/Core/ANNScreenAppearance.h +60 -0
  516. package/ios/Core/ANNScreenAppearance.mm +44 -0
  517. package/ios/Core/ANNShownScreens.h +27 -0
  518. package/ios/Core/ANNShownScreens.mm +16 -0
  519. package/ios/Core/ANNSystemUI.h +95 -0
  520. package/ios/Core/ANNSystemUI.mm +401 -0
  521. package/ios/Core/ANNSystemUIRules.h +35 -0
  522. package/ios/Core/ANNSystemUIRules.mm +139 -0
  523. package/ios/Core/ANNUtils.h +35 -0
  524. package/ios/Core/ANNUtils.mm +111 -0
  525. package/ios/Core/ApexNavigation+Internal.h +26 -0
  526. package/ios/Core/ApexNavigation.mm +177 -0
  527. package/ios/Core/UIViewController+LayoutProtocol.h +102 -0
  528. package/ios/Core/UIViewController+LayoutProtocol.mm +253 -0
  529. package/ios/Layouts/Arrangement/ANNArrangementScreenDelegate.h +18 -0
  530. package/ios/Layouts/Arrangement/ANNArrangementState.h +30 -0
  531. package/ios/Layouts/Arrangement/ANNArrangementState.mm +53 -0
  532. package/ios/Layouts/Arrangement/ANNArrangementViewController.h +38 -0
  533. package/ios/Layouts/Arrangement/ANNArrangementViewController.mm +573 -0
  534. package/ios/Layouts/External/ANNExternalViewController.h +28 -0
  535. package/ios/Layouts/External/ANNExternalViewController.mm +118 -0
  536. package/ios/Layouts/External/ANNNativeScreenCalls.h +27 -0
  537. package/ios/Layouts/External/ANNNativeScreenCalls.mm +77 -0
  538. package/ios/Layouts/Modal/ANNModal.h +121 -0
  539. package/ios/Layouts/Modal/ANNModal.mm +64 -0
  540. package/ios/Layouts/Modal/ANNModalCoordinator.h +99 -0
  541. package/ios/Layouts/Modal/ANNModalCoordinator.mm +1965 -0
  542. package/ios/Layouts/Modal/ANNModalHostViewComponentView.h +13 -0
  543. package/ios/Layouts/Modal/ANNModalHostViewComponentView.mm +24 -0
  544. package/ios/Layouts/Modal/ANNModalPresentation.h +73 -0
  545. package/ios/Layouts/Modal/ANNModalPresentation.mm +189 -0
  546. package/ios/Layouts/Modal/ANNModalSizePresenter.h +13 -0
  547. package/ios/Layouts/Modal/ANNModalSizePresenter.mm +65 -0
  548. package/ios/Layouts/Modal/ANNModalTransitions.h +29 -0
  549. package/ios/Layouts/Modal/ANNModalTransitions.mm +40 -0
  550. package/ios/Layouts/Modal/ANNPopoverPresenter.h +29 -0
  551. package/ios/Layouts/Modal/ANNPopoverPresenter.mm +158 -0
  552. package/ios/Layouts/Modal/ANNPresentationGate.h +52 -0
  553. package/ios/Layouts/Modal/ANNPresentationGate.mm +153 -0
  554. package/ios/Layouts/Modal/ANNSheetPresenter.h +31 -0
  555. package/ios/Layouts/Modal/ANNSheetPresenter.mm +247 -0
  556. package/ios/Layouts/Overlay/ANNOverlayCoordinator.h +66 -0
  557. package/ios/Layouts/Overlay/ANNOverlayCoordinator.mm +604 -0
  558. package/ios/Layouts/Overlay/ANNOverlayWindow.h +10 -0
  559. package/ios/Layouts/Overlay/ANNOverlayWindow.mm +71 -0
  560. package/ios/Layouts/Root/ANNLayoutFactory.h +31 -0
  561. package/ios/Layouts/Root/ANNLayoutFactory.mm +349 -0
  562. package/ios/Layouts/Root/ANNRootCoordinator.h +42 -0
  563. package/ios/Layouts/Root/ANNRootCoordinator.mm +847 -0
  564. package/ios/Layouts/Root/ANNSplashViewController.h +30 -0
  565. package/ios/Layouts/Root/ANNSplashViewController.mm +138 -0
  566. package/ios/Layouts/Screen/ANNComponentPresenter.h +32 -0
  567. package/ios/Layouts/Screen/ANNComponentPresenter.mm +136 -0
  568. package/ios/Layouts/Screen/ANNComponentViewController.h +100 -0
  569. package/ios/Layouts/Screen/ANNComponentViewController.mm +652 -0
  570. package/ios/Layouts/Screen/ANNNativeScreenContext+Internal.h +19 -0
  571. package/ios/Layouts/Screen/ANNNativeScreenContext.mm +84 -0
  572. package/ios/Layouts/Screen/ANNPreviewInteraction.h +38 -0
  573. package/ios/Layouts/Screen/ANNPreviewInteraction.mm +252 -0
  574. package/ios/Layouts/Screen/ANNScreenBars.h +29 -0
  575. package/ios/Layouts/Screen/ANNScreenBars.mm +47 -0
  576. package/ios/Layouts/Screen/ANNScreenInsets.h +30 -0
  577. package/ios/Layouts/Screen/ANNScreenInsets.mm +68 -0
  578. package/ios/Layouts/Screen/ANNScreenReadiness.h +92 -0
  579. package/ios/Layouts/Screen/ANNScreenReadiness.mm +186 -0
  580. package/ios/Layouts/Screen/ANNScreenRegions.h +33 -0
  581. package/ios/Layouts/Screen/ANNScreenRegions.mm +105 -0
  582. package/ios/Layouts/Screen/ANNScreenSafeArea.h +38 -0
  583. package/ios/Layouts/Screen/ANNScreenSafeArea.mm +58 -0
  584. package/ios/Layouts/SideMenu/ANNSideMenuChildViewController.h +41 -0
  585. package/ios/Layouts/SideMenu/ANNSideMenuChildViewController.mm +113 -0
  586. package/ios/Layouts/SideMenu/ANNSideMenuPresenter.h +28 -0
  587. package/ios/Layouts/SideMenu/ANNSideMenuPresenter.mm +260 -0
  588. package/ios/Layouts/SideMenu/ANNSideMenuTypes.h +19 -0
  589. package/ios/Layouts/SideMenu/ANNSideMenuViewController.h +46 -0
  590. package/ios/Layouts/SideMenu/ANNSideMenuViewController.mm +891 -0
  591. package/ios/Layouts/SplitView/ANNSplitViewCommands.h +39 -0
  592. package/ios/Layouts/SplitView/ANNSplitViewCommands.mm +612 -0
  593. package/ios/Layouts/SplitView/ANNSplitViewController.h +52 -0
  594. package/ios/Layouts/SplitView/ANNSplitViewController.mm +494 -0
  595. package/ios/Layouts/SplitView/ANNSplitViewPresenter.h +18 -0
  596. package/ios/Layouts/SplitView/ANNSplitViewPresenter.mm +181 -0
  597. package/ios/Layouts/SplitView/UISplitViewController+ANNOptions.h +32 -0
  598. package/ios/Layouts/SplitView/UISplitViewController+ANNOptions.mm +133 -0
  599. package/ios/Layouts/Stack/ANNPreviewPush.h +46 -0
  600. package/ios/Layouts/Stack/ANNPreviewPush.mm +298 -0
  601. package/ios/Layouts/Stack/ANNStackAnimatingDelegate.h +32 -0
  602. package/ios/Layouts/Stack/ANNStackAnimatingDelegate.mm +92 -0
  603. package/ios/Layouts/Stack/ANNStackCommands.h +51 -0
  604. package/ios/Layouts/Stack/ANNStackCommands.mm +403 -0
  605. package/ios/Layouts/Stack/ANNStackController.h +161 -0
  606. package/ios/Layouts/Stack/ANNStackController.mm +1597 -0
  607. package/ios/Layouts/Stack/ANNStackPresenter.h +44 -0
  608. package/ios/Layouts/Stack/ANNStackPresenter.mm +181 -0
  609. package/ios/Layouts/Stack/ANNStackQueue.h +194 -0
  610. package/ios/Layouts/Stack/ANNStackQueue.mm +1300 -0
  611. package/ios/Layouts/Stack/InteractivePopGestureDelegate.h +53 -0
  612. package/ios/Layouts/Stack/InteractivePopGestureDelegate.mm +228 -0
  613. package/ios/Layouts/Stack/UINavigationController+ANNCommands.h +19 -0
  614. package/ios/Layouts/Stack/UINavigationController+ANNCommands.mm +29 -0
  615. package/ios/Layouts/Tabs/ANNBottomTabCellView.h +33 -0
  616. package/ios/Layouts/Tabs/ANNBottomTabCellView.mm +100 -0
  617. package/ios/Layouts/Tabs/ANNBottomTabItemBuilder.h +49 -0
  618. package/ios/Layouts/Tabs/ANNBottomTabItemBuilder.mm +153 -0
  619. package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.h +17 -0
  620. package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.mm +56 -0
  621. package/ios/Layouts/Tabs/ANNBottomTabsController.h +121 -0
  622. package/ios/Layouts/Tabs/ANNBottomTabsController.mm +1404 -0
  623. package/ios/Layouts/Tabs/ANNBottomTabsCustomRow.h +47 -0
  624. package/ios/Layouts/Tabs/ANNBottomTabsCustomRow.mm +280 -0
  625. package/ios/Layouts/Tabs/ANNBottomTabsPresenter.h +81 -0
  626. package/ios/Layouts/Tabs/ANNBottomTabsPresenter.mm +1026 -0
  627. package/ios/Layouts/Tabs/ANNMoreNavigationDelegate.h +24 -0
  628. package/ios/Layouts/Tabs/ANNMoreNavigationDelegate.mm +58 -0
  629. package/ios/Layouts/Tabs/ANNScrollToTop.h +23 -0
  630. package/ios/Layouts/Tabs/ANNScrollToTop.mm +55 -0
  631. package/ios/Layouts/Tabs/ANNTabDotView.h +19 -0
  632. package/ios/Layouts/Tabs/ANNTabDotView.mm +46 -0
  633. package/ios/Layouts/Tabs/ANNTabLongPress.h +28 -0
  634. package/ios/Layouts/Tabs/ANNTabLongPress.mm +98 -0
  635. package/ios/Layouts/Tabs/ANNTabsDesign.h +26 -0
  636. package/ios/Layouts/Tabs/ANNTabsDesign.mm +34 -0
  637. package/ios/Layouts/Tabs/ANNTabsPreloadWindow.h +27 -0
  638. package/ios/Layouts/Tabs/ANNTabsPreloadWindow.mm +55 -0
  639. package/ios/Layouts/Tabs/UITabBar+utils.h +24 -0
  640. package/ios/Layouts/Tabs/UITabBar+utils.mm +103 -0
  641. package/ios/Options/ANNAnimationOptions.h +22 -0
  642. package/ios/Options/ANNAnimationOptions.mm +16 -0
  643. package/ios/Options/ANNAnimationPropertyOptions.h +17 -0
  644. package/ios/Options/ANNAnimationPropertyOptions.mm +15 -0
  645. package/ios/Options/ANNBottomTabDotIndicatorOptions.h +14 -0
  646. package/ios/Options/ANNBottomTabDotIndicatorOptions.mm +13 -0
  647. package/ios/Options/ANNBottomTabOptions.h +51 -0
  648. package/ios/Options/ANNBottomTabOptions.mm +47 -0
  649. package/ios/Options/ANNBottomTabsAccessoryOptions.h +19 -0
  650. package/ios/Options/ANNBottomTabsAccessoryOptions.mm +25 -0
  651. package/ios/Options/ANNBottomTabsAnimationOptions.h +12 -0
  652. package/ios/Options/ANNBottomTabsAnimationOptions.mm +11 -0
  653. package/ios/Options/ANNBottomTabsCustomRowOptions.h +19 -0
  654. package/ios/Options/ANNBottomTabsCustomRowOptions.mm +17 -0
  655. package/ios/Options/ANNBottomTabsOptions.h +51 -0
  656. package/ios/Options/ANNBottomTabsOptions.mm +48 -0
  657. package/ios/Options/ANNBottomTabsShadowOptions.h +14 -0
  658. package/ios/Options/ANNBottomTabsShadowOptions.mm +13 -0
  659. package/ios/Options/ANNButtonComponentOptions.h +13 -0
  660. package/ios/Options/ANNButtonComponentOptions.mm +12 -0
  661. package/ios/Options/ANNButtonOptions.h +56 -0
  662. package/ios/Options/ANNButtonOptions.mm +53 -0
  663. package/ios/Options/ANNButtonsParser.h +13 -0
  664. package/ios/Options/ANNButtonsParser.mm +18 -0
  665. package/ios/Options/ANNComponentOptions.h +14 -0
  666. package/ios/Options/ANNComponentOptions.mm +12 -0
  667. package/ios/Options/ANNDefaultOptions.h +18 -0
  668. package/ios/Options/ANNDefaultOptions.mm +22 -0
  669. package/ios/Options/ANNElementAnimationOptions.h +18 -0
  670. package/ios/Options/ANNElementAnimationOptions.mm +15 -0
  671. package/ios/Options/ANNElementTransitionOptions.h +26 -0
  672. package/ios/Options/ANNElementTransitionOptions.mm +28 -0
  673. package/ios/Options/ANNEnterExitBottomTabsAnimationOptions.h +14 -0
  674. package/ios/Options/ANNEnterExitBottomTabsAnimationOptions.mm +12 -0
  675. package/ios/Options/ANNEnterExitScreenAnimationOptions.h +14 -0
  676. package/ios/Options/ANNEnterExitScreenAnimationOptions.mm +12 -0
  677. package/ios/Options/ANNEnterExitTopBarAnimationOptions.h +14 -0
  678. package/ios/Options/ANNEnterExitTopBarAnimationOptions.mm +12 -0
  679. package/ios/Options/ANNFabOptions.h +26 -0
  680. package/ios/Options/ANNFabOptions.mm +23 -0
  681. package/ios/Options/ANNFontOptions.h +24 -0
  682. package/ios/Options/ANNFontOptions.mm +65 -0
  683. package/ios/Options/ANNHardwareBackButtonOptions.h +15 -0
  684. package/ios/Options/ANNHardwareBackButtonOptions.mm +13 -0
  685. package/ios/Options/ANNIconBackgroundOptions.h +16 -0
  686. package/ios/Options/ANNIconBackgroundOptions.mm +15 -0
  687. package/ios/Options/ANNIconInsetsOptions.h +16 -0
  688. package/ios/Options/ANNIconInsetsOptions.mm +14 -0
  689. package/ios/Options/ANNInterpolationOptions.h +22 -0
  690. package/ios/Options/ANNInterpolationOptions.mm +22 -0
  691. package/ios/Options/ANNLayoutOptions.h +26 -0
  692. package/ios/Options/ANNLayoutOptions.mm +25 -0
  693. package/ios/Options/ANNMenuOptions.h +37 -0
  694. package/ios/Options/ANNMenuOptions.mm +136 -0
  695. package/ios/Options/ANNModalAnimationOptions.h +17 -0
  696. package/ios/Options/ANNModalAnimationOptions.mm +15 -0
  697. package/ios/Options/ANNModalContentSizeOptions.h +14 -0
  698. package/ios/Options/ANNModalContentSizeOptions.mm +15 -0
  699. package/ios/Options/ANNModalOptions.h +19 -0
  700. package/ios/Options/ANNModalOptions.mm +15 -0
  701. package/ios/Options/ANNNavigationBarOptions.h +14 -0
  702. package/ios/Options/ANNNavigationBarOptions.mm +13 -0
  703. package/ios/Options/ANNNavigationOptions.h +60 -0
  704. package/ios/Options/ANNNavigationOptions.mm +54 -0
  705. package/ios/Options/ANNOptionField.h +91 -0
  706. package/ios/Options/ANNOptionField.mm +173 -0
  707. package/ios/Options/ANNOptions.h +62 -0
  708. package/ios/Options/ANNOptions.mm +329 -0
  709. package/ios/Options/ANNOptionsCache.h +22 -0
  710. package/ios/Options/ANNOptionsCache.mm +17 -0
  711. package/ios/Options/ANNOptionsReader.h +33 -0
  712. package/ios/Options/ANNOptionsReader.mm +63 -0
  713. package/ios/Options/ANNOverlayOptions.h +14 -0
  714. package/ios/Options/ANNOverlayOptions.mm +12 -0
  715. package/ios/Options/ANNPopoverOptions.h +17 -0
  716. package/ios/Options/ANNPopoverOptions.mm +31 -0
  717. package/ios/Options/ANNPreviewOptions.h +17 -0
  718. package/ios/Options/ANNPreviewOptions.mm +15 -0
  719. package/ios/Options/ANNScreenAnimationOptions.h +13 -0
  720. package/ios/Options/ANNScreenAnimationOptions.mm +12 -0
  721. package/ios/Options/ANNScrollEdgeEffectOptions.h +20 -0
  722. package/ios/Options/ANNScrollEdgeEffectOptions.mm +16 -0
  723. package/ios/Options/ANNScrollEdgeOptions.h +14 -0
  724. package/ios/Options/ANNScrollEdgeOptions.mm +12 -0
  725. package/ios/Options/ANNSearchBarOptions.h +49 -0
  726. package/ios/Options/ANNSearchBarOptions.mm +41 -0
  727. package/ios/Options/ANNSearchScopeOptions.h +15 -0
  728. package/ios/Options/ANNSearchScopeOptions.mm +13 -0
  729. package/ios/Options/ANNSearchSuggestionOptions.h +19 -0
  730. package/ios/Options/ANNSearchSuggestionOptions.mm +16 -0
  731. package/ios/Options/ANNSearchTokenOptions.h +18 -0
  732. package/ios/Options/ANNSearchTokenOptions.mm +15 -0
  733. package/ios/Options/ANNSetStackRootAnimationOptions.h +12 -0
  734. package/ios/Options/ANNSetStackRootAnimationOptions.mm +11 -0
  735. package/ios/Options/ANNSharedElementTransitionOptions.h +17 -0
  736. package/ios/Options/ANNSharedElementTransitionOptions.mm +15 -0
  737. package/ios/Options/ANNSheetOptions.h +25 -0
  738. package/ios/Options/ANNSheetOptions.mm +41 -0
  739. package/ios/Options/ANNSideMenuOptions.h +19 -0
  740. package/ios/Options/ANNSideMenuOptions.mm +16 -0
  741. package/ios/Options/ANNSideMenuSideOptions.h +23 -0
  742. package/ios/Options/ANNSideMenuSideOptions.mm +20 -0
  743. package/ios/Options/ANNSplitViewColumnOptions.h +14 -0
  744. package/ios/Options/ANNSplitViewColumnOptions.mm +13 -0
  745. package/ios/Options/ANNSplitViewInspectorOptions.h +13 -0
  746. package/ios/Options/ANNSplitViewInspectorOptions.mm +9 -0
  747. package/ios/Options/ANNSplitViewOptions.h +29 -0
  748. package/ios/Options/ANNSplitViewOptions.mm +26 -0
  749. package/ios/Options/ANNStackAnimationOptions.h +23 -0
  750. package/ios/Options/ANNStackAnimationOptions.mm +20 -0
  751. package/ios/Options/ANNStackPushAnimationOptions.h +13 -0
  752. package/ios/Options/ANNStackPushAnimationOptions.mm +11 -0
  753. package/ios/Options/ANNStatusBarOptions.h +20 -0
  754. package/ios/Options/ANNStatusBarOptions.mm +18 -0
  755. package/ios/Options/ANNToolbarOptions.h +14 -0
  756. package/ios/Options/ANNToolbarOptions.mm +27 -0
  757. package/ios/Options/ANNTopBarAnimationOptions.h +12 -0
  758. package/ios/Options/ANNTopBarAnimationOptions.mm +11 -0
  759. package/ios/Options/ANNTopBarBackButtonOptions.h +31 -0
  760. package/ios/Options/ANNTopBarBackButtonOptions.mm +35 -0
  761. package/ios/Options/ANNTopBarBackgroundComponentOptions.h +13 -0
  762. package/ios/Options/ANNTopBarBackgroundComponentOptions.mm +11 -0
  763. package/ios/Options/ANNTopBarBackgroundOptions.h +17 -0
  764. package/ios/Options/ANNTopBarBackgroundOptions.mm +15 -0
  765. package/ios/Options/ANNTopBarLargeTitleOptions.h +19 -0
  766. package/ios/Options/ANNTopBarLargeTitleOptions.mm +15 -0
  767. package/ios/Options/ANNTopBarOptions.h +62 -0
  768. package/ios/Options/ANNTopBarOptions.mm +49 -0
  769. package/ios/Options/ANNTopBarScrollEdgeAppearanceBackgroundOptions.h +14 -0
  770. package/ios/Options/ANNTopBarScrollEdgeAppearanceBackgroundOptions.mm +12 -0
  771. package/ios/Options/ANNTopBarScrollEdgeAppearanceOptions.h +19 -0
  772. package/ios/Options/ANNTopBarScrollEdgeAppearanceOptions.mm +16 -0
  773. package/ios/Options/ANNTopBarScrollEdgeAppearanceTitleOptions.h +16 -0
  774. package/ios/Options/ANNTopBarScrollEdgeAppearanceTitleOptions.mm +12 -0
  775. package/ios/Options/ANNTopBarSubtitleOptions.h +18 -0
  776. package/ios/Options/ANNTopBarSubtitleOptions.mm +14 -0
  777. package/ios/Options/ANNTopBarTitleComponentOptions.h +15 -0
  778. package/ios/Options/ANNTopBarTitleComponentOptions.mm +12 -0
  779. package/ios/Options/ANNTopBarTitleDocumentOptions.h +12 -0
  780. package/ios/Options/ANNTopBarTitleDocumentOptions.mm +11 -0
  781. package/ios/Options/ANNTopBarTitleOptions.h +29 -0
  782. package/ios/Options/ANNTopBarTitleOptions.mm +21 -0
  783. package/ios/Options/ANNViewAnimationOptions.h +26 -0
  784. package/ios/Options/ANNViewAnimationOptions.mm +58 -0
  785. package/ios/Options/ANNWindowOptions.h +12 -0
  786. package/ios/Options/ANNWindowOptions.mm +9 -0
  787. package/ios/Options/ANNZoomTransitionOptions.h +13 -0
  788. package/ios/Options/ANNZoomTransitionOptions.mm +12 -0
  789. package/ios/Options/Params/ANNIntegerParam.h +14 -0
  790. package/ios/Options/Params/ANNIntegerParam.mm +13 -0
  791. package/ios/Options/Params/ANNParam.h +28 -0
  792. package/ios/Options/Params/ANNParam.mm +29 -0
  793. package/ios/Options/Params/Bool.h +17 -0
  794. package/ios/Options/Params/Bool.mm +17 -0
  795. package/ios/Options/Params/BoolParser.h +12 -0
  796. package/ios/Options/Params/BoolParser.mm +10 -0
  797. package/ios/Options/Params/Color.h +43 -0
  798. package/ios/Options/Params/Color.mm +65 -0
  799. package/ios/Options/Params/ColorParser.h +14 -0
  800. package/ios/Options/Params/ColorParser.mm +95 -0
  801. package/ios/Options/Params/Double.h +14 -0
  802. package/ios/Options/Params/Double.mm +13 -0
  803. package/ios/Options/Params/DoubleParser.h +16 -0
  804. package/ios/Options/Params/DoubleParser.mm +16 -0
  805. package/ios/Options/Params/Image.h +15 -0
  806. package/ios/Options/Params/Image.mm +13 -0
  807. package/ios/Options/Params/ImageParser.h +16 -0
  808. package/ios/Options/Params/ImageParser.mm +103 -0
  809. package/ios/Options/Params/Number.h +14 -0
  810. package/ios/Options/Params/Number.mm +13 -0
  811. package/ios/Options/Params/NumberParser.h +13 -0
  812. package/ios/Options/Params/NumberParser.mm +10 -0
  813. package/ios/Options/Params/Param.h +16 -0
  814. package/ios/Options/Params/Param.mm +13 -0
  815. package/ios/Options/Params/Text.h +17 -0
  816. package/ios/Options/Params/Text.mm +17 -0
  817. package/ios/Options/Params/TextParser.h +17 -0
  818. package/ios/Options/Params/TextParser.mm +17 -0
  819. package/ios/Package.swift +58 -0
  820. package/ios/Public/ApexNavigation/ANNAppDelegate.h +66 -0
  821. package/ios/Public/ApexNavigation/ANNSceneDelegate.h +19 -0
  822. package/ios/Public/ApexNavigation/ApexNavigation.h +92 -0
  823. package/ios/Public/module.modulemap +8 -0
  824. package/ios/RECIPES.md +41 -0
  825. package/ios/React/ANNComponentType.h +22 -0
  826. package/ios/React/ANNComponentViewCreator.h +18 -0
  827. package/ios/React/ANNReactComponentRegistry.h +53 -0
  828. package/ios/React/ANNReactComponentRegistry.mm +153 -0
  829. package/ios/React/ANNReactView.h +104 -0
  830. package/ios/React/ANNReactView.mm +374 -0
  831. package/ios/React/ANNReactViewCreator.h +20 -0
  832. package/ios/React/ANNReactViewCreator.mm +42 -0
  833. package/ios/React/ANNSafeAreaViewComponentView.h +13 -0
  834. package/ios/React/ANNSafeAreaViewComponentView.mm +153 -0
  835. package/ios/React/ANNSurfaceHostingView.h +17 -0
  836. package/ios/React/ANNSurfaceHostingView.mm +68 -0
  837. package/ios/React/Slots/ANNSlotComponentView.h +10 -0
  838. package/ios/React/Slots/ANNSlotComponentView.mm +122 -0
  839. package/ios/React/Slots/ANNSlotContainers.h +34 -0
  840. package/ios/React/Slots/ANNSlotContainers.mm +39 -0
  841. package/ios/React/Slots/ANNSlotContentView.h +12 -0
  842. package/ios/React/Slots/ANNSlotContentView.mm +18 -0
  843. package/ios/React/Slots/ANNSlotHost.h +29 -0
  844. package/ios/React/Slots/ANNSlotHost.mm +59 -0
  845. package/ios/React/Slots/ANNSlotScreenView.h +38 -0
  846. package/ios/React/Slots/ANNSlotScreenView.mm +254 -0
  847. package/ios/TopBar/ANNBackButtonPresenter.h +35 -0
  848. package/ios/TopBar/ANNBackButtonPresenter.mm +187 -0
  849. package/ios/TopBar/ANNBarAppearance.h +53 -0
  850. package/ios/TopBar/ANNBarAppearance.mm +278 -0
  851. package/ios/TopBar/ANNBarBackgroundComponent.h +46 -0
  852. package/ios/TopBar/ANNBarBackgroundComponent.mm +163 -0
  853. package/ios/TopBar/ANNBarButtonComponentView.h +30 -0
  854. package/ios/TopBar/ANNBarButtonComponentView.mm +110 -0
  855. package/ios/TopBar/ANNBarButtons.h +65 -0
  856. package/ios/TopBar/ANNBarButtons.mm +1125 -0
  857. package/ios/TopBar/ANNBarComponentsWait.h +37 -0
  858. package/ios/TopBar/ANNBarComponentsWait.mm +116 -0
  859. package/ios/TopBar/ANNIconButtonImage.h +25 -0
  860. package/ios/TopBar/ANNIconButtonImage.mm +94 -0
  861. package/ios/TopBar/ANNLargeTitlePresenter.h +117 -0
  862. package/ios/TopBar/ANNLargeTitlePresenter.mm +402 -0
  863. package/ios/TopBar/ANNMainList.h +28 -0
  864. package/ios/TopBar/ANNMainList.mm +72 -0
  865. package/ios/TopBar/ANNScrollEdgeEffects.h +29 -0
  866. package/ios/TopBar/ANNScrollEdgeEffects.mm +122 -0
  867. package/ios/TopBar/ANNSearchPresenter.h +29 -0
  868. package/ios/TopBar/ANNSearchPresenter.mm +637 -0
  869. package/ios/TopBar/ANNSearchResultsViewController.h +16 -0
  870. package/ios/TopBar/ANNSearchResultsViewController.mm +56 -0
  871. package/ios/TopBar/ANNShowTextButton.h +22 -0
  872. package/ios/TopBar/ANNShowTextButton.mm +63 -0
  873. package/ios/TopBar/ANNTitleComponentView.h +37 -0
  874. package/ios/TopBar/ANNTitleComponentView.mm +86 -0
  875. package/ios/TopBar/ANNTitleGlassView.h +33 -0
  876. package/ios/TopBar/ANNTitleGlassView.mm +126 -0
  877. package/ios/TopBar/ANNTitleView.h +18 -0
  878. package/ios/TopBar/ANNTitleView.mm +63 -0
  879. package/ios/TopBar/ANNToolbarPresenter.h +26 -0
  880. package/ios/TopBar/ANNToolbarPresenter.mm +24 -0
  881. package/ios/TopBar/ANNTopBarPresenter.h +120 -0
  882. package/ios/TopBar/ANNTopBarPresenter.mm +1252 -0
  883. package/ios/TopBar/ANNUIBarButtonItem.h +16 -0
  884. package/ios/TopBar/ANNUIBarButtonItem.mm +5 -0
  885. package/ios/TurboModules/ANNTurboEventEmitter.h +31 -0
  886. package/ios/TurboModules/ANNTurboEventEmitter.mm +129 -0
  887. package/ios/TurboModules/ANNTurboModule.h +11 -0
  888. package/ios/TurboModules/ANNTurboModule.mm +626 -0
  889. package/ios/Utils/UIColor+ANNLuminance.h +13 -0
  890. package/ios/Utils/UIColor+ANNLuminance.mm +32 -0
  891. package/ios/Utils/UIView+Utils.h +12 -0
  892. package/ios/Utils/UIView+Utils.mm +21 -0
  893. package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSafeAreaViewComponentDescriptor.h +19 -0
  894. package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSafeAreaViewShadowNode.h +60 -0
  895. package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSafeAreaViewState.h +33 -0
  896. package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotComponentDescriptor.h +22 -0
  897. package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotShadowNode.h +87 -0
  898. package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.h +101 -0
  899. package/lib/module/ARCHITECTURE.md +289 -0
  900. package/lib/module/adapters/NativeANNTurboEventEmitter.js +12 -0
  901. package/lib/module/adapters/NativeANNTurboEventEmitter.js.map +1 -0
  902. package/lib/module/adapters/NativeANNTurboModule.js +13 -0
  903. package/lib/module/adapters/NativeANNTurboModule.js.map +1 -0
  904. package/lib/module/api/app/AppRegistry.js +52 -0
  905. package/lib/module/api/app/AppRegistry.js.map +1 -0
  906. package/lib/module/api/app/activeApp.js +12 -0
  907. package/lib/module/api/app/activeApp.js.map +1 -0
  908. package/lib/module/api/app/createNavigation.js +365 -0
  909. package/lib/module/api/app/createNavigation.js.map +1 -0
  910. package/lib/module/api/app/roots.js +20 -0
  911. package/lib/module/api/app/roots.js.map +1 -0
  912. package/lib/module/api/app/splash.js +124 -0
  913. package/lib/module/api/app/splash.js.map +1 -0
  914. package/lib/module/api/app/startFailure.js +38 -0
  915. package/lib/module/api/app/startFailure.js.map +1 -0
  916. package/lib/module/api/arrangement/arrangementState.js +86 -0
  917. package/lib/module/api/arrangement/arrangementState.js.map +1 -0
  918. package/lib/module/api/commands/commands.js +375 -0
  919. package/lib/module/api/commands/commands.js.map +1 -0
  920. package/lib/module/api/commands/errors.js +94 -0
  921. package/lib/module/api/commands/errors.js.map +1 -0
  922. package/lib/module/api/commands/presentation.js +4 -0
  923. package/lib/module/api/commands/presentation.js.map +1 -0
  924. package/lib/module/api/commands/sideMenus.js +134 -0
  925. package/lib/module/api/commands/sideMenus.js.map +1 -0
  926. package/lib/module/api/commands/transitions.js +245 -0
  927. package/lib/module/api/commands/transitions.js.map +1 -0
  928. package/lib/module/api/context/appContext.js +22 -0
  929. package/lib/module/api/context/appContext.js.map +1 -0
  930. package/lib/module/api/events/navigationEvents.js +69 -0
  931. package/lib/module/api/events/navigationEvents.js.map +1 -0
  932. package/lib/module/api/events/screenLifecycle.js +30 -0
  933. package/lib/module/api/events/screenLifecycle.js.map +1 -0
  934. package/lib/module/api/events/tabPresses.js +32 -0
  935. package/lib/module/api/events/tabPresses.js.map +1 -0
  936. package/lib/module/api/hinge/hinge.js +73 -0
  937. package/lib/module/api/hinge/hinge.js.map +1 -0
  938. package/lib/module/api/hooks/appHooks.js +26 -0
  939. package/lib/module/api/hooks/appHooks.js.map +1 -0
  940. package/lib/module/api/hooks/screenHooks.js +250 -0
  941. package/lib/module/api/hooks/screenHooks.js.map +1 -0
  942. package/lib/module/api/hooks/useArrangement.js +24 -0
  943. package/lib/module/api/hooks/useArrangement.js.map +1 -0
  944. package/lib/module/api/hooks/useHinge.js +29 -0
  945. package/lib/module/api/hooks/useHinge.js.map +1 -0
  946. package/lib/module/api/hooks/useNavigation.js +117 -0
  947. package/lib/module/api/hooks/useNavigation.js.map +1 -0
  948. package/lib/module/api/hooks/usePendingLink.js +12 -0
  949. package/lib/module/api/hooks/usePendingLink.js.map +1 -0
  950. package/lib/module/api/hooks/usePreview.js +97 -0
  951. package/lib/module/api/hooks/usePreview.js.map +1 -0
  952. package/lib/module/api/hooks/useReservedRegions.js +24 -0
  953. package/lib/module/api/hooks/useReservedRegions.js.map +1 -0
  954. package/lib/module/api/hooks/useSafeAreaInsets.js +25 -0
  955. package/lib/module/api/hooks/useSafeAreaInsets.js.map +1 -0
  956. package/lib/module/api/index.js +26 -0
  957. package/lib/module/api/index.js.map +1 -0
  958. package/lib/module/api/layout/Root.js +121 -0
  959. package/lib/module/api/layout/Root.js.map +1 -0
  960. package/lib/module/api/layout/Screen.js +52 -0
  961. package/lib/module/api/layout/Screen.js.map +1 -0
  962. package/lib/module/api/layout/SideMenu.js +85 -0
  963. package/lib/module/api/layout/SideMenu.js.map +1 -0
  964. package/lib/module/api/layout/SplitView.js +137 -0
  965. package/lib/module/api/layout/SplitView.js.map +1 -0
  966. package/lib/module/api/layout/Stack.js +36 -0
  967. package/lib/module/api/layout/Stack.js.map +1 -0
  968. package/lib/module/api/layout/Tabs.js +326 -0
  969. package/lib/module/api/layout/Tabs.js.map +1 -0
  970. package/lib/module/api/layout/element.js +100 -0
  971. package/lib/module/api/layout/element.js.map +1 -0
  972. package/lib/module/api/linking/linkPaths.js +132 -0
  973. package/lib/module/api/linking/linkPaths.js.map +1 -0
  974. package/lib/module/api/linking/linking.js +244 -0
  975. package/lib/module/api/linking/linking.js.map +1 -0
  976. package/lib/module/api/linking/pendingLinks.js +34 -0
  977. package/lib/module/api/linking/pendingLinks.js.map +1 -0
  978. package/lib/module/api/linking/types.js +4 -0
  979. package/lib/module/api/linking/types.js.map +1 -0
  980. package/lib/module/api/navigation.js +105 -0
  981. package/lib/module/api/navigation.js.map +1 -0
  982. package/lib/module/api/options/OptionsChain.js +158 -0
  983. package/lib/module/api/options/OptionsChain.js.map +1 -0
  984. package/lib/module/api/options/ScreenOptions.js +83 -0
  985. package/lib/module/api/options/ScreenOptions.js.map +1 -0
  986. package/lib/module/api/options/buttons.js +4 -0
  987. package/lib/module/api/options/buttons.js.map +1 -0
  988. package/lib/module/api/safeArea/ANNSafeAreaViewNativeComponent.ts +28 -0
  989. package/lib/module/api/safeArea/screenInsets.js +86 -0
  990. package/lib/module/api/safeArea/screenInsets.js.map +1 -0
  991. package/lib/module/api/safeArea/screenRegions.js +84 -0
  992. package/lib/module/api/safeArea/screenRegions.js.map +1 -0
  993. package/lib/module/api/screens/ScreenBoundary.js +44 -0
  994. package/lib/module/api/screens/ScreenBoundary.js.map +1 -0
  995. package/lib/module/api/screens/arrangement.js +63 -0
  996. package/lib/module/api/screens/arrangement.js.map +1 -0
  997. package/lib/module/api/screens/defineScreen.js +29 -0
  998. package/lib/module/api/screens/defineScreen.js.map +1 -0
  999. package/lib/module/api/screens/nativeScreenCalls.js +34 -0
  1000. package/lib/module/api/screens/nativeScreenCalls.js.map +1 -0
  1001. package/lib/module/api/screens/nativeScreens.js +43 -0
  1002. package/lib/module/api/screens/nativeScreens.js.map +1 -0
  1003. package/lib/module/api/screens/registerScreens.js +305 -0
  1004. package/lib/module/api/screens/registerScreens.js.map +1 -0
  1005. package/lib/module/api/slots/ANNSlotNativeComponent.ts +23 -0
  1006. package/lib/module/api/slots/SlotHost.js +92 -0
  1007. package/lib/module/api/slots/SlotHost.js.map +1 -0
  1008. package/lib/module/api/state/navigationState.js +98 -0
  1009. package/lib/module/api/state/navigationState.js.map +1 -0
  1010. package/lib/module/api/testIDs.js +14 -0
  1011. package/lib/module/api/testIDs.js.map +1 -0
  1012. package/lib/module/api/theme/theme.js +180 -0
  1013. package/lib/module/api/theme/theme.js.map +1 -0
  1014. package/lib/module/api/types.js +4 -0
  1015. package/lib/module/api/types.js.map +1 -0
  1016. package/lib/module/engine/backListeners.js +39 -0
  1017. package/lib/module/engine/backListeners.js.map +1 -0
  1018. package/lib/module/engine/buttons.js +105 -0
  1019. package/lib/module/engine/buttons.js.map +1 -0
  1020. package/lib/module/engine/commands.js +388 -0
  1021. package/lib/module/engine/commands.js.map +1 -0
  1022. package/lib/module/engine/events.js +30 -0
  1023. package/lib/module/engine/events.js.map +1 -0
  1024. package/lib/module/engine/ids.js +10 -0
  1025. package/lib/module/engine/ids.js.map +1 -0
  1026. package/lib/module/engine/launchState.js +34 -0
  1027. package/lib/module/engine/launchState.js.map +1 -0
  1028. package/lib/module/engine/layout.js +202 -0
  1029. package/lib/module/engine/layout.js.map +1 -0
  1030. package/lib/module/engine/mergeOptions.js +23 -0
  1031. package/lib/module/engine/mergeOptions.js.map +1 -0
  1032. package/lib/module/engine/native.js +45 -0
  1033. package/lib/module/engine/native.js.map +1 -0
  1034. package/lib/module/engine/nativeScreens.js +265 -0
  1035. package/lib/module/engine/nativeScreens.js.map +1 -0
  1036. package/lib/module/engine/options.js +170 -0
  1037. package/lib/module/engine/options.js.map +1 -0
  1038. package/lib/module/engine/places.js +178 -0
  1039. package/lib/module/engine/places.js.map +1 -0
  1040. package/lib/module/engine/props.js +44 -0
  1041. package/lib/module/engine/props.js.map +1 -0
  1042. package/lib/module/engine/reactMeasures.js +23 -0
  1043. package/lib/module/engine/reactMeasures.js.map +1 -0
  1044. package/lib/module/engine/rememberedOptions.js +118 -0
  1045. package/lib/module/engine/rememberedOptions.js.map +1 -0
  1046. package/lib/module/engine/screens.js +194 -0
  1047. package/lib/module/engine/screens.js.map +1 -0
  1048. package/lib/module/engine/slots.js +200 -0
  1049. package/lib/module/engine/slots.js.map +1 -0
  1050. package/lib/module/engine/tabs.js +79 -0
  1051. package/lib/module/engine/tabs.js.map +1 -0
  1052. package/lib/module/index.js +5 -0
  1053. package/lib/module/index.js.map +1 -0
  1054. package/lib/module/interfaces/ComponentEvents.js +2 -0
  1055. package/lib/module/interfaces/ComponentEvents.js.map +1 -0
  1056. package/lib/module/interfaces/Events.js +2 -0
  1057. package/lib/module/interfaces/Events.js.map +1 -0
  1058. package/lib/module/interfaces/Layout.js +4 -0
  1059. package/lib/module/interfaces/Layout.js.map +1 -0
  1060. package/lib/module/interfaces/Options.js +4 -0
  1061. package/lib/module/interfaces/Options.js.map +1 -0
  1062. package/lib/module/interfaces/options/animations.js +2 -0
  1063. package/lib/module/interfaces/options/animations.js.map +1 -0
  1064. package/lib/module/interfaces/options/bottomTabs.js +4 -0
  1065. package/lib/module/interfaces/options/bottomTabs.js.map +1 -0
  1066. package/lib/module/interfaces/options/buttons.js +4 -0
  1067. package/lib/module/interfaces/options/buttons.js.map +1 -0
  1068. package/lib/module/interfaces/options/common.js +4 -0
  1069. package/lib/module/interfaces/options/common.js.map +1 -0
  1070. package/lib/module/interfaces/options/modals.js +2 -0
  1071. package/lib/module/interfaces/options/modals.js.map +1 -0
  1072. package/lib/module/interfaces/options/preview.js +2 -0
  1073. package/lib/module/interfaces/options/preview.js.map +1 -0
  1074. package/lib/module/interfaces/options/sideMenu.js +2 -0
  1075. package/lib/module/interfaces/options/sideMenu.js.map +1 -0
  1076. package/lib/module/interfaces/options/splitView.js +2 -0
  1077. package/lib/module/interfaces/options/splitView.js.map +1 -0
  1078. package/lib/module/interfaces/options/stack.js +4 -0
  1079. package/lib/module/interfaces/options/stack.js.map +1 -0
  1080. package/lib/module/interfaces/options/system.js +4 -0
  1081. package/lib/module/interfaces/options/system.js.map +1 -0
  1082. package/lib/module/interfaces/options/toolbar.js +4 -0
  1083. package/lib/module/interfaces/options/toolbar.js.map +1 -0
  1084. package/lib/module/interfaces/options/topBar.js +4 -0
  1085. package/lib/module/interfaces/options/topBar.js.map +1 -0
  1086. package/lib/module/package.json +1 -0
  1087. package/lib/typescript/adapters/NativeANNTurboEventEmitter.d.ts +14 -0
  1088. package/lib/typescript/adapters/NativeANNTurboEventEmitter.d.ts.map +1 -0
  1089. package/lib/typescript/adapters/NativeANNTurboModule.d.ts +77 -0
  1090. package/lib/typescript/adapters/NativeANNTurboModule.d.ts.map +1 -0
  1091. package/lib/typescript/api/app/AppRegistry.d.ts +14 -0
  1092. package/lib/typescript/api/app/AppRegistry.d.ts.map +1 -0
  1093. package/lib/typescript/api/app/activeApp.d.ts +12 -0
  1094. package/lib/typescript/api/app/activeApp.d.ts.map +1 -0
  1095. package/lib/typescript/api/app/createNavigation.d.ts +182 -0
  1096. package/lib/typescript/api/app/createNavigation.d.ts.map +1 -0
  1097. package/lib/typescript/api/app/roots.d.ts +15 -0
  1098. package/lib/typescript/api/app/roots.d.ts.map +1 -0
  1099. package/lib/typescript/api/app/splash.d.ts +81 -0
  1100. package/lib/typescript/api/app/splash.d.ts.map +1 -0
  1101. package/lib/typescript/api/app/startFailure.d.ts +15 -0
  1102. package/lib/typescript/api/app/startFailure.d.ts.map +1 -0
  1103. package/lib/typescript/api/arrangement/arrangementState.d.ts +21 -0
  1104. package/lib/typescript/api/arrangement/arrangementState.d.ts.map +1 -0
  1105. package/lib/typescript/api/commands/commands.d.ts +57 -0
  1106. package/lib/typescript/api/commands/commands.d.ts.map +1 -0
  1107. package/lib/typescript/api/commands/errors.d.ts +24 -0
  1108. package/lib/typescript/api/commands/errors.d.ts.map +1 -0
  1109. package/lib/typescript/api/commands/presentation.d.ts +69 -0
  1110. package/lib/typescript/api/commands/presentation.d.ts.map +1 -0
  1111. package/lib/typescript/api/commands/sideMenus.d.ts +14 -0
  1112. package/lib/typescript/api/commands/sideMenus.d.ts.map +1 -0
  1113. package/lib/typescript/api/commands/transitions.d.ts +33 -0
  1114. package/lib/typescript/api/commands/transitions.d.ts.map +1 -0
  1115. package/lib/typescript/api/context/appContext.d.ts +4 -0
  1116. package/lib/typescript/api/context/appContext.d.ts.map +1 -0
  1117. package/lib/typescript/api/events/navigationEvents.d.ts +70 -0
  1118. package/lib/typescript/api/events/navigationEvents.d.ts.map +1 -0
  1119. package/lib/typescript/api/events/screenLifecycle.d.ts +5 -0
  1120. package/lib/typescript/api/events/screenLifecycle.d.ts.map +1 -0
  1121. package/lib/typescript/api/events/tabPresses.d.ts +5 -0
  1122. package/lib/typescript/api/events/tabPresses.d.ts.map +1 -0
  1123. package/lib/typescript/api/hinge/hinge.d.ts +21 -0
  1124. package/lib/typescript/api/hinge/hinge.d.ts.map +1 -0
  1125. package/lib/typescript/api/hooks/appHooks.d.ts +15 -0
  1126. package/lib/typescript/api/hooks/appHooks.d.ts.map +1 -0
  1127. package/lib/typescript/api/hooks/screenHooks.d.ts +74 -0
  1128. package/lib/typescript/api/hooks/screenHooks.d.ts.map +1 -0
  1129. package/lib/typescript/api/hooks/useArrangement.d.ts +13 -0
  1130. package/lib/typescript/api/hooks/useArrangement.d.ts.map +1 -0
  1131. package/lib/typescript/api/hooks/useHinge.d.ts +16 -0
  1132. package/lib/typescript/api/hooks/useHinge.d.ts.map +1 -0
  1133. package/lib/typescript/api/hooks/useNavigation.d.ts +108 -0
  1134. package/lib/typescript/api/hooks/useNavigation.d.ts.map +1 -0
  1135. package/lib/typescript/api/hooks/usePendingLink.d.ts +7 -0
  1136. package/lib/typescript/api/hooks/usePendingLink.d.ts.map +1 -0
  1137. package/lib/typescript/api/hooks/usePreview.d.ts +29 -0
  1138. package/lib/typescript/api/hooks/usePreview.d.ts.map +1 -0
  1139. package/lib/typescript/api/hooks/useReservedRegions.d.ts +13 -0
  1140. package/lib/typescript/api/hooks/useReservedRegions.d.ts.map +1 -0
  1141. package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts +14 -0
  1142. package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts.map +1 -0
  1143. package/lib/typescript/api/index.d.ts +60 -0
  1144. package/lib/typescript/api/index.d.ts.map +1 -0
  1145. package/lib/typescript/api/layout/Root.d.ts +47 -0
  1146. package/lib/typescript/api/layout/Root.d.ts.map +1 -0
  1147. package/lib/typescript/api/layout/Screen.d.ts +32 -0
  1148. package/lib/typescript/api/layout/Screen.d.ts.map +1 -0
  1149. package/lib/typescript/api/layout/SideMenu.d.ts +33 -0
  1150. package/lib/typescript/api/layout/SideMenu.d.ts.map +1 -0
  1151. package/lib/typescript/api/layout/SplitView.d.ts +48 -0
  1152. package/lib/typescript/api/layout/SplitView.d.ts.map +1 -0
  1153. package/lib/typescript/api/layout/Stack.d.ts +21 -0
  1154. package/lib/typescript/api/layout/Stack.d.ts.map +1 -0
  1155. package/lib/typescript/api/layout/Tabs.d.ts +120 -0
  1156. package/lib/typescript/api/layout/Tabs.d.ts.map +1 -0
  1157. package/lib/typescript/api/layout/element.d.ts +52 -0
  1158. package/lib/typescript/api/layout/element.d.ts.map +1 -0
  1159. package/lib/typescript/api/linking/linkPaths.d.ts +31 -0
  1160. package/lib/typescript/api/linking/linkPaths.d.ts.map +1 -0
  1161. package/lib/typescript/api/linking/linking.d.ts +37 -0
  1162. package/lib/typescript/api/linking/linking.d.ts.map +1 -0
  1163. package/lib/typescript/api/linking/pendingLinks.d.ts +8 -0
  1164. package/lib/typescript/api/linking/pendingLinks.d.ts.map +1 -0
  1165. package/lib/typescript/api/linking/types.d.ts +105 -0
  1166. package/lib/typescript/api/linking/types.d.ts.map +1 -0
  1167. package/lib/typescript/api/navigation.d.ts +115 -0
  1168. package/lib/typescript/api/navigation.d.ts.map +1 -0
  1169. package/lib/typescript/api/options/OptionsChain.d.ts +47 -0
  1170. package/lib/typescript/api/options/OptionsChain.d.ts.map +1 -0
  1171. package/lib/typescript/api/options/ScreenOptions.d.ts +32 -0
  1172. package/lib/typescript/api/options/ScreenOptions.d.ts.map +1 -0
  1173. package/lib/typescript/api/options/buttons.d.ts +35 -0
  1174. package/lib/typescript/api/options/buttons.d.ts.map +1 -0
  1175. package/lib/typescript/api/safeArea/ANNSafeAreaViewNativeComponent.d.ts +20 -0
  1176. package/lib/typescript/api/safeArea/ANNSafeAreaViewNativeComponent.d.ts.map +1 -0
  1177. package/lib/typescript/api/safeArea/screenInsets.d.ts +20 -0
  1178. package/lib/typescript/api/safeArea/screenInsets.d.ts.map +1 -0
  1179. package/lib/typescript/api/safeArea/screenRegions.d.ts +24 -0
  1180. package/lib/typescript/api/safeArea/screenRegions.d.ts.map +1 -0
  1181. package/lib/typescript/api/screens/ScreenBoundary.d.ts +34 -0
  1182. package/lib/typescript/api/screens/ScreenBoundary.d.ts.map +1 -0
  1183. package/lib/typescript/api/screens/arrangement.d.ts +70 -0
  1184. package/lib/typescript/api/screens/arrangement.d.ts.map +1 -0
  1185. package/lib/typescript/api/screens/defineScreen.d.ts +41 -0
  1186. package/lib/typescript/api/screens/defineScreen.d.ts.map +1 -0
  1187. package/lib/typescript/api/screens/nativeScreenCalls.d.ts +3 -0
  1188. package/lib/typescript/api/screens/nativeScreenCalls.d.ts.map +1 -0
  1189. package/lib/typescript/api/screens/nativeScreens.d.ts +47 -0
  1190. package/lib/typescript/api/screens/nativeScreens.d.ts.map +1 -0
  1191. package/lib/typescript/api/screens/registerScreens.d.ts +61 -0
  1192. package/lib/typescript/api/screens/registerScreens.d.ts.map +1 -0
  1193. package/lib/typescript/api/slots/ANNSlotNativeComponent.d.ts +15 -0
  1194. package/lib/typescript/api/slots/ANNSlotNativeComponent.d.ts.map +1 -0
  1195. package/lib/typescript/api/slots/SlotHost.d.ts +8 -0
  1196. package/lib/typescript/api/slots/SlotHost.d.ts.map +1 -0
  1197. package/lib/typescript/api/state/navigationState.d.ts +26 -0
  1198. package/lib/typescript/api/state/navigationState.d.ts.map +1 -0
  1199. package/lib/typescript/api/testIDs.d.ts +12 -0
  1200. package/lib/typescript/api/testIDs.d.ts.map +1 -0
  1201. package/lib/typescript/api/theme/theme.d.ts +70 -0
  1202. package/lib/typescript/api/theme/theme.d.ts.map +1 -0
  1203. package/lib/typescript/api/types.d.ts +64 -0
  1204. package/lib/typescript/api/types.d.ts.map +1 -0
  1205. package/lib/typescript/engine/backListeners.d.ts +8 -0
  1206. package/lib/typescript/engine/backListeners.d.ts.map +1 -0
  1207. package/lib/typescript/engine/buttons.d.ts +11 -0
  1208. package/lib/typescript/engine/buttons.d.ts.map +1 -0
  1209. package/lib/typescript/engine/commands.d.ts +38 -0
  1210. package/lib/typescript/engine/commands.d.ts.map +1 -0
  1211. package/lib/typescript/engine/events.d.ts +17 -0
  1212. package/lib/typescript/engine/events.d.ts.map +1 -0
  1213. package/lib/typescript/engine/ids.d.ts +3 -0
  1214. package/lib/typescript/engine/ids.d.ts.map +1 -0
  1215. package/lib/typescript/engine/launchState.d.ts +25 -0
  1216. package/lib/typescript/engine/launchState.d.ts.map +1 -0
  1217. package/lib/typescript/engine/layout.d.ts +32 -0
  1218. package/lib/typescript/engine/layout.d.ts.map +1 -0
  1219. package/lib/typescript/engine/mergeOptions.d.ts +6 -0
  1220. package/lib/typescript/engine/mergeOptions.d.ts.map +1 -0
  1221. package/lib/typescript/engine/native.d.ts +22 -0
  1222. package/lib/typescript/engine/native.d.ts.map +1 -0
  1223. package/lib/typescript/engine/nativeScreens.d.ts +49 -0
  1224. package/lib/typescript/engine/nativeScreens.d.ts.map +1 -0
  1225. package/lib/typescript/engine/options.d.ts +12 -0
  1226. package/lib/typescript/engine/options.d.ts.map +1 -0
  1227. package/lib/typescript/engine/places.d.ts +57 -0
  1228. package/lib/typescript/engine/places.d.ts.map +1 -0
  1229. package/lib/typescript/engine/props.d.ts +10 -0
  1230. package/lib/typescript/engine/props.d.ts.map +1 -0
  1231. package/lib/typescript/engine/reactMeasures.d.ts +3 -0
  1232. package/lib/typescript/engine/reactMeasures.d.ts.map +1 -0
  1233. package/lib/typescript/engine/rememberedOptions.d.ts +28 -0
  1234. package/lib/typescript/engine/rememberedOptions.d.ts.map +1 -0
  1235. package/lib/typescript/engine/screens.d.ts +90 -0
  1236. package/lib/typescript/engine/screens.d.ts.map +1 -0
  1237. package/lib/typescript/engine/slots.d.ts +71 -0
  1238. package/lib/typescript/engine/slots.d.ts.map +1 -0
  1239. package/lib/typescript/engine/tabs.d.ts +24 -0
  1240. package/lib/typescript/engine/tabs.d.ts.map +1 -0
  1241. package/lib/typescript/index.d.ts +3 -0
  1242. package/lib/typescript/index.d.ts.map +1 -0
  1243. package/lib/typescript/interfaces/ComponentEvents.d.ts +189 -0
  1244. package/lib/typescript/interfaces/ComponentEvents.d.ts.map +1 -0
  1245. package/lib/typescript/interfaces/Events.d.ts +199 -0
  1246. package/lib/typescript/interfaces/Events.d.ts.map +1 -0
  1247. package/lib/typescript/interfaces/Layout.d.ts +150 -0
  1248. package/lib/typescript/interfaces/Layout.d.ts.map +1 -0
  1249. package/lib/typescript/interfaces/Options.d.ts +93 -0
  1250. package/lib/typescript/interfaces/Options.d.ts.map +1 -0
  1251. package/lib/typescript/interfaces/options/animations.d.ts +452 -0
  1252. package/lib/typescript/interfaces/options/animations.d.ts.map +1 -0
  1253. package/lib/typescript/interfaces/options/bottomTabs.d.ts +462 -0
  1254. package/lib/typescript/interfaces/options/bottomTabs.d.ts.map +1 -0
  1255. package/lib/typescript/interfaces/options/buttons.d.ts +331 -0
  1256. package/lib/typescript/interfaces/options/buttons.d.ts.map +1 -0
  1257. package/lib/typescript/interfaces/options/common.d.ts +51 -0
  1258. package/lib/typescript/interfaces/options/common.d.ts.map +1 -0
  1259. package/lib/typescript/interfaces/options/modals.d.ts +202 -0
  1260. package/lib/typescript/interfaces/options/modals.d.ts.map +1 -0
  1261. package/lib/typescript/interfaces/options/preview.d.ts +40 -0
  1262. package/lib/typescript/interfaces/options/preview.d.ts.map +1 -0
  1263. package/lib/typescript/interfaces/options/sideMenu.d.ts +130 -0
  1264. package/lib/typescript/interfaces/options/sideMenu.d.ts.map +1 -0
  1265. package/lib/typescript/interfaces/options/splitView.d.ts +118 -0
  1266. package/lib/typescript/interfaces/options/splitView.d.ts.map +1 -0
  1267. package/lib/typescript/interfaces/options/stack.d.ts +109 -0
  1268. package/lib/typescript/interfaces/options/stack.d.ts.map +1 -0
  1269. package/lib/typescript/interfaces/options/system.d.ts +238 -0
  1270. package/lib/typescript/interfaces/options/system.d.ts.map +1 -0
  1271. package/lib/typescript/interfaces/options/toolbar.d.ts +45 -0
  1272. package/lib/typescript/interfaces/options/toolbar.d.ts.map +1 -0
  1273. package/lib/typescript/interfaces/options/topBar.d.ts +804 -0
  1274. package/lib/typescript/interfaces/options/topBar.d.ts.map +1 -0
  1275. package/lib/typescript/package.json +1 -0
  1276. package/package.json +189 -4
  1277. package/react-native.config.js +22 -0
  1278. package/src/ARCHITECTURE.md +289 -0
  1279. package/src/adapters/NativeANNTurboEventEmitter.ts +15 -0
  1280. package/src/adapters/NativeANNTurboModule.ts +100 -0
  1281. package/src/api/app/AppRegistry.ts +57 -0
  1282. package/src/api/app/activeApp.ts +20 -0
  1283. package/src/api/app/createNavigation.ts +566 -0
  1284. package/src/api/app/roots.ts +40 -0
  1285. package/src/api/app/splash.ts +154 -0
  1286. package/src/api/app/startFailure.tsx +39 -0
  1287. package/src/api/arrangement/arrangementState.ts +98 -0
  1288. package/src/api/commands/commands.ts +371 -0
  1289. package/src/api/commands/errors.ts +99 -0
  1290. package/src/api/commands/presentation.ts +78 -0
  1291. package/src/api/commands/sideMenus.ts +122 -0
  1292. package/src/api/commands/transitions.ts +133 -0
  1293. package/src/api/context/appContext.ts +23 -0
  1294. package/src/api/events/navigationEvents.ts +175 -0
  1295. package/src/api/events/screenLifecycle.ts +27 -0
  1296. package/src/api/events/tabPresses.ts +35 -0
  1297. package/src/api/hinge/hinge.ts +84 -0
  1298. package/src/api/hooks/appHooks.ts +37 -0
  1299. package/src/api/hooks/screenHooks.ts +272 -0
  1300. package/src/api/hooks/useArrangement.ts +26 -0
  1301. package/src/api/hooks/useHinge.ts +26 -0
  1302. package/src/api/hooks/useNavigation.ts +267 -0
  1303. package/src/api/hooks/usePendingLink.ts +11 -0
  1304. package/src/api/hooks/usePreview.ts +111 -0
  1305. package/src/api/hooks/useReservedRegions.ts +26 -0
  1306. package/src/api/hooks/useSafeAreaInsets.ts +23 -0
  1307. package/src/api/index.ts +139 -0
  1308. package/src/api/layout/Root.ts +113 -0
  1309. package/src/api/layout/Screen.ts +55 -0
  1310. package/src/api/layout/SideMenu.ts +87 -0
  1311. package/src/api/layout/SplitView.ts +146 -0
  1312. package/src/api/layout/Stack.ts +48 -0
  1313. package/src/api/layout/Tabs.ts +339 -0
  1314. package/src/api/layout/element.ts +114 -0
  1315. package/src/api/linking/linkPaths.ts +159 -0
  1316. package/src/api/linking/linking.ts +242 -0
  1317. package/src/api/linking/pendingLinks.ts +37 -0
  1318. package/src/api/linking/types.ts +130 -0
  1319. package/src/api/navigation.ts +269 -0
  1320. package/src/api/options/OptionsChain.ts +142 -0
  1321. package/src/api/options/ScreenOptions.ts +81 -0
  1322. package/src/api/options/buttons.ts +43 -0
  1323. package/src/api/safeArea/ANNSafeAreaViewNativeComponent.ts +28 -0
  1324. package/src/api/safeArea/screenInsets.ts +86 -0
  1325. package/src/api/safeArea/screenRegions.ts +99 -0
  1326. package/src/api/screens/ScreenBoundary.tsx +52 -0
  1327. package/src/api/screens/arrangement.ts +106 -0
  1328. package/src/api/screens/defineScreen.ts +57 -0
  1329. package/src/api/screens/nativeScreenCalls.ts +59 -0
  1330. package/src/api/screens/nativeScreens.ts +58 -0
  1331. package/src/api/screens/registerScreens.tsx +364 -0
  1332. package/src/api/slots/ANNSlotNativeComponent.ts +23 -0
  1333. package/src/api/slots/SlotHost.tsx +64 -0
  1334. package/src/api/state/navigationState.ts +95 -0
  1335. package/src/api/testIDs.ts +11 -0
  1336. package/src/api/theme/theme.ts +184 -0
  1337. package/src/api/types.ts +95 -0
  1338. package/src/engine/backListeners.ts +36 -0
  1339. package/src/engine/buttons.ts +91 -0
  1340. package/src/engine/commands.ts +469 -0
  1341. package/src/engine/events.ts +24 -0
  1342. package/src/engine/ids.ts +7 -0
  1343. package/src/engine/launchState.ts +35 -0
  1344. package/src/engine/layout.ts +247 -0
  1345. package/src/engine/mergeOptions.ts +20 -0
  1346. package/src/engine/native.ts +51 -0
  1347. package/src/engine/nativeScreens.ts +263 -0
  1348. package/src/engine/options.ts +165 -0
  1349. package/src/engine/places.ts +205 -0
  1350. package/src/engine/props.ts +45 -0
  1351. package/src/engine/reactMeasures.ts +24 -0
  1352. package/src/engine/rememberedOptions.ts +111 -0
  1353. package/src/engine/screens.tsx +239 -0
  1354. package/src/engine/slots.ts +191 -0
  1355. package/src/engine/tabs.ts +95 -0
  1356. package/src/index.ts +3 -0
  1357. package/src/interfaces/ComponentEvents.ts +214 -0
  1358. package/src/interfaces/Events.ts +227 -0
  1359. package/src/interfaces/Layout.ts +161 -0
  1360. package/src/interfaces/Options.ts +175 -0
  1361. package/src/interfaces/options/animations.ts +480 -0
  1362. package/src/interfaces/options/bottomTabs.ts +481 -0
  1363. package/src/interfaces/options/buttons.ts +364 -0
  1364. package/src/interfaces/options/common.ts +76 -0
  1365. package/src/interfaces/options/modals.ts +217 -0
  1366. package/src/interfaces/options/preview.ts +40 -0
  1367. package/src/interfaces/options/sideMenu.ts +132 -0
  1368. package/src/interfaces/options/splitView.ts +127 -0
  1369. package/src/interfaces/options/stack.ts +110 -0
  1370. package/src/interfaces/options/system.ts +252 -0
  1371. package/src/interfaces/options/toolbar.ts +47 -0
  1372. package/src/interfaces/options/topBar.ts +828 -0
@@ -0,0 +1,1965 @@
1
+ #import "ANNModalCoordinator.h"
2
+ #import "ANNAnimationRules.h"
3
+ #import "ANNAppearanceDispatcher.h"
4
+ #import "ANNAssert.h"
5
+ #import "ANNCommandRunner.h"
6
+ #import "ANNComponentViewController.h"
7
+ #import "ANNErrorTexts.h"
8
+ #import "ANNLayoutFactory.h"
9
+ #import "ANNLayoutTreeOptions.h"
10
+ #import "ANNLayoutValidator.h"
11
+ #import "ANNModal.h"
12
+ #import "ANNModalPresentation.h"
13
+ #import "ANNModalSizePresenter.h"
14
+ #import "ANNModalTransitions.h"
15
+ #import "ANNNavigationState.h"
16
+ #import "ANNNodeRegistry.h"
17
+ #import "ANNOptionsReader.h"
18
+ #import "ANNParking.h"
19
+ #import "ANNPendingLayers.h"
20
+ #import "ANNPresentationGate.h"
21
+ #import "ANNRenderWait.h"
22
+ #import "ANNSheetPresenter.h"
23
+ #import "ANNSystemUI.h"
24
+ #import "ANNTransitionPlan.h"
25
+ #import "ANNZoomAnchor.h"
26
+ #import "ApexNavigation+Internal.h"
27
+ #import "UIViewController+LayoutProtocol.h"
28
+ #import <QuartzCore/QuartzCore.h>
29
+ #import <React/RCTLog.h>
30
+ #import <React/RCTUtils.h>
31
+
32
+ // How long a modal waits for its screens when `animations.showModal.enter.waitForRender` is not set: from the start of
33
+ // the wait, for the screens and their bar components together.
34
+ static const NSTimeInterval ANNModalRenderLimit = 0.5;
35
+
36
+ // UIKit runs some completions inside a block of its animation queue (the end of a zoom): the end steps, which stop
37
+ // React surfaces, run on the main queue.
38
+ static void ANNOnMainQueue(dispatch_block_t block) {
39
+ if (RCTIsMainQueue()) {
40
+ block();
41
+ } else {
42
+ dispatch_async(dispatch_get_main_queue(), block);
43
+ }
44
+ }
45
+
46
+ // One `dismissAllModals`: the modals it takes, those that count in its event, the drags it waits for.
47
+ @interface ANNModalBatch : NSObject
48
+ @property(nonatomic, strong, nullable) ANNCommandAnswer *answer;
49
+ @property(nonatomic) BOOL animated;
50
+ // Bottom to top.
51
+ @property(nonatomic, strong) NSMutableArray<ANNModal *> *records;
52
+ @property(nonatomic, strong) NSHashTable<ANNModal *> *counted;
53
+ @property(nonatomic) NSUInteger dragsPending;
54
+ @property(nonatomic, strong, nullable) ANNGateStep *step;
55
+ // A second `dismissAllModals` while this one runs answers at its end (N6).
56
+ @property(nonatomic, strong) NSMutableArray<ANNCommandAnswer *> *waiters;
57
+ @end
58
+
59
+ @implementation ANNModalBatch
60
+
61
+ - (instancetype)init {
62
+ if (self = [super init]) {
63
+ _records = [NSMutableArray new];
64
+ _counted = [NSHashTable weakObjectsHashTable];
65
+ _waiters = [NSMutableArray new];
66
+ }
67
+ return self;
68
+ }
69
+
70
+ @end
71
+
72
+ // Main queue. The records bottom to top, the running batches, and the ids of modals the user closed: a `dismissModal`
73
+ // with one of them completes without an event until a new node takes the id or JavaScript reloads.
74
+ static NSMutableArray<ANNModal *> *ANNModals;
75
+ static NSMutableArray<ANNModalBatch *> *ANNBatches;
76
+ static NSMutableArray<NSDictionary *> *ANNClosedByUser;
77
+
78
+ static NSString *const ANNClosedIdsKey = @"ids";
79
+ static NSString *const ANNClosedRootIdKey = @"rootId";
80
+
81
+ // The state UIKit, the user and the navigation state see: a modal that goes with the old root is still on screen.
82
+ static ANNModalState ANNSeenState(ANNModal *modal) {
83
+ return modal.state == ANNModalStateWithOldRoot ? modal.stateBeforeRoot : modal.state;
84
+ }
85
+
86
+ // Presenting, shown or dragged: on screen.
87
+ static BOOL ANNIsOnScreen(ANNModal *modal) {
88
+ ANNModalState state = ANNSeenState(modal);
89
+ return state == ANNModalStatePresenting || state == ANNModalStateShown ||
90
+ state == ANNModalStateGesture;
91
+ }
92
+
93
+ // The view of the node is in a window that shows (N2: UIKit presents only from there).
94
+ static BOOL ANNIsInShownWindow(UIViewController *node) {
95
+ UIWindow *window = node.viewIfLoaded.window;
96
+ return window != nil && !window.hidden;
97
+ }
98
+
99
+ // Every id of the node's tree.
100
+ static void ANNCollectIds(UIViewController *node, NSMutableSet<NSString *> *ids) {
101
+ NSString *componentId = node.layoutInfo.componentId;
102
+ if (componentId) {
103
+ [ids addObject:componentId];
104
+ }
105
+ for (UIViewController *child in node.layoutChildren) {
106
+ ANNCollectIds(child, ids);
107
+ }
108
+ }
109
+
110
+ @implementation ANNModalCoordinator
111
+
112
+ + (void)initialize {
113
+ if (self == ANNModalCoordinator.class) {
114
+ ANNModals = [NSMutableArray new];
115
+ ANNBatches = [NSMutableArray new];
116
+ ANNClosedByUser = [NSMutableArray new];
117
+ }
118
+ }
119
+
120
+ #pragma mark - showModal
121
+
122
+ + (void)showModal:(ANNLayoutNode *)tree answer:(ANNCommandAnswer *)answer {
123
+ ANNAssertMainQueue();
124
+ // Before any node: a type without a maker (none is left: the guard stays for safety), an id that shows already
125
+ // (the nodes of modals that go with the old root count), a value of the options that can't be read.
126
+ if (![ANNLayoutFactory canMakeTrees:@[ tree ]]) {
127
+ [answer reject:[ANNErrorTexts notDoneYet:@"showModal"]];
128
+ return;
129
+ }
130
+ NSString *shownId = [ANNLayoutValidator firstShownIdIn:tree allowed:nil];
131
+ if (shownId) {
132
+ [answer reject:[ANNErrorTexts alreadyShown:shownId]];
133
+ return;
134
+ }
135
+ NSString *rejection = nil;
136
+ NSDictionary<NSString *, ANNNavigationOptions *> *optionsById =
137
+ [ANNLayoutTreeOptions optionsOfTree:tree rejection:&rejection];
138
+ if (!optionsById) {
139
+ [answer reject:rejection];
140
+ return;
141
+ }
142
+ ANNModal *modal = [self makeModal:tree options:optionsById];
143
+ modal.showAnswer = answer;
144
+ // The record is listed and parked already: a failure at the start of its wait goes as a cancel.
145
+ [self protect:modal
146
+ step:^{
147
+ [ANNModalCoordinator startWaitOf:modal];
148
+ }];
149
+ }
150
+
151
+ + (ANNModal *)showChainModal:(ANNLayoutNode *)tree
152
+ options:(NSDictionary<NSString *, ANNNavigationOptions *> *)optionsById
153
+ animated:(BOOL)animated
154
+ ended:(void (^)(BOOL shown))ended {
155
+ ANNAssertMainQueue();
156
+ ANNModal *modal = nil;
157
+ @try {
158
+ modal = [self makeModal:tree options:optionsById];
159
+ } @catch (NSException *exception) {
160
+ [self logChainFailureOf:tree.nodeId reason:exception.reason ?: exception.name];
161
+ ended(NO);
162
+ return nil;
163
+ }
164
+ modal.chainStep = ended;
165
+ modal.animatedOverride = animated ? nil : @NO;
166
+ [self protect:modal
167
+ step:^{
168
+ [ANNModalCoordinator startWaitOf:modal];
169
+ }];
170
+ return modal;
171
+ }
172
+
173
+ + (void)logChainFailureOf:(NSString *)rootId reason:(NSString *)reason {
174
+ NSString *what = [NSString stringWithFormat:@"show the screen '%@'", rootId];
175
+ [ANNCommandRunner logFailure:@"setRoot" text:[ANNErrorTexts couldNot:what reason:reason]];
176
+ }
177
+
178
+ // The tree is made, renders at once at the window's size and lays out, so that its surfaces start with their size, as
179
+ // the root's does; then the record is the top of the stack of modals at once (`showModal` step 2): findable and
180
+ // closable. Its view waits in the window, unseen, and it is a layer that waits to show (`ANNPendingLayers`): a stack in
181
+ // it runs its commands at once and tells the wait of its new top.
182
+ + (ANNModal *)makeModal:(ANNLayoutNode *)tree
183
+ options:(NSDictionary<NSString *, ANNNavigationOptions *> *)optionsById {
184
+ UIWindow *window = ApexNavigation.mainWindow;
185
+ UIViewController *root = [ANNLayoutFactory nodeFromLayout:tree options:optionsById];
186
+ @try {
187
+ [root render];
188
+ if (window) {
189
+ root.view.frame = window.bounds;
190
+ }
191
+ [root.view setNeedsLayout];
192
+ [root.view layoutIfNeeded];
193
+ } @catch (NSException *exception) {
194
+ [root destroy];
195
+ @throw;
196
+ }
197
+ ANNModal *modal = [[ANNModal alloc] initWithRoot:root rootId:tree.nodeId];
198
+ [ANNModals addObject:modal];
199
+ __weak ANNModal *weakModal = modal;
200
+ [ANNPendingLayers add:root
201
+ onShownScreensChanged:^{
202
+ [ANNModalCoordinator shownScreensChangedOf:weakModal];
203
+ }];
204
+ if (window) {
205
+ [modal.parking park:root inView:window];
206
+ }
207
+ return modal;
208
+ }
209
+
210
+ #pragma mark - The wait
211
+
212
+ // The root's rule (`ANNRootCoordinator`): `waitForRender: false` nothing; `true` the waited screens as long as it
213
+ // takes, then their bar components at most 0.5 s; unset, both together at most 0.5 s from the start, then
214
+ // `markReady`. A screen the user won't see at once (an unselected tab's) never holds the modal longer than 0.5 s.
215
+ + (void)startWaitOf:(ANNModal *)modal {
216
+ ANNNavigationOptions *resolved = [modal.root resolveOptionsWithDefault];
217
+ Bool *waitForRender = resolved.animations.showModal.enter.waitForRender;
218
+ if (waitForRender.hasValue && !waitForRender.get) {
219
+ [self waitEndedOf:modal];
220
+ return;
221
+ }
222
+ __weak ANNModal *weakModal = modal;
223
+ BOOL contentFirst = waitForRender.hasValue;
224
+ modal.waitStarted = contentFirst ? 0 : CACurrentMediaTime();
225
+ ANNBarWaitLimits withContent = {0, 0};
226
+ ANNBarWaitLimits ownPhase = {ANNModalRenderLimit, ANNModalRenderLimit};
227
+ ANNRenderWait *wait = [[ANNRenderWait alloc]
228
+ initWithContent:ANNRenderWaitContentEachScreen
229
+ node:nil
230
+ screens:^NSArray<UIViewController *> * {
231
+ return weakModal.root.waitedComponentViewControllers ?: @[];
232
+ }
233
+ limit:contentFirst ? 0 : ANNModalRenderLimit
234
+ bar:contentFirst ? ANNRenderWaitBarAfterContent : ANNRenderWaitBarWithContent
235
+ barLimits:contentFirst ? ownPhase : withContent];
236
+ wait.mountLimit = ANNModalRenderLimit;
237
+ wait.protect = ^(dispatch_block_t step) {
238
+ [ANNModalCoordinator protect:weakModal step:step];
239
+ };
240
+ wait.ended = ^{
241
+ ANNModal *rendered = weakModal;
242
+ if (rendered) {
243
+ [ANNModalCoordinator waitEndedOf:rendered];
244
+ }
245
+ };
246
+ modal.wait = wait;
247
+ [wait start];
248
+ }
249
+
250
+ // A stack command inside the waiting modal changed its top: the wait takes the modal's waited screens again.
251
+ + (void)shownScreensChangedOf:(ANNModal *)modal {
252
+ ANNAssertMainQueue();
253
+ if (!modal || modal.state != ANNModalStateWaiting || !modal.wait.isWaiting) {
254
+ return;
255
+ }
256
+ [self protect:modal
257
+ step:^{
258
+ [modal.wait retakeScreens:!modal.root.nodeHelper.destroyed];
259
+ }];
260
+ }
261
+
262
+ // The steps after the command's body are outside the runner's protection: a failure while the modal waits rejects its
263
+ // show and it goes as a cancel; later, it is logged.
264
+ + (void)protect:(ANNModal *)modal step:(dispatch_block_t)step {
265
+ @try {
266
+ step();
267
+ } @catch (NSException *exception) {
268
+ NSString *reason = exception.reason.length > 0 ? exception.reason : exception.name;
269
+ if (modal && modal.state == ANNModalStateWaiting) {
270
+ [self failShowOf:modal reason:reason];
271
+ } else {
272
+ RCTLogWarn(@"[ApexNavigation] %@",
273
+ [ANNErrorTexts couldNot:@"show a modal" reason:reason]);
274
+ }
275
+ }
276
+ }
277
+
278
+ // The end steps of a record (its show presented, its dismissal ended, closed by the user) run inside UIKit's
279
+ // completions and delegate calls, outside the runner's protection, in any state: a failure there is logged in one line,
280
+ // rejects what of the record still waits for an answer (its show, a chain step, its dismissals), and its drive stops.
281
+ // The gate's `done` ran before the step, as without a failure.
282
+ + (void)protectEndOf:(ANNModal *)modal showing:(BOOL)showing step:(dispatch_block_t)step {
283
+ @try {
284
+ step();
285
+ } @catch (NSException *exception) {
286
+ NSString *format = showing ? @"show the screen '%@'" : @"dismiss the modal '%@'";
287
+ NSString *what = modal ? [NSString stringWithFormat:format, modal.rootId]
288
+ : (showing ? @"show a modal" : @"dismiss a modal");
289
+ NSString *reason = exception.reason.length > 0 ? exception.reason : exception.name;
290
+ RCTLogWarn(@"[ApexNavigation] %@", [ANNErrorTexts couldNot:what reason:reason]);
291
+ [self endFailedOf:modal exception:exception];
292
+ }
293
+ }
294
+
295
+ + (void)endFailedOf:(ANNModal *)modal exception:(NSException *)exception {
296
+ if (!modal) {
297
+ return;
298
+ }
299
+ [self stopDriving:modal];
300
+ NSString *show = [NSString stringWithFormat:@"show the screen '%@'", modal.rootId];
301
+ NSString *dismiss = [NSString stringWithFormat:@"dismiss the modal '%@'", modal.rootId];
302
+ [modal.showAnswer reject:[ANNCommandRunner rejectionOf:exception what:show]];
303
+ NSString *dismissText = [ANNCommandRunner rejectionOf:exception what:dismiss];
304
+ [modal.dismissal.answer reject:dismissText];
305
+ NSArray<ANNModalDismissal *> *pending = modal.pending.copy;
306
+ [modal.pending removeAllObjects];
307
+ for (ANNModalDismissal *waiting in pending) {
308
+ [waiting.answer reject:dismissText];
309
+ }
310
+ // A `setRoot` chain goes on (its own steps are guarded by the root coordinator).
311
+ void (^chainStep)(BOOL) = modal.chainStep;
312
+ modal.chainStep = nil;
313
+ if (chainStep) {
314
+ chainStep(NO);
315
+ }
316
+ }
317
+
318
+ // The batch's end runs inside UIKit's completion: a failure is logged in one line and rejects the answers still open
319
+ // (the batch's, those that wait for its end, its records').
320
+ + (void)protectBatch:(ANNModalBatch *)batch step:(dispatch_block_t)step {
321
+ @try {
322
+ step();
323
+ } @catch (NSException *exception) {
324
+ NSString *reason = exception.reason.length > 0 ? exception.reason : exception.name;
325
+ RCTLogWarn(@"[ApexNavigation] %@",
326
+ [ANNErrorTexts couldNot:@"dismiss all modals" reason:reason]);
327
+ if (!batch) {
328
+ return;
329
+ }
330
+ NSString *text = [ANNCommandRunner rejectionOf:exception what:@"dismiss all modals"];
331
+ [batch.answer reject:text];
332
+ for (ANNCommandAnswer *waiter in batch.waiters) {
333
+ [waiter reject:text];
334
+ }
335
+ for (ANNModal *modal in batch.records.copy) {
336
+ [self endFailedOf:modal exception:exception];
337
+ }
338
+ }
339
+ }
340
+
341
+ + (void)waitEndedOf:(ANNModal *)modal {
342
+ if (modal.state != ANNModalStateWaiting) {
343
+ return;
344
+ }
345
+ modal.ready = YES;
346
+ [self presentReadyModals];
347
+ }
348
+
349
+ // N1: a ready modal presents only after every older waiting one presented or went, so that UIKit's chain keeps the
350
+ // order of the records.
351
+ + (void)presentReadyModals {
352
+ for (ANNModal *modal in ANNModals.copy) {
353
+ if (modal.state != ANNModalStateWaiting) {
354
+ continue;
355
+ }
356
+ if (!modal.ready) {
357
+ return;
358
+ }
359
+ if (!modal.step) {
360
+ [self queuePresentOf:modal];
361
+ }
362
+ }
363
+ }
364
+
365
+ #pragma mark - The present
366
+
367
+ // The topmost controller of the main window's chain that is not being dismissed: a modal closed below and a foreign
368
+ // controller count; before the first root, the splash.
369
+ + (UIViewController *)presentingController {
370
+ UIViewController *top = ApexNavigation.mainWindow.rootViewController;
371
+ while (top.presentedViewController && !top.presentedViewController.isBeingDismissed) {
372
+ top = top.presentedViewController;
373
+ }
374
+ return top;
375
+ }
376
+
377
+ + (void)queuePresentOf:(ANNModal *)modal {
378
+ __weak ANNModal *weakModal = modal;
379
+ ANNGateStep *step = [[ANNGateStep alloc] initWithRun:^(dispatch_block_t done) {
380
+ [ANNModalCoordinator present:weakModal done:done];
381
+ }];
382
+ // N2: UIKit presents only from a controller in a shown window; the step waits for the scene or the first root.
383
+ step.canRun = ^BOOL {
384
+ UIViewController *presenting = [ANNModalCoordinator presentingController];
385
+ return presenting != nil && ANNIsInShownWindow(presenting);
386
+ };
387
+ modal.step = step;
388
+ [ANNPresentationGate enqueue:step];
389
+ }
390
+
391
+ + (void)present:(ANNModal *)modal done:(dispatch_block_t)done {
392
+ if (!modal || modal.state != ANNModalStateWaiting) {
393
+ done();
394
+ return;
395
+ }
396
+ modal.step = nil;
397
+ UIViewController *root = modal.root;
398
+ if (root.nodeHelper.destroyed) {
399
+ [self cancel:modal rejection:nil dismissal:nil sendsEvent:NO];
400
+ done();
401
+ return;
402
+ }
403
+ UIViewController *windowRoot = ApexNavigation.mainWindow.rootViewController;
404
+ UIViewController *presenting = [self presentingController];
405
+ @try {
406
+ // The options at the present: a first render's options of the screen count.
407
+ ANNNavigationOptions *resolved = [root resolveOptionsWithDefault];
408
+ ANNModalPresentation *presentation =
409
+ [[ANNModalPresentation alloc] initWithOptions:resolved animated:modal.animatedOverride];
410
+ NSString *problem = [presentation problemPresentingFrom:presenting windowRoot:windowRoot];
411
+ if (problem) {
412
+ [self failShowOf:modal reason:problem];
413
+ done();
414
+ return;
415
+ }
416
+ modal.presentation = presentation;
417
+ // The popover's source is looked for on the layout the user sees.
418
+ UIViewController *presentingLayout = [self visibleLayout] ?: presenting;
419
+ modal.layerUnder = [self layerUnder:modal];
420
+ // The custom show's delegate, before the presentation controller is made (UIKit reads it at the present).
421
+ [self setUpShowOf:modal resolved:resolved presentingLayout:presentingLayout];
422
+ [presentation prepare:root
423
+ options:resolved
424
+ delegate:modal
425
+ presentingLayout:presentingLayout];
426
+ // The command reports the modal's appearance itself, from before its view leaves the parking: UIKit's callbacks
427
+ // would come at its own moments.
428
+ [self drive:modal nodes:@[ root ]];
429
+ modal.state = ANNModalStatePresenting;
430
+ [ANNPendingLayers remove:root];
431
+ [ANNAppearanceDispatcher beginTransitionShowing:@[ root ]];
432
+ // UIKit shows the view in the same turn: its departure from the window ends here.
433
+ [modal.parking unpark:root endingDeparture:YES];
434
+ __weak ANNModal *weakModal = modal;
435
+ [presenting presentViewController:root
436
+ animated:presentation.animated
437
+ completion:^{
438
+ // A zoom's show ends in a block of UIKit's animation queue.
439
+ ANNOnMainQueue(^{
440
+ done();
441
+ ANNModal *presented = weakModal;
442
+ [ANNModalCoordinator protectEndOf:presented
443
+ showing:YES
444
+ step:^{
445
+ [ANNModalCoordinator
446
+ presented:presented];
447
+ }];
448
+ });
449
+ }];
450
+ } @catch (NSException *exception) {
451
+ NSString *reason = exception.reason.length > 0 ? exception.reason : exception.name;
452
+ if (!root.presentingViewController) {
453
+ // UIKit didn't take it: the show is rejected and the modal goes as a cancel.
454
+ [self stopDriving:modal];
455
+ modal.state = ANNModalStateWaiting;
456
+ [self failShowOf:modal reason:reason];
457
+ done();
458
+ } else {
459
+ // UIKit took it: its completion still ends the show. The gate is free either way (a running transition
460
+ // still holds the next step back).
461
+ RCTLogWarn(@"[ApexNavigation] %@",
462
+ [ANNErrorTexts couldNot:@"show a modal" reason:reason]);
463
+ done();
464
+ }
465
+ }
466
+ }
467
+
468
+ // The custom show: its plan and the delegate that gives it to UIKit; without one, the iOS 18 zoom when `showModal.zoom`
469
+ // names a view of the shown screens (in a split view every visible column). Own animations win over the zoom.
470
+ + (void)setUpShowOf:(ANNModal *)modal
471
+ resolved:(ANNNavigationOptions *)resolved
472
+ presentingLayout:(UIViewController *)presentingLayout {
473
+ ANNModalPresentation *presentation = modal.presentation;
474
+ UIViewController *root = modal.root;
475
+ // What the modal's own wait left of its 0.5 s; after a wait without limit the targets 0.5 s.
476
+ NSTimeInterval limit = [ANNAnimationRules customWaitLimitAfterWaitStartedAt:modal.waitStarted
477
+ commandLimit:ANNModalRenderLimit];
478
+ ANNTransitionPlan *plan = [presentation showPlanOf:root under:modal.layerUnder waitLimit:limit];
479
+ if (plan) {
480
+ if (!modal.transitions) {
481
+ modal.transitions = [ANNModalTransitions new];
482
+ }
483
+ modal.transitions.showPlan = plan;
484
+ root.transitioningDelegate = modal.transitions;
485
+ return;
486
+ }
487
+ if (@available(iOS 18.0, *)) {
488
+ ANNModalAnimationOptions *showModal = resolved.animations.showModal;
489
+ NSString *fromId = [showModal.zoom.fromId withDefault:nil];
490
+ if (!presentation.animated || [ANNAnimationRules modalIsOwn:showModal] ||
491
+ ![showModal.zoom.enabled withDefault:YES] || ![fromId isKindOfClass:NSString.class] ||
492
+ fromId.length == 0) {
493
+ return;
494
+ }
495
+ __weak UIViewController *weakLayout = presentingLayout;
496
+ [ANNZoomAnchor zoom:root
497
+ fromId:fromId
498
+ sourceScreens:^NSArray<UIViewController *> * {
499
+ UIViewController *layout = weakLayout;
500
+ return layout ? layout.shownComponentViewControllers : @[];
501
+ }];
502
+ }
503
+ }
504
+
505
+ // The show couldn't be made: its answer rejects (a `setRoot` chain logs it and goes on) and the modal goes as a cancel.
506
+ + (void)failShowOf:(ANNModal *)modal reason:(NSString *)reason {
507
+ NSString *what = [NSString stringWithFormat:@"show the screen '%@'", modal.rootId];
508
+ [self cancel:modal
509
+ rejection:[ANNErrorTexts couldNot:what reason:reason]
510
+ dismissal:nil
511
+ sendsEvent:NO];
512
+ }
513
+
514
+ // The show's end: `DidDisappear` of the layer under when UIKit took it out of the window, `DidAppear` of the modal, the
515
+ // state, the answer. A modal of a `setRoot` chain sends no state of its own: the chain goes on. Then the size again and
516
+ // the hold; then its first waiting command. A modal that joined a `dismissAllModals` while it presented answers its
517
+ // show and stays in the batch.
518
+ + (void)presented:(ANNModal *)modal {
519
+ if (!modal) {
520
+ return;
521
+ }
522
+ ANNModalState state = modal.state;
523
+ BOOL inBatch = state == ANNModalStateDismissing && modal.batch != nil;
524
+ BOOL withOldRoot =
525
+ state == ANNModalStateWithOldRoot && modal.stateBeforeRoot == ANNModalStatePresenting;
526
+ if (state != ANNModalStatePresenting && !inBatch && !withOldRoot) {
527
+ [self stopDriving:modal];
528
+ return;
529
+ }
530
+ if (withOldRoot) {
531
+ modal.stateBeforeRoot = ANNModalStateShown;
532
+ } else if (!inBatch) {
533
+ modal.state = ANNModalStateShown;
534
+ }
535
+ UIViewController *root = modal.root;
536
+ UIViewController *under = modal.layerUnder;
537
+ modal.coversUnder = under != nil && under.viewIfLoaded.window == nil;
538
+ NSArray<UIViewController *> *hidden = modal.coversUnder ? @[ under ] : @[];
539
+ @try {
540
+ // The chain step stays on the record until its events went: a failure there tells the chain (`endFailedOf:`).
541
+ void (^chainStep)(BOOL) = modal.chainStep;
542
+ if (chainStep) {
543
+ [ANNAppearanceDispatcher endSwitchHiding:hidden showing:@[ root ] events:nil];
544
+ modal.chainStep = nil;
545
+ chainStep(YES);
546
+ } else {
547
+ [ANNAppearanceDispatcher endTransitionHiding:hidden
548
+ showing:@[ root ]
549
+ events:nil
550
+ answer:modal.showAnswer
551
+ value:modal.rootId];
552
+ }
553
+ } @finally {
554
+ [self stopDriving:modal];
555
+ }
556
+ [ANNZoomAnchor transitionEndedOf:root];
557
+ [ANNModalSizePresenter applyOptions:[root resolveOptionsWithDefault].modal toModal:root];
558
+ [ANNModalPresentation applyHoldTo:root];
559
+ if (modal.presentation.isSheet) {
560
+ modal.knownDetent = [self knownDetentOf:modal];
561
+ }
562
+ if (modal.state == ANNModalStateShown) {
563
+ [self runPendingOf:modal];
564
+ }
565
+ }
566
+
567
+ #pragma mark - The layers
568
+
569
+ // The layer under a modal: the root of the nearest modal below it that is on screen, else the window's root when it is
570
+ // a node (none over the splash).
571
+ + (UIViewController *)layerUnder:(ANNModal *)modal {
572
+ NSUInteger index = [ANNModals indexOfObjectIdenticalTo:modal];
573
+ if (index == NSNotFound) {
574
+ index = ANNModals.count;
575
+ }
576
+ for (NSUInteger i = index; i > 0; i--) {
577
+ ANNModal *below = ANNModals[i - 1];
578
+ if (ANNIsOnScreen(below)) {
579
+ return below.root;
580
+ }
581
+ }
582
+ UIViewController *root = ApexNavigation.mainWindow.rootViewController;
583
+ return root.isLayoutNode ? root : nil;
584
+ }
585
+
586
+ // The layer under had disappeared: the modal or a modal closed below between them covered it.
587
+ + (BOOL)layerUnder:(UIViewController *)under hadDisappearedFor:(ANNModal *)modal {
588
+ if (!under) {
589
+ return NO;
590
+ }
591
+ if (modal.coversUnder) {
592
+ return YES;
593
+ }
594
+ NSUInteger index = [ANNModals indexOfObjectIdenticalTo:modal];
595
+ for (NSUInteger i = index; i != NSNotFound && i > 0; i--) {
596
+ ANNModal *below = ANNModals[i - 1];
597
+ if (below.root == under) {
598
+ break;
599
+ }
600
+ if (below.state == ANNModalStateClosedBelow && below.coversUnder) {
601
+ return YES;
602
+ }
603
+ }
604
+ return NO;
605
+ }
606
+
607
+ // A modal is the top when no modal above it waits, presents, shows or is dragged (`showModal` step 2; one being
608
+ // dismissed doesn't count).
609
+ + (BOOL)isTop:(ANNModal *)modal {
610
+ NSUInteger index = [ANNModals indexOfObjectIdenticalTo:modal];
611
+ if (index == NSNotFound) {
612
+ return NO;
613
+ }
614
+ for (NSUInteger i = index + 1; i < ANNModals.count; i++) {
615
+ ANNModal *above = ANNModals[i];
616
+ ANNModalState state = ANNSeenState(above);
617
+ if (state == ANNModalStateWaiting || state == ANNModalStatePresenting ||
618
+ state == ANNModalStateShown || state == ANNModalStateGesture) {
619
+ return NO;
620
+ }
621
+ // One whose dismissal waits for its turn at the gate is still in UIKit's chain above.
622
+ if (state == ANNModalStateDismissing && !above.dismissalStarted && !above.batch) {
623
+ return NO;
624
+ }
625
+ }
626
+ return YES;
627
+ }
628
+
629
+ // The modals closed below right under `modal` (waiting ones, which UIKit doesn't show, are passed over): one dismissal
630
+ // from the lowest one's presenting controller takes them all.
631
+ + (NSArray<ANNModal *> *)closedBelowUnder:(ANNModal *)modal {
632
+ NSMutableArray<ANNModal *> *closed = [NSMutableArray new];
633
+ NSUInteger index = [ANNModals indexOfObjectIdenticalTo:modal];
634
+ for (NSUInteger i = index; i != NSNotFound && i > 0; i--) {
635
+ ANNModal *below = ANNModals[i - 1];
636
+ if (below.state == ANNModalStateWaiting) {
637
+ continue;
638
+ }
639
+ if (below.state != ANNModalStateClosedBelow) {
640
+ break;
641
+ }
642
+ [closed addObject:below];
643
+ }
644
+ return closed;
645
+ }
646
+
647
+ + (void)drive:(ANNModal *)modal nodes:(NSArray<UIViewController *> *)nodes {
648
+ [self stopDriving:modal];
649
+ modal.driven = nodes;
650
+ [ANNAppearanceDispatcher driveAppearanceOf:nodes];
651
+ }
652
+
653
+ + (void)stopDriving:(ANNModal *)modal {
654
+ NSArray<UIViewController *> *driven = modal.driven;
655
+ if (driven) {
656
+ modal.driven = nil;
657
+ [ANNAppearanceDispatcher stopDrivingAppearanceOf:driven];
658
+ }
659
+ }
660
+
661
+ + (void)remove:(ANNModal *)modal {
662
+ modal.state = ANNModalStateGone;
663
+ [ANNModals removeObjectIdenticalTo:modal];
664
+ // UIKit removed it (or is about to): its container is UIKit's again as it was.
665
+ modal.hiddenContainer.hidden = NO;
666
+ modal.hiddenContainer = nil;
667
+ }
668
+
669
+ + (void)resolvePendingOf:(ANNModal *)modal {
670
+ NSArray<ANNModalDismissal *> *pending = modal.pending.copy;
671
+ [modal.pending removeAllObjects];
672
+ for (ANNModalDismissal *dismissal in pending) {
673
+ [dismissal.answer resolve:modal.rootId];
674
+ }
675
+ }
676
+
677
+ #pragma mark - The cancel
678
+
679
+ // A modal that waits goes without showing: its wait stops, its view leaves the window, its root is destroyed without
680
+ // events (nothing appeared), the layer under is not touched. Its show resolves with its root's id (or rejects with
681
+ // `rejection`); a chain is told. A cancel by `dismissModal` sends one `ModalDismissed` after the show's answer, then
682
+ // that dismissal resolves.
683
+ + (void)cancel:(ANNModal *)modal
684
+ rejection:(NSString *)rejection
685
+ dismissal:(ANNModalDismissal *)dismissal
686
+ sendsEvent:(BOOL)sendsEvent {
687
+ [self stopWaitOf:modal];
688
+ [self remove:modal];
689
+ UIViewController *root = modal.root;
690
+ @try {
691
+ ANNCommandAnswer *showAnswer = modal.showAnswer;
692
+ void (^chainStep)(BOOL) = modal.chainStep;
693
+ modal.chainStep = nil;
694
+ if (rejection) {
695
+ [showAnswer reject:rejection];
696
+ if (chainStep) {
697
+ [ANNCommandRunner logFailure:@"setRoot" text:rejection];
698
+ }
699
+ } else {
700
+ [showAnswer resolve:modal.rootId];
701
+ }
702
+ if (sendsEvent && !modal.reported) {
703
+ modal.reported = YES;
704
+ [ANNAppearanceDispatcher modalDismissed:root count:1];
705
+ }
706
+ [root destroy];
707
+ [dismissal.answer resolve:modal.rootId];
708
+ [self resolvePendingOf:modal];
709
+ if (chainStep) {
710
+ chainStep(NO);
711
+ }
712
+ } @finally {
713
+ [self cleanTopOfChain];
714
+ [self presentReadyModals];
715
+ }
716
+ }
717
+
718
+ // What a waiting modal holds goes: its wait, its place in the window, its turn at the gate.
719
+ + (void)stopWaitOf:(ANNModal *)modal {
720
+ [modal.wait cancel];
721
+ modal.wait = nil;
722
+ [ANNPendingLayers remove:modal.root];
723
+ [modal.parking unpark:modal.root endingDeparture:YES];
724
+ if (modal.step) {
725
+ [ANNPresentationGate drop:modal.step];
726
+ modal.step = nil;
727
+ }
728
+ [self stopDriving:modal];
729
+ }
730
+
731
+ + (void)cancelChainModal:(ANNModal *)modal {
732
+ ANNAssertMainQueue();
733
+ if (modal.state != ANNModalStateWaiting) {
734
+ return;
735
+ }
736
+ modal.chainStep = nil;
737
+ [self cancel:modal rejection:nil dismissal:nil sendsEvent:NO];
738
+ }
739
+
740
+ #pragma mark - dismissModal
741
+
742
+ + (void)dismissModal:(NSString *)componentId
743
+ options:(NSDictionary *)options
744
+ answer:(ANNCommandAnswer *)answer {
745
+ ANNAssertMainQueue();
746
+ UIViewController *node = [ANNNodeRegistry nodeForComponentId:componentId];
747
+ ANNModal *modal = nil;
748
+ if (node) {
749
+ modal = [self modalOf:node];
750
+ if (!modal) {
751
+ [answer reject:[ANNErrorTexts notInModal:componentId]];
752
+ return;
753
+ }
754
+ } else {
755
+ // The nodes of a modal closed below or going with the old root may be destroyed: their ids are kept.
756
+ for (ANNModal *candidate in ANNModals) {
757
+ if ((candidate.state == ANNModalStateClosedBelow ||
758
+ candidate.state == ANNModalStateWithOldRoot) &&
759
+ [candidate.ids containsObject:componentId]) {
760
+ modal = candidate;
761
+ break;
762
+ }
763
+ }
764
+ if (!modal) {
765
+ // Closed by the user: it just completes, without an event.
766
+ for (NSDictionary *closed in ANNClosedByUser.reverseObjectEnumerator) {
767
+ if ([closed[ANNClosedIdsKey] containsObject:componentId]) {
768
+ [answer resolve:closed[ANNClosedRootIdKey]];
769
+ return;
770
+ }
771
+ }
772
+ [answer reject:[ANNErrorTexts screenNotShown:componentId]];
773
+ return;
774
+ }
775
+ }
776
+ // Commands by the ids of the modals that go with the old root find nothing.
777
+ if (modal.state == ANNModalStateWithOldRoot) {
778
+ [answer reject:[ANNErrorTexts screenNotShown:componentId]];
779
+ return;
780
+ }
781
+ // Step 1: the options, read on the main queue; one that can't be read rejects before anything changes. They merge
782
+ // into the modal's visible screen as `mergeOptions` would.
783
+ if (options.count > 0) {
784
+ NSString *unreadablePath = nil;
785
+ ANNNavigationOptions *merge = [ANNOptionsReader optionsFrom:options
786
+ unreadablePath:&unreadablePath];
787
+ if (unreadablePath) {
788
+ [answer reject:[ANNErrorTexts unreadableOption:unreadablePath componentId:componentId]];
789
+ return;
790
+ }
791
+ UIViewController *screen =
792
+ [ANNAppearanceDispatcher visibleScreenOf:modal.root] ?: modal.root;
793
+ if (!screen.nodeHelper.destroyed) {
794
+ [CATransaction begin];
795
+ @try {
796
+ [screen mergeOptions:merge];
797
+ } @finally {
798
+ [CATransaction commit];
799
+ }
800
+ [self optionsMerged:merge into:screen];
801
+ [ANNSystemUI optionsMerged:merge];
802
+ }
803
+ }
804
+ // Step 2: the animation from the command's screen with its parents and the defaults, read now.
805
+ ANNModalDismissal *dismissal = [ANNModalDismissal new];
806
+ dismissal.answer = answer;
807
+ dismissal.animated = YES;
808
+ if (node && !node.nodeHelper.destroyed) {
809
+ // `exit.enabled: false` turns the dismissal's animation off; its own animation plays when the dismissal starts.
810
+ ANNModalAnimationOptions *animation =
811
+ [node resolveOptionsWithDefault].animations.dismissModal;
812
+ dismissal.animated = ![ANNAnimationRules sideIsDisabled:animation.exit];
813
+ dismissal.animation = animation;
814
+ }
815
+ [self dismiss:modal with:dismissal];
816
+ }
817
+
818
+ // The modal of `node`: the record whose root is the top of `node`'s layout.
819
+ + (ANNModal *)modalOf:(UIViewController *)node {
820
+ UIViewController *top = node;
821
+ for (UIViewController *parent = node.layoutParent; parent; parent = parent.layoutParent) {
822
+ top = parent;
823
+ }
824
+ for (ANNModal *modal in ANNModals) {
825
+ if (modal.root == top && modal.state != ANNModalStateGone) {
826
+ return modal;
827
+ }
828
+ }
829
+ return nil;
830
+ }
831
+ + (void)dismiss:(ANNModal *)modal with:(ANNModalDismissal *)dismissal {
832
+ switch (modal.state) {
833
+ case ANNModalStateWaiting:
834
+ [self cancel:modal rejection:nil dismissal:dismissal sendsEvent:YES];
835
+ break;
836
+ case ANNModalStatePresenting:
837
+ case ANNModalStateGesture:
838
+ case ANNModalStateDismissing:
839
+ // It waits for the running transition: no second event.
840
+ [modal.pending addObject:dismissal];
841
+ break;
842
+ case ANNModalStateShown:
843
+ [self startDismissing:modal with:dismissal];
844
+ break;
845
+ case ANNModalStateClosedBelow:
846
+ // It went already; the command just completes.
847
+ [dismissal.answer resolve:modal.rootId];
848
+ break;
849
+ case ANNModalStateWithOldRoot:
850
+ case ANNModalStateGone:
851
+ [dismissal.answer resolve:modal.rootId];
852
+ break;
853
+ }
854
+ }
855
+
856
+ // An accepted dismissal makes the modal `Dismissing` at once; only UIKit's call waits for the gate. When it runs, the
857
+ // modal's place decides: the top goes with its animation, any other closes below.
858
+ + (void)startDismissing:(ANNModal *)modal with:(ANNModalDismissal *)dismissal {
859
+ modal.state = ANNModalStateDismissing;
860
+ modal.dismissal = dismissal;
861
+ modal.dismissalStarted = NO;
862
+ __weak ANNModal *weakModal = modal;
863
+ ANNGateStep *step = [[ANNGateStep alloc] initWithRun:^(dispatch_block_t done) {
864
+ [ANNModalCoordinator runDismissalOf:weakModal done:done];
865
+ }];
866
+ modal.step = step;
867
+ [ANNPresentationGate enqueue:step];
868
+ }
869
+
870
+ // The modal's first waiting command runs as in `Shown` (after its show, after a cancelled drag); the others wait for
871
+ // its end.
872
+ + (void)runPendingOf:(ANNModal *)modal {
873
+ if (modal.state != ANNModalStateShown || modal.pending.count == 0) {
874
+ return;
875
+ }
876
+ ANNModalDismissal *first = modal.pending.firstObject;
877
+ [modal.pending removeObjectAtIndex:0];
878
+ [self startDismissing:modal with:first];
879
+ }
880
+
881
+ + (void)runDismissalOf:(ANNModal *)modal done:(dispatch_block_t)done {
882
+ if (!modal || modal.state != ANNModalStateDismissing || modal.batch || modal.dismissalStarted) {
883
+ done();
884
+ return;
885
+ }
886
+ modal.step = nil;
887
+ @try {
888
+ if (![self isTop:modal]) {
889
+ [self closeBelow:modal];
890
+ done();
891
+ return;
892
+ }
893
+ [self startDismissalOf:modal done:done];
894
+ } @catch (NSException *exception) {
895
+ NSString *what = [NSString stringWithFormat:@"dismiss the modal '%@'", modal.rootId];
896
+ RCTLogWarn(@"[ApexNavigation] %@",
897
+ [ANNErrorTexts couldNot:what reason:exception.reason ?: exception.name]);
898
+ // The dismissal still open answers, and so do the dismissals waiting behind it (an answer given already
899
+ // stays as it was).
900
+ [self endFailedOf:modal exception:exception];
901
+ done();
902
+ }
903
+ }
904
+
905
+ #pragma mark - Closed below
906
+
907
+ // The modal's view hides (it is never unloaded), `DidDisappear` of its screens that showed, `ModalDismissed` at once,
908
+ // its content stops, the answer. Its controller stays in UIKit's chain until UIKit removes it with the modals above it.
909
+ + (void)closeBelow:(ANNModal *)modal {
910
+ UIViewController *root = modal.root;
911
+ NSMutableSet<NSString *> *ids = [NSMutableSet new];
912
+ ANNCollectIds(root, ids);
913
+ modal.ids = ids;
914
+ modal.state = ANNModalStateClosedBelow;
915
+ modal.reported = YES;
916
+ root.viewIfLoaded.hidden = YES;
917
+ // A sheet's card and shadow are UIKit's views around the root's: the presentation's public container hides too;
918
+ // nothing is unloaded.
919
+ UIView *container = root.presentationController.containerView;
920
+ if (container && !container.hidden) {
921
+ container.hidden = YES;
922
+ modal.hiddenContainer = container;
923
+ }
924
+ ANNModalDismissal *dismissal = modal.dismissal;
925
+ modal.dismissal = nil;
926
+ @try {
927
+ [ANNComponentViewController nodeWillLeave:root];
928
+ [ANNAppearanceDispatcher endTransitionHiding:@[ root ]
929
+ showing:@[]
930
+ events:^{
931
+ [ANNAppearanceDispatcher modalDismissed:root count:1];
932
+ [root destroy];
933
+ }
934
+ answer:dismissal.answer
935
+ value:modal.rootId];
936
+ } @catch (NSException *exception) {
937
+ // Back on the record: `runDismissalOf:` rejects its answer if it is still open.
938
+ if (!modal.dismissal) {
939
+ modal.dismissal = dismissal;
940
+ }
941
+ @throw;
942
+ }
943
+ [self resolvePendingOf:modal];
944
+ }
945
+
946
+ #pragma mark - The dismissal
947
+
948
+ // At the start: `blurOnUnmount`, `WillAppear` of the layer under when it had disappeared; the command reports the
949
+ // appearance of what it moves. UIKit is asked from the presenting controller of the lowest modal closed below right
950
+ // under it, so that one dismissal takes them too; a search controller the modal shows goes first, without animation
951
+ // (`dismissModal` step 3). A modal UIKit doesn't hold any more (N3) ends at once.
952
+ + (void)startDismissalOf:(ANNModal *)modal done:(dispatch_block_t)done {
953
+ UIViewController *root = modal.root;
954
+ modal.dismissalStarted = YES;
955
+ UIViewController *under = [self layerUnder:modal];
956
+ BOOL revealed = [self layerUnder:under hadDisappearedFor:modal];
957
+ NSArray<ANNModal *> *closedBelow = [self closedBelowUnder:modal];
958
+ UIViewController *from = closedBelow.count > 0
959
+ ? closedBelow.lastObject.root.presentingViewController
960
+ : root.presentingViewController;
961
+ [ANNComponentViewController nodeWillLeave:root];
962
+ NSMutableArray<UIViewController *> *driven = [NSMutableArray arrayWithObject:root];
963
+ for (ANNModal *closed in closedBelow) {
964
+ [driven addObject:closed.root];
965
+ }
966
+ if (revealed) {
967
+ [driven addObject:under];
968
+ }
969
+ [self drive:modal nodes:driven];
970
+ if (revealed) {
971
+ [ANNAppearanceDispatcher beginTransitionShowing:@[ under ]];
972
+ }
973
+ __weak ANNModal *weakModal = modal;
974
+ void (^ended)(void) = ^{
975
+ ANNModal *dismissed = weakModal;
976
+ [ANNModalCoordinator protectEndOf:dismissed
977
+ showing:NO
978
+ step:^{
979
+ [ANNModalCoordinator dismissalEndedOf:dismissed
980
+ under:revealed ? under : nil
981
+ closedBelow:closedBelow];
982
+ }];
983
+ };
984
+ if (!from) {
985
+ ended();
986
+ done();
987
+ return;
988
+ }
989
+ BOOL animated = modal.dismissal ? modal.dismissal.animated : YES;
990
+ ANNTransitionPlan *plan =
991
+ animated ? [modal.presentation dismissPlanOf:root
992
+ animation:modal.dismissal.animation
993
+ under:under]
994
+ : nil;
995
+ void (^dismiss)(void) = ^{
996
+ [ANNModalCoordinator markCoreDismissalOf:root plan:plan record:weakModal];
997
+ [from dismissViewControllerAnimated:animated
998
+ completion:^{
999
+ ANNOnMainQueue(^{
1000
+ [ANNModalCoordinator coreDismissalEndedOf:weakModal];
1001
+ done();
1002
+ ended();
1003
+ });
1004
+ }];
1005
+ };
1006
+ UIViewController *search = [self presentedSearchControllerIn:root];
1007
+ if (search.presentingViewController) {
1008
+ [search.presentingViewController dismissViewControllerAnimated:NO
1009
+ completion:^{
1010
+ dismiss();
1011
+ }];
1012
+ } else {
1013
+ dismiss();
1014
+ }
1015
+ }
1016
+
1017
+ // Right before the core's own dismissal: the plan of its custom animation goes to the modal's transitioning delegate,
1018
+ // which UIKit asks now, and the delegate knows the dismissal is the core's (the user's swipe gets UIKit's).
1019
+ + (void)markCoreDismissalOf:(UIViewController *)root
1020
+ plan:(ANNTransitionPlan *)plan
1021
+ record:(ANNModal *)modal {
1022
+ if (!modal || (!plan && !modal.transitions)) {
1023
+ return;
1024
+ }
1025
+ if (!modal.transitions) {
1026
+ modal.transitions = [ANNModalTransitions new];
1027
+ }
1028
+ modal.transitions.dismissPlan = plan;
1029
+ modal.transitions.coreDismissal = YES;
1030
+ if (plan && root.transitioningDelegate != modal.transitions) {
1031
+ root.transitioningDelegate = modal.transitions;
1032
+ }
1033
+ // The own `exit` wins over the show's zoom: UIKit plays the zoom back instead of asking the delegate while the
1034
+ // modal keeps it, so a core dismissal with its own plan drops it (as a command's own pop does). The user's swipe
1035
+ // keeps UIKit's zoom.
1036
+ if (@available(iOS 18.0, *)) {
1037
+ if (plan && root.preferredTransition) {
1038
+ root.preferredTransition = nil;
1039
+ }
1040
+ }
1041
+ }
1042
+
1043
+ + (void)coreDismissalEndedOf:(ANNModal *)modal {
1044
+ modal.transitions.coreDismissal = NO;
1045
+ modal.transitions.dismissPlan = nil;
1046
+ }
1047
+
1048
+ // A search controller UIKit presents inside the modal (a screen with a search bar defines the presentation context).
1049
+ + (UIViewController *)presentedSearchControllerIn:(UIViewController *)node {
1050
+ UISearchController *search = node.navigationItem.searchController;
1051
+ if (search.presentingViewController && !search.isBeingDismissed) {
1052
+ return search;
1053
+ }
1054
+ for (UIViewController *child in node.layoutChildren) {
1055
+ UIViewController *found = [self presentedSearchControllerIn:child];
1056
+ if (found) {
1057
+ return found;
1058
+ }
1059
+ }
1060
+ return nil;
1061
+ }
1062
+
1063
+ // At the end: `DidDisappear` of its screens, `DidAppear` of the layer under when it had disappeared, the state,
1064
+ // `ModalDismissed` unless it went already, its content stops, the answer; its waiting commands resolve; the modals
1065
+ // closed below that UIKit took with it go.
1066
+ + (void)dismissalEndedOf:(ANNModal *)modal
1067
+ under:(UIViewController *)under
1068
+ closedBelow:(NSArray<ANNModal *> *)closedBelow {
1069
+ if (!modal || modal.state != ANNModalStateDismissing) {
1070
+ [self stopDriving:modal];
1071
+ return;
1072
+ }
1073
+ if (modal.batch) {
1074
+ // A `dismissAllModals` took it while UIKit dismissed it: UIKit removed it, the batch reports it.
1075
+ [self stopDriving:modal];
1076
+ [self queueBatchIfReady:modal.batch];
1077
+ return;
1078
+ }
1079
+ [self remove:modal];
1080
+ for (ANNModal *closed in closedBelow) {
1081
+ [self remove:closed];
1082
+ }
1083
+ UIViewController *root = modal.root;
1084
+ [ANNZoomAnchor transitionEndedOf:root];
1085
+ ANNModalDismissal *dismissal = modal.dismissal;
1086
+ modal.dismissal = nil;
1087
+ @try {
1088
+ [ANNAppearanceDispatcher endTransitionHiding:@[ root ]
1089
+ showing:under ? @[ under ] : @[]
1090
+ events:^{
1091
+ if (!modal.reported) {
1092
+ modal.reported = YES;
1093
+ [ANNAppearanceDispatcher modalDismissed:root
1094
+ count:1];
1095
+ }
1096
+ [root destroy];
1097
+ }
1098
+ answer:dismissal.answer
1099
+ value:modal.rootId];
1100
+ } @catch (NSException *exception) {
1101
+ // The dismissal goes back on the record so that the end step's guard rejects its answer if it is still open.
1102
+ if (!modal.dismissal) {
1103
+ modal.dismissal = dismissal;
1104
+ }
1105
+ @throw;
1106
+ } @finally {
1107
+ [self stopDriving:modal];
1108
+ [self resolvePendingOf:modal];
1109
+ [self cleanTopOfChain];
1110
+ [self presentReadyModals];
1111
+ }
1112
+ }
1113
+
1114
+ #pragma mark - The top of UIKit's chain
1115
+
1116
+ // After a modal left, the modals closed below that UIKit now shows on top (nothing above them but foreign
1117
+ // controllers) are dismissed without animation from the presenting controller of the lowest of them: no invisible
1118
+ // modal stays presented and takes touches. Decided when the step runs. `revealing`: the layer they kept from the user,
1119
+ // shown in that dismissal; `then` runs at its end.
1120
+ + (void)cleanTopOfChain {
1121
+ [self cleanTopOfChainRevealing:nil then:nil];
1122
+ }
1123
+
1124
+ + (void)cleanTopOfChainRevealing:(UIViewController *)revealing then:(dispatch_block_t)then {
1125
+ BOOL closedBelow = NO;
1126
+ for (ANNModal *modal in ANNModals) {
1127
+ if (modal.state == ANNModalStateClosedBelow && !modal.batch) {
1128
+ closedBelow = YES;
1129
+ break;
1130
+ }
1131
+ }
1132
+ if (!closedBelow) {
1133
+ if (then) {
1134
+ then();
1135
+ }
1136
+ return;
1137
+ }
1138
+ __weak UIViewController *weakRevealing = revealing;
1139
+ ANNGateStep *step = [[ANNGateStep alloc] initWithRun:^(dispatch_block_t done) {
1140
+ [ANNModalCoordinator runCleanRevealing:weakRevealing then:then done:done];
1141
+ }];
1142
+ [ANNPresentationGate enqueue:step];
1143
+ }
1144
+
1145
+ + (void)runCleanRevealing:(UIViewController *)revealing
1146
+ then:(dispatch_block_t)then
1147
+ done:(dispatch_block_t)done {
1148
+ NSMutableArray<ANNModal *> *top = [NSMutableArray new];
1149
+ for (ANNModal *modal in ANNModals.reverseObjectEnumerator) {
1150
+ if (modal.state == ANNModalStateWaiting) {
1151
+ continue;
1152
+ }
1153
+ if (modal.state != ANNModalStateClosedBelow || modal.batch) {
1154
+ break;
1155
+ }
1156
+ [top addObject:modal];
1157
+ }
1158
+ UIViewController *from = top.lastObject.root.presentingViewController;
1159
+ if (!from) {
1160
+ for (ANNModal *modal in top) {
1161
+ [self remove:modal];
1162
+ }
1163
+ done();
1164
+ if (then) {
1165
+ then();
1166
+ }
1167
+ return;
1168
+ }
1169
+ NSMutableArray<UIViewController *> *driven = [NSMutableArray new];
1170
+ for (ANNModal *modal in top) {
1171
+ [driven addObject:modal.root];
1172
+ }
1173
+ if (revealing) {
1174
+ [driven addObject:revealing];
1175
+ }
1176
+ [ANNAppearanceDispatcher driveAppearanceOf:driven];
1177
+ if (revealing) {
1178
+ [ANNAppearanceDispatcher beginTransitionShowing:@[ revealing ]];
1179
+ }
1180
+ [from dismissViewControllerAnimated:NO
1181
+ completion:^{
1182
+ for (ANNModal *modal in top) {
1183
+ [ANNModalCoordinator remove:modal];
1184
+ }
1185
+ done();
1186
+ @try {
1187
+ if (then) {
1188
+ then();
1189
+ }
1190
+ } @finally {
1191
+ [ANNAppearanceDispatcher stopDrivingAppearanceOf:driven];
1192
+ }
1193
+ }];
1194
+ }
1195
+
1196
+ #pragma mark - The user
1197
+
1198
+ // UIKit's delegate call: guarded as the record's end steps (the drag sends the appearance events of what it moves).
1199
+ + (void)modalWillBeDraggedAway:(ANNModal *)modal {
1200
+ ANNAssertMainQueue();
1201
+ [self protectEndOf:modal
1202
+ showing:NO
1203
+ step:^{
1204
+ [ANNModalCoordinator willBeDraggedAway:modal];
1205
+ }];
1206
+ }
1207
+
1208
+ + (void)willBeDraggedAway:(ANNModal *)modal {
1209
+ ANNModalState state = ANNSeenState(modal);
1210
+ BOOL dismissingLater = modal.state == ANNModalStateDismissing && !modal.dismissalStarted &&
1211
+ !modal.batch;
1212
+ if (state != ANNModalStateShown && !dismissingLater) {
1213
+ return;
1214
+ }
1215
+ if (dismissingLater) {
1216
+ // A dismissal whose UIKit call didn't start waits for the drag, as in `Shown`.
1217
+ if (modal.step) {
1218
+ [ANNPresentationGate drop:modal.step];
1219
+ modal.step = nil;
1220
+ }
1221
+ if (modal.dismissal) {
1222
+ [modal.pending insertObject:modal.dismissal atIndex:0];
1223
+ modal.dismissal = nil;
1224
+ }
1225
+ modal.state = ANNModalStateShown;
1226
+ }
1227
+ BOOL withOldRoot = modal.state == ANNModalStateWithOldRoot;
1228
+ if (withOldRoot) {
1229
+ modal.stateBeforeRoot = ANNModalStateGesture;
1230
+ } else {
1231
+ modal.state = ANNModalStateGesture;
1232
+ }
1233
+ // The drag ends cancelled: the coordinator's completion says so. When it promises none, the next turn looks. Both
1234
+ // are set before the drive, so a failure in the drive still leaves the record a way out of `Gesture`.
1235
+ __weak ANNModal *weakModal = modal;
1236
+ id<UIViewControllerTransitionCoordinator> coordinator = modal.root.transitionCoordinator;
1237
+ BOOL queued = [coordinator
1238
+ animateAlongsideTransition:nil
1239
+ completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
1240
+ if (context.isCancelled) {
1241
+ [ANNModalCoordinator dragCancelledOf:weakModal];
1242
+ }
1243
+ }];
1244
+ if (!queued) {
1245
+ dispatch_async(dispatch_get_main_queue(), ^{
1246
+ ANNModal *dragged = weakModal;
1247
+ if (dragged && !dragged.root.isBeingDismissed && dragged.root.presentingViewController) {
1248
+ [ANNModalCoordinator dragCancelledOf:dragged];
1249
+ }
1250
+ });
1251
+ }
1252
+ if (!withOldRoot) {
1253
+ [self driveDragOf:modal];
1254
+ }
1255
+ }
1256
+
1257
+ // The drag reveals the layer under a modal that covered it (no modal closed below between them): the command reports
1258
+ // both from now on, as the stack does for its swipe; UIKit's own callbacks of the layer under would send its
1259
+ // `DidAppear` before the modal's `DidDisappear`.
1260
+ + (void)driveDragOf:(ANNModal *)modal {
1261
+ UIViewController *under = [self layerUnder:modal];
1262
+ if (modal.driven || !under || [self closedBelowUnder:modal].count > 0 ||
1263
+ ![self layerUnder:under hadDisappearedFor:modal]) {
1264
+ return;
1265
+ }
1266
+ modal.dragRevealed = under;
1267
+ [self drive:modal nodes:@[ modal.root, under ]];
1268
+ [ANNAppearanceDispatcher beginTransitionShowing:@[ under ]];
1269
+ }
1270
+
1271
+ // A drag ended without closing: the layer under goes again (as a cancelled swipe of a stack).
1272
+ + (void)endDragDriveOf:(ANNModal *)modal {
1273
+ UIViewController *under = modal.dragRevealed;
1274
+ modal.dragRevealed = nil;
1275
+ if (!modal.driven) {
1276
+ return;
1277
+ }
1278
+ @try {
1279
+ if (under) {
1280
+ [ANNAppearanceDispatcher endTransitionHiding:@[ under ]
1281
+ showing:@[]
1282
+ events:nil
1283
+ answer:nil
1284
+ value:nil];
1285
+ }
1286
+ } @finally {
1287
+ [self stopDriving:modal];
1288
+ }
1289
+ }
1290
+
1291
+ // From the transition coordinator's completion or the next turn, outside the runner's protection: guarded as the
1292
+ // record's end steps (`DidDisappear` of the layer under goes from here).
1293
+ + (void)dragCancelledOf:(ANNModal *)modal {
1294
+ [self protectEndOf:modal
1295
+ showing:NO
1296
+ step:^{
1297
+ [ANNModalCoordinator cancelDragOf:modal];
1298
+ }];
1299
+ }
1300
+
1301
+ + (void)cancelDragOf:(ANNModal *)modal {
1302
+ if (!modal || ANNSeenState(modal) != ANNModalStateGesture) {
1303
+ return;
1304
+ }
1305
+ @try {
1306
+ [self endDragDriveOf:modal];
1307
+ } @catch (NSException *exception) {
1308
+ // The drag is over all the same: the record leaves `Gesture`, so a later command of it and a batch that
1309
+ // waited for the drag go on. The guard logs the failure and rejects the dismissals that waited for the drag.
1310
+ [self dragEndedOf:modal runPending:NO];
1311
+ @throw;
1312
+ }
1313
+ [self dragEndedOf:modal runPending:YES];
1314
+ }
1315
+
1316
+ + (void)dragEndedOf:(ANNModal *)modal runPending:(BOOL)runPending {
1317
+ if (modal.state == ANNModalStateWithOldRoot) {
1318
+ modal.stateBeforeRoot = ANNModalStateShown;
1319
+ return;
1320
+ }
1321
+ if (modal.takenWithDrag) {
1322
+ modal.takenWithDrag = NO;
1323
+ modal.stateBeforeRoot = ANNModalStateShown;
1324
+ modal.state = ANNModalStateWithOldRoot;
1325
+ [self collectIdsOf:modal];
1326
+ // A `dismissAllModals` that waited for this drag doesn't take a modal that goes with the old root (as at its
1327
+ // start): the record leaves the batch, which goes on without it.
1328
+ ANNModalBatch *waited = modal.batch;
1329
+ if (waited) {
1330
+ modal.batch = nil;
1331
+ [waited.records removeObjectIdenticalTo:modal];
1332
+ [waited.counted removeObject:modal];
1333
+ [self batchDragEnded:waited];
1334
+ }
1335
+ return;
1336
+ }
1337
+ modal.state = ANNModalStateShown;
1338
+ ANNModalBatch *batch = modal.batch;
1339
+ if (batch) {
1340
+ // It joins the batch that waited for its drag.
1341
+ modal.state = ANNModalStateDismissing;
1342
+ [batch.counted addObject:modal];
1343
+ [self batchDragEnded:batch];
1344
+ return;
1345
+ }
1346
+ if (runPending) {
1347
+ [self runPendingOf:modal];
1348
+ }
1349
+ }
1350
+
1351
+ // UIKit closed it for the user (a sheet swiped down, the dim or the outside of a popover tapped). The end steps of a
1352
+ // dismissal without an answer: the layer under comes back when it had disappeared; behind modals closed below, only
1353
+ // once UIKit removed them too.
1354
+ + (void)modalWasClosedByUser:(ANNModal *)modal {
1355
+ ANNAssertMainQueue();
1356
+ [self protectEndOf:modal
1357
+ showing:NO
1358
+ step:^{
1359
+ [ANNModalCoordinator closedByUser:modal];
1360
+ }];
1361
+ }
1362
+
1363
+ + (void)closedByUser:(ANNModal *)modal {
1364
+ if (!modal || modal.state == ANNModalStateGone || modal.state == ANNModalStateClosedBelow ||
1365
+ modal.state == ANNModalStateWaiting ||
1366
+ (modal.state == ANNModalStateDismissing && modal.dismissalStarted)) {
1367
+ return;
1368
+ }
1369
+ if (modal.step) {
1370
+ [ANNPresentationGate drop:modal.step];
1371
+ modal.step = nil;
1372
+ }
1373
+ if (modal.dismissal) {
1374
+ [modal.pending insertObject:modal.dismissal atIndex:0];
1375
+ modal.dismissal = nil;
1376
+ }
1377
+ // A drag a `dismissAllModals` waited for completed: it went by itself, not counted.
1378
+ ANNModalBatch *batch = modal.batch;
1379
+ BOOL batchWaitedForDrag = batch && modal.state == ANNModalStateGesture;
1380
+ if (batch) {
1381
+ modal.batch = nil;
1382
+ [batch.records removeObjectIdenticalTo:modal];
1383
+ [batch.counted removeObject:modal];
1384
+ }
1385
+ UIViewController *under = [self layerUnder:modal];
1386
+ BOOL revealed = [self layerUnder:under hadDisappearedFor:modal];
1387
+ BOOL behindClosed = [self closedBelowUnder:modal].count > 0;
1388
+ [self collectIdsOf:modal];
1389
+ [ANNClosedByUser addObject:@{ANNClosedIdsKey : modal.ids, ANNClosedRootIdKey : modal.rootId}];
1390
+ [self remove:modal];
1391
+ __weak UIViewController *weakUnder = under;
1392
+ BOOL deferred = revealed && behindClosed;
1393
+ // Also the `then` of the clean-up dismissal, inside UIKit's completion: guarded as the record's end step.
1394
+ dispatch_block_t end = ^{
1395
+ [ANNModalCoordinator protectEndOf:modal
1396
+ showing:NO
1397
+ step:^{
1398
+ // The state waited for these end steps (after `DidAppear` of the layer under).
1399
+ if (deferred) {
1400
+ [ANNNavigationState releaseUpdates];
1401
+ }
1402
+ UIViewController *shown = revealed ? weakUnder : nil;
1403
+ [ANNModalCoordinator userCloseEndedOf:modal under:shown];
1404
+ }];
1405
+ };
1406
+ if (deferred) {
1407
+ [ANNNavigationState holdUpdates];
1408
+ [self cleanTopOfChainRevealing:under then:end];
1409
+ } else {
1410
+ end();
1411
+ [self cleanTopOfChain];
1412
+ }
1413
+ if (batchWaitedForDrag) {
1414
+ [self batchDragEnded:batch];
1415
+ } else if (batch) {
1416
+ [self queueBatchIfReady:batch];
1417
+ }
1418
+ [self presentReadyModals];
1419
+ }
1420
+
1421
+ + (void)userCloseEndedOf:(ANNModal *)modal under:(UIViewController *)under {
1422
+ UIViewController *root = modal.root;
1423
+ [ANNZoomAnchor transitionEndedOf:root];
1424
+ @try {
1425
+ [ANNAppearanceDispatcher endTransitionHiding:@[ root ]
1426
+ showing:under ? @[ under ] : @[]
1427
+ events:^{
1428
+ if (!modal.reported) {
1429
+ modal.reported = YES;
1430
+ [ANNAppearanceDispatcher modalDismissed:root
1431
+ count:1];
1432
+ }
1433
+ [root destroy];
1434
+ }
1435
+ answer:nil
1436
+ value:nil];
1437
+ } @finally {
1438
+ // The drag's own report of the layer under ends with it.
1439
+ modal.dragRevealed = nil;
1440
+ [self stopDriving:modal];
1441
+ [self resolvePendingOf:modal];
1442
+ }
1443
+ }
1444
+
1445
+ + (void)collectIdsOf:(ANNModal *)modal {
1446
+ NSMutableSet<NSString *> *ids = [NSMutableSet new];
1447
+ ANNCollectIds(modal.root, ids);
1448
+ modal.ids = ids;
1449
+ }
1450
+
1451
+ // The user tried to close a held modal.
1452
+ + (void)userTriedToClose:(ANNModal *)modal {
1453
+ ANNAssertMainQueue();
1454
+ ANNModalState state = ANNSeenState(modal);
1455
+ if (state != ANNModalStateShown && state != ANNModalStateGesture &&
1456
+ state != ANNModalStateDismissing) {
1457
+ return;
1458
+ }
1459
+ UIViewController *screen = [ANNAppearanceDispatcher visibleScreenOf:modal.root];
1460
+ NSString *componentId = screen.layoutInfo.componentId ?: modal.rootId;
1461
+ [modal.root.eventEmitter sendModalAttemptedToDismiss:componentId];
1462
+ }
1463
+
1464
+ // The finger chose another detent. UIKit tells also of a drag that ends where the sheet stood (its selected identifier
1465
+ // goes from none to the lowest): only a change is sent.
1466
+ + (void)modal:(ANNModal *)modal detentChanged:(id)detent {
1467
+ ANNAssertMainQueue();
1468
+ if (modal.state == ANNModalStateGone || modal.state == ANNModalStateClosedBelow) {
1469
+ return;
1470
+ }
1471
+ if ([detent isEqual:modal.knownDetent]) {
1472
+ return;
1473
+ }
1474
+ modal.knownDetent = detent;
1475
+ UIViewController *screen = [ANNAppearanceDispatcher visibleScreenOf:modal.root];
1476
+ NSString *componentId = screen.layoutInfo.componentId ?: modal.rootId;
1477
+ [modal.root.eventEmitter sendSheetDetentChanged:componentId detent:detent];
1478
+ }
1479
+
1480
+ // The detent a sheet stands at by its options: `selectedDetent` when it is one of the detents, else the lowest (UIKit's
1481
+ // rule). Heights: `medium` half the window, `large` the window, a number its points, `content` the content's measure
1482
+ // (the window's height when nothing is measured yet); iOS 15 has only `medium` and `large`.
1483
+ + (id)knownDetentOf:(ANNModal *)modal {
1484
+ UIViewController *root = modal.root;
1485
+ ANNSheetOptions *sheet = [root resolveOptionsWithDefault].modal.sheet;
1486
+ NSArray *detents = sheet.detents.count > 0 ? sheet.detents : @[ @"large" ];
1487
+ id selected = [sheet.selectedDetent get];
1488
+ if (selected && [detents containsObject:selected]) {
1489
+ return selected;
1490
+ }
1491
+ CGFloat full = root.viewIfLoaded.window.bounds.size.height;
1492
+ if (full <= 0) {
1493
+ full = ApexNavigation.mainWindow.bounds.size.height;
1494
+ }
1495
+ id lowest = nil;
1496
+ CGFloat lowestHeight = CGFLOAT_MAX;
1497
+ for (id value in detents) {
1498
+ CGFloat height = 0;
1499
+ if ([value isEqual:@"medium"]) {
1500
+ height = full / 2;
1501
+ } else if ([value isEqual:@"large"]) {
1502
+ height = full;
1503
+ } else if (@available(iOS 16.0, *)) {
1504
+ if ([value isKindOfClass:NSNumber.class]) {
1505
+ height = MIN([value doubleValue], full);
1506
+ } else if ([value isEqual:@"content"]) {
1507
+ CGFloat content = [ANNSheetPresenter contentHeightOf:root
1508
+ width:root.view.bounds.size.width];
1509
+ height = content > 0 ? MIN(content, full) : full;
1510
+ } else {
1511
+ continue;
1512
+ }
1513
+ } else {
1514
+ continue;
1515
+ }
1516
+ if (height < lowestHeight) {
1517
+ lowestHeight = height;
1518
+ lowest = value;
1519
+ }
1520
+ }
1521
+ return lowest ?: @"large";
1522
+ }
1523
+
1524
+ #pragma mark - dismissAllModals
1525
+
1526
+ + (void)dismissAllModals:(NSDictionary *)options answer:(ANNCommandAnswer *)answer {
1527
+ ANNAssertMainQueue();
1528
+ NSMutableArray<ANNModal *> *taken = [NSMutableArray new];
1529
+ for (ANNModal *modal in ANNModals) {
1530
+ if (modal.state == ANNModalStateGone || modal.state == ANNModalStateWithOldRoot ||
1531
+ modal.batch) {
1532
+ continue;
1533
+ }
1534
+ [taken addObject:modal];
1535
+ }
1536
+ // The options give only whether the top modal leaves with its animation; a value that can't be read rejects with
1537
+ // the id of the top modal's visible screen.
1538
+ BOOL animated = YES;
1539
+ if (options.count > 0 && taken.count > 0) {
1540
+ NSString *unreadablePath = nil;
1541
+ ANNNavigationOptions *read = [ANNOptionsReader optionsFrom:options
1542
+ unreadablePath:&unreadablePath];
1543
+ if (unreadablePath) {
1544
+ UIViewController *root = taken.lastObject.root;
1545
+ UIViewController *screen = [ANNAppearanceDispatcher visibleScreenOf:root];
1546
+ NSString *componentId = screen.layoutInfo.componentId ?: taken.lastObject.rootId;
1547
+ [answer reject:[ANNErrorTexts unreadableOption:unreadablePath componentId:componentId]];
1548
+ return;
1549
+ }
1550
+ Bool *enabled = read.animations.dismissModal.exit.enabled;
1551
+ animated = !(enabled.hasValue && !enabled.get);
1552
+ }
1553
+ if (taken.count == 0) {
1554
+ // N6: a running batch still has its modals on screen; this one answers at its end.
1555
+ ANNModalBatch *running = ANNBatches.lastObject;
1556
+ if (running) {
1557
+ [running.waiters addObject:answer];
1558
+ } else {
1559
+ [answer resolve:@""];
1560
+ }
1561
+ return;
1562
+ }
1563
+ ANNModalBatch *batch = [ANNModalBatch new];
1564
+ batch.answer = answer;
1565
+ batch.animated = animated;
1566
+ [ANNBatches addObject:batch];
1567
+ for (ANNModal *modal in taken) {
1568
+ [self take:modal intoBatch:batch];
1569
+ }
1570
+ // The command doesn't wait for a show or a dismissal of its own animation that runs: it ends at its
1571
+ // end state now, as at a reload, and the batch's dismissal follows on the next turn. UIKit's own transition and
1572
+ // the user's drag still end first: UIKit drops a dismissal asked for while they run.
1573
+ for (ANNModal *modal in taken) {
1574
+ [modal.transitions cancel];
1575
+ }
1576
+ [self queueBatchIfReady:batch];
1577
+ }
1578
+ + (void)take:(ANNModal *)modal intoBatch:(ANNModalBatch *)batch {
1579
+ modal.batch = batch;
1580
+ [batch.records addObject:modal];
1581
+ switch (modal.state) {
1582
+ case ANNModalStateWaiting:
1583
+ // Cancelled without its own event, counted; its root goes at the batch's end.
1584
+ [self stopWaitOf:modal];
1585
+ [modal.showAnswer resolve:modal.rootId];
1586
+ if (modal.chainStep) {
1587
+ void (^chainStep)(BOOL) = modal.chainStep;
1588
+ modal.chainStep = nil;
1589
+ chainStep(NO);
1590
+ }
1591
+ modal.state = ANNModalStateDismissing;
1592
+ modal.dismissalStarted = NO;
1593
+ [batch.counted addObject:modal];
1594
+ break;
1595
+ case ANNModalStatePresenting:
1596
+ case ANNModalStateShown:
1597
+ modal.state = ANNModalStateDismissing;
1598
+ [batch.counted addObject:modal];
1599
+ break;
1600
+ case ANNModalStateGesture:
1601
+ batch.dragsPending++;
1602
+ break;
1603
+ case ANNModalStateDismissing:
1604
+ // Its own command resolves at the batch's end; one whose UIKit dismissal runs ends with the batch too
1605
+ // (one event).
1606
+ if (modal.step) {
1607
+ [ANNPresentationGate drop:modal.step];
1608
+ modal.step = nil;
1609
+ }
1610
+ if (modal.dismissal) {
1611
+ [modal.pending addObject:modal.dismissal];
1612
+ modal.dismissal = nil;
1613
+ }
1614
+ if (!modal.reported) {
1615
+ [batch.counted addObject:modal];
1616
+ }
1617
+ break;
1618
+ case ANNModalStateClosedBelow:
1619
+ case ANNModalStateWithOldRoot:
1620
+ case ANNModalStateGone:
1621
+ break;
1622
+ }
1623
+ }
1624
+
1625
+ // A drag the batch waited for ended.
1626
+ + (void)batchDragEnded:(ANNModalBatch *)batch {
1627
+ if (batch.dragsPending > 0) {
1628
+ batch.dragsPending--;
1629
+ }
1630
+ [self queueBatchIfReady:batch];
1631
+ }
1632
+
1633
+ // No drag left to wait for: the batch's dismissal waits for the gate.
1634
+ + (void)queueBatchIfReady:(ANNModalBatch *)batch {
1635
+ if (batch.dragsPending > 0 || batch.step || ![ANNBatches containsObject:batch]) {
1636
+ return;
1637
+ }
1638
+ __weak ANNModalBatch *weakBatch = batch;
1639
+ ANNGateStep *step = [[ANNGateStep alloc] initWithRun:^(dispatch_block_t done) {
1640
+ [ANNModalCoordinator runBatch:weakBatch done:done];
1641
+ }];
1642
+ batch.step = step;
1643
+ [ANNPresentationGate enqueue:step];
1644
+ }
1645
+
1646
+ // The top modal of the batch leaves with its animation (unless the options turn it off), every other at once: one
1647
+ // UIKit dismissal from the presenting controller of the lowest of them. The layer under them appears at the start
1648
+ // when it had disappeared.
1649
+ + (void)runBatch:(ANNModalBatch *)batch done:(dispatch_block_t)done {
1650
+ if (!batch) {
1651
+ done();
1652
+ return;
1653
+ }
1654
+ NSMutableArray<ANNModal *> *presented = [NSMutableArray new];
1655
+ for (ANNModal *modal in batch.records) {
1656
+ if (modal.state != ANNModalStateGone && modal.root.presentingViewController) {
1657
+ [presented addObject:modal];
1658
+ }
1659
+ }
1660
+ // The layer under the lowest modal of the batch still listed (also one UIKit dismissed already on its own
1661
+ // command: its dismissal began that layer's appearance).
1662
+ ANNModal *lowest = presented.firstObject;
1663
+ ANNModal *lowestListed = nil;
1664
+ BOOL revealed = NO;
1665
+ for (ANNModal *modal in batch.records) {
1666
+ if (modal.state == ANNModalStateGone) {
1667
+ continue;
1668
+ }
1669
+ lowestListed = lowestListed ?: modal;
1670
+ revealed = revealed || modal.coversUnder;
1671
+ }
1672
+ UIViewController *under = lowestListed ? [self layerUnder:lowestListed] : nil;
1673
+ revealed = revealed && under != nil;
1674
+ UIViewController *from = lowest.root.presentingViewController;
1675
+ NSMutableArray<UIViewController *> *driven = [NSMutableArray new];
1676
+ for (ANNModal *modal in batch.records) {
1677
+ [ANNComponentViewController nodeWillLeave:modal.root];
1678
+ [driven addObject:modal.root];
1679
+ }
1680
+ if (revealed) {
1681
+ [driven addObject:under];
1682
+ }
1683
+ [ANNAppearanceDispatcher driveAppearanceOf:driven];
1684
+ if (revealed) {
1685
+ [ANNAppearanceDispatcher beginTransitionShowing:@[ under ]];
1686
+ }
1687
+ __weak ANNModalBatch *weakBatch = batch;
1688
+ void (^ended)(void) = ^{
1689
+ ANNModalBatch *ending = weakBatch;
1690
+ [ANNModalCoordinator protectBatch:ending
1691
+ step:^{
1692
+ @try {
1693
+ [ANNModalCoordinator batchEnded:ending
1694
+ under:revealed ? under : nil];
1695
+ } @finally {
1696
+ [ANNAppearanceDispatcher stopDrivingAppearanceOf:driven];
1697
+ }
1698
+ }];
1699
+ };
1700
+ if (!from) {
1701
+ ended();
1702
+ done();
1703
+ return;
1704
+ }
1705
+ // The top modal plays its own dismissal (its `animations.dismissModal`), unless the command's options turned the
1706
+ // animation off.
1707
+ ANNModal *top = presented.lastObject;
1708
+ ANNTransitionPlan *plan =
1709
+ batch.animated && top
1710
+ ? [top.presentation dismissPlanOf:top.root
1711
+ animation:[top.root resolveOptionsWithDefault]
1712
+ .animations.dismissModal
1713
+ under:under]
1714
+ : nil;
1715
+ [self markCoreDismissalOf:top.root plan:plan record:top];
1716
+ __weak ANNModal *weakTop = top;
1717
+ [from dismissViewControllerAnimated:batch.animated
1718
+ completion:^{
1719
+ ANNOnMainQueue(^{
1720
+ [ANNModalCoordinator coreDismissalEndedOf:weakTop];
1721
+ done();
1722
+ ended();
1723
+ });
1724
+ }];
1725
+ }
1726
+
1727
+ // The end: `DidDisappear` of every modal's screens that showed, `DidAppear` of the layer under when it had disappeared,
1728
+ // the state, one `ModalDismissed` with the number of modals not reported before and the visible screen of the topmost
1729
+ // of them, every content stops, the answer `""`; the commands and shows that waited for a modal of the batch resolve
1730
+ // with its root's id.
1731
+ + (void)batchEnded:(ANNModalBatch *)batch under:(UIViewController *)under {
1732
+ if (!batch || ![ANNBatches containsObject:batch]) {
1733
+ return;
1734
+ }
1735
+ [ANNBatches removeObjectIdenticalTo:batch];
1736
+ NSArray<ANNModal *> *records = batch.records.copy;
1737
+ NSMutableArray<UIViewController *> *hidden = [NSMutableArray new];
1738
+ ANNModal *topCounted = nil;
1739
+ NSUInteger count = 0;
1740
+ for (ANNModal *modal in records) {
1741
+ [self remove:modal];
1742
+ [ANNZoomAnchor transitionEndedOf:modal.root];
1743
+ [hidden addObject:modal.root];
1744
+ if ([batch.counted containsObject:modal]) {
1745
+ count++;
1746
+ topCounted = modal;
1747
+ }
1748
+ }
1749
+ @try {
1750
+ [ANNAppearanceDispatcher endTransitionHiding:hidden
1751
+ showing:under ? @[ under ] : @[]
1752
+ events:^{
1753
+ if (count > 0) {
1754
+ [ANNAppearanceDispatcher
1755
+ modalDismissed:topCounted.root
1756
+ count:count];
1757
+ }
1758
+ for (ANNModal *modal in records) {
1759
+ modal.reported = YES;
1760
+ [modal.root destroy];
1761
+ }
1762
+ }
1763
+ answer:batch.answer
1764
+ value:@""];
1765
+ } @finally {
1766
+ for (ANNModal *modal in records) {
1767
+ [modal.showAnswer resolve:modal.rootId];
1768
+ [modal.dismissal.answer resolve:modal.rootId];
1769
+ modal.dismissal = nil;
1770
+ [self resolvePendingOf:modal];
1771
+ }
1772
+ for (ANNCommandAnswer *waiter in batch.waiters) {
1773
+ [waiter resolve:@""];
1774
+ }
1775
+ [self cleanTopOfChain];
1776
+ [self presentReadyModals];
1777
+ }
1778
+ }
1779
+
1780
+ #pragma mark - setRoot (rows 12 … 14)
1781
+
1782
+ + (void)takeForNewRoot {
1783
+ ANNAssertMainQueue();
1784
+ for (ANNModal *modal in ANNModals.copy) {
1785
+ switch (modal.state) {
1786
+ case ANNModalStateWaiting:
1787
+ // It would only show over the root that goes: it never shows.
1788
+ [self cancel:modal rejection:nil dismissal:nil sendsEvent:NO];
1789
+ break;
1790
+ case ANNModalStatePresenting:
1791
+ case ANNModalStateShown:
1792
+ case ANNModalStateClosedBelow:
1793
+ // A modal closed below kept its ids when its nodes went.
1794
+ if (modal.state != ANNModalStateClosedBelow) {
1795
+ [self collectIdsOf:modal];
1796
+ }
1797
+ modal.stateBeforeRoot = modal.state;
1798
+ modal.state = ANNModalStateWithOldRoot;
1799
+ break;
1800
+ case ANNModalStateGesture:
1801
+ modal.takenWithDrag = YES;
1802
+ break;
1803
+ case ANNModalStateDismissing:
1804
+ case ANNModalStateWithOldRoot:
1805
+ case ANNModalStateGone:
1806
+ break;
1807
+ }
1808
+ }
1809
+ }
1810
+
1811
+ + (void)restoreTakenForNewRoot {
1812
+ ANNAssertMainQueue();
1813
+ for (ANNModal *modal in ANNModals.copy) {
1814
+ if (modal.state == ANNModalStateWithOldRoot) {
1815
+ modal.state = modal.stateBeforeRoot;
1816
+ // A command that waited for its show or its drag runs now (row 14).
1817
+ [self runPendingOf:modal];
1818
+ }
1819
+ modal.takenWithDrag = NO;
1820
+ }
1821
+ }
1822
+
1823
+ + (NSArray<UIViewController *> *)takeAtReplacement {
1824
+ ANNAssertMainQueue();
1825
+ NSMutableArray<UIViewController *> *roots = [NSMutableArray new];
1826
+ NSMutableArray<ANNModal *> *taken = [NSMutableArray new];
1827
+ for (ANNModal *modal in ANNModals.copy) {
1828
+ if (modal.state == ANNModalStateWaiting) {
1829
+ [self cancel:modal rejection:nil dismissal:nil sendsEvent:NO];
1830
+ continue;
1831
+ }
1832
+ [self stopWaitOf:modal];
1833
+ [self remove:modal];
1834
+ [roots addObject:modal.root];
1835
+ [taken addObject:modal];
1836
+ }
1837
+ // Their commands and shows that still wait resolve with their roots' ids (2.6 g); the chain of the `setRoot` that
1838
+ // showed one was superseded already.
1839
+ for (ANNModal *modal in taken) {
1840
+ modal.chainStep = nil;
1841
+ [modal.showAnswer resolve:modal.rootId];
1842
+ [modal.dismissal.answer resolve:modal.rootId];
1843
+ modal.dismissal = nil;
1844
+ [self resolvePendingOf:modal];
1845
+ }
1846
+ NSArray<ANNModalBatch *> *batches = ANNBatches.copy;
1847
+ [ANNBatches removeAllObjects];
1848
+ for (ANNModalBatch *batch in batches) {
1849
+ if (batch.step) {
1850
+ [ANNPresentationGate drop:batch.step];
1851
+ }
1852
+ [batch.answer resolve:@""];
1853
+ for (ANNCommandAnswer *waiter in batch.waiters) {
1854
+ [waiter resolve:@""];
1855
+ }
1856
+ }
1857
+ return roots;
1858
+ }
1859
+
1860
+ + (NSArray<UIViewController *> *)takeAllForReload {
1861
+ ANNAssertMainQueue();
1862
+ NSMutableArray<UIViewController *> *roots = [NSMutableArray new];
1863
+ NSArray<ANNModal *> *modals = ANNModals.copy;
1864
+ for (ANNModal *modal in modals) {
1865
+ [self stopWaitOf:modal];
1866
+ modal.state = ANNModalStateGone;
1867
+ [roots addObject:modal.root];
1868
+ }
1869
+ [ANNModals removeAllObjects];
1870
+ // A custom transition running now ends at its end state (8), once the records are gone: the end steps its
1871
+ // completion would run find nothing (a reload answers nothing, N4).
1872
+ for (ANNModal *modal in modals) {
1873
+ [modal.transitions cancel];
1874
+ }
1875
+ for (ANNModalBatch *batch in ANNBatches) {
1876
+ if (batch.step) {
1877
+ [ANNPresentationGate drop:batch.step];
1878
+ }
1879
+ }
1880
+ [ANNBatches removeAllObjects];
1881
+ [ANNClosedByUser removeAllObjects];
1882
+ return roots;
1883
+ }
1884
+
1885
+ #pragma mark - Questions
1886
+
1887
+ + (UIViewController *)visibleLayout {
1888
+ ANNAssertMainQueue();
1889
+ for (ANNModal *modal in ANNModals.reverseObjectEnumerator) {
1890
+ // A modal being dismissed shows until its end steps remove it: a state asked for meanwhile still names it, and
1891
+ // the state of the layer under goes after its appearance.
1892
+ if (ANNIsOnScreen(modal) || ANNSeenState(modal) == ANNModalStateDismissing) {
1893
+ return modal.root;
1894
+ }
1895
+ }
1896
+ UIViewController *root = ApexNavigation.mainWindow.rootViewController;
1897
+ return root.isLayoutNode ? root : nil;
1898
+ }
1899
+
1900
+ + (BOOL)isWithOldRoot:(UIViewController *)node {
1901
+ ANNAssertMainQueue();
1902
+ if (ANNModals.count == 0) {
1903
+ return NO;
1904
+ }
1905
+ return [self modalOf:node].state == ANNModalStateWithOldRoot;
1906
+ }
1907
+
1908
+ + (NSArray<UIViewController *> *)modalRoots {
1909
+ ANNAssertMainQueue();
1910
+ NSMutableArray<UIViewController *> *roots = [NSMutableArray new];
1911
+ for (ANNModal *modal in ANNModals) {
1912
+ if (!modal.root.nodeHelper.destroyed) {
1913
+ [roots addObject:modal.root];
1914
+ }
1915
+ }
1916
+ return roots;
1917
+ }
1918
+
1919
+ #pragma mark - What changes in a modal
1920
+
1921
+ // One call per merge: the modules find the presented root themselves and act only when it is presented: the sheet takes
1922
+ // only the fields that came, the size its resolved options.
1923
+ + (void)optionsMerged:(ANNNavigationOptions *)options into:(UIViewController *)node {
1924
+ ANNAssertMainQueue();
1925
+ if (ANNModals.count == 0 || node.nodeHelper.destroyed) {
1926
+ return;
1927
+ }
1928
+ ANNModal *modal = [self modalOf:node];
1929
+ if (!modal || modal.state == ANNModalStateWaiting || modal.state == ANNModalStateGone) {
1930
+ return;
1931
+ }
1932
+ ANNModalOptions *merge = options.modal;
1933
+ if (merge.sheet.hasValue) {
1934
+ [ANNSheetPresenter mergeOptions:merge.sheet ofViewController:node];
1935
+ // A detent set from the options sends nothing and is the one the sheet stands at now; new detents without
1936
+ // the one it stood at move it to the selected or the lowest.
1937
+ if (modal.presentation.isSheet &&
1938
+ (merge.sheet.selectedDetent.hasValue ||
1939
+ (merge.sheet.detents && ![merge.sheet.detents containsObject:modal.knownDetent]))) {
1940
+ modal.knownDetent = [self knownDetentOf:modal];
1941
+ }
1942
+ }
1943
+ [ANNModalSizePresenter mergeOptions:merge ofViewController:node];
1944
+ if (merge.swipeToDismiss.hasValue) {
1945
+ [ANNModalPresentation applyHoldTo:modal.root];
1946
+ }
1947
+ if (merge.testID.hasValue || merge.sheet.testID.hasValue) {
1948
+ [ANNModalPresentation applyTestIDTo:modal.root sheet:modal.presentation.isSheet];
1949
+ }
1950
+ }
1951
+
1952
+ + (void)visibleScreenChangedIn:(UIViewController *)node {
1953
+ ANNAssertMainQueue();
1954
+ if (ANNModals.count == 0) {
1955
+ return;
1956
+ }
1957
+ ANNModal *modal = [self modalOf:node];
1958
+ if (!modal || modal.state == ANNModalStateWaiting || modal.state == ANNModalStateGone ||
1959
+ modal.state == ANNModalStateClosedBelow) {
1960
+ return;
1961
+ }
1962
+ [ANNModalPresentation applyHoldTo:modal.root];
1963
+ }
1964
+
1965
+ @end