@apexnative/navigation 1.0.0-alpha.0 → 1.0.0-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (574) hide show
  1. package/ApexNavigation.podspec +2 -1
  2. package/CHANGELOG.md +128 -0
  3. package/README.md +147 -51
  4. package/android/CLAUDE.md +78 -25
  5. package/android/CORE.md +49 -25
  6. package/android/RECIPES.md +13 -6
  7. package/android/consumer-rules.pro +6 -0
  8. package/android/src/main/java/dev/apexnative/navigation/NavigationActivity.kt +85 -10
  9. package/android/src/main/java/dev/apexnative/navigation/NavigationApplication.kt +34 -13
  10. package/android/src/main/java/dev/apexnative/navigation/layout/LayoutChecks.kt +5 -1
  11. package/android/src/main/java/dev/apexnative/navigation/layout/LayoutNode.kt +6 -2
  12. package/android/src/main/java/dev/apexnative/navigation/nativescreen/NativeScreenContext.kt +2 -2
  13. package/android/src/main/java/dev/apexnative/navigation/options/AnimationsOptions.kt +2 -2
  14. package/android/src/main/java/dev/apexnative/navigation/options/BottomTabOptions.kt +1 -1
  15. package/android/src/main/java/dev/apexnative/navigation/options/BottomTabsOptions.kt +13 -8
  16. package/android/src/main/java/dev/apexnative/navigation/options/ButtonMenuOptions.kt +2 -2
  17. package/android/src/main/java/dev/apexnative/navigation/options/ButtonOptions.kt +3 -3
  18. package/android/src/main/java/dev/apexnative/navigation/options/HardwareBackButtonOptions.kt +9 -1
  19. package/android/src/main/java/dev/apexnative/navigation/options/LargeTitleOptions.kt +1 -1
  20. package/android/src/main/java/dev/apexnative/navigation/options/LayoutAnimation.kt +1 -1
  21. package/android/src/main/java/dev/apexnative/navigation/options/OptionKey.kt +18 -0
  22. package/android/src/main/java/dev/apexnative/navigation/options/OptionPaths.kt +91 -0
  23. package/android/src/main/java/dev/apexnative/navigation/options/OptionsCache.kt +8 -4
  24. package/android/src/main/java/dev/apexnative/navigation/options/SheetOptions.kt +7 -4
  25. package/android/src/main/java/dev/apexnative/navigation/options/SideMenuOptions.kt +6 -1
  26. package/android/src/main/java/dev/apexnative/navigation/options/StackAnimationOptions.kt +40 -2
  27. package/android/src/main/java/dev/apexnative/navigation/options/StatusBarOptions.kt +7 -3
  28. package/android/src/main/java/dev/apexnative/navigation/options/TitleOptions.kt +2 -2
  29. package/android/src/main/java/dev/apexnative/navigation/options/TopBarAppearanceOptions.kt +1 -1
  30. package/android/src/main/java/dev/apexnative/navigation/options/TopBarOptions.kt +16 -7
  31. package/android/src/main/java/dev/apexnative/navigation/options/UserChoices.kt +159 -0
  32. package/android/src/main/java/dev/apexnative/navigation/react/CommandAnswer.kt +29 -36
  33. package/android/src/main/java/dev/apexnative/navigation/react/CommandContract.kt +59 -0
  34. package/android/src/main/java/dev/apexnative/navigation/react/ContentHeights.kt +95 -0
  35. package/android/src/main/java/dev/apexnative/navigation/react/ContentMounts.kt +66 -0
  36. package/android/src/main/java/dev/apexnative/navigation/react/ErrorTexts.kt +75 -60
  37. package/android/src/main/java/dev/apexnative/navigation/react/Hinge.kt +35 -23
  38. package/android/src/main/java/dev/apexnative/navigation/react/NavigationTurboModule.kt +12 -7
  39. package/android/src/main/java/dev/apexnative/navigation/react/OptionsCommands.kt +42 -4
  40. package/android/src/main/java/dev/apexnative/navigation/react/PendingCalls.kt +48 -0
  41. package/android/src/main/java/dev/apexnative/navigation/react/ReactView.kt +54 -20
  42. package/android/src/main/java/dev/apexnative/navigation/react/ReloadCoordinator.kt +7 -6
  43. package/android/src/main/java/dev/apexnative/navigation/react/ScreenEnvironment.kt +177 -0
  44. package/android/src/main/java/dev/apexnative/navigation/react/ScreenRegions.kt +19 -50
  45. package/android/src/main/java/dev/apexnative/navigation/react/ScrollEvents.kt +49 -128
  46. package/android/src/main/java/dev/apexnative/navigation/react/events/AppearanceDispatcher.kt +50 -81
  47. package/android/src/main/java/dev/apexnative/navigation/react/events/EventContract.kt +226 -0
  48. package/android/src/main/java/dev/apexnative/navigation/react/events/EventEmitter.kt +135 -94
  49. package/android/src/main/java/dev/apexnative/navigation/react/events/NavigationState.kt +154 -0
  50. package/android/src/main/java/dev/apexnative/navigation/react/events/ScreenAppearance.kt +0 -6
  51. package/android/src/main/java/dev/apexnative/navigation/safearea/SafeAreaView.kt +12 -10
  52. package/android/src/main/java/dev/apexnative/navigation/slots/SlotContainers.kt +10 -7
  53. package/android/src/main/java/dev/apexnative/navigation/slots/SlotScreenView.kt +39 -19
  54. package/android/src/main/java/dev/apexnative/navigation/slots/SlotView.kt +16 -4
  55. package/android/src/main/java/dev/apexnative/navigation/slots/SlotViews.kt +40 -0
  56. package/android/src/main/java/dev/apexnative/navigation/utils/ImageKey.kt +66 -0
  57. package/android/src/main/java/dev/apexnative/navigation/utils/ImageLoader.kt +7 -89
  58. package/android/src/main/java/dev/apexnative/navigation/utils/ImageRequests.kt +76 -0
  59. package/android/src/main/java/dev/apexnative/navigation/utils/MaterialTheme.kt +5 -6
  60. package/android/src/main/java/dev/apexnative/navigation/utils/OptionImages.kt +262 -0
  61. package/android/src/main/java/dev/apexnative/navigation/utils/SystemAnimations.kt +36 -0
  62. package/android/src/main/java/dev/apexnative/navigation/utils/UiUtils.kt +3 -3
  63. package/android/src/main/java/dev/apexnative/navigation/utils/ViewController.kt +3 -1
  64. package/android/src/main/java/dev/apexnative/navigation/utils/ViewExtensions.kt +0 -13
  65. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/ArrangementController.kt +10 -7
  66. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/SecondaryScreenPresenter.kt +13 -5
  67. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/AppliedTabCalls.kt +49 -0
  68. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsCollapseBehavior.kt +5 -3
  69. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsController.kt +108 -34
  70. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsPresenter.kt +25 -24
  71. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowGeometry.kt +22 -0
  72. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabItems.kt +3 -3
  73. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabsRoom.kt +0 -5
  74. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentPresenter.kt +28 -7
  75. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentViewController.kt +12 -9
  76. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ContentReadiness.kt +2 -2
  77. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/RenderWait.kt +27 -7
  78. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenFrame.kt +1 -1
  79. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenReadiness.kt +103 -56
  80. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenSafeArea.kt +29 -11
  81. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/externalcomponent/ExternalComponentViewController.kt +2 -6
  82. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalAnimations.kt +22 -24
  83. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalCoordinator.kt +109 -21
  84. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalRecord.kt +21 -6
  85. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalSheet.kt +476 -73
  86. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalViews.kt +57 -25
  87. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetBack.kt +42 -0
  88. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetStops.kt +83 -0
  89. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/BackCallbackCheck.kt +50 -0
  90. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/BackCallbackState.kt +49 -14
  91. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/Navigator.kt +71 -12
  92. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/RootCoordinator.kt +37 -11
  93. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/overlay/OverlayCoordinator.kt +10 -8
  94. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/Capabilities.kt +11 -4
  95. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ContainerBackground.kt +3 -3
  96. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ParentController.kt +6 -6
  97. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuController.kt +42 -9
  98. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuMotion.kt +19 -8
  99. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuPresenter.kt +16 -7
  100. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuRules.kt +43 -4
  101. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitPanes.kt +23 -0
  102. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitViewController.kt +77 -17
  103. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/BackPreview.kt +315 -0
  104. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/PreparedFrame.kt +3 -3
  105. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackCommands.kt +30 -20
  106. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackController.kt +216 -18
  107. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackDisplay.kt +26 -1
  108. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackQueue.kt +149 -41
  109. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackTransitions.kt +26 -8
  110. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackViews.kt +115 -6
  111. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabMotion.kt +142 -0
  112. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabPresenter.kt +222 -48
  113. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/ScreenSearch.kt +3 -5
  114. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/StackSearchPresenter.kt +30 -34
  115. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/BarComponents.kt +5 -51
  116. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/BarRowTransition.kt +3 -2
  117. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/ButtonPlaces.kt +11 -5
  118. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/MenuChecks.kt +13 -56
  119. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarPresenter.kt +219 -54
  120. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarVisibility.kt +9 -2
  121. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ScrollEventListener.kt +6 -9
  122. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ViewController.kt +75 -21
  123. package/android/src/main/java/dev/apexnative/navigation/views/animations/AnimationLayer.kt +73 -0
  124. package/android/src/main/java/dev/apexnative/navigation/views/animations/Curves.kt +29 -11
  125. package/android/src/main/java/dev/apexnative/navigation/views/animations/ValueInterpolation.kt +14 -0
  126. package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabs.kt +9 -7
  127. package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabsLayout.kt +61 -2
  128. package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomBottomTabItemView.kt +0 -5
  129. package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomTabRow.kt +72 -10
  130. package/android/src/main/java/dev/apexnative/navigation/views/element/ElementStep.kt +31 -0
  131. package/android/src/main/java/dev/apexnative/navigation/views/element/ElementTransitions.kt +143 -135
  132. package/android/src/main/java/dev/apexnative/navigation/views/element/TargetsWait.kt +13 -5
  133. package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionLayer.kt +37 -112
  134. package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionTargets.kt +9 -6
  135. package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionViews.kt +100 -0
  136. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ElementPictures.kt +112 -4
  137. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/FlightGeometry.kt +346 -36
  138. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMorph.kt +199 -0
  139. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/SharedAnimatorFactory.kt +56 -41
  140. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextMorph.kt +176 -0
  141. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewMorph.kt +108 -0
  142. package/android/src/main/java/dev/apexnative/navigation/views/sidemenu/SideMenuView.kt +12 -3
  143. package/android/src/main/java/dev/apexnative/navigation/views/stack/ScreenEdge.kt +45 -0
  144. package/android/src/main/java/dev/apexnative/navigation/views/stack/StackLayout.kt +140 -1
  145. package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/Fab.kt +14 -10
  146. package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabCopy.kt +85 -0
  147. package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabMenu.kt +13 -0
  148. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TitleBar.kt +5 -17
  149. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TopBar.kt +73 -34
  150. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonComponentCell.kt +6 -6
  151. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonView.kt +113 -0
  152. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarMenu.kt +219 -0
  153. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonBar.kt +125 -178
  154. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonMenus.kt +34 -64
  155. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonRow.kt +216 -0
  156. package/android/src/main/jni/ANNContentHeights.cpp +82 -0
  157. package/android/src/main/res/drawable/apex_navigation_ic_arrow_right.xml +14 -0
  158. package/android/src/main/res/layout/apex_navigation_menu_header.xml +19 -0
  159. package/android/src/main/res/layout/apex_navigation_menu_item.xml +68 -0
  160. package/android/src/main/res/values/styles.xml +1 -1
  161. package/android/src/main/res/values-night/styles.xml +1 -1
  162. package/cli/app.js +1 -1
  163. package/cli/doctor/checks/app.js +77 -14
  164. package/cli/doctor/checks/splash.js +4 -22
  165. package/cli/migrate/native.js +18 -0
  166. package/cli/project.js +10 -2
  167. package/cli/setup/index.js +18 -0
  168. package/cli/setup/source.js +2 -1
  169. package/cli/setup/steps/appDelegate.js +66 -11
  170. package/cli/setup/steps/mainApplication.js +134 -19
  171. package/cli/setup/steps/metro.js +46 -0
  172. package/cli/setup/steps/sceneDelegate.js +108 -0
  173. package/cli/splash/index.js +3 -1
  174. package/cli/upgrade/changelog.js +2 -2
  175. package/docs-md/architecture/native-screens.md +4 -0
  176. package/docs-md/architecture/theme-and-context.md +131 -12
  177. package/docs-md/architecture/transitions.md +58 -12
  178. package/docs-md/containers/modals.md +8 -4
  179. package/docs-md/containers/overlays.md +3 -1
  180. package/docs-md/containers/side-menu.md +19 -2
  181. package/docs-md/containers/tabs.md +5 -1
  182. package/docs-md/flows/bottom-sheets.md +4 -2
  183. package/docs-md/flows/forms-in-a-modal.md +1 -1
  184. package/docs-md/fundamentals/screens-and-props.md +9 -1
  185. package/docs-md/fundamentals/starting-the-app.md +1 -1
  186. package/docs-md/guides/cli.md +4 -3
  187. package/docs-md/guides/deep-links.md +15 -33
  188. package/docs-md/help/glossary.md +4 -4
  189. package/docs-md/help/troubleshooting.md +44 -6
  190. package/docs-md/index.json +57 -1
  191. package/docs-md/migration/from-expo-router.md +1 -1
  192. package/docs-md/migration/from-react-native-navigation.md +9 -3
  193. package/docs-md/migration/from-react-navigation.md +2 -2
  194. package/docs-md/screen-ui/back-and-gestures.md +46 -2
  195. package/docs-md/screen-ui/bar-buttons.md +5 -5
  196. package/docs-md/screen-ui/search.md +1 -1
  197. package/docs-md/screen-ui/system-ui.md +17 -12
  198. package/docs-md/screen-ui/toolbar-and-fab.md +4 -2
  199. package/docs-md/screen-ui/top-bar.md +8 -4
  200. package/docs-md/start/installation.md +21 -3
  201. package/ios/Animations/ANNFrameDriver.h +55 -15
  202. package/ios/Animations/ANNFrameDriver.mm +216 -60
  203. package/ios/Animations/ANNTransitionAnimator.h +26 -5
  204. package/ios/Animations/ANNTransitionAnimator.mm +61 -13
  205. package/ios/Animations/ANNTransitionPlan.h +2 -2
  206. package/ios/Animations/ANNTransitionPlan.mm +10 -0
  207. package/ios/Animations/ANNTransitionWait.mm +6 -7
  208. package/ios/Animations/Elements/ANNElementFinder.h +57 -0
  209. package/ios/Animations/Elements/ANNElementFinder.mm +174 -2
  210. package/ios/Animations/Elements/ANNElementTransition.h +10 -8
  211. package/ios/Animations/Elements/ANNElementTransition.mm +19 -21
  212. package/ios/Animations/Elements/ANNSharedElementFlight.h +16 -11
  213. package/ios/Animations/Elements/ANNSharedElementFlight.mm +308 -69
  214. package/ios/Animations/Interpolators/ANNInterpolate.h +2 -30
  215. package/ios/Animations/Interpolators/ANNTransformParts.h +48 -0
  216. package/ios/Animations/Interpolators/ANNTransformParts.mm +507 -0
  217. package/ios/Animations/Interpolators/ANNViewTracks.h +9 -6
  218. package/ios/Animations/Interpolators/ANNViewTracks.mm +100 -30
  219. package/ios/CLAUDE.md +60 -24
  220. package/ios/CORE.md +44 -34
  221. package/ios/Contract/ANNCommandAnswer.h +13 -5
  222. package/ios/Contract/ANNCommandAnswer.mm +40 -32
  223. package/ios/Contract/ANNCommandContract.h +15 -0
  224. package/ios/Contract/ANNCommandContract.mm +78 -0
  225. package/ios/Contract/ANNCommandRunner.h +10 -9
  226. package/ios/Contract/ANNCommandRunner.mm +22 -28
  227. package/ios/Contract/ANNErrorTexts.h +6 -2
  228. package/ios/Contract/ANNErrorTexts.mm +18 -10
  229. package/ios/Contract/ANNLayoutNode.h +3 -3
  230. package/ios/Contract/ANNLayoutReader.h +3 -3
  231. package/ios/Core/ANNAppDelegate.mm +0 -2
  232. package/ios/Core/ANNAppearanceDispatcher.h +5 -4
  233. package/ios/Core/ANNAppearanceDispatcher.mm +12 -1
  234. package/ios/Core/ANNDeepLinkQueue.h +22 -2
  235. package/ios/Core/ANNDeepLinkQueue.mm +121 -14
  236. package/ios/Core/ANNErrorHandler.h +9 -4
  237. package/ios/Core/ANNErrorHandler.mm +20 -2
  238. package/ios/Core/ANNEventContract.h +246 -0
  239. package/ios/Core/ANNEventContract.mm +225 -0
  240. package/ios/Core/ANNEventEmitter.h +6 -2
  241. package/ios/Core/ANNEventEmitter.mm +117 -80
  242. package/ios/Core/ANNHinge.h +6 -0
  243. package/ios/Core/ANNHinge.mm +15 -4
  244. package/ios/Core/ANNJavaScriptCalls.h +33 -0
  245. package/ios/Core/ANNJavaScriptCalls.mm +52 -0
  246. package/ios/Core/ANNLayoutProtocol.h +5 -5
  247. package/ios/Core/ANNNavigationState.h +7 -5
  248. package/ios/Core/ANNNavigationState.mm +8 -7
  249. package/ios/Core/ANNNodeHelper.h +32 -12
  250. package/ios/Core/ANNNodeHelper.mm +100 -3
  251. package/ios/Core/ANNParking.h +5 -4
  252. package/ios/Core/ANNReloadCoordinator.mm +5 -12
  253. package/ios/Core/ANNRenderWait.h +20 -6
  254. package/ios/Core/ANNRenderWait.mm +143 -56
  255. package/ios/Core/ANNSceneDelegate.mm +25 -15
  256. package/ios/Core/ANNSystemUI.h +3 -2
  257. package/ios/Core/ANNSystemUI.mm +7 -0
  258. package/ios/Core/ANNUtils.h +7 -0
  259. package/ios/Core/ANNUtils.mm +10 -0
  260. package/ios/Core/ApexNavigation+Internal.h +1 -1
  261. package/ios/Core/ApexNavigation.mm +7 -6
  262. package/ios/Core/UIViewController+LayoutProtocol.h +9 -2
  263. package/ios/Core/UIViewController+LayoutProtocol.mm +8 -0
  264. package/ios/Layouts/Arrangement/ANNArrangementState.h +2 -17
  265. package/ios/Layouts/Arrangement/ANNArrangementState.mm +0 -38
  266. package/ios/Layouts/Arrangement/ANNArrangementViewController.mm +10 -8
  267. package/ios/Layouts/Modal/ANNModalCoordinator.h +1 -1
  268. package/ios/Layouts/Modal/ANNModalCoordinator.mm +57 -16
  269. package/ios/Layouts/Modal/ANNModalPresentation.h +8 -5
  270. package/ios/Layouts/Modal/ANNModalPresentation.mm +12 -12
  271. package/ios/Layouts/Modal/ANNSheetPresenter.mm +83 -1
  272. package/ios/Layouts/Overlay/ANNOverlayCoordinator.mm +2 -8
  273. package/ios/Layouts/Root/ANNRootCoordinator.mm +58 -19
  274. package/ios/Layouts/Root/ANNSplashViewController.h +5 -3
  275. package/ios/Layouts/Root/ANNSplashViewController.mm +147 -0
  276. package/ios/Layouts/Screen/ANNComponentPresenter.h +11 -3
  277. package/ios/Layouts/Screen/ANNComponentPresenter.mm +34 -6
  278. package/ios/Layouts/Screen/ANNComponentViewController.h +15 -13
  279. package/ios/Layouts/Screen/ANNComponentViewController.mm +130 -75
  280. package/ios/Layouts/Screen/ANNNativeScreenContext.mm +7 -5
  281. package/ios/Layouts/Screen/ANNPreviewInteraction.h +7 -4
  282. package/ios/Layouts/Screen/ANNPreviewInteraction.mm +72 -10
  283. package/ios/Layouts/Screen/ANNScreenEnvironment.h +63 -0
  284. package/ios/Layouts/Screen/ANNScreenEnvironment.mm +181 -0
  285. package/ios/Layouts/Screen/ANNScreenPlace.h +53 -0
  286. package/ios/Layouts/Screen/ANNScreenPlace.mm +205 -0
  287. package/ios/Layouts/Screen/ANNScreenRegions.h +3 -18
  288. package/ios/Layouts/Screen/ANNScreenRegions.mm +9 -44
  289. package/ios/Layouts/Screen/ANNScreenSafeArea.h +4 -9
  290. package/ios/Layouts/Screen/ANNScreenSafeArea.mm +14 -16
  291. package/ios/Layouts/Screen/ANNScreenSettling.h +32 -0
  292. package/ios/Layouts/Screen/ANNScreenSettling.mm +137 -0
  293. package/ios/Layouts/SideMenu/ANNSideMenuTypes.h +8 -0
  294. package/ios/Layouts/SideMenu/ANNSideMenuViewController.mm +83 -14
  295. package/ios/Layouts/SplitView/ANNSplitViewCommands.h +3 -2
  296. package/ios/Layouts/SplitView/ANNSplitViewCommands.mm +105 -39
  297. package/ios/Layouts/SplitView/ANNSplitViewController.mm +7 -8
  298. package/ios/Layouts/Stack/ANNPreviewPush.h +7 -6
  299. package/ios/Layouts/Stack/ANNPreviewPush.mm +142 -27
  300. package/ios/Layouts/Stack/ANNStackAnimatingDelegate.h +11 -2
  301. package/ios/Layouts/Stack/ANNStackAnimatingDelegate.mm +14 -7
  302. package/ios/Layouts/Stack/ANNStackCommands.mm +1 -0
  303. package/ios/Layouts/Stack/ANNStackController.h +8 -0
  304. package/ios/Layouts/Stack/ANNStackController.mm +184 -16
  305. package/ios/Layouts/Stack/ANNStackQueue.h +5 -2
  306. package/ios/Layouts/Stack/ANNStackQueue.mm +56 -43
  307. package/ios/Layouts/Stack/ANNSwipePopInteraction.h +26 -0
  308. package/ios/Layouts/Stack/ANNSwipePopInteraction.mm +185 -0
  309. package/ios/Layouts/Stack/InteractivePopGestureDelegate.mm +28 -4
  310. package/ios/Layouts/Stack/UINavigationController+ANNCommands.h +4 -2
  311. package/ios/Layouts/Stack/UINavigationController+ANNCommands.mm +2 -3
  312. package/ios/Layouts/Tabs/ANNBottomTabItemBuilder.h +4 -0
  313. package/ios/Layouts/Tabs/ANNBottomTabItemBuilder.mm +11 -0
  314. package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.h +12 -1
  315. package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.mm +23 -0
  316. package/ios/Layouts/Tabs/ANNBottomTabsController.h +3 -0
  317. package/ios/Layouts/Tabs/ANNBottomTabsController.mm +237 -57
  318. package/ios/Layouts/Tabs/ANNBottomTabsCustomRow.mm +8 -3
  319. package/ios/Layouts/Tabs/ANNBottomTabsPresenter.h +6 -2
  320. package/ios/Layouts/Tabs/ANNBottomTabsPresenter.mm +232 -43
  321. package/ios/Layouts/Tabs/ANNTabsDesign.h +6 -5
  322. package/ios/Layouts/Tabs/ANNTabsDesign.mm +9 -1
  323. package/ios/Layouts/Tabs/UITabBar+utils.h +5 -5
  324. package/ios/Layouts/Tabs/UITabBar+utils.mm +32 -13
  325. package/ios/Options/ANNAnimationOptions.h +2 -1
  326. package/ios/Options/ANNAnimationOptions.mm +1 -1
  327. package/ios/Options/ANNBottomTabsOptions.h +2 -0
  328. package/ios/Options/ANNBottomTabsOptions.mm +1 -0
  329. package/ios/Options/ANNOptions.h +25 -0
  330. package/ios/Options/ANNOptions.mm +157 -1
  331. package/ios/Options/ANNOptionsCache.h +7 -6
  332. package/ios/Options/ANNOptionsReader.mm +108 -0
  333. package/ios/Options/ANNSearchBarOptions.h +4 -3
  334. package/ios/Options/ANNSheetOptions.h +4 -1
  335. package/ios/Options/ANNSideMenuOptions.h +2 -0
  336. package/ios/Options/ANNSideMenuOptions.mm +2 -0
  337. package/ios/Options/ANNStackPopAnimationOptions.h +13 -0
  338. package/ios/Options/ANNStackPopAnimationOptions.mm +11 -0
  339. package/ios/Options/ANNUserChoice.h +57 -0
  340. package/ios/Options/ANNUserChoice.mm +44 -0
  341. package/ios/Options/Params/ANNImageSource.h +61 -0
  342. package/ios/Options/Params/ANNImageSource.mm +101 -0
  343. package/ios/Options/Params/ANNOptionImages.h +37 -0
  344. package/ios/Options/Params/ANNOptionImages.mm +284 -0
  345. package/ios/Options/Params/ANNParam.h +15 -0
  346. package/ios/Options/Params/ANNParam.mm +61 -0
  347. package/ios/Options/Params/Color.h +3 -0
  348. package/ios/Options/Params/Color.mm +21 -0
  349. package/ios/Options/Params/ColorParser.h +4 -3
  350. package/ios/Options/Params/ColorParser.mm +22 -4
  351. package/ios/Options/Params/Image.h +15 -2
  352. package/ios/Options/Params/Image.mm +35 -2
  353. package/ios/Options/Params/ImageParser.h +5 -5
  354. package/ios/Options/Params/ImageParser.mm +28 -46
  355. package/ios/Public/ApexNavigation/ANNSceneDelegate.h +3 -0
  356. package/ios/Public/ApexNavigation/ApexNavigation.h +1 -1
  357. package/ios/RECIPES.md +13 -6
  358. package/ios/React/ANNReactView.mm +6 -25
  359. package/ios/React/ANNSafeAreaViewComponentView.mm +28 -17
  360. package/ios/React/ANNSurfaceHostingView.h +14 -0
  361. package/ios/React/ANNSurfaceHostingView.mm +144 -1
  362. package/ios/React/Slots/ANNSlotComponentView.mm +24 -17
  363. package/ios/React/Slots/ANNSlotContainers.h +14 -6
  364. package/ios/React/Slots/ANNSlotContainers.mm +75 -2
  365. package/ios/React/Slots/ANNSlotHost.mm +1 -3
  366. package/ios/React/Slots/ANNSlotScreenView.mm +8 -2
  367. package/ios/TopBar/ANNBackButtonPresenter.mm +6 -5
  368. package/ios/TopBar/ANNBarAppearance.h +2 -1
  369. package/ios/TopBar/ANNBarAppearance.mm +111 -30
  370. package/ios/TopBar/ANNBarBackgroundComponent.mm +16 -0
  371. package/ios/TopBar/ANNBarButtonComponentView.h +4 -4
  372. package/ios/TopBar/ANNBarButtonComponentView.mm +1 -1
  373. package/ios/TopBar/ANNBarButtons.h +14 -8
  374. package/ios/TopBar/ANNBarButtons.mm +397 -80
  375. package/ios/TopBar/ANNIconButtonImage.h +1 -0
  376. package/ios/TopBar/ANNIconButtonImage.mm +34 -1
  377. package/ios/TopBar/ANNLargeTitlePresenter.h +13 -0
  378. package/ios/TopBar/ANNLargeTitlePresenter.mm +50 -7
  379. package/ios/TopBar/ANNMainList.h +3 -0
  380. package/ios/TopBar/ANNMainList.mm +4 -0
  381. package/ios/TopBar/ANNScrollEdgeEffects.h +22 -6
  382. package/ios/TopBar/ANNScrollEdgeEffects.mm +123 -16
  383. package/ios/TopBar/ANNSearchPresenter.mm +172 -21
  384. package/ios/TopBar/ANNSearchResultsViewController.mm +29 -6
  385. package/ios/TopBar/ANNTopBarPresenter.h +8 -2
  386. package/ios/TopBar/ANNTopBarPresenter.mm +155 -33
  387. package/ios/TurboModules/ANNTurboEventEmitter.mm +4 -35
  388. package/ios/TurboModules/ANNTurboModule.mm +104 -33
  389. package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.cpp +20 -0
  390. package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.h +5 -14
  391. package/lib/module/ARCHITECTURE.md +40 -27
  392. package/lib/module/adapters/NativeANNTurboModule.js.map +1 -1
  393. package/lib/module/api/app/AppRegistry.js +14 -2
  394. package/lib/module/api/app/AppRegistry.js.map +1 -1
  395. package/lib/module/api/app/createNavigation.js +190 -66
  396. package/lib/module/api/app/createNavigation.js.map +1 -1
  397. package/lib/module/api/commands/commands.js +54 -6
  398. package/lib/module/api/commands/commands.js.map +1 -1
  399. package/lib/module/api/events/navigationEvents.js +6 -2
  400. package/lib/module/api/events/navigationEvents.js.map +1 -1
  401. package/lib/module/api/hooks/useNavigation.js +8 -3
  402. package/lib/module/api/hooks/useNavigation.js.map +1 -1
  403. package/lib/module/api/hooks/useSafeAreaInsets.js +4 -3
  404. package/lib/module/api/hooks/useSafeAreaInsets.js.map +1 -1
  405. package/lib/module/api/linking/dispatchedLinks.js +23 -0
  406. package/lib/module/api/linking/dispatchedLinks.js.map +1 -0
  407. package/lib/module/api/linking/linking.js +11 -0
  408. package/lib/module/api/linking/linking.js.map +1 -1
  409. package/lib/module/api/navigation.js.map +1 -1
  410. package/lib/module/api/options/OptionsChain.js +2 -2
  411. package/lib/module/api/screens/defineScreen.js +45 -3
  412. package/lib/module/api/screens/defineScreen.js.map +1 -1
  413. package/lib/module/api/screens/nativeScreens.js +31 -6
  414. package/lib/module/api/screens/nativeScreens.js.map +1 -1
  415. package/lib/module/api/screens/registerScreens.js +193 -35
  416. package/lib/module/api/screens/registerScreens.js.map +1 -1
  417. package/lib/module/api/theme/theme.js +5 -0
  418. package/lib/module/api/theme/theme.js.map +1 -1
  419. package/lib/module/engine/commands.js +51 -9
  420. package/lib/module/engine/commands.js.map +1 -1
  421. package/lib/module/engine/layout.js +20 -11
  422. package/lib/module/engine/layout.js.map +1 -1
  423. package/lib/module/engine/nativeScreens.js +9 -0
  424. package/lib/module/engine/nativeScreens.js.map +1 -1
  425. package/lib/module/engine/options.js +49 -15
  426. package/lib/module/engine/options.js.map +1 -1
  427. package/lib/module/engine/optionsChange.js +102 -0
  428. package/lib/module/engine/optionsChange.js.map +1 -0
  429. package/lib/module/engine/places.js +52 -7
  430. package/lib/module/engine/places.js.map +1 -1
  431. package/lib/module/engine/props.js +30 -1
  432. package/lib/module/engine/props.js.map +1 -1
  433. package/lib/module/engine/refresh.js +85 -0
  434. package/lib/module/engine/refresh.js.map +1 -0
  435. package/lib/module/engine/rememberedOptions.js +61 -1
  436. package/lib/module/engine/rememberedOptions.js.map +1 -1
  437. package/lib/module/engine/screens.js +77 -16
  438. package/lib/module/engine/screens.js.map +1 -1
  439. package/lib/module/interfaces/contract/commands.json +101 -0
  440. package/lib/module/interfaces/contract/errors.json +275 -0
  441. package/lib/typescript/adapters/NativeANNTurboModule.d.ts +12 -2
  442. package/lib/typescript/adapters/NativeANNTurboModule.d.ts.map +1 -1
  443. package/lib/typescript/api/app/AppRegistry.d.ts.map +1 -1
  444. package/lib/typescript/api/app/createNavigation.d.ts +8 -3
  445. package/lib/typescript/api/app/createNavigation.d.ts.map +1 -1
  446. package/lib/typescript/api/commands/commands.d.ts.map +1 -1
  447. package/lib/typescript/api/commands/presentation.d.ts +4 -3
  448. package/lib/typescript/api/commands/presentation.d.ts.map +1 -1
  449. package/lib/typescript/api/events/navigationEvents.d.ts +3 -3
  450. package/lib/typescript/api/events/navigationEvents.d.ts.map +1 -1
  451. package/lib/typescript/api/hooks/useNavigation.d.ts +1 -1
  452. package/lib/typescript/api/hooks/useNavigation.d.ts.map +1 -1
  453. package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts +4 -3
  454. package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts.map +1 -1
  455. package/lib/typescript/api/index.d.ts +1 -1
  456. package/lib/typescript/api/index.d.ts.map +1 -1
  457. package/lib/typescript/api/linking/dispatchedLinks.d.ts +7 -0
  458. package/lib/typescript/api/linking/dispatchedLinks.d.ts.map +1 -0
  459. package/lib/typescript/api/linking/linking.d.ts +8 -0
  460. package/lib/typescript/api/linking/linking.d.ts.map +1 -1
  461. package/lib/typescript/api/navigation.d.ts +4 -1
  462. package/lib/typescript/api/navigation.d.ts.map +1 -1
  463. package/lib/typescript/api/options/OptionsChain.d.ts +2 -2
  464. package/lib/typescript/api/screens/defineScreen.d.ts +23 -4
  465. package/lib/typescript/api/screens/defineScreen.d.ts.map +1 -1
  466. package/lib/typescript/api/screens/nativeScreens.d.ts +8 -1
  467. package/lib/typescript/api/screens/nativeScreens.d.ts.map +1 -1
  468. package/lib/typescript/api/screens/registerScreens.d.ts.map +1 -1
  469. package/lib/typescript/api/theme/theme.d.ts +2 -0
  470. package/lib/typescript/api/theme/theme.d.ts.map +1 -1
  471. package/lib/typescript/engine/commands.d.ts +5 -0
  472. package/lib/typescript/engine/commands.d.ts.map +1 -1
  473. package/lib/typescript/engine/layout.d.ts.map +1 -1
  474. package/lib/typescript/engine/nativeScreens.d.ts +5 -0
  475. package/lib/typescript/engine/nativeScreens.d.ts.map +1 -1
  476. package/lib/typescript/engine/options.d.ts +5 -2
  477. package/lib/typescript/engine/options.d.ts.map +1 -1
  478. package/lib/typescript/engine/optionsChange.d.ts +28 -0
  479. package/lib/typescript/engine/optionsChange.d.ts.map +1 -0
  480. package/lib/typescript/engine/places.d.ts +7 -2
  481. package/lib/typescript/engine/places.d.ts.map +1 -1
  482. package/lib/typescript/engine/props.d.ts +8 -1
  483. package/lib/typescript/engine/props.d.ts.map +1 -1
  484. package/lib/typescript/engine/refresh.d.ts +35 -0
  485. package/lib/typescript/engine/refresh.d.ts.map +1 -0
  486. package/lib/typescript/engine/rememberedOptions.d.ts +13 -0
  487. package/lib/typescript/engine/rememberedOptions.d.ts.map +1 -1
  488. package/lib/typescript/engine/screens.d.ts +27 -6
  489. package/lib/typescript/engine/screens.d.ts.map +1 -1
  490. package/lib/typescript/interfaces/ComponentEvents.d.ts +4 -4
  491. package/lib/typescript/interfaces/ComponentEvents.d.ts.map +1 -1
  492. package/lib/typescript/interfaces/Events.d.ts +28 -10
  493. package/lib/typescript/interfaces/Events.d.ts.map +1 -1
  494. package/lib/typescript/interfaces/Options.d.ts +1 -1
  495. package/lib/typescript/interfaces/Options.d.ts.map +1 -1
  496. package/lib/typescript/interfaces/options/animations.d.ts +80 -22
  497. package/lib/typescript/interfaces/options/animations.d.ts.map +1 -1
  498. package/lib/typescript/interfaces/options/bottomTabs.d.ts +21 -7
  499. package/lib/typescript/interfaces/options/bottomTabs.d.ts.map +1 -1
  500. package/lib/typescript/interfaces/options/buttons.d.ts +23 -15
  501. package/lib/typescript/interfaces/options/buttons.d.ts.map +1 -1
  502. package/lib/typescript/interfaces/options/modals.d.ts +34 -26
  503. package/lib/typescript/interfaces/options/modals.d.ts.map +1 -1
  504. package/lib/typescript/interfaces/options/sideMenu.d.ts +23 -6
  505. package/lib/typescript/interfaces/options/sideMenu.d.ts.map +1 -1
  506. package/lib/typescript/interfaces/options/stack.d.ts +17 -3
  507. package/lib/typescript/interfaces/options/stack.d.ts.map +1 -1
  508. package/lib/typescript/interfaces/options/system.d.ts +18 -11
  509. package/lib/typescript/interfaces/options/system.d.ts.map +1 -1
  510. package/lib/typescript/interfaces/options/toolbar.d.ts +2 -2
  511. package/lib/typescript/interfaces/options/topBar.d.ts +68 -38
  512. package/lib/typescript/interfaces/options/topBar.d.ts.map +1 -1
  513. package/metro/acceptPlugin.js +57 -0
  514. package/metro/babelTransformer.js +45 -0
  515. package/metro/index.js +36 -0
  516. package/package.json +4 -25
  517. package/src/ARCHITECTURE.md +40 -27
  518. package/src/adapters/NativeANNTurboModule.ts +12 -2
  519. package/src/api/app/AppRegistry.ts +16 -2
  520. package/src/api/app/createNavigation.ts +203 -69
  521. package/src/api/commands/commands.ts +48 -7
  522. package/src/api/commands/presentation.ts +4 -3
  523. package/src/api/events/navigationEvents.ts +10 -4
  524. package/src/api/hooks/useNavigation.ts +9 -4
  525. package/src/api/hooks/useSafeAreaInsets.ts +4 -3
  526. package/src/api/index.ts +1 -0
  527. package/src/api/linking/dispatchedLinks.ts +18 -0
  528. package/src/api/linking/linking.ts +22 -1
  529. package/src/api/navigation.ts +4 -1
  530. package/src/api/options/OptionsChain.ts +2 -2
  531. package/src/api/screens/defineScreen.ts +49 -5
  532. package/src/api/screens/nativeScreens.ts +40 -4
  533. package/src/api/screens/registerScreens.tsx +185 -42
  534. package/src/api/theme/theme.ts +5 -0
  535. package/src/engine/commands.ts +70 -13
  536. package/src/engine/layout.ts +27 -11
  537. package/src/engine/nativeScreens.ts +10 -1
  538. package/src/engine/options.ts +45 -19
  539. package/src/engine/optionsChange.ts +107 -0
  540. package/src/engine/places.ts +65 -7
  541. package/src/engine/props.ts +30 -1
  542. package/src/engine/refresh.ts +97 -0
  543. package/src/engine/rememberedOptions.ts +74 -1
  544. package/src/engine/screens.tsx +76 -21
  545. package/src/interfaces/ComponentEvents.ts +4 -4
  546. package/src/interfaces/Events.ts +29 -10
  547. package/src/interfaces/Options.ts +1 -0
  548. package/src/interfaces/contract/commands.json +101 -0
  549. package/src/interfaces/contract/errors.json +275 -0
  550. package/src/interfaces/options/animations.ts +81 -22
  551. package/src/interfaces/options/bottomTabs.ts +21 -7
  552. package/src/interfaces/options/buttons.ts +23 -15
  553. package/src/interfaces/options/modals.ts +34 -26
  554. package/src/interfaces/options/sideMenu.ts +24 -6
  555. package/src/interfaces/options/stack.ts +17 -3
  556. package/src/interfaces/options/system.ts +18 -11
  557. package/src/interfaces/options/toolbar.ts +2 -2
  558. package/src/interfaces/options/topBar.ts +68 -38
  559. package/android/src/main/java/dev/apexnative/navigation/react/ArrangementStates.kt +0 -41
  560. package/android/src/main/java/dev/apexnative/navigation/react/ScreenInsets.kt +0 -69
  561. package/android/src/main/java/dev/apexnative/navigation/react/events/NavigationStateReporter.kt +0 -62
  562. package/android/src/main/java/dev/apexnative/navigation/react/events/StateHold.kt +0 -62
  563. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowPlacer.kt +0 -223
  564. package/android/src/main/java/dev/apexnative/navigation/views/element/ElementStub.kt +0 -31
  565. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMatrixAnimator.kt +0 -138
  566. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PlainViewAnimator.kt +0 -88
  567. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PropertyAnimatorCreator.kt +0 -33
  568. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ReactImageAnimator.kt +0 -66
  569. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextChangeAnimator.kt +0 -179
  570. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewChangeAnimator.kt +0 -139
  571. package/ios/Layouts/Screen/ANNScreenInsets.h +0 -30
  572. package/ios/Layouts/Screen/ANNScreenInsets.mm +0 -68
  573. package/ios/Layouts/Tabs/ANNTabsPreloadWindow.h +0 -27
  574. package/ios/Layouts/Tabs/ANNTabsPreloadWindow.mm +0 -55
@@ -8,11 +8,13 @@
8
8
 
9
9
  using namespace facebook::react;
10
10
 
11
+ @interface ANNSlotComponentView () <ANNSlotView>
12
+ @end
13
+
11
14
  @implementation ANNSlotComponentView {
12
15
  // The React children live here. It waits hidden inside the slot, then moves into the container.
13
16
  ANNSlotContentView *_contentView;
14
17
  ANNSlotShadowNode::ConcreteState::Shared _state;
15
- BOOL _observing;
16
18
  // The layout that measures the content was asked for once.
17
19
  BOOL _measureAsked;
18
20
  }
@@ -33,19 +35,8 @@ using namespace facebook::react;
33
35
  return self;
34
36
  }
35
37
 
36
- - (void)dealloc {
37
- [NSNotificationCenter.defaultCenter removeObserver:self];
38
- }
39
-
40
38
  - (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &)oldProps {
41
39
  [super updateProps:props oldProps:oldProps];
42
- if (!_observing) {
43
- _observing = YES;
44
- [NSNotificationCenter.defaultCenter addObserver:self
45
- selector:@selector(containerDidChange:)
46
- name:ANNSlotContainerDidChangeNotification
47
- object:nil];
48
- }
49
40
  [self attachContent];
50
41
  }
51
42
 
@@ -54,13 +45,23 @@ using namespace facebook::react;
54
45
  [self attachContent];
55
46
  }
56
47
 
57
- - (void)containerDidChange:(NSNotification *)notification {
58
- if ([notification.object isEqual:self.nativeId]) {
48
+ #pragma mark - ANNSlotView
49
+
50
+ - (void)slotContainerDidChange:(NSString *)slotId {
51
+ if ([slotId isEqualToString:self.nativeId]) {
59
52
  [self attachContent];
60
53
  }
61
54
  }
62
55
 
56
+ #pragma mark - Content
57
+
63
58
  - (void)attachContent {
59
+ // The view hears the changes of the container under the slot id it has now, and no other.
60
+ if (self.nativeId != nil) {
61
+ [ANNSlotContainers registerSlotView:self forSlotId:self.nativeId];
62
+ } else {
63
+ [ANNSlotContainers unregisterSlotView:self];
64
+ }
64
65
  UIView *container = self.nativeId ? [ANNSlotContainers containerForSlotId:self.nativeId] : nil;
65
66
  UIView *target = container ?: self;
66
67
  if (_contentView.superview != target) {
@@ -108,15 +109,21 @@ using namespace facebook::react;
108
109
  return nil;
109
110
  }
110
111
 
111
- // A recycled slot waits for another screen: it stops listening and drops the old screen's state.
112
+ // A recycled slot waits for another screen: it leaves its slot id and drops the old screen's state. Its new props put
113
+ // it under the new id.
112
114
  - (void)prepareForRecycle {
113
115
  [super prepareForRecycle];
114
- [NSNotificationCenter.defaultCenter removeObserver:self];
115
- _observing = NO;
116
+ [ANNSlotContainers unregisterSlotView:self];
116
117
  _measureAsked = NO;
117
118
  _state.reset();
118
119
  [_contentView removeFromSuperview];
119
120
  _contentView.hidden = YES;
120
121
  }
121
122
 
123
+ // An unmounted slot that Fabric doesn't keep for reuse leaves its slot id too.
124
+ - (void)invalidate {
125
+ [super invalidate];
126
+ [ANNSlotContainers unregisterSlotView:self];
127
+ }
128
+
122
129
  @end
@@ -2,9 +2,6 @@
2
2
 
3
3
  NS_ASSUME_NONNULL_BEGIN
4
4
 
5
- /// Posted when the container of a slot appears or changes its size; the object is the slot id.
6
- extern NSNotificationName const ANNSlotContainerDidChangeNotification;
7
-
8
5
  /// A component named with this prefix is a screen of the app's one React tree: it has no React surface of its own,
9
6
  /// and the slot of the tree with its componentId shows it. Events and the state give its name without the prefix.
10
7
  extern NSString *const ANNSlotPrefix;
@@ -17,8 +14,14 @@ NSString *ANNComponentNameWithoutSlotPrefix(NSString *name);
17
14
  - (void)slotContentDidMount;
18
15
  @end
19
16
 
20
- /// The native containers the slots of the app's React tree show their children in, by slot id. A destroyed
21
- /// container drops out on its own.
17
+ /// A slot view of the app's React tree: it hears when the container of its slot id appears, goes or changes its size.
18
+ @protocol ANNSlotView <NSObject>
19
+ - (void)slotContainerDidChange:(NSString *)slotId;
20
+ @end
21
+
22
+ /// The native containers the slots of the app's React tree show their children in, by slot id, and the slot views by
23
+ /// the same id: a change of a container goes straight to the views of its id. A destroyed container and a deallocated
24
+ /// view drop out on their own. Main queue only.
22
25
  @interface ANNSlotContainers : NSObject
23
26
 
24
27
  + (void)setContainer:(UIView *)container forSlotId:(NSString *)slotId;
@@ -26,9 +29,14 @@ NSString *ANNComponentNameWithoutSlotPrefix(NSString *name);
26
29
  /// The container goes: its slot takes its content back.
27
30
  + (void)removeContainerForSlotId:(NSString *)slotId;
28
31
 
29
- /// The container of a slot appeared or changed its size.
32
+ /// The container of a slot appeared or changed its size: the slot views under its id, and only they, hear it.
30
33
  + (void)containerDidChange:(NSString *)slotId;
31
34
 
35
+ /// The slot view goes under its slot id, and out from under the id it had. Held weakly.
36
+ + (void)registerSlotView:(id<ANNSlotView>)view forSlotId:(NSString *)slotId;
37
+ /// The slot view unmounted or lost its slot id: no change of a container reaches it.
38
+ + (void)unregisterSlotView:(id<ANNSlotView>)view;
39
+
32
40
  @end
33
41
 
34
42
  NS_ASSUME_NONNULL_END
@@ -1,6 +1,6 @@
1
1
  #import "ANNSlotContainers.h"
2
+ #import "ANNAssert.h"
2
3
 
3
- NSNotificationName const ANNSlotContainerDidChangeNotification = @"ANNSlotContainerDidChange";
4
4
  NSString *const ANNSlotPrefix = @"slot:";
5
5
 
6
6
  NSString *ANNComponentNameWithoutSlotPrefix(NSString *name) {
@@ -32,8 +32,81 @@ NSString *ANNComponentNameWithoutSlotPrefix(NSString *name) {
32
32
  [self containerDidChange:slotId];
33
33
  }
34
34
 
35
+ // The slot views by slot id, weakly, in the order they came. Two live views under one id both stay and both hear
36
+ // the change, in that order, as every view with the id did when the change went to all of them.
37
+ + (NSMutableDictionary<NSString *, NSPointerArray *> *)slotViews {
38
+ static NSMutableDictionary *slotViews;
39
+ static dispatch_once_t once;
40
+ dispatch_once(&once, ^{
41
+ slotViews = [NSMutableDictionary dictionary];
42
+ });
43
+ return slotViews;
44
+ }
45
+
46
+ // The id each slot view is under, so a view is under one id at a time.
47
+ + (NSMapTable<id<ANNSlotView>, NSString *> *)slotIds {
48
+ static NSMapTable *slotIds;
49
+ static dispatch_once_t once;
50
+ dispatch_once(&once, ^{
51
+ slotIds = [[NSMapTable alloc]
52
+ initWithKeyOptions:NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPointerPersonality
53
+ valueOptions:NSPointerFunctionsStrongMemory
54
+ capacity:0];
55
+ });
56
+ return slotIds;
57
+ }
58
+
35
59
  + (void)containerDidChange:(NSString *)slotId {
36
- [NSNotificationCenter.defaultCenter postNotificationName:ANNSlotContainerDidChangeNotification object:slotId];
60
+ ANNAssertMainQueue();
61
+ // A copy: a view may register or leave while it hears the change.
62
+ for (id<ANNSlotView> view in [self slotViewsForSlotId:slotId]) {
63
+ [view slotContainerDidChange:slotId];
64
+ }
65
+ }
66
+
67
+ + (void)registerSlotView:(id<ANNSlotView>)view forSlotId:(NSString *)slotId {
68
+ ANNAssertMainQueue();
69
+ if ([[self.slotIds objectForKey:view] isEqualToString:slotId]) {
70
+ return;
71
+ }
72
+ [self unregisterSlotView:view];
73
+ [self.slotIds setObject:slotId forKey:view];
74
+ NSPointerArray *views = self.slotViews[slotId];
75
+ if (views == nil) {
76
+ views = [NSPointerArray weakObjectsPointerArray];
77
+ self.slotViews[slotId] = views;
78
+ }
79
+ [views addPointer:(__bridge void *)view];
80
+ }
81
+
82
+ + (void)unregisterSlotView:(id<ANNSlotView>)view {
83
+ ANNAssertMainQueue();
84
+ NSString *slotId = [self.slotIds objectForKey:view];
85
+ if (slotId == nil) {
86
+ return;
87
+ }
88
+ [self.slotIds removeObjectForKey:view];
89
+ [self pruneSlotId:slotId dropping:view];
90
+ }
91
+
92
+ + (NSArray<id<ANNSlotView>> *)slotViewsForSlotId:(NSString *)slotId {
93
+ [self pruneSlotId:slotId dropping:nil];
94
+ return self.slotViews[slotId].allObjects ?: @[];
95
+ }
96
+
97
+ // Drops the deallocated views under the id and `view`; an id with no views left goes. By hand rather than with
98
+ // `compact`, which keeps the nil entries of a weak pointer array.
99
+ + (void)pruneSlotId:(NSString *)slotId dropping:(nullable id<ANNSlotView>)view {
100
+ NSPointerArray *views = self.slotViews[slotId];
101
+ for (NSInteger index = (NSInteger)views.count - 1; index >= 0; index--) {
102
+ void *pointer = [views pointerAtIndex:(NSUInteger)index];
103
+ if (pointer == NULL || pointer == (__bridge void *)view) {
104
+ [views removePointerAtIndex:(NSUInteger)index];
105
+ }
106
+ }
107
+ if (views != nil && views.count == 0) {
108
+ [self.slotViews removeObjectForKey:slotId];
109
+ }
37
110
  }
38
111
 
39
112
  @end
@@ -35,9 +35,7 @@ static RCTFabricSurface *ANNSlotHostSurface;
35
35
 
36
36
  // Hidden and without a root view controller: it takes no touches and has no say in the orientation or the status
37
37
  // bar (a visible window above the app does). The tree still mounts; the slots move their content into screens.
38
- UIWindowScene *scene = ANNUtils.mainWindow.windowScene;
39
- UIWindow *window = scene ? [[UIWindow alloc] initWithWindowScene:scene]
40
- : [[UIWindow alloc] initWithFrame:ANNUtils.mainScreen.bounds];
38
+ UIWindow *window = [ANNUtils makeWindowOfClass:UIWindow.class];
41
39
  surfaceView.frame = window.bounds;
42
40
  [window addSubview:surfaceView];
43
41
  window.hidden = YES;
@@ -3,6 +3,7 @@
3
3
  #import "ANNScreenAppearance.h"
4
4
  #import "ANNScreenReadiness.h"
5
5
  #import "ANNSlotHost.h"
6
+ #import "ANNSurfaceHostingView.h"
6
7
  #import "../../cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.h"
7
8
  #import <React/RCTConstants.h>
8
9
  #import <React/RCTSurfacePresenter.h>
@@ -62,12 +63,17 @@
62
63
  return nil;
63
64
  }
64
65
 
65
- // The slot lays its content out at this size: every change goes to it (rotation, a sheet detent, the bars).
66
+ // The slot lays its content out at this size: every change goes to it (rotation, a sheet detent, the bars). Its state
67
+ // update mounts synchronously, here: during a rotation the content takes its new layout at once, as a screen's surface
68
+ // does (`+[ANNSurfaceHostingView layOutContent:]`).
66
69
  - (void)layoutSubviews {
67
70
  [super layoutSubviews];
68
71
  if (!CGSizeEqualToSize(self.bounds.size, _lastSize)) {
69
72
  _lastSize = self.bounds.size;
70
- [ANNSlotContainers containerDidChange:_componentId];
73
+ NSString *componentId = _componentId;
74
+ [ANNSurfaceHostingView layOutContent:^{
75
+ [ANNSlotContainers containerDidChange:componentId];
76
+ }];
71
77
  }
72
78
  }
73
79
 
@@ -2,6 +2,7 @@
2
2
  #import "ANNExternalViewController.h"
3
3
  #import "ANNIconButtonImage.h"
4
4
  #import "ANNStackController.h"
5
+ #import "ANNTabsDesign.h"
5
6
  #import <objc/runtime.h>
6
7
 
7
8
  // The item below that the core configured: what it set may go again.
@@ -141,10 +142,8 @@ static const void *ANNBackButtonConfiguredKey = &ANNBackButtonConfiguredKey;
141
142
  ANNBackBarButtonItem *item = [ANNBackBarButtonItem new];
142
143
  item.allowsMenu = [backButton.enableMenu withDefault:YES];
143
144
  item.style = UIBarButtonItemStylePlain;
144
- BOOL before26 = YES;
145
- if (@available(iOS 26.0, *)) {
146
- before26 = NO;
147
- }
145
+ // The compatibility mode of iOS 26 shows the title below too, as the design before it.
146
+ BOOL before26 = !ANNTabsDesign.isGlass;
148
147
  item.title = title ?: (before26 ? belowTitle : nil);
149
148
  UIColor *background = [self iconBackgroundColorOf:backButton];
150
149
  if (background) {
@@ -165,7 +164,9 @@ static const void *ANNBackButtonConfiguredKey = &ANNBackButtonConfiguredKey;
165
164
  [iconBackground.height withDefault:0])
166
165
  insets:UIEdgeInsetsZero];
167
166
  if (@available(iOS 26.0, *)) {
168
- item.hidesSharedBackground = [backButton.hideSharedBackground withDefault:YES];
167
+ if (ANNTabsDesign.isGlass) {
168
+ item.hidesSharedBackground = [backButton.hideSharedBackground withDefault:YES];
169
+ }
169
170
  }
170
171
  }
171
172
  return item;
@@ -45,7 +45,8 @@ typedef struct {
45
45
  /// (a clear color is a clear bar). The one rule for the bar, its color in the list and the top edge effect.
46
46
  + (nullable UIColor *)solidColorOf:(nullable Color *)color traits:(UITraitCollection *)traits;
47
47
 
48
- /// A 1×1 image of `color` resolved for `traits`.
48
+ /// A 1×1 image of `color` resolved for `traits`, with a variant for each style: the same image for the same resolved
49
+ /// colors, so a look filled again equals the one before (as the back button's tinted arrow).
49
50
  + (UIImage *)imageOfColor:(UIColor *)color traits:(UITraitCollection *)traits;
50
51
 
51
52
  @end
@@ -1,5 +1,12 @@
1
1
  #import "ANNBarAppearance.h"
2
2
  #import "ANNBackButtonPresenter.h"
3
+ #import "ANNTabsDesign.h"
4
+ #import <objc/runtime.h>
5
+
6
+ // The icon an indicator was tinted from: an entry found by the icon's address counts only for that icon. An indicator
7
+ // that is the icon itself (already an original image) carries nothing: the icon must not hold itself, and it may be
8
+ // the image the options' cache keeps.
9
+ static const void *ANNIndicatorIconKey = &ANNIndicatorIconKey;
3
10
 
4
11
  // UIKit's fonts of the places the options build over: the title of the row, the large title, the text of the back
5
12
  // button.
@@ -28,6 +35,27 @@ static BOOL ANNIsClear(UIColor *color, UITraitCollection *traits) {
28
35
  return CGColorGetAlpha([color resolvedColorWithTraitCollection:traits].CGColor) == 0;
29
36
  }
30
37
 
38
+ // The images the looks are made of, by what they are drawn from, so a look filled again from the same options is
39
+ // equal to the one before (UIKit compares appearances by value, images by identity) and nothing is set again. Main
40
+ // queue; a memory warning empties it.
41
+ static NSCache<id, UIImage *> *ANNLookImages(void) {
42
+ static NSCache<id, UIImage *> *images;
43
+ static dispatch_once_t once;
44
+ dispatch_once(&once, ^{
45
+ images = [NSCache new];
46
+ images.countLimit = 64;
47
+ });
48
+ return images;
49
+ }
50
+
51
+ // A color of the options as a key: a pair by its sides (its dynamic color is made anew), else its value.
52
+ static NSArray *ANNColorKeyOf(Color *color) {
53
+ if (color.light || color.dark) {
54
+ return @[ color.light ?: NSNull.null, color.dark ?: NSNull.null ];
55
+ }
56
+ return @[ color.value ?: NSNull.null ];
57
+ }
58
+
31
59
  static NSDictionary<NSAttributedStringKey, id> *ANNTextAttributes(ANNFontOptions *font,
32
60
  Color *color,
33
61
  UIFont *placeFont) {
@@ -104,16 +132,14 @@ static NSDictionary<NSAttributedStringKey, id> *ANNTextAttributes(ANNFontOptions
104
132
  return resolved && !ANNIsClear(resolved, traits) ? resolved : nil;
105
133
  }
106
134
 
135
+ // The glass bar is translucent by default; the design before iOS 26 (and its compatibility mode) opaque.
107
136
  + (BOOL)translucentByDefault {
108
- if (@available(iOS 26.0, *)) {
109
- return YES;
110
- }
111
- return NO;
137
+ return ANNTabsDesign.isGlass;
112
138
  }
113
139
 
114
- // `color` beats `blur` and `translucent`; a clear color is a clear bar. On iOS 26 a color is a solid bar: a clear base
115
- // with the color and a 1×1 image of it, without the system effect. `blur` is the system's chrome material on a clear
116
- // base, with no view of its own in the bar.
140
+ // `color` beats `blur` and `translucent`; a clear color is a clear bar. On the glass of iOS 26 a color is a solid
141
+ // bar: a clear base with the color and a 1×1 image of it, without the system effect. `blur` is the system's chrome
142
+ // material on a clear base, with no view of its own in the bar.
117
143
  + (void)configure:(UINavigationBarAppearance *)appearance
118
144
  color:(UIColor *)color
119
145
  blur:(BOOL)blur
@@ -124,7 +150,7 @@ static NSDictionary<NSAttributedStringKey, id> *ANNTextAttributes(ANNFontOptions
124
150
  [appearance configureWithTransparentBackground];
125
151
  return;
126
152
  }
127
- if (@available(iOS 26.0, *)) {
153
+ if (ANNTabsDesign.isGlass) {
128
154
  [appearance configureWithTransparentBackground];
129
155
  appearance.backgroundEffect = nil;
130
156
  appearance.backgroundColor = color;
@@ -219,23 +245,51 @@ static NSDictionary<NSAttributedStringKey, id> *ANNTextAttributes(ANNFontOptions
219
245
  if (!color) {
220
246
  return nil;
221
247
  }
222
- icon = [UIImage systemImageNamed:@"chevron.backward"];
248
+ symbol = @"chevron.backward";
249
+ icon = [UIImage systemImageNamed:symbol];
223
250
  isSymbol = YES;
224
251
  }
252
+ // A symbol by its name; an image by its object, which the entry keeps, so its address is never another's.
253
+ id iconKey = isSymbol ? symbol : [NSValue valueWithNonretainedObject:icon];
254
+ NSArray *key = @[
255
+ @"back", iconKey, color ? ANNColorKeyOf(backButton.color) : NSNull.null
256
+ ];
257
+ NSCache<id, UIImage *> *images = ANNLookImages();
258
+ UIImage *cached = [images objectForKey:key];
259
+ if (cached && (isSymbol || cached == icon ||
260
+ objc_getAssociatedObject(cached, ANNIndicatorIconKey) == icon)) {
261
+ return cached;
262
+ }
263
+ UIImage *indicator = nil;
225
264
  if (color) {
226
- return [icon imageWithTintColor:color renderingMode:UIImageRenderingModeAlwaysOriginal];
265
+ indicator = [icon imageWithTintColor:color
266
+ renderingMode:UIImageRenderingModeAlwaysOriginal];
267
+ } else {
268
+ indicator =
269
+ isSymbol ? icon : [icon imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
270
+ }
271
+ if (!isSymbol && indicator != icon) {
272
+ objc_setAssociatedObject(indicator, ANNIndicatorIconKey, icon,
273
+ OBJC_ASSOCIATION_RETAIN_NONATOMIC);
227
274
  }
228
- return isSymbol ? icon : [icon imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
275
+ [images setObject:indicator forKey:key];
276
+ return indicator;
229
277
  }
230
278
 
279
+ // One for the app: every look that hides the arrow holds the same image.
231
280
  + (UIImage *)emptyIndicator {
232
- UIGraphicsImageRendererFormat *format = [UIGraphicsImageRendererFormat preferredFormat];
233
- format.opaque = NO;
234
- UIGraphicsImageRenderer *renderer =
235
- [[UIGraphicsImageRenderer alloc] initWithSize:CGSizeMake(1, 1) format:format];
236
- UIImage *empty = [renderer imageWithActions:^(UIGraphicsImageRendererContext *context){
237
- }];
238
- return [empty imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
281
+ static UIImage *empty;
282
+ static dispatch_once_t once;
283
+ dispatch_once(&once, ^{
284
+ UIGraphicsImageRendererFormat *format = [UIGraphicsImageRendererFormat preferredFormat];
285
+ format.opaque = NO;
286
+ UIGraphicsImageRenderer *renderer =
287
+ [[UIGraphicsImageRenderer alloc] initWithSize:CGSizeMake(1, 1) format:format];
288
+ UIImage *drawn = [renderer imageWithActions:^(UIGraphicsImageRendererContext *context){
289
+ }];
290
+ empty = [drawn imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
291
+ });
292
+ return empty;
239
293
  }
240
294
 
241
295
  + (UIColor *)pinnedTitleColor:(Color *)color traits:(UITraitCollection *)traits {
@@ -244,8 +298,44 @@ static NSDictionary<NSAttributedStringKey, id> *ANNTextAttributes(ANNFontOptions
244
298
  }
245
299
 
246
300
  // The 1×1 picture of the color in both styles: the bar's image view picks the variant of its own style, so a `{ light,
247
- // dark }` color follows a switch of the style without a new appearance.
301
+ // dark }` color follows a switch of the style without a new appearance. Made once for the two resolved colors and the
302
+ // style picked.
248
303
  + (UIImage *)imageOfColor:(UIColor *)color traits:(UITraitCollection *)traits {
304
+ UITraitCollection *light =
305
+ [UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleLight];
306
+ UITraitCollection *dark =
307
+ [UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleDark];
308
+ // Each variant is drawn with the window's other traits (contrast, elevation) and registered by its style only.
309
+ NSArray<UITraitCollection *> *base = traits ? @[ traits ] : @[];
310
+ UITraitCollection *lightTraits = [UITraitCollection
311
+ traitCollectionWithTraitsFromCollections:[base arrayByAddingObject:light]];
312
+ UITraitCollection *darkTraits = [UITraitCollection
313
+ traitCollectionWithTraitsFromCollections:[base arrayByAddingObject:dark]];
314
+ UIColor *lightColor = [color resolvedColorWithTraitCollection:lightTraits];
315
+ UIColor *darkColor = [color resolvedColorWithTraitCollection:darkTraits];
316
+ BOOL isDark = traits.userInterfaceStyle == UIUserInterfaceStyleDark;
317
+ NSArray *key = @[ @"color", lightColor, darkColor, @(isDark) ];
318
+ NSCache<id, UIImage *> *images = ANNLookImages();
319
+ UIImage *cached = [images objectForKey:key];
320
+ if (cached) {
321
+ return cached;
322
+ }
323
+ UIImage *image = [self drawImageOf:color
324
+ light:light
325
+ dark:dark
326
+ lightTraits:lightTraits
327
+ darkTraits:darkTraits
328
+ isDark:isDark];
329
+ [images setObject:image forKey:key];
330
+ return image;
331
+ }
332
+
333
+ + (UIImage *)drawImageOf:(UIColor *)color
334
+ light:(UITraitCollection *)light
335
+ dark:(UITraitCollection *)dark
336
+ lightTraits:(UITraitCollection *)lightTraits
337
+ darkTraits:(UITraitCollection *)darkTraits
338
+ isDark:(BOOL)isDark {
249
339
  UIImage * (^draw)(UITraitCollection *) = ^UIImage *(UITraitCollection *variant) {
250
340
  UIColor *resolved = [color resolvedColorWithTraitCollection:variant];
251
341
  UIGraphicsImageRendererFormat *format = [UIGraphicsImageRendererFormat preferredFormat];
@@ -257,20 +347,11 @@ static NSDictionary<NSAttributedStringKey, id> *ANNTextAttributes(ANNFontOptions
257
347
  [context fillRect:CGRectMake(0, 0, 1, 1)];
258
348
  }];
259
349
  };
260
- UITraitCollection *light =
261
- [UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleLight];
262
- UITraitCollection *dark =
263
- [UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleDark];
264
- // Each variant is drawn with the window's other traits (contrast, elevation) and registered by its style only.
265
- NSArray<UITraitCollection *> *base = traits ? @[ traits ] : @[];
266
- UIImage *lightImage =
267
- draw([UITraitCollection traitCollectionWithTraitsFromCollections:[base arrayByAddingObject:light]]);
268
- UIImage *darkImage =
269
- draw([UITraitCollection traitCollectionWithTraitsFromCollections:[base arrayByAddingObject:dark]]);
350
+ UIImage *lightImage = draw(lightTraits);
351
+ UIImage *darkImage = draw(darkTraits);
270
352
  UIImageAsset *asset = [UIImageAsset new];
271
353
  [asset registerImage:lightImage withTraitCollection:light];
272
354
  [asset registerImage:darkImage withTraitCollection:dark];
273
- BOOL isDark = traits.userInterfaceStyle == UIUserInterfaceStyleDark;
274
355
  UIImage *picked = [asset imageWithTraitCollection:isDark ? dark : light];
275
356
  return picked ?: (isDark ? darkImage : lightImage);
276
357
  }
@@ -1,4 +1,5 @@
1
1
  #import "ANNBarBackgroundComponent.h"
2
+ #import <React/RCTLog.h>
2
3
  #import <objc/runtime.h>
3
4
 
4
5
  // The background a bar shows now.
@@ -13,6 +14,21 @@ static UIView *ANNBackgroundHostOf(UINavigationBar *bar) {
13
14
  return subview;
14
15
  }
15
16
  }
17
+ #if DEBUG
18
+ // The name is UIKit's private one: a system that renames the view puts the components on the bar itself. Told
19
+ // once, in development, and only for a bar that has its views already (one not laid out yet has none).
20
+ static BOOL told = NO;
21
+ if (!told && bar.subviews.count > 0) {
22
+ told = YES;
23
+ NSMutableArray<NSString *> *names = [NSMutableArray new];
24
+ for (UIView *subview in bar.subviews) {
25
+ [names addObject:NSStringFromClass(subview.class)];
26
+ }
27
+ RCTLogWarn(@"[ApexNavigation] the bar has no view named …BarBackground, so a background "
28
+ @"component goes on the bar itself at index 1; its views: %@",
29
+ [names componentsJoinedByString:@", "]);
30
+ }
31
+ #endif
16
32
  return bar;
17
33
  }
18
34
 
@@ -4,10 +4,10 @@
4
4
  NS_ASSUME_NONNULL_BEGIN
5
5
 
6
6
  /// The slot of a React button (`topBar.leftButtons[].component`) as the custom view of its bar item. It takes a content
7
- /// view (`UIView<ANNComponentProtocol>`), never a class of the roots. On iOS 26 without `UIDesignRequiresCompatibility`
8
- /// in the app's Info.plist the slot is 44 pt high and as wide as the content, at least 44 pt; the width follows the
9
- /// content both ways (measured after every mount; a change over 0.5 pt only), and the slot's constraints live with the
10
- /// view, so a new item built around it reuses them. With that key and before iOS 26: the content's size, no
7
+ /// view (`UIView<ANNComponentProtocol>`), never a class of the roots. In the glass design of iOS 26 (`ANNTabsDesign`)
8
+ /// the slot is 44 pt high and as wide as the content, at least 44 pt; the width follows the content both ways
9
+ /// (measured after every mount; a change over 0.5 pt only), and the slot's constraints live with the view, so a new
10
+ /// item built around it reuses them. In the compatibility mode and before iOS 26: the content's size, no
11
11
  /// constraints. A button rendered before the screen shows enters at its width. The core measures only the surface and
12
12
  /// never moves the views inside it: the JS wrapper centres them.
13
13
  @interface ANNBarButtonComponentView : UIView
@@ -7,7 +7,7 @@ static const CGFloat ANNBarButtonSlotHeight = 44;
7
7
  static const CGFloat ANNBarButtonSlotMinimumWidth = 44;
8
8
  static const CGFloat ANNBarButtonWidthTolerance = 0.5;
9
9
 
10
- // The slot of iOS 26's bar: unless the app keeps the earlier design (`UIDesignRequiresCompatibility`).
10
+ // The slot of iOS 26's bar: unless UIKit keeps the earlier design for the app (`ANNTabsDesign`).
11
11
  static BOOL ANNUsesSlotConstraints(void) {
12
12
  return ANNTabsDesign.isGlass;
13
13
  }
@@ -14,10 +14,11 @@ typedef NS_ENUM(NSInteger, ANNBarButtonsSide) {
14
14
 
15
15
  /// The buttons of one screen's bar and toolbar (`topBar.leftButtons[].*`, the side options, `overflowMenu`,
16
16
  /// `toolbar.buttons`): built from the resolved options, whole, at the screen's creation, at each appearance and at a
17
- /// merge of a side. Each button is an `ANNUIBarButtonItem` of the first kind its fields give (React view → icon and
18
- /// text → image button → SF Symbol → image → text → system item); a button without `id` is not placed. Side colors go
17
+ /// merge of a side, when anything the side's build reads changed or the item no longer holds what it put there.
18
+ /// Each button is an `ANNUIBarButtonItem` of the first kind its fields give (React view → icon and text → image
19
+ /// button → SF Symbol → image → text → system item); a button without `id` is not placed. Side colors go
19
20
  /// onto what is built, never into the options; what the user chose (a toggle, a menu's check) goes into the screen's
20
- /// own options. The React buttons' slots are kept by component id, so a button built again reuses its slot. Main queue.
21
+ /// user layer. The React buttons' slots are kept by component id, so a button built again reuses its slot. Main queue.
21
22
  @interface ANNBarButtons : NSObject
22
23
 
23
24
  - (instancetype)initWithScreen:(UIViewController *)screen
@@ -27,7 +28,8 @@ typedef NS_ENUM(NSInteger, ANNBarButtonsSide) {
27
28
  + (instancetype)new NS_UNAVAILABLE;
28
29
 
29
30
  /// Sets `side` of the screen's item (left, right, center) from `options`; `animated` fades new buttons in (a side set
30
- /// as groups changes at once).
31
+ /// as groups changes at once). Nothing when the side's buttons, colors, loaded images, React roots and traits are the
32
+ /// same as at its last build and the item still holds what that build set: iOS 26 animates even equal new items.
31
33
  - (void)applySide:(ANNBarButtonsSide)side
32
34
  options:(ANNNavigationOptions *)options
33
35
  animated:(BOOL)animated;
@@ -49,12 +51,16 @@ typedef NS_ENUM(NSInteger, ANNBarButtonsSide) {
49
51
  /// The width the slot of a React button measured; 0 before it rendered.
50
52
  - (CGFloat)measuredWidthOf:(NSString *)componentId;
51
53
 
52
- /// A menu item `itemId` was picked: `ANN.NavigationButtonPressed` with its id, then the check of a single-selection
53
- /// menu written into the screen's own copy of the menu. `menuOf` gives the menu in `options` (a button's, the title's,
54
- /// the overflow menu); `setMenu` puts the copy into the own options.
54
+ /// A menu item `itemId` was picked: `ANN.NavigationButtonPressed` with its id, then, in a single-selection list, the
55
+ /// pick kept in the screen's user layer under `choiceKey`, one choice per menu. The resolution plays the picks again on
56
+ /// a copy of the menu it has. `menuOf` gives the menu in `options` (a button's, the title's, the overflow menu),
57
+ /// `setMenu` puts a changed copy there. A merge into the screen takes a pick away when the screen's resolution after it
58
+ /// has no such item, or when it gives the menu with other checks in the pick's level than the app had there, as on
59
+ /// Android. The two blocks capture no presenter: the node keeps them with the choice.
55
60
  - (void)menuItemPicked:(NSString *)itemId
61
+ choiceKey:(NSString *)choiceKey
56
62
  menuOf:(ANNMenuOptions *_Nullable (^)(ANNNavigationOptions *options))menuOf
57
- setMenu:(void (^)(ANNNavigationOptions *own, ANNMenuOptions *menu))setMenu;
63
+ setMenu:(void (^)(ANNNavigationOptions *options, ANNMenuOptions *menu))setMenu;
58
64
 
59
65
  /// A copy of `menu` that shares no item with it (a new `ANNMenuOptions` and a new `ANNMenuItemOptions` per item, at
60
66
  /// any depth).