@apexnative/navigation 1.0.0-alpha.5 → 1.0.0-alpha.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ApexNavigation.podspec +2 -1
- package/CHANGELOG.md +32 -0
- package/README.md +1 -1
- package/android/CLAUDE.md +31 -20
- package/android/CORE.md +12 -8
- package/android/consumer-rules.pro +6 -0
- package/android/src/main/java/dev/apexnative/navigation/NavigationActivity.kt +36 -5
- package/android/src/main/java/dev/apexnative/navigation/options/BottomTabOptions.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/BottomTabsOptions.kt +13 -8
- package/android/src/main/java/dev/apexnative/navigation/options/ButtonOptions.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/LargeTitleOptions.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/LayoutAnimation.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/OptionKey.kt +18 -0
- package/android/src/main/java/dev/apexnative/navigation/options/OptionPaths.kt +91 -0
- package/android/src/main/java/dev/apexnative/navigation/options/SheetOptions.kt +7 -4
- package/android/src/main/java/dev/apexnative/navigation/options/TitleOptions.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/options/TopBarAppearanceOptions.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/TopBarOptions.kt +16 -7
- package/android/src/main/java/dev/apexnative/navigation/react/ContentHeights.kt +95 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ContentMounts.kt +66 -0
- package/android/src/main/java/dev/apexnative/navigation/react/NavigationTurboModule.kt +7 -3
- package/android/src/main/java/dev/apexnative/navigation/react/OptionsCommands.kt +41 -3
- package/android/src/main/java/dev/apexnative/navigation/react/ReactView.kt +16 -1
- package/android/src/main/java/dev/apexnative/navigation/react/ReloadCoordinator.kt +0 -2
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenEnvironment.kt +177 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenRegions.kt +12 -49
- package/android/src/main/java/dev/apexnative/navigation/react/ScrollEvents.kt +49 -128
- package/android/src/main/java/dev/apexnative/navigation/safearea/SafeAreaView.kt +6 -6
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotScreenView.kt +27 -7
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotView.kt +12 -1
- package/android/src/main/java/dev/apexnative/navigation/utils/MaterialTheme.kt +5 -6
- package/android/src/main/java/dev/apexnative/navigation/utils/SystemAnimations.kt +36 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/ViewExtensions.kt +0 -13
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/ArrangementController.kt +9 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsCollapseBehavior.kt +5 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsController.kt +13 -10
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowGeometry.kt +22 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabsRoom.kt +0 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentViewController.kt +7 -8
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenSafeArea.kt +29 -11
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/externalcomponent/ExternalComponentViewController.kt +2 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalCoordinator.kt +20 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalSheet.kt +443 -58
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalViews.kt +33 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetBack.kt +42 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetStops.kt +60 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/Navigator.kt +4 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ParentController.kt +3 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuMotion.kt +8 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/BackPreview.kt +32 -4
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/PreparedFrame.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackCommands.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackController.kt +50 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackQueue.kt +15 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackViews.kt +10 -4
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabMotion.kt +142 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabPresenter.kt +215 -43
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/StackSearchPresenter.kt +25 -26
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/BarRowTransition.kt +3 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/ButtonPlaces.kt +11 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarPresenter.kt +36 -38
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ScrollEventListener.kt +6 -9
- package/android/src/main/java/dev/apexnative/navigation/views/animations/AnimationLayer.kt +73 -0
- package/android/src/main/java/dev/apexnative/navigation/views/animations/ValueInterpolation.kt +14 -0
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabsLayout.kt +61 -2
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomTabRow.kt +72 -10
- package/android/src/main/java/dev/apexnative/navigation/views/element/ElementTransitions.kt +129 -179
- package/android/src/main/java/dev/apexnative/navigation/views/element/TargetsWait.kt +8 -1
- package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionLayer.kt +37 -112
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ElementPictures.kt +67 -3
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/FlightGeometry.kt +346 -36
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMorph.kt +199 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/SharedAnimatorFactory.kt +55 -42
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextMorph.kt +176 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewMorph.kt +108 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabCopy.kt +85 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabMenu.kt +13 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TitleBar.kt +5 -24
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TopBar.kt +51 -34
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonComponentCell.kt +6 -6
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonView.kt +113 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarMenu.kt +219 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonBar.kt +121 -175
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonMenus.kt +34 -64
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonRow.kt +216 -0
- package/android/src/main/jni/ANNContentHeights.cpp +82 -0
- package/android/src/main/res/drawable/apex_navigation_ic_arrow_right.xml +14 -0
- package/android/src/main/res/layout/apex_navigation_menu_header.xml +19 -0
- package/android/src/main/res/layout/apex_navigation_menu_item.xml +68 -0
- package/android/src/main/res/values/styles.xml +1 -1
- package/android/src/main/res/values-night/styles.xml +1 -1
- package/cli/doctor/checks/app.js +16 -1
- package/cli/project.js +4 -0
- package/cli/setup/index.js +5 -0
- package/cli/setup/steps/metro.js +46 -0
- package/docs-md/architecture/native-screens.md +4 -0
- package/docs-md/architecture/theme-and-context.md +131 -12
- package/docs-md/architecture/transitions.md +46 -5
- package/docs-md/containers/modals.md +2 -0
- package/docs-md/containers/overlays.md +1 -1
- package/docs-md/containers/side-menu.md +1 -1
- package/docs-md/containers/tabs.md +2 -0
- package/docs-md/flows/bottom-sheets.md +4 -2
- package/docs-md/fundamentals/screens-and-props.md +9 -1
- package/docs-md/fundamentals/starting-the-app.md +1 -1
- package/docs-md/guides/cli.md +3 -1
- package/docs-md/help/glossary.md +2 -2
- package/docs-md/help/troubleshooting.md +22 -1
- package/docs-md/index.json +41 -1
- package/docs-md/migration/from-expo-router.md +1 -1
- package/docs-md/migration/from-react-native-navigation.md +1 -1
- package/docs-md/migration/from-react-navigation.md +2 -2
- package/docs-md/screen-ui/back-and-gestures.md +17 -1
- package/docs-md/screen-ui/bar-buttons.md +5 -5
- package/docs-md/screen-ui/search.md +1 -1
- package/docs-md/screen-ui/system-ui.md +16 -11
- package/docs-md/screen-ui/toolbar-and-fab.md +4 -2
- package/docs-md/screen-ui/top-bar.md +8 -4
- package/docs-md/start/installation.md +16 -1
- package/ios/Animations/ANNFrameDriver.h +55 -15
- package/ios/Animations/ANNFrameDriver.mm +216 -60
- package/ios/Animations/ANNTransitionAnimator.h +26 -5
- package/ios/Animations/ANNTransitionAnimator.mm +49 -3
- package/ios/Animations/ANNTransitionPlan.h +2 -2
- package/ios/Animations/ANNTransitionPlan.mm +10 -0
- package/ios/Animations/Elements/ANNElementFinder.h +2 -2
- package/ios/Animations/Elements/ANNElementFinder.mm +2 -2
- package/ios/Animations/Elements/ANNElementTransition.h +3 -3
- package/ios/Animations/Elements/ANNElementTransition.mm +2 -2
- package/ios/Animations/Elements/ANNSharedElementFlight.h +3 -3
- package/ios/Animations/Elements/ANNSharedElementFlight.mm +249 -45
- package/ios/Animations/Interpolators/ANNInterpolate.h +2 -30
- package/ios/Animations/Interpolators/ANNTransformParts.h +48 -0
- package/ios/Animations/Interpolators/ANNTransformParts.mm +507 -0
- package/ios/Animations/Interpolators/ANNViewTracks.h +9 -6
- package/ios/Animations/Interpolators/ANNViewTracks.mm +100 -30
- package/ios/CLAUDE.md +32 -22
- package/ios/CORE.md +25 -21
- package/ios/Contract/ANNCommandRunner.h +8 -7
- package/ios/Contract/ANNCommandRunner.mm +21 -27
- package/ios/Contract/ANNLayoutNode.h +3 -3
- package/ios/Contract/ANNLayoutReader.h +3 -3
- package/ios/Core/ANNAppDelegate.mm +0 -2
- package/ios/Core/ANNDeepLinkQueue.h +6 -5
- package/ios/Core/ANNDeepLinkQueue.mm +22 -10
- package/ios/Core/ANNJavaScriptCalls.h +11 -12
- package/ios/Core/ANNJavaScriptCalls.mm +7 -16
- package/ios/Core/ANNReloadCoordinator.mm +4 -8
- package/ios/Core/ANNSceneDelegate.mm +2 -2
- package/ios/Core/ApexNavigation+Internal.h +1 -1
- package/ios/Core/ApexNavigation.mm +6 -2
- package/ios/Layouts/Arrangement/ANNArrangementState.h +2 -17
- package/ios/Layouts/Arrangement/ANNArrangementState.mm +0 -38
- package/ios/Layouts/Arrangement/ANNArrangementViewController.mm +4 -4
- package/ios/Layouts/Root/ANNRootCoordinator.mm +45 -15
- package/ios/Layouts/Screen/ANNComponentViewController.h +2 -2
- package/ios/Layouts/Screen/ANNComponentViewController.mm +13 -23
- package/ios/Layouts/Screen/ANNPreviewInteraction.h +7 -4
- package/ios/Layouts/Screen/ANNPreviewInteraction.mm +72 -10
- package/ios/Layouts/Screen/ANNScreenEnvironment.h +63 -0
- package/ios/Layouts/Screen/ANNScreenEnvironment.mm +181 -0
- package/ios/Layouts/Screen/ANNScreenRegions.h +3 -18
- package/ios/Layouts/Screen/ANNScreenRegions.mm +0 -38
- package/ios/Layouts/Screen/ANNScreenSafeArea.h +4 -9
- package/ios/Layouts/Screen/ANNScreenSafeArea.mm +14 -16
- package/ios/Layouts/Stack/ANNPreviewPush.h +7 -6
- package/ios/Layouts/Stack/ANNPreviewPush.mm +57 -5
- package/ios/Layouts/Stack/ANNStackAnimatingDelegate.h +11 -2
- package/ios/Layouts/Stack/ANNStackAnimatingDelegate.mm +14 -7
- package/ios/Layouts/Stack/ANNStackController.h +8 -0
- package/ios/Layouts/Stack/ANNStackController.mm +153 -11
- package/ios/Layouts/Stack/ANNSwipePopInteraction.h +26 -0
- package/ios/Layouts/Stack/ANNSwipePopInteraction.mm +185 -0
- package/ios/Layouts/Stack/InteractivePopGestureDelegate.mm +28 -4
- package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.h +12 -1
- package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.mm +23 -0
- package/ios/Layouts/Tabs/ANNBottomTabsController.mm +2 -1
- package/ios/Layouts/Tabs/ANNBottomTabsCustomRow.mm +8 -3
- package/ios/Layouts/Tabs/ANNBottomTabsPresenter.h +4 -0
- package/ios/Layouts/Tabs/ANNBottomTabsPresenter.mm +123 -36
- package/ios/Layouts/Tabs/ANNTabsDesign.h +6 -5
- package/ios/Layouts/Tabs/ANNTabsDesign.mm +9 -1
- package/ios/Layouts/Tabs/UITabBar+utils.h +5 -5
- package/ios/Layouts/Tabs/UITabBar+utils.mm +32 -13
- package/ios/Options/ANNAnimationOptions.h +2 -1
- package/ios/Options/ANNAnimationOptions.mm +1 -1
- package/ios/Options/ANNBottomTabsOptions.h +2 -0
- package/ios/Options/ANNBottomTabsOptions.mm +1 -0
- package/ios/Options/ANNOptions.h +25 -0
- package/ios/Options/ANNOptions.mm +157 -1
- package/ios/Options/ANNOptionsReader.mm +108 -0
- package/ios/Options/ANNStackPopAnimationOptions.h +13 -0
- package/ios/Options/ANNStackPopAnimationOptions.mm +11 -0
- package/ios/Options/Params/ANNParam.h +15 -0
- package/ios/Options/Params/ANNParam.mm +61 -0
- package/ios/Options/Params/Color.h +3 -0
- package/ios/Options/Params/Color.mm +21 -0
- package/ios/Options/Params/ColorParser.h +4 -3
- package/ios/Options/Params/ColorParser.mm +22 -4
- package/ios/Options/Params/Image.h +4 -0
- package/ios/Options/Params/Image.mm +20 -0
- package/ios/React/ANNReactView.mm +6 -25
- package/ios/React/ANNSafeAreaViewComponentView.mm +26 -15
- package/ios/React/ANNSurfaceHostingView.h +14 -0
- package/ios/React/ANNSurfaceHostingView.mm +144 -1
- package/ios/React/Slots/ANNSlotScreenView.mm +8 -2
- package/ios/TopBar/ANNBackButtonPresenter.mm +6 -5
- package/ios/TopBar/ANNBarAppearance.h +2 -1
- package/ios/TopBar/ANNBarAppearance.mm +111 -30
- package/ios/TopBar/ANNBarBackgroundComponent.mm +16 -0
- package/ios/TopBar/ANNBarButtonComponentView.h +4 -4
- package/ios/TopBar/ANNBarButtonComponentView.mm +1 -1
- package/ios/TopBar/ANNBarButtons.h +5 -3
- package/ios/TopBar/ANNBarButtons.mm +186 -17
- package/ios/TopBar/ANNLargeTitlePresenter.mm +24 -4
- package/ios/TopBar/ANNMainList.h +3 -0
- package/ios/TopBar/ANNMainList.mm +4 -0
- package/ios/TopBar/ANNScrollEdgeEffects.h +22 -6
- package/ios/TopBar/ANNScrollEdgeEffects.mm +123 -16
- package/ios/TopBar/ANNSearchPresenter.mm +2 -2
- package/ios/TopBar/ANNSearchResultsViewController.mm +5 -5
- package/ios/TopBar/ANNTopBarPresenter.h +3 -2
- package/ios/TopBar/ANNTopBarPresenter.mm +95 -22
- package/ios/TurboModules/ANNTurboModule.mm +66 -16
- package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.cpp +20 -0
- package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.h +5 -14
- package/lib/module/ARCHITECTURE.md +17 -7
- package/lib/module/adapters/NativeANNTurboModule.js.map +1 -1
- package/lib/module/api/app/AppRegistry.js +14 -2
- package/lib/module/api/app/AppRegistry.js.map +1 -1
- package/lib/module/api/app/createNavigation.js +188 -66
- package/lib/module/api/app/createNavigation.js.map +1 -1
- package/lib/module/api/events/navigationEvents.js +6 -2
- package/lib/module/api/events/navigationEvents.js.map +1 -1
- package/lib/module/api/hooks/useSafeAreaInsets.js +4 -3
- package/lib/module/api/hooks/useSafeAreaInsets.js.map +1 -1
- package/lib/module/api/linking/linking.js +11 -0
- package/lib/module/api/linking/linking.js.map +1 -1
- package/lib/module/api/options/OptionsChain.js +2 -2
- package/lib/module/api/screens/defineScreen.js +45 -3
- package/lib/module/api/screens/defineScreen.js.map +1 -1
- package/lib/module/api/screens/nativeScreens.js +31 -6
- package/lib/module/api/screens/nativeScreens.js.map +1 -1
- package/lib/module/api/screens/registerScreens.js +172 -35
- package/lib/module/api/screens/registerScreens.js.map +1 -1
- package/lib/module/api/theme/theme.js +5 -0
- package/lib/module/api/theme/theme.js.map +1 -1
- package/lib/module/engine/commands.js +42 -2
- package/lib/module/engine/commands.js.map +1 -1
- package/lib/module/engine/layout.js +7 -2
- package/lib/module/engine/layout.js.map +1 -1
- package/lib/module/engine/nativeScreens.js +9 -0
- package/lib/module/engine/nativeScreens.js.map +1 -1
- package/lib/module/engine/options.js +5 -4
- package/lib/module/engine/options.js.map +1 -1
- package/lib/module/engine/optionsChange.js +102 -0
- package/lib/module/engine/optionsChange.js.map +1 -0
- package/lib/module/engine/refresh.js +85 -0
- package/lib/module/engine/refresh.js.map +1 -0
- package/lib/module/engine/rememberedOptions.js +60 -0
- package/lib/module/engine/rememberedOptions.js.map +1 -1
- package/lib/module/engine/screens.js +55 -4
- package/lib/module/engine/screens.js.map +1 -1
- package/lib/typescript/adapters/NativeANNTurboModule.d.ts +7 -0
- package/lib/typescript/adapters/NativeANNTurboModule.d.ts.map +1 -1
- package/lib/typescript/api/app/AppRegistry.d.ts.map +1 -1
- package/lib/typescript/api/app/createNavigation.d.ts +8 -3
- package/lib/typescript/api/app/createNavigation.d.ts.map +1 -1
- package/lib/typescript/api/events/navigationEvents.d.ts +2 -2
- package/lib/typescript/api/events/navigationEvents.d.ts.map +1 -1
- package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts +4 -3
- package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts.map +1 -1
- package/lib/typescript/api/index.d.ts +1 -1
- package/lib/typescript/api/index.d.ts.map +1 -1
- package/lib/typescript/api/linking/linking.d.ts +8 -0
- package/lib/typescript/api/linking/linking.d.ts.map +1 -1
- package/lib/typescript/api/options/OptionsChain.d.ts +2 -2
- package/lib/typescript/api/screens/defineScreen.d.ts +23 -4
- package/lib/typescript/api/screens/defineScreen.d.ts.map +1 -1
- package/lib/typescript/api/screens/nativeScreens.d.ts +8 -1
- package/lib/typescript/api/screens/nativeScreens.d.ts.map +1 -1
- package/lib/typescript/api/screens/registerScreens.d.ts.map +1 -1
- package/lib/typescript/api/theme/theme.d.ts +2 -0
- package/lib/typescript/api/theme/theme.d.ts.map +1 -1
- package/lib/typescript/engine/commands.d.ts +5 -0
- package/lib/typescript/engine/commands.d.ts.map +1 -1
- package/lib/typescript/engine/layout.d.ts.map +1 -1
- package/lib/typescript/engine/nativeScreens.d.ts +5 -0
- package/lib/typescript/engine/nativeScreens.d.ts.map +1 -1
- package/lib/typescript/engine/optionsChange.d.ts +28 -0
- package/lib/typescript/engine/optionsChange.d.ts.map +1 -0
- package/lib/typescript/engine/refresh.d.ts +35 -0
- package/lib/typescript/engine/refresh.d.ts.map +1 -0
- package/lib/typescript/engine/rememberedOptions.d.ts +13 -0
- package/lib/typescript/engine/rememberedOptions.d.ts.map +1 -1
- package/lib/typescript/engine/screens.d.ts +27 -6
- package/lib/typescript/engine/screens.d.ts.map +1 -1
- package/lib/typescript/interfaces/ComponentEvents.d.ts +2 -2
- package/lib/typescript/interfaces/options/animations.d.ts +44 -14
- package/lib/typescript/interfaces/options/animations.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/bottomTabs.d.ts +19 -6
- package/lib/typescript/interfaces/options/bottomTabs.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/buttons.d.ts +10 -10
- package/lib/typescript/interfaces/options/modals.d.ts +6 -7
- package/lib/typescript/interfaces/options/modals.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/stack.d.ts +8 -3
- package/lib/typescript/interfaces/options/stack.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/system.d.ts +8 -5
- package/lib/typescript/interfaces/options/system.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/toolbar.d.ts +2 -2
- package/lib/typescript/interfaces/options/topBar.d.ts +46 -29
- package/lib/typescript/interfaces/options/topBar.d.ts.map +1 -1
- package/metro/acceptPlugin.js +57 -0
- package/metro/babelTransformer.js +45 -0
- package/metro/index.js +36 -0
- package/package.json +3 -1
- package/src/ARCHITECTURE.md +17 -7
- package/src/adapters/NativeANNTurboModule.ts +7 -0
- package/src/api/app/AppRegistry.ts +16 -2
- package/src/api/app/createNavigation.ts +201 -69
- package/src/api/events/navigationEvents.ts +9 -3
- package/src/api/hooks/useSafeAreaInsets.ts +4 -3
- package/src/api/index.ts +1 -0
- package/src/api/linking/linking.ts +22 -1
- package/src/api/options/OptionsChain.ts +2 -2
- package/src/api/screens/defineScreen.ts +49 -5
- package/src/api/screens/nativeScreens.ts +40 -4
- package/src/api/screens/registerScreens.tsx +170 -42
- package/src/api/theme/theme.ts +5 -0
- package/src/engine/commands.ts +51 -6
- package/src/engine/layout.ts +11 -2
- package/src/engine/nativeScreens.ts +10 -1
- package/src/engine/options.ts +6 -8
- package/src/engine/optionsChange.ts +107 -0
- package/src/engine/refresh.ts +97 -0
- package/src/engine/rememberedOptions.ts +70 -0
- package/src/engine/screens.tsx +53 -8
- package/src/interfaces/ComponentEvents.ts +2 -2
- package/src/interfaces/options/animations.ts +44 -14
- package/src/interfaces/options/bottomTabs.ts +19 -6
- package/src/interfaces/options/buttons.ts +10 -10
- package/src/interfaces/options/modals.ts +6 -7
- package/src/interfaces/options/stack.ts +8 -3
- package/src/interfaces/options/system.ts +8 -5
- package/src/interfaces/options/toolbar.ts +2 -2
- package/src/interfaces/options/topBar.ts +46 -29
- package/android/src/main/java/dev/apexnative/navigation/react/ArrangementStates.kt +0 -42
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenInsets.kt +0 -70
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowPlacer.kt +0 -223
- package/android/src/main/java/dev/apexnative/navigation/views/element/ElementStub.kt +0 -31
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMatrixAnimator.kt +0 -136
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PlainViewAnimator.kt +0 -86
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PropertyAnimatorCreator.kt +0 -33
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ReactImageAnimator.kt +0 -64
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextChangeAnimator.kt +0 -177
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewChangeAnimator.kt +0 -137
- package/ios/Layouts/Screen/ANNScreenInsets.h +0 -30
- package/ios/Layouts/Screen/ANNScreenInsets.mm +0 -70
package/ios/TopBar/ANNMainList.h
CHANGED
|
@@ -23,6 +23,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
23
23
|
/// search takes it, or what is in it, for the screen's list.
|
|
24
24
|
+ (void)excludeView:(UIView *)view;
|
|
25
25
|
|
|
26
|
+
/// The view is one of those (`excludeView:`).
|
|
27
|
+
+ (BOOL)isExcludedView:(UIView *)view;
|
|
28
|
+
|
|
26
29
|
@end
|
|
27
30
|
|
|
28
31
|
NS_ASSUME_NONNULL_END
|
|
@@ -22,6 +22,10 @@ static const CGFloat ANNMainListTolerance = 1;
|
|
|
22
22
|
objc_setAssociatedObject(view, ANNMainListExcludedKey, @YES, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
+ (BOOL)isExcludedView:(UIView *)view {
|
|
26
|
+
return objc_getAssociatedObject(view, ANNMainListExcludedKey) != nil;
|
|
27
|
+
}
|
|
28
|
+
|
|
25
29
|
- (UIScrollView *)keptList {
|
|
26
30
|
UIScrollView *list = _list;
|
|
27
31
|
UIView *screenView = _screenView;
|
|
@@ -5,9 +5,12 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
5
5
|
|
|
6
6
|
/// The scroll edge effect of a screen's lists (iOS 26; `scrollEdgeEffect.*`): each edge's own `hidden` / `style` beat
|
|
7
7
|
/// the general ones, through the public API. No top effect under a solid `background.color` (not a clear one) or
|
|
8
|
-
/// `background.component` unless the screen set its own for the top or for all edges. The
|
|
9
|
-
///
|
|
10
|
-
///
|
|
8
|
+
/// `background.component` unless the screen set its own for the top or for all edges. The lists are the scroll views
|
|
9
|
+
/// of the screen's view down to 16 levels, outside hidden views (`display: none`), not inside a list that scrolls
|
|
10
|
+
/// vertically (its rows) or a text view; a scroll view that doesn't (a pager, a carousel) is looked into for its
|
|
11
|
+
/// lists. The screen remembers the lists it set and gives them the system values back when it leaves, at its destroy
|
|
12
|
+
/// and when they leave its view for no screen (Fabric's pool; in another screen they may be that screen's already).
|
|
13
|
+
/// Before iOS 26 nothing. Main queue.
|
|
11
14
|
@interface ANNScrollEdgeEffects : NSObject
|
|
12
15
|
|
|
13
16
|
- (instancetype)initWithScreenView:(UIView *)screenView;
|
|
@@ -15,13 +18,26 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
15
18
|
- (instancetype)init NS_UNAVAILABLE;
|
|
16
19
|
+ (instancetype)new NS_UNAVAILABLE;
|
|
17
20
|
|
|
18
|
-
/// At the appearance and at a merge:
|
|
21
|
+
/// At the appearance and at a merge: the lists of the screen's view, set again whole. Without a walk (only the known
|
|
22
|
+
/// lists still in the view set again) when the options it reads and the traits are the same as at the last walk and
|
|
23
|
+
/// no content mounted since, while the screen's content tells all its mounts (`mountsReported`) and that walk found
|
|
24
|
+
/// no pager.
|
|
19
25
|
- (void)applyToAllWithOptions:(ANNNavigationOptions *)options;
|
|
20
26
|
|
|
21
|
-
///
|
|
27
|
+
/// The screen's content tells each of its mounts, also out of the window (a React root): without it every call walks
|
|
28
|
+
/// the view.
|
|
29
|
+
@property(nonatomic) BOOL mountsReported;
|
|
30
|
+
|
|
31
|
+
/// After a mount of the content: the main list only; lists React took out of the screen get the system values, and
|
|
32
|
+
/// the next `applyToAllWithOptions:` walks the view again.
|
|
22
33
|
- (void)applyToList:(nullable UIScrollView *)list options:(ANNNavigationOptions *)options;
|
|
23
34
|
|
|
24
|
-
/// The lists
|
|
35
|
+
/// The screen left: its lists get the system values back (a list Fabric recycles from it comes clean), and stay
|
|
36
|
+
/// known for its next appearance.
|
|
37
|
+
- (void)screenDidDisappear;
|
|
38
|
+
|
|
39
|
+
/// The lists set get the system values back and are forgotten (the screen's content goes, its destroy); the next
|
|
40
|
+
/// `applyToAllWithOptions:` walks the view again.
|
|
25
41
|
- (void)reset;
|
|
26
42
|
|
|
27
43
|
@end
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
#import "ANNScrollEdgeEffects.h"
|
|
2
2
|
#import "ANNBarAppearance.h"
|
|
3
|
+
#import "ANNMainList.h"
|
|
4
|
+
|
|
5
|
+
// How deep the walk looks for lists, as the main list's search.
|
|
6
|
+
static const NSUInteger ANNEdgeWalkMaxDepth = 16;
|
|
7
|
+
static const CGFloat ANNEdgeWalkTolerance = 1;
|
|
8
|
+
|
|
9
|
+
// A list that scrolls (or bounces) vertically: what is in it is its rows, which never meet a bar themselves.
|
|
10
|
+
static BOOL ANNScrollsVertically(UIScrollView *list) {
|
|
11
|
+
return list.alwaysBounceVertical ||
|
|
12
|
+
list.contentSize.height > CGRectGetHeight(list.bounds) + ANNEdgeWalkTolerance;
|
|
13
|
+
}
|
|
3
14
|
|
|
4
15
|
// What one edge gets: whether it is hidden and its style; `nil` style is automatic.
|
|
5
16
|
typedef struct {
|
|
@@ -18,6 +29,11 @@ static ANNEdgeEffect ANNEdgeEffectOf(ANNScrollEdgeEffectOptions *effect,
|
|
|
18
29
|
@implementation ANNScrollEdgeEffects {
|
|
19
30
|
__weak UIView *_screenView;
|
|
20
31
|
NSHashTable<UIScrollView *> *_lists;
|
|
32
|
+
// What the last walk read (nil: walk at the next call), and whether content mounted since or the walk found a
|
|
33
|
+
// scroll view whose lists come and go without a mount (a pager's pages).
|
|
34
|
+
NSArray *_walkInputs;
|
|
35
|
+
BOOL _mountedSinceWalk;
|
|
36
|
+
BOOL _walkFoundPager;
|
|
21
37
|
}
|
|
22
38
|
|
|
23
39
|
- (instancetype)initWithScreenView:(UIView *)screenView {
|
|
@@ -30,46 +46,137 @@ static ANNEdgeEffect ANNEdgeEffectOf(ANNScrollEdgeEffectOptions *effect,
|
|
|
30
46
|
|
|
31
47
|
- (void)applyToAllWithOptions:(ANNNavigationOptions *)options {
|
|
32
48
|
if (@available(iOS 26.0, *)) {
|
|
33
|
-
[self reset];
|
|
34
49
|
UIView *screenView = _screenView;
|
|
35
|
-
if (screenView) {
|
|
36
|
-
[self
|
|
50
|
+
if (!screenView) {
|
|
51
|
+
[self reset];
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
NSArray *inputs = [self inputsOf:options traits:screenView.traitCollection];
|
|
55
|
+
[self dropListsOutside:screenView];
|
|
56
|
+
// The lists are the same as at the last walk: they take the values again (the screen gave them the system
|
|
57
|
+
// ones as it went), without a walk.
|
|
58
|
+
if (_walkInputs && _mountsReported && !_mountedSinceWalk && !_walkFoundPager &&
|
|
59
|
+
ANNOptionValuesSame(_walkInputs, inputs)) {
|
|
60
|
+
for (UIScrollView *list in _lists.allObjects) {
|
|
61
|
+
[self apply:options to:list];
|
|
62
|
+
}
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
NSMutableArray<UIScrollView *> *found = [NSMutableArray new];
|
|
66
|
+
BOOL pager = NO;
|
|
67
|
+
[self collectIn:screenView depth:0 into:found pager:&pager];
|
|
68
|
+
// The screen's lists that the walk no longer finds get the system values; the others are set again.
|
|
69
|
+
for (UIScrollView *kept in _lists.allObjects) {
|
|
70
|
+
if ([found indexOfObjectIdenticalTo:kept] == NSNotFound) {
|
|
71
|
+
[ANNScrollEdgeEffects resetList:kept];
|
|
72
|
+
[_lists removeObject:kept];
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
for (UIScrollView *list in found) {
|
|
76
|
+
[self apply:options to:list];
|
|
37
77
|
}
|
|
78
|
+
_walkInputs = inputs;
|
|
79
|
+
_mountedSinceWalk = NO;
|
|
80
|
+
_walkFoundPager = pager;
|
|
38
81
|
}
|
|
39
82
|
}
|
|
40
83
|
|
|
41
|
-
|
|
84
|
+
// What the effects of a list read: the effect's options, the bar's background (a solid one hides the top), the traits
|
|
85
|
+
// a clear color is told by.
|
|
86
|
+
- (NSArray *)inputsOf:(ANNNavigationOptions *)options traits:(UITraitCollection *)traits {
|
|
87
|
+
ANNTopBarBackgroundOptions *background = options.topBar.background;
|
|
88
|
+
return @[
|
|
89
|
+
options.scrollEdgeEffect, background.color, background.component.name,
|
|
90
|
+
@(traits.userInterfaceStyle), @(traits.accessibilityContrast)
|
|
91
|
+
];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// The lists of `view`, bounded as the main list's search: hidden views (`display: none`) and the core's own views are
|
|
95
|
+
// left out with what is in them. A view at alpha 0 is not: an animation (a fade in, a transition) changes it without a
|
|
96
|
+
// mount. A list that scrolls vertically and a text view are set, not looked into; a scroll view that doesn't is looked
|
|
97
|
+
// into for the lists of its pages, and such a walk is never skipped.
|
|
98
|
+
- (void)collectIn:(UIView *)view
|
|
99
|
+
depth:(NSUInteger)depth
|
|
100
|
+
into:(NSMutableArray<UIScrollView *> *)found
|
|
101
|
+
pager:(BOOL *)pager {
|
|
102
|
+
if (depth > ANNEdgeWalkMaxDepth) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
42
105
|
for (UIView *subview in view.subviews) {
|
|
106
|
+
if (subview.hidden || [ANNMainList isExcludedView:subview]) {
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
43
109
|
if ([subview isKindOfClass:UIScrollView.class]) {
|
|
44
|
-
|
|
110
|
+
UIScrollView *list = (UIScrollView *)subview;
|
|
111
|
+
[found addObject:list];
|
|
112
|
+
if ([list isKindOfClass:UITextView.class] || ANNScrollsVertically(list)) {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
*pager = YES;
|
|
45
116
|
}
|
|
46
|
-
[self
|
|
117
|
+
[self collectIn:subview depth:depth + 1 into:found pager:pager];
|
|
47
118
|
}
|
|
48
119
|
}
|
|
49
120
|
|
|
50
121
|
- (void)applyToList:(UIScrollView *)list options:(ANNNavigationOptions *)options {
|
|
122
|
+
_mountedSinceWalk = YES;
|
|
51
123
|
if (@available(iOS 26.0, *)) {
|
|
52
|
-
|
|
53
|
-
UIView *screenView = _screenView;
|
|
54
|
-
for (UIScrollView *kept in _lists.allObjects) {
|
|
55
|
-
if (!screenView || ![kept isDescendantOfView:screenView]) {
|
|
56
|
-
[ANNScrollEdgeEffects resetList:kept];
|
|
57
|
-
[_lists removeObject:kept];
|
|
58
|
-
}
|
|
59
|
-
}
|
|
124
|
+
[self dropListsOutside:_screenView];
|
|
60
125
|
if (list) {
|
|
61
126
|
[self apply:options to:list];
|
|
62
127
|
}
|
|
63
128
|
}
|
|
64
129
|
}
|
|
65
130
|
|
|
66
|
-
|
|
131
|
+
// Whether `view` is in some screen: one of its views is the view of a view controller, in a window or not. A list in
|
|
132
|
+
// Fabric's pool is not: its component view (the list's own superview) has no superview there.
|
|
133
|
+
static BOOL ANNIsInAScreen(UIView *view) {
|
|
134
|
+
for (UIView *ancestor = view; ancestor; ancestor = ancestor.superview) {
|
|
135
|
+
if ([ancestor.nextResponder isKindOfClass:UIViewController.class]) {
|
|
136
|
+
return YES;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return NO;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// A list React took out of the screen is no longer the screen's: outside every screen (in the pool Fabric recycles
|
|
143
|
+
// its views from, shared by every surface) it gets the system values, so it comes clean into the screen that takes it;
|
|
144
|
+
// in another screen it may be that screen's already, which set its values: it is only forgotten.
|
|
145
|
+
- (void)dropListsOutside:(nullable UIView *)screenView {
|
|
146
|
+
for (UIScrollView *kept in _lists.allObjects) {
|
|
147
|
+
if (screenView && [kept isDescendantOfView:screenView]) {
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
if (@available(iOS 26.0, *)) {
|
|
151
|
+
if (!ANNIsInAScreen(kept)) {
|
|
152
|
+
[ANNScrollEdgeEffects resetList:kept];
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
[_lists removeObject:kept];
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// The screen's lists get the system values; with `keepingLists` they stay known, with what the last walk read, for
|
|
160
|
+
// the next appearance to set them again without a walk.
|
|
161
|
+
- (void)giveBackKeepingLists:(BOOL)keepingLists {
|
|
162
|
+
[self dropListsOutside:_screenView];
|
|
67
163
|
if (@available(iOS 26.0, *)) {
|
|
68
164
|
for (UIScrollView *list in _lists.allObjects) {
|
|
69
165
|
[ANNScrollEdgeEffects resetList:list];
|
|
70
166
|
}
|
|
71
167
|
}
|
|
72
|
-
|
|
168
|
+
if (!keepingLists) {
|
|
169
|
+
[_lists removeAllObjects];
|
|
170
|
+
_walkInputs = nil;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
- (void)screenDidDisappear {
|
|
175
|
+
[self giveBackKeepingLists:YES];
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
- (void)reset {
|
|
179
|
+
[self giveBackKeepingLists:NO];
|
|
73
180
|
}
|
|
74
181
|
|
|
75
182
|
+ (void)resetList:(UIScrollView *)list API_AVAILABLE(ios(26.0)) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#import "ANNSearchPresenter.h"
|
|
2
2
|
#import "ANNEventEmitter.h"
|
|
3
|
-
#import "
|
|
3
|
+
#import "ANNScreenEnvironment.h"
|
|
4
4
|
#import "ANNSearchResultsViewController.h"
|
|
5
5
|
#import "ANNUserChoice.h"
|
|
6
6
|
|
|
@@ -298,7 +298,7 @@ static ANNUserChoice *ANNScopeChoice(NSString *scope) {
|
|
|
298
298
|
_appliedSuggestions = nil;
|
|
299
299
|
if (_resultsComponentId) {
|
|
300
300
|
[_componentRegistry removeChildComponent:_resultsComponentId];
|
|
301
|
-
[
|
|
301
|
+
[ANNScreenEnvironment removeScreenId:_resultsComponentId];
|
|
302
302
|
}
|
|
303
303
|
_resultsKey = nil;
|
|
304
304
|
_resultsComponentId = nil;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#import "ANNSearchResultsViewController.h"
|
|
2
|
-
#import "
|
|
2
|
+
#import "ANNScreenEnvironment.h"
|
|
3
3
|
|
|
4
4
|
@implementation ANNSearchResultsViewController {
|
|
5
5
|
NSString *_componentId;
|
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
[super viewDidLayoutSubviews];
|
|
31
31
|
_reactView.frame = self.view.bounds;
|
|
32
32
|
if (_componentId) {
|
|
33
|
-
[
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
[ANNScreenEnvironment setInsets:self.view.safeAreaInsets
|
|
34
|
+
padding:UIEdgeInsetsZero
|
|
35
|
+
forScreenId:_componentId
|
|
36
|
+
eventEmitter:_eventEmitter];
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -70,8 +70,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
70
70
|
- (void)screenDidLayOut;
|
|
71
71
|
- (void)contentDidMount;
|
|
72
72
|
|
|
73
|
-
/// The screen's content is about to go (a pop removes it before `viewDidDisappear`): its lists get the
|
|
74
|
-
/// effect back and the large title's color leaves them; the place of the large title during a pop leaves
|
|
73
|
+
/// The screen's content is about to go (its destroy; a pop removes it before `viewDidDisappear`): its lists get the
|
|
74
|
+
/// system edge effect back and the large title's color leaves them; the place of the large title during a pop leaves
|
|
75
|
+
/// the screen. At `screenDidDisappear` the same, the lists of the edge effects kept for the screen's next appearance.
|
|
75
76
|
- (void)releaseLists;
|
|
76
77
|
|
|
77
78
|
/// Every root of the screen's bar still alive stops, once, on the main queue.
|
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
#import "ANNScreenBars.h"
|
|
10
10
|
#import "ANNScrollEdgeEffects.h"
|
|
11
11
|
#import "ANNSearchPresenter.h"
|
|
12
|
+
#import "ANNSlotScreenView.h"
|
|
12
13
|
#import "ANNStackController.h"
|
|
14
|
+
#import "ANNTabsDesign.h"
|
|
13
15
|
#import "ANNTitleComponentView.h"
|
|
14
16
|
#import "ANNTitleGlassView.h"
|
|
15
17
|
#import "ANNTitleView.h"
|
|
@@ -34,11 +36,27 @@ typedef NS_ENUM(NSInteger, ANNBarPhase) {
|
|
|
34
36
|
ANNBarPhaseDidAppear,
|
|
35
37
|
};
|
|
36
38
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
// The glass design of iOS 26, not its compatibility mode: the large title in the list, the title's capsule, the
|
|
40
|
+
// system subtitle and the pin of the title's color are its own (`ANNTabsDesign`).
|
|
41
|
+
static BOOL ANNIsGlass(void) {
|
|
42
|
+
return ANNTabsDesign.isGlass;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// The same look: the item's appearance is the one set last, or one equal to it.
|
|
46
|
+
static BOOL ANNSameAppearance(UINavigationBarAppearance *a, UINavigationBarAppearance *b) {
|
|
47
|
+
return a == b || [a isEqual:b];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// The traits a look's colors and fonts resolve with: the style, the contrast, the elevation (the 1×1 background is
|
|
51
|
+
// drawn with them) and the text size.
|
|
52
|
+
static NSArray *ANNLookTraitsOf(UITraitCollection *traits) {
|
|
53
|
+
if (!traits) {
|
|
54
|
+
return @[];
|
|
40
55
|
}
|
|
41
|
-
return
|
|
56
|
+
return @[
|
|
57
|
+
@(traits.userInterfaceStyle), @(traits.accessibilityContrast), @(traits.userInterfaceLevel),
|
|
58
|
+
traits.preferredContentSizeCategory ?: @""
|
|
59
|
+
];
|
|
42
60
|
}
|
|
43
61
|
|
|
44
62
|
static BOOL ANNHasComponentName(ANNComponentOptions *component) {
|
|
@@ -110,6 +128,10 @@ static ANNUserChoice *ANNRenameChoice(NSString *title) {
|
|
|
110
128
|
NSUInteger _pinToken;
|
|
111
129
|
// A pop's band under the title keeps the bar's look as it is (the screen leaves for one without a band of its own).
|
|
112
130
|
BOOL _bandKeepsLook;
|
|
131
|
+
// What the last look was filled from, and the two appearances the item held right after it.
|
|
132
|
+
NSArray *_lookInputs;
|
|
133
|
+
UINavigationBarAppearance *_lookStandard;
|
|
134
|
+
UINavigationBarAppearance *_lookEdge;
|
|
113
135
|
}
|
|
114
136
|
|
|
115
137
|
- (instancetype)initWithScreen:(UIViewController *)screen {
|
|
@@ -177,13 +199,13 @@ static ANNUserChoice *ANNRenameChoice(NSString *title) {
|
|
|
177
199
|
BOOL collapses = [ANNLargeTitlePresenter collapsesIntoList:options];
|
|
178
200
|
BOOL inlineInRow = [self inlineInRow:options];
|
|
179
201
|
BOOL ownEdge = [options.topBar.scrollEdgeAppearance.active withDefault:NO];
|
|
180
|
-
context.transparentEdge =
|
|
202
|
+
context.transparentEdge = ANNIsGlass() && collapses && !inlineInRow && !ownEdge;
|
|
181
203
|
// While a pop draws the band behind the title in the title's own place, the bar's edge stays clear: UIKit grows
|
|
182
204
|
// the bar's background with an interactive pop, over the screen's top where the title is.
|
|
183
205
|
if ([_largeTitle drawsTitleBand] && !_bandKeepsLook && !ownEdge) {
|
|
184
206
|
context.transparentEdge = YES;
|
|
185
207
|
}
|
|
186
|
-
context.largeTitleNeedsBackground =
|
|
208
|
+
context.largeTitleNeedsBackground = ANNIsGlass() && canShow && !collapses && !inlineInRow;
|
|
187
209
|
return context;
|
|
188
210
|
}
|
|
189
211
|
|
|
@@ -367,26 +389,64 @@ static ANNUserChoice *ANNRenameChoice(NSString *title) {
|
|
|
367
389
|
|
|
368
390
|
#pragma mark - The look
|
|
369
391
|
|
|
392
|
+
// Several callers ask for the look along one appearance (the screen's, a merge, the band and the pin of iOS 26): it
|
|
393
|
+
// is filled only when what the fill reads changed or the item holds another look, and set only when it differs from
|
|
394
|
+
// the item's. A look set again makes UIKit lay the bar out anew, and on iOS 26 copy it into the stack's bar.
|
|
370
395
|
- (void)applyLook:(ANNNavigationOptions *)options {
|
|
371
396
|
UIViewController *screen = _screen;
|
|
372
397
|
UINavigationItem *item = screen.navigationItem;
|
|
398
|
+
UITraitCollection *traits =
|
|
399
|
+
screen.viewIfLoaded.window.traitCollection ?: screen.traitCollection;
|
|
400
|
+
ANNBarAppearanceContext context = [self appearanceContextOf:options];
|
|
401
|
+
UITraitCollection *pinned = ANNIsGlass() ? _pinnedTraits : nil;
|
|
402
|
+
NSArray *inputs = [self lookInputsOf:options context:context traits:traits pinned:pinned];
|
|
403
|
+
if (_lookInputs && ANNOptionValuesSame(_lookInputs, inputs) &&
|
|
404
|
+
ANNSameAppearance(item.standardAppearance, _lookStandard) &&
|
|
405
|
+
ANNSameAppearance(item.scrollEdgeAppearance, _lookEdge)) {
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
373
408
|
// The screen's own looks, filled whole and set again (the item copies them).
|
|
374
409
|
UINavigationBarAppearance *standard =
|
|
375
410
|
[item.standardAppearance copy] ?: [UINavigationBarAppearance new];
|
|
376
411
|
UINavigationBarAppearance *edge =
|
|
377
412
|
[item.scrollEdgeAppearance copy] ?: [UINavigationBarAppearance new];
|
|
378
|
-
UITraitCollection *traits =
|
|
379
|
-
screen.viewIfLoaded.window.traitCollection ?: screen.traitCollection;
|
|
380
413
|
[ANNBarAppearance fillStandard:standard
|
|
381
414
|
scrollEdge:edge
|
|
382
415
|
withOptions:options
|
|
383
|
-
context:
|
|
416
|
+
context:context
|
|
384
417
|
traits:traits];
|
|
385
|
-
if (
|
|
386
|
-
[self pinTitleColorsOf:standard edge:edge options:options traits:
|
|
418
|
+
if (pinned) {
|
|
419
|
+
[self pinTitleColorsOf:standard edge:edge options:options traits:pinned];
|
|
420
|
+
}
|
|
421
|
+
if (!ANNSameAppearance(item.standardAppearance, standard)) {
|
|
422
|
+
item.standardAppearance = standard;
|
|
387
423
|
}
|
|
388
|
-
item.
|
|
389
|
-
|
|
424
|
+
if (!ANNSameAppearance(item.scrollEdgeAppearance, edge)) {
|
|
425
|
+
item.scrollEdgeAppearance = edge;
|
|
426
|
+
}
|
|
427
|
+
_lookInputs = inputs;
|
|
428
|
+
_lookStandard = item.standardAppearance;
|
|
429
|
+
_lookEdge = item.scrollEdgeAppearance;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// What `fillStandard:scrollEdge:withOptions:context:traits:` and the pin read: the bar's options by value, the
|
|
433
|
+
// image the back button's icon loads (a file written again at its path is another image), the context, the traits.
|
|
434
|
+
- (NSArray *)lookInputsOf:(ANNNavigationOptions *)options
|
|
435
|
+
context:(ANNBarAppearanceContext)context
|
|
436
|
+
traits:(UITraitCollection *)traits
|
|
437
|
+
pinned:(nullable UITraitCollection *)pinned {
|
|
438
|
+
ANNTopBarOptions *topBar = options.topBar;
|
|
439
|
+
Image *backIcon = topBar.backButton.icon;
|
|
440
|
+
ANNImageSource *source = backIcon.source;
|
|
441
|
+
BOOL loads = backIcon.hasValue && !(source && source.kind == ANNImageSourceKindSymbol);
|
|
442
|
+
id backImage = loads ? [backIcon withDefault:nil] : nil;
|
|
443
|
+
return @[
|
|
444
|
+
topBar.background, topBar.scrollEdgeAppearance, topBar.noBorder, topBar.borderColor,
|
|
445
|
+
topBar.title.font, topBar.title.color, topBar.largeTitle.font, topBar.largeTitle.color,
|
|
446
|
+
topBar.backButton, backImage ?: NSNull.null, @(context.transparentEdge),
|
|
447
|
+
@(context.largeTitleNeedsBackground), ANNLookTraitsOf(traits),
|
|
448
|
+
pinned ? ANNLookTraitsOf(pinned) : NSNull.null
|
|
449
|
+
];
|
|
390
450
|
}
|
|
391
451
|
|
|
392
452
|
// The title colors resolved for `traits`: fixed colors that don't follow the glass's style.
|
|
@@ -414,7 +474,7 @@ static ANNUserChoice *ANNRenameChoice(NSString *title) {
|
|
|
414
474
|
- (void)pinTitleColorAlong:(id<UIViewControllerTransitionCoordinator>)coordinator
|
|
415
475
|
traits:(UITraitCollection *)traits {
|
|
416
476
|
UIViewController *screen = _screen;
|
|
417
|
-
if (!screen || !
|
|
477
|
+
if (!screen || !ANNIsGlass()) {
|
|
418
478
|
return;
|
|
419
479
|
}
|
|
420
480
|
NSUInteger token = ++_pinToken;
|
|
@@ -461,7 +521,7 @@ static ANNUserChoice *ANNRenameChoice(NSString *title) {
|
|
|
461
521
|
NSString *glass = [title.glass withDefault:nil];
|
|
462
522
|
BOOL glassShows = NO;
|
|
463
523
|
if (@available(iOS 26.0, *)) {
|
|
464
|
-
glassShows = [ANNTitleGlassView isGlass:glass];
|
|
524
|
+
glassShows = ANNIsGlass() && [ANNTitleGlassView isGlass:glass];
|
|
465
525
|
}
|
|
466
526
|
[self applySubtitle:options glass:glassShows];
|
|
467
527
|
|
|
@@ -497,7 +557,7 @@ static ANNUserChoice *ANNRenameChoice(NSString *title) {
|
|
|
497
557
|
}
|
|
498
558
|
} else if (_titleComponent) {
|
|
499
559
|
titleView = _titleComponent;
|
|
500
|
-
} else if (!
|
|
560
|
+
} else if (!ANNIsGlass() && subtitle.length > 0 && !ANNLargeTitleCanShow(options)) {
|
|
501
561
|
// Before iOS 26 a subtitle is a two-label title, without a large title that can show.
|
|
502
562
|
titleView = [[ANNTitleView alloc] initWithOptions:options];
|
|
503
563
|
}
|
|
@@ -538,7 +598,8 @@ static ANNUserChoice *ANNRenameChoice(NSString *title) {
|
|
|
538
598
|
if (_native && !subtitle.text.hasValue) {
|
|
539
599
|
return;
|
|
540
600
|
}
|
|
541
|
-
|
|
601
|
+
// The compatibility mode draws no system subtitle: a two-label title shows it, as before iOS 26.
|
|
602
|
+
if (text.length == 0 || !ANNIsGlass()) {
|
|
542
603
|
item.attributedSubtitle = nil;
|
|
543
604
|
item.largeAttributedSubtitle = nil;
|
|
544
605
|
return;
|
|
@@ -590,7 +651,7 @@ static ANNUserChoice *ANNRenameChoice(NSString *title) {
|
|
|
590
651
|
return NO;
|
|
591
652
|
}
|
|
592
653
|
CGFloat height = ANNTitleRowHeight;
|
|
593
|
-
if (!
|
|
654
|
+
if (!ANNIsGlass()) {
|
|
594
655
|
if (_screen.traitCollection.userInterfaceIdiom == UIUserInterfaceIdiomPad) {
|
|
595
656
|
height = ANNTitleRowHeightPad;
|
|
596
657
|
}
|
|
@@ -1029,8 +1090,10 @@ static ANNUserChoice *ANNRenameChoice(NSString *title) {
|
|
|
1029
1090
|
ANNNavigationOptions *options = [screen resolveOptionsWithDefault];
|
|
1030
1091
|
[_largeTitle screenDidDisappear:options list:[self followedList]];
|
|
1031
1092
|
}
|
|
1032
|
-
// The lists the screen set leave with it
|
|
1033
|
-
|
|
1093
|
+
// The lists the screen set leave with it (the edge effects stay known for its next appearance); its color and its
|
|
1094
|
+
// React background leave the main list.
|
|
1095
|
+
[_edgeEffects screenDidDisappear];
|
|
1096
|
+
[self releaseListsKeepingEdgeEffects:YES];
|
|
1034
1097
|
_bandKeepsLook = NO;
|
|
1035
1098
|
// A swipe back given up: the screen keeps the bar's own look for its next appearance.
|
|
1036
1099
|
if (band && screen) {
|
|
@@ -1039,7 +1102,13 @@ static ANNUserChoice *ANNRenameChoice(NSString *title) {
|
|
|
1039
1102
|
}
|
|
1040
1103
|
|
|
1041
1104
|
- (void)releaseLists {
|
|
1042
|
-
[
|
|
1105
|
+
[self releaseListsKeepingEdgeEffects:NO];
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
- (void)releaseListsKeepingEdgeEffects:(BOOL)keepEdgeEffects {
|
|
1109
|
+
if (!keepEdgeEffects) {
|
|
1110
|
+
[_edgeEffects reset];
|
|
1111
|
+
}
|
|
1043
1112
|
[_largeTitle removeListFill];
|
|
1044
1113
|
[_largeTitle removeTitlePlaceFill];
|
|
1045
1114
|
[_largeTitle removeTitleHost];
|
|
@@ -1084,6 +1153,10 @@ static ANNUserChoice *ANNRenameChoice(NSString *title) {
|
|
|
1084
1153
|
[weakSelf contentDidMount];
|
|
1085
1154
|
}
|
|
1086
1155
|
forKey:ANNTopBarMountKey];
|
|
1156
|
+
// The edge effect walks the screen again only after a mount. A native screen's views are the app's, never told; a
|
|
1157
|
+
// screen of one tree (`appProvider`) hears the mounts only in the window, so it walks at each appearance.
|
|
1158
|
+
[self edgeEffects].mountsReported =
|
|
1159
|
+
!_native && ![content isKindOfClass:ANNSlotScreenView.class];
|
|
1087
1160
|
}
|
|
1088
1161
|
|
|
1089
1162
|
// The list the bar follows at the top edge under a large title that folds into it: the main list of a React screen;
|
|
@@ -1224,7 +1297,7 @@ static ANNUserChoice *ANNRenameChoice(NSString *title) {
|
|
|
1224
1297
|
return;
|
|
1225
1298
|
}
|
|
1226
1299
|
ANNNavigationOptions *options = [screen resolveOptionsWithDefault];
|
|
1227
|
-
BOOL eligible =
|
|
1300
|
+
BOOL eligible = ANNIsGlass() && [self isShownTop] && screen.viewIfLoaded.window != nil &&
|
|
1228
1301
|
[background isShownInBar:bar] &&
|
|
1229
1302
|
[ANNLargeTitlePresenter collapsesIntoList:options] &&
|
|
1230
1303
|
![self inlineInRow:options];
|