@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.
- package/ApexNavigation.podspec +2 -1
- package/CHANGELOG.md +128 -0
- package/README.md +147 -51
- package/android/CLAUDE.md +78 -25
- package/android/CORE.md +49 -25
- package/android/RECIPES.md +13 -6
- package/android/consumer-rules.pro +6 -0
- package/android/src/main/java/dev/apexnative/navigation/NavigationActivity.kt +85 -10
- package/android/src/main/java/dev/apexnative/navigation/NavigationApplication.kt +34 -13
- package/android/src/main/java/dev/apexnative/navigation/layout/LayoutChecks.kt +5 -1
- package/android/src/main/java/dev/apexnative/navigation/layout/LayoutNode.kt +6 -2
- package/android/src/main/java/dev/apexnative/navigation/nativescreen/NativeScreenContext.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/options/AnimationsOptions.kt +2 -2
- 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/ButtonMenuOptions.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/options/ButtonOptions.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/options/HardwareBackButtonOptions.kt +9 -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/OptionsCache.kt +8 -4
- package/android/src/main/java/dev/apexnative/navigation/options/SheetOptions.kt +7 -4
- package/android/src/main/java/dev/apexnative/navigation/options/SideMenuOptions.kt +6 -1
- package/android/src/main/java/dev/apexnative/navigation/options/StackAnimationOptions.kt +40 -2
- package/android/src/main/java/dev/apexnative/navigation/options/StatusBarOptions.kt +7 -3
- 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/options/UserChoices.kt +159 -0
- package/android/src/main/java/dev/apexnative/navigation/react/CommandAnswer.kt +29 -36
- package/android/src/main/java/dev/apexnative/navigation/react/CommandContract.kt +59 -0
- 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/ErrorTexts.kt +75 -60
- package/android/src/main/java/dev/apexnative/navigation/react/Hinge.kt +35 -23
- package/android/src/main/java/dev/apexnative/navigation/react/NavigationTurboModule.kt +12 -7
- package/android/src/main/java/dev/apexnative/navigation/react/OptionsCommands.kt +42 -4
- package/android/src/main/java/dev/apexnative/navigation/react/PendingCalls.kt +48 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ReactView.kt +54 -20
- package/android/src/main/java/dev/apexnative/navigation/react/ReloadCoordinator.kt +7 -6
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenEnvironment.kt +177 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenRegions.kt +19 -50
- package/android/src/main/java/dev/apexnative/navigation/react/ScrollEvents.kt +49 -128
- package/android/src/main/java/dev/apexnative/navigation/react/events/AppearanceDispatcher.kt +50 -81
- package/android/src/main/java/dev/apexnative/navigation/react/events/EventContract.kt +226 -0
- package/android/src/main/java/dev/apexnative/navigation/react/events/EventEmitter.kt +135 -94
- package/android/src/main/java/dev/apexnative/navigation/react/events/NavigationState.kt +154 -0
- package/android/src/main/java/dev/apexnative/navigation/react/events/ScreenAppearance.kt +0 -6
- package/android/src/main/java/dev/apexnative/navigation/safearea/SafeAreaView.kt +12 -10
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotContainers.kt +10 -7
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotScreenView.kt +39 -19
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotView.kt +16 -4
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotViews.kt +40 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/ImageKey.kt +66 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/ImageLoader.kt +7 -89
- package/android/src/main/java/dev/apexnative/navigation/utils/ImageRequests.kt +76 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/MaterialTheme.kt +5 -6
- package/android/src/main/java/dev/apexnative/navigation/utils/OptionImages.kt +262 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/SystemAnimations.kt +36 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/UiUtils.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/utils/ViewController.kt +3 -1
- 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 +10 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/SecondaryScreenPresenter.kt +13 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/AppliedTabCalls.kt +49 -0
- 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 +108 -34
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsPresenter.kt +25 -24
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowGeometry.kt +22 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabItems.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabsRoom.kt +0 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentPresenter.kt +28 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentViewController.kt +12 -9
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ContentReadiness.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/RenderWait.kt +27 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenFrame.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenReadiness.kt +103 -56
- 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/ModalAnimations.kt +22 -24
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalCoordinator.kt +109 -21
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalRecord.kt +21 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalSheet.kt +476 -73
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalViews.kt +57 -25
- 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 +83 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/BackCallbackCheck.kt +50 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/BackCallbackState.kt +49 -14
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/Navigator.kt +71 -12
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/RootCoordinator.kt +37 -11
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/overlay/OverlayCoordinator.kt +10 -8
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/Capabilities.kt +11 -4
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ContainerBackground.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ParentController.kt +6 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuController.kt +42 -9
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuMotion.kt +19 -8
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuPresenter.kt +16 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuRules.kt +43 -4
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitPanes.kt +23 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitViewController.kt +77 -17
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/BackPreview.kt +315 -0
- 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 +30 -20
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackController.kt +216 -18
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackDisplay.kt +26 -1
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackQueue.kt +149 -41
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackTransitions.kt +26 -8
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackViews.kt +115 -6
- 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 +222 -48
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/ScreenSearch.kt +3 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/StackSearchPresenter.kt +30 -34
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/BarComponents.kt +5 -51
- 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/MenuChecks.kt +13 -56
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarPresenter.kt +219 -54
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarVisibility.kt +9 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ScrollEventListener.kt +6 -9
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ViewController.kt +75 -21
- package/android/src/main/java/dev/apexnative/navigation/views/animations/AnimationLayer.kt +73 -0
- package/android/src/main/java/dev/apexnative/navigation/views/animations/Curves.kt +29 -11
- package/android/src/main/java/dev/apexnative/navigation/views/animations/ValueInterpolation.kt +14 -0
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabs.kt +9 -7
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabsLayout.kt +61 -2
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomBottomTabItemView.kt +0 -5
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomTabRow.kt +72 -10
- package/android/src/main/java/dev/apexnative/navigation/views/element/ElementStep.kt +31 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/ElementTransitions.kt +143 -135
- package/android/src/main/java/dev/apexnative/navigation/views/element/TargetsWait.kt +13 -5
- package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionLayer.kt +37 -112
- package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionTargets.kt +9 -6
- package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionViews.kt +100 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ElementPictures.kt +112 -4
- 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 +56 -41
- 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/sidemenu/SideMenuView.kt +12 -3
- package/android/src/main/java/dev/apexnative/navigation/views/stack/ScreenEdge.kt +45 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/StackLayout.kt +140 -1
- package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/Fab.kt +14 -10
- 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 -17
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TopBar.kt +73 -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 +125 -178
- 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/app.js +1 -1
- package/cli/doctor/checks/app.js +77 -14
- package/cli/doctor/checks/splash.js +4 -22
- package/cli/migrate/native.js +18 -0
- package/cli/project.js +10 -2
- package/cli/setup/index.js +18 -0
- package/cli/setup/source.js +2 -1
- package/cli/setup/steps/appDelegate.js +66 -11
- package/cli/setup/steps/mainApplication.js +134 -19
- package/cli/setup/steps/metro.js +46 -0
- package/cli/setup/steps/sceneDelegate.js +108 -0
- package/cli/splash/index.js +3 -1
- package/cli/upgrade/changelog.js +2 -2
- 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 +58 -12
- package/docs-md/containers/modals.md +8 -4
- package/docs-md/containers/overlays.md +3 -1
- package/docs-md/containers/side-menu.md +19 -2
- package/docs-md/containers/tabs.md +5 -1
- package/docs-md/flows/bottom-sheets.md +4 -2
- package/docs-md/flows/forms-in-a-modal.md +1 -1
- 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 +4 -3
- package/docs-md/guides/deep-links.md +15 -33
- package/docs-md/help/glossary.md +4 -4
- package/docs-md/help/troubleshooting.md +44 -6
- package/docs-md/index.json +57 -1
- package/docs-md/migration/from-expo-router.md +1 -1
- package/docs-md/migration/from-react-native-navigation.md +9 -3
- package/docs-md/migration/from-react-navigation.md +2 -2
- package/docs-md/screen-ui/back-and-gestures.md +46 -2
- 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 +17 -12
- 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 +21 -3
- 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 +61 -13
- package/ios/Animations/ANNTransitionPlan.h +2 -2
- package/ios/Animations/ANNTransitionPlan.mm +10 -0
- package/ios/Animations/ANNTransitionWait.mm +6 -7
- package/ios/Animations/Elements/ANNElementFinder.h +57 -0
- package/ios/Animations/Elements/ANNElementFinder.mm +174 -2
- package/ios/Animations/Elements/ANNElementTransition.h +10 -8
- package/ios/Animations/Elements/ANNElementTransition.mm +19 -21
- package/ios/Animations/Elements/ANNSharedElementFlight.h +16 -11
- package/ios/Animations/Elements/ANNSharedElementFlight.mm +308 -69
- 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 +60 -24
- package/ios/CORE.md +44 -34
- package/ios/Contract/ANNCommandAnswer.h +13 -5
- package/ios/Contract/ANNCommandAnswer.mm +40 -32
- package/ios/Contract/ANNCommandContract.h +15 -0
- package/ios/Contract/ANNCommandContract.mm +78 -0
- package/ios/Contract/ANNCommandRunner.h +10 -9
- package/ios/Contract/ANNCommandRunner.mm +22 -28
- package/ios/Contract/ANNErrorTexts.h +6 -2
- package/ios/Contract/ANNErrorTexts.mm +18 -10
- package/ios/Contract/ANNLayoutNode.h +3 -3
- package/ios/Contract/ANNLayoutReader.h +3 -3
- package/ios/Core/ANNAppDelegate.mm +0 -2
- package/ios/Core/ANNAppearanceDispatcher.h +5 -4
- package/ios/Core/ANNAppearanceDispatcher.mm +12 -1
- package/ios/Core/ANNDeepLinkQueue.h +22 -2
- package/ios/Core/ANNDeepLinkQueue.mm +121 -14
- package/ios/Core/ANNErrorHandler.h +9 -4
- package/ios/Core/ANNErrorHandler.mm +20 -2
- package/ios/Core/ANNEventContract.h +246 -0
- package/ios/Core/ANNEventContract.mm +225 -0
- package/ios/Core/ANNEventEmitter.h +6 -2
- package/ios/Core/ANNEventEmitter.mm +117 -80
- package/ios/Core/ANNHinge.h +6 -0
- package/ios/Core/ANNHinge.mm +15 -4
- package/ios/Core/ANNJavaScriptCalls.h +33 -0
- package/ios/Core/ANNJavaScriptCalls.mm +52 -0
- package/ios/Core/ANNLayoutProtocol.h +5 -5
- package/ios/Core/ANNNavigationState.h +7 -5
- package/ios/Core/ANNNavigationState.mm +8 -7
- package/ios/Core/ANNNodeHelper.h +32 -12
- package/ios/Core/ANNNodeHelper.mm +100 -3
- package/ios/Core/ANNParking.h +5 -4
- package/ios/Core/ANNReloadCoordinator.mm +5 -12
- package/ios/Core/ANNRenderWait.h +20 -6
- package/ios/Core/ANNRenderWait.mm +143 -56
- package/ios/Core/ANNSceneDelegate.mm +25 -15
- package/ios/Core/ANNSystemUI.h +3 -2
- package/ios/Core/ANNSystemUI.mm +7 -0
- package/ios/Core/ANNUtils.h +7 -0
- package/ios/Core/ANNUtils.mm +10 -0
- package/ios/Core/ApexNavigation+Internal.h +1 -1
- package/ios/Core/ApexNavigation.mm +7 -6
- package/ios/Core/UIViewController+LayoutProtocol.h +9 -2
- package/ios/Core/UIViewController+LayoutProtocol.mm +8 -0
- package/ios/Layouts/Arrangement/ANNArrangementState.h +2 -17
- package/ios/Layouts/Arrangement/ANNArrangementState.mm +0 -38
- package/ios/Layouts/Arrangement/ANNArrangementViewController.mm +10 -8
- package/ios/Layouts/Modal/ANNModalCoordinator.h +1 -1
- package/ios/Layouts/Modal/ANNModalCoordinator.mm +57 -16
- package/ios/Layouts/Modal/ANNModalPresentation.h +8 -5
- package/ios/Layouts/Modal/ANNModalPresentation.mm +12 -12
- package/ios/Layouts/Modal/ANNSheetPresenter.mm +83 -1
- package/ios/Layouts/Overlay/ANNOverlayCoordinator.mm +2 -8
- package/ios/Layouts/Root/ANNRootCoordinator.mm +58 -19
- package/ios/Layouts/Root/ANNSplashViewController.h +5 -3
- package/ios/Layouts/Root/ANNSplashViewController.mm +147 -0
- package/ios/Layouts/Screen/ANNComponentPresenter.h +11 -3
- package/ios/Layouts/Screen/ANNComponentPresenter.mm +34 -6
- package/ios/Layouts/Screen/ANNComponentViewController.h +15 -13
- package/ios/Layouts/Screen/ANNComponentViewController.mm +130 -75
- package/ios/Layouts/Screen/ANNNativeScreenContext.mm +7 -5
- 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/ANNScreenPlace.h +53 -0
- package/ios/Layouts/Screen/ANNScreenPlace.mm +205 -0
- package/ios/Layouts/Screen/ANNScreenRegions.h +3 -18
- package/ios/Layouts/Screen/ANNScreenRegions.mm +9 -44
- package/ios/Layouts/Screen/ANNScreenSafeArea.h +4 -9
- package/ios/Layouts/Screen/ANNScreenSafeArea.mm +14 -16
- package/ios/Layouts/Screen/ANNScreenSettling.h +32 -0
- package/ios/Layouts/Screen/ANNScreenSettling.mm +137 -0
- package/ios/Layouts/SideMenu/ANNSideMenuTypes.h +8 -0
- package/ios/Layouts/SideMenu/ANNSideMenuViewController.mm +83 -14
- package/ios/Layouts/SplitView/ANNSplitViewCommands.h +3 -2
- package/ios/Layouts/SplitView/ANNSplitViewCommands.mm +105 -39
- package/ios/Layouts/SplitView/ANNSplitViewController.mm +7 -8
- package/ios/Layouts/Stack/ANNPreviewPush.h +7 -6
- package/ios/Layouts/Stack/ANNPreviewPush.mm +142 -27
- package/ios/Layouts/Stack/ANNStackAnimatingDelegate.h +11 -2
- package/ios/Layouts/Stack/ANNStackAnimatingDelegate.mm +14 -7
- package/ios/Layouts/Stack/ANNStackCommands.mm +1 -0
- package/ios/Layouts/Stack/ANNStackController.h +8 -0
- package/ios/Layouts/Stack/ANNStackController.mm +184 -16
- package/ios/Layouts/Stack/ANNStackQueue.h +5 -2
- package/ios/Layouts/Stack/ANNStackQueue.mm +56 -43
- 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/Stack/UINavigationController+ANNCommands.h +4 -2
- package/ios/Layouts/Stack/UINavigationController+ANNCommands.mm +2 -3
- package/ios/Layouts/Tabs/ANNBottomTabItemBuilder.h +4 -0
- package/ios/Layouts/Tabs/ANNBottomTabItemBuilder.mm +11 -0
- package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.h +12 -1
- package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.mm +23 -0
- package/ios/Layouts/Tabs/ANNBottomTabsController.h +3 -0
- package/ios/Layouts/Tabs/ANNBottomTabsController.mm +237 -57
- package/ios/Layouts/Tabs/ANNBottomTabsCustomRow.mm +8 -3
- package/ios/Layouts/Tabs/ANNBottomTabsPresenter.h +6 -2
- package/ios/Layouts/Tabs/ANNBottomTabsPresenter.mm +232 -43
- 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/ANNOptionsCache.h +7 -6
- package/ios/Options/ANNOptionsReader.mm +108 -0
- package/ios/Options/ANNSearchBarOptions.h +4 -3
- package/ios/Options/ANNSheetOptions.h +4 -1
- package/ios/Options/ANNSideMenuOptions.h +2 -0
- package/ios/Options/ANNSideMenuOptions.mm +2 -0
- package/ios/Options/ANNStackPopAnimationOptions.h +13 -0
- package/ios/Options/ANNStackPopAnimationOptions.mm +11 -0
- package/ios/Options/ANNUserChoice.h +57 -0
- package/ios/Options/ANNUserChoice.mm +44 -0
- package/ios/Options/Params/ANNImageSource.h +61 -0
- package/ios/Options/Params/ANNImageSource.mm +101 -0
- package/ios/Options/Params/ANNOptionImages.h +37 -0
- package/ios/Options/Params/ANNOptionImages.mm +284 -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 +15 -2
- package/ios/Options/Params/Image.mm +35 -2
- package/ios/Options/Params/ImageParser.h +5 -5
- package/ios/Options/Params/ImageParser.mm +28 -46
- package/ios/Public/ApexNavigation/ANNSceneDelegate.h +3 -0
- package/ios/Public/ApexNavigation/ApexNavigation.h +1 -1
- package/ios/RECIPES.md +13 -6
- package/ios/React/ANNReactView.mm +6 -25
- package/ios/React/ANNSafeAreaViewComponentView.mm +28 -17
- package/ios/React/ANNSurfaceHostingView.h +14 -0
- package/ios/React/ANNSurfaceHostingView.mm +144 -1
- package/ios/React/Slots/ANNSlotComponentView.mm +24 -17
- package/ios/React/Slots/ANNSlotContainers.h +14 -6
- package/ios/React/Slots/ANNSlotContainers.mm +75 -2
- package/ios/React/Slots/ANNSlotHost.mm +1 -3
- 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 +14 -8
- package/ios/TopBar/ANNBarButtons.mm +397 -80
- package/ios/TopBar/ANNIconButtonImage.h +1 -0
- package/ios/TopBar/ANNIconButtonImage.mm +34 -1
- package/ios/TopBar/ANNLargeTitlePresenter.h +13 -0
- package/ios/TopBar/ANNLargeTitlePresenter.mm +50 -7
- 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 +172 -21
- package/ios/TopBar/ANNSearchResultsViewController.mm +29 -6
- package/ios/TopBar/ANNTopBarPresenter.h +8 -2
- package/ios/TopBar/ANNTopBarPresenter.mm +155 -33
- package/ios/TurboModules/ANNTurboEventEmitter.mm +4 -35
- package/ios/TurboModules/ANNTurboModule.mm +104 -33
- 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 +40 -27
- 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 +190 -66
- package/lib/module/api/app/createNavigation.js.map +1 -1
- package/lib/module/api/commands/commands.js +54 -6
- package/lib/module/api/commands/commands.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/useNavigation.js +8 -3
- package/lib/module/api/hooks/useNavigation.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/dispatchedLinks.js +23 -0
- package/lib/module/api/linking/dispatchedLinks.js.map +1 -0
- package/lib/module/api/linking/linking.js +11 -0
- package/lib/module/api/linking/linking.js.map +1 -1
- package/lib/module/api/navigation.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 +193 -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 +51 -9
- package/lib/module/engine/commands.js.map +1 -1
- package/lib/module/engine/layout.js +20 -11
- 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 +49 -15
- 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/places.js +52 -7
- package/lib/module/engine/places.js.map +1 -1
- package/lib/module/engine/props.js +30 -1
- package/lib/module/engine/props.js.map +1 -1
- package/lib/module/engine/refresh.js +85 -0
- package/lib/module/engine/refresh.js.map +1 -0
- package/lib/module/engine/rememberedOptions.js +61 -1
- package/lib/module/engine/rememberedOptions.js.map +1 -1
- package/lib/module/engine/screens.js +77 -16
- package/lib/module/engine/screens.js.map +1 -1
- package/lib/module/interfaces/contract/commands.json +101 -0
- package/lib/module/interfaces/contract/errors.json +275 -0
- package/lib/typescript/adapters/NativeANNTurboModule.d.ts +12 -2
- 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/commands/commands.d.ts.map +1 -1
- package/lib/typescript/api/commands/presentation.d.ts +4 -3
- package/lib/typescript/api/commands/presentation.d.ts.map +1 -1
- package/lib/typescript/api/events/navigationEvents.d.ts +3 -3
- package/lib/typescript/api/events/navigationEvents.d.ts.map +1 -1
- package/lib/typescript/api/hooks/useNavigation.d.ts +1 -1
- package/lib/typescript/api/hooks/useNavigation.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/dispatchedLinks.d.ts +7 -0
- package/lib/typescript/api/linking/dispatchedLinks.d.ts.map +1 -0
- 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/navigation.d.ts +4 -1
- package/lib/typescript/api/navigation.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/options.d.ts +5 -2
- package/lib/typescript/engine/options.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/places.d.ts +7 -2
- package/lib/typescript/engine/places.d.ts.map +1 -1
- package/lib/typescript/engine/props.d.ts +8 -1
- package/lib/typescript/engine/props.d.ts.map +1 -1
- 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 +4 -4
- package/lib/typescript/interfaces/ComponentEvents.d.ts.map +1 -1
- package/lib/typescript/interfaces/Events.d.ts +28 -10
- package/lib/typescript/interfaces/Events.d.ts.map +1 -1
- package/lib/typescript/interfaces/Options.d.ts +1 -1
- package/lib/typescript/interfaces/Options.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/animations.d.ts +80 -22
- package/lib/typescript/interfaces/options/animations.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/bottomTabs.d.ts +21 -7
- package/lib/typescript/interfaces/options/bottomTabs.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/buttons.d.ts +23 -15
- package/lib/typescript/interfaces/options/buttons.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/modals.d.ts +34 -26
- package/lib/typescript/interfaces/options/modals.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/sideMenu.d.ts +23 -6
- package/lib/typescript/interfaces/options/sideMenu.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/stack.d.ts +17 -3
- package/lib/typescript/interfaces/options/stack.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/system.d.ts +18 -11
- 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 +68 -38
- 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 +4 -25
- package/src/ARCHITECTURE.md +40 -27
- package/src/adapters/NativeANNTurboModule.ts +12 -2
- package/src/api/app/AppRegistry.ts +16 -2
- package/src/api/app/createNavigation.ts +203 -69
- package/src/api/commands/commands.ts +48 -7
- package/src/api/commands/presentation.ts +4 -3
- package/src/api/events/navigationEvents.ts +10 -4
- package/src/api/hooks/useNavigation.ts +9 -4
- package/src/api/hooks/useSafeAreaInsets.ts +4 -3
- package/src/api/index.ts +1 -0
- package/src/api/linking/dispatchedLinks.ts +18 -0
- package/src/api/linking/linking.ts +22 -1
- package/src/api/navigation.ts +4 -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 +185 -42
- package/src/api/theme/theme.ts +5 -0
- package/src/engine/commands.ts +70 -13
- package/src/engine/layout.ts +27 -11
- package/src/engine/nativeScreens.ts +10 -1
- package/src/engine/options.ts +45 -19
- package/src/engine/optionsChange.ts +107 -0
- package/src/engine/places.ts +65 -7
- package/src/engine/props.ts +30 -1
- package/src/engine/refresh.ts +97 -0
- package/src/engine/rememberedOptions.ts +74 -1
- package/src/engine/screens.tsx +76 -21
- package/src/interfaces/ComponentEvents.ts +4 -4
- package/src/interfaces/Events.ts +29 -10
- package/src/interfaces/Options.ts +1 -0
- package/src/interfaces/contract/commands.json +101 -0
- package/src/interfaces/contract/errors.json +275 -0
- package/src/interfaces/options/animations.ts +81 -22
- package/src/interfaces/options/bottomTabs.ts +21 -7
- package/src/interfaces/options/buttons.ts +23 -15
- package/src/interfaces/options/modals.ts +34 -26
- package/src/interfaces/options/sideMenu.ts +24 -6
- package/src/interfaces/options/stack.ts +17 -3
- package/src/interfaces/options/system.ts +18 -11
- package/src/interfaces/options/toolbar.ts +2 -2
- package/src/interfaces/options/topBar.ts +68 -38
- package/android/src/main/java/dev/apexnative/navigation/react/ArrangementStates.kt +0 -41
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenInsets.kt +0 -69
- package/android/src/main/java/dev/apexnative/navigation/react/events/NavigationStateReporter.kt +0 -62
- package/android/src/main/java/dev/apexnative/navigation/react/events/StateHold.kt +0 -62
- 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 -138
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PlainViewAnimator.kt +0 -88
- 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 -66
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextChangeAnimator.kt +0 -179
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewChangeAnimator.kt +0 -139
- package/ios/Layouts/Screen/ANNScreenInsets.h +0 -30
- package/ios/Layouts/Screen/ANNScreenInsets.mm +0 -68
- package/ios/Layouts/Tabs/ANNTabsPreloadWindow.h +0 -27
- package/ios/Layouts/Tabs/ANNTabsPreloadWindow.mm +0 -55
package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/RootCoordinator.kt
CHANGED
|
@@ -36,7 +36,8 @@ import dev.apexnative.navigation.views.animations.AnimationRules
|
|
|
36
36
|
* The modals over the old root ([ModalsOverRoot]): taken as the `setRoot` is accepted (commands don't find them), given
|
|
37
37
|
* back when it ends without replacing the root, carried with the old root into its transition and destroyed with it,
|
|
38
38
|
* without `ANN.ModalDismissed`. The modals and the overlays of the layout ([LayerStep]) show after the root, one by
|
|
39
|
-
* one, before the answer: a newer `setRoot` stops them.
|
|
39
|
+
* one, before the answer: a newer `setRoot` stops them. Its modals are made with the root ([LayerStep.prepare]) and
|
|
40
|
+
* render unseen while it waits and comes in, so each shows in its turn without a wait of its own.
|
|
40
41
|
*
|
|
41
42
|
* The steps that come later (the wait's timers and readiness signals, the end of the transition, the end of a layer,
|
|
42
43
|
* a stack of the waiting root that changed its top) run under no runner: each goes through one guard, and a failure
|
|
@@ -128,11 +129,20 @@ internal class RootCoordinator(
|
|
|
128
129
|
}
|
|
129
130
|
|
|
130
131
|
/**
|
|
131
|
-
* A modal or an overlay of the layout of a `setRoot`, shown after its root: [show]
|
|
132
|
-
* its argument once it showed or went (a failure is logged and skipped); what it
|
|
133
|
-
* a newer `setRoot`: it goes without a word.
|
|
132
|
+
* A modal or an overlay of the layout of a `setRoot`, shown after its root: [show] shows it (made then, unless
|
|
133
|
+
* [prepare] made it), and calls its argument once it showed or went (a failure is logged and skipped); what it
|
|
134
|
+
* returns stops it while it waits — a newer `setRoot`: it goes without a word.
|
|
134
135
|
*/
|
|
135
136
|
fun interface LayerStep {
|
|
137
|
+
/**
|
|
138
|
+
* Right after the root is placed, before its wait: a step may make its layer now, so that it renders unseen
|
|
139
|
+
* while the root waits and comes in, and shows without a wait of its own in its turn.
|
|
140
|
+
*/
|
|
141
|
+
fun prepare() = Unit
|
|
142
|
+
|
|
143
|
+
/** The `setRoot` ended before this step's turn: what [prepare] made goes without a word. */
|
|
144
|
+
fun discard() = Unit
|
|
145
|
+
|
|
136
146
|
fun show(done: () -> Unit): () -> Unit
|
|
137
147
|
}
|
|
138
148
|
|
|
@@ -221,6 +231,7 @@ internal class RootCoordinator(
|
|
|
221
231
|
modals.rootAccepted()
|
|
222
232
|
val waitForRender = animationsOf(root).enter.waitForRender
|
|
223
233
|
this.pending = pending
|
|
234
|
+
layers.forEach { it.prepare() }
|
|
224
235
|
firstRoot.rootSet(waitForRender)
|
|
225
236
|
await(pending, waitForRender)
|
|
226
237
|
}
|
|
@@ -229,8 +240,9 @@ internal class RootCoordinator(
|
|
|
229
240
|
/**
|
|
230
241
|
* The activity's layers go: the `setRoot` on its way ends, then the root it replaced, the current root and its root
|
|
231
242
|
* are destroyed, as at any destroy (their events reach only their own JavaScript). [answerPending]: the activity
|
|
232
|
-
* went
|
|
233
|
-
* (
|
|
243
|
+
* went; a `setRoot` whose root still waited resolves with `''` (JavaScript sets the root again in the next
|
|
244
|
+
* activity), one whose root showed (its transition ran, or the modals and overlays of its layout were showing)
|
|
245
|
+
* resolves with the root's id. Otherwise (a reload) it gets no answer.
|
|
234
246
|
*/
|
|
235
247
|
fun destroyAll(answerPending: Boolean) {
|
|
236
248
|
val pending = pending
|
|
@@ -245,7 +257,9 @@ internal class RootCoordinator(
|
|
|
245
257
|
modals.replacedRootGone()
|
|
246
258
|
pending?.let(::releaseState)
|
|
247
259
|
if (pending != null && pending.phase == Phase.Waiting) firstRoot.rootDestroyed()
|
|
248
|
-
if (answerPending
|
|
260
|
+
if (!answerPending || pending == null) return
|
|
261
|
+
// An empty id tells JavaScript the root didn't show: its start waits for the next activity and sets it there.
|
|
262
|
+
pending.answer.resolve(if (pending.phase == Phase.Waiting) "" else pending.root.id)
|
|
249
263
|
}
|
|
250
264
|
|
|
251
265
|
// Waits for the screens that show when the root shows, then runs its transition. Without `waitForRender` one limit
|
|
@@ -367,6 +381,14 @@ internal class RootCoordinator(
|
|
|
367
381
|
if (!done) pending.stopLayer = stop
|
|
368
382
|
}
|
|
369
383
|
|
|
384
|
+
// The layers of [pending] not shown yet go: what they made ahead goes unseen, the others aren't made. Each on its
|
|
385
|
+
// own: one that fails doesn't keep the others.
|
|
386
|
+
private fun discardLayers(pending: Pending) {
|
|
387
|
+
val rest = pending.layers.drop(pending.nextLayer)
|
|
388
|
+
pending.nextLayer = pending.layers.size
|
|
389
|
+
rest.forEach { attempt { it.discard() } }
|
|
390
|
+
}
|
|
391
|
+
|
|
370
392
|
// A new `setRoot` came while this one was on its way.
|
|
371
393
|
private fun supersede() {
|
|
372
394
|
val pending = pending ?: return
|
|
@@ -389,14 +411,15 @@ internal class RootCoordinator(
|
|
|
389
411
|
pending.replaced = null
|
|
390
412
|
modals.replacedRootGone()
|
|
391
413
|
}
|
|
392
|
-
// Its root is the current root: the modal or the overlay that waits now goes without a word, the others
|
|
393
|
-
// aren't made; those shown stay over its root, and go with it when the new root replaces it.
|
|
414
|
+
// Its root is the current root: the modal or the overlay that waits now goes without a word, the others go
|
|
415
|
+
// unseen or aren't made; those shown stay over its root, and go with it when the new root replaces it.
|
|
394
416
|
Phase.Layers -> {
|
|
395
417
|
pending.stopLayer?.invoke()
|
|
396
418
|
pending.stopLayer = null
|
|
397
419
|
releaseState(pending)
|
|
398
420
|
}
|
|
399
421
|
}
|
|
422
|
+
discardLayers(pending)
|
|
400
423
|
pending.answer.reject(ErrorTexts.setRootReplaced(pending.root.id))
|
|
401
424
|
}
|
|
402
425
|
|
|
@@ -426,6 +449,7 @@ internal class RootCoordinator(
|
|
|
426
449
|
pending.wait = null
|
|
427
450
|
when (pending.phase) {
|
|
428
451
|
Phase.Waiting -> {
|
|
452
|
+
discardLayers(pending)
|
|
429
453
|
attempt { takeAway(pending.root) }
|
|
430
454
|
attempt { modals.rootKept() }
|
|
431
455
|
attempt { firstRoot.rootDestroyed() }
|
|
@@ -451,6 +475,7 @@ internal class RootCoordinator(
|
|
|
451
475
|
pending.stopLayer = null
|
|
452
476
|
}
|
|
453
477
|
}
|
|
478
|
+
discardLayers(pending)
|
|
454
479
|
// A root that is up takes the splash away, as at its show.
|
|
455
480
|
if (pending.phase != Phase.Waiting) attempt { onRootShown() }
|
|
456
481
|
attempt { releaseState(pending) }
|
|
@@ -463,8 +488,8 @@ internal class RootCoordinator(
|
|
|
463
488
|
}
|
|
464
489
|
|
|
465
490
|
// The navigation state goes once, when the root is in place and its layers have shown, right before the answer:
|
|
466
|
-
// what the old root's destroy, the root's appearance and each layer ask for meanwhile waits (
|
|
467
|
-
// per `setRoot`, before the old root goes.
|
|
491
|
+
// what the old root's destroy, the root's appearance and each layer ask for meanwhile waits (the hold of
|
|
492
|
+
// NavigationState). Taken once per `setRoot`, before the old root goes.
|
|
468
493
|
private fun holdState(pending: Pending) {
|
|
469
494
|
if (pending.holdsState) return
|
|
470
495
|
pending.holdsState = true
|
|
@@ -482,6 +507,7 @@ internal class RootCoordinator(
|
|
|
482
507
|
// The root was destroyed while it waited, by something other than a newer `setRoot` or the activity going.
|
|
483
508
|
private fun rootGone(pending: Pending) {
|
|
484
509
|
this.pending = null
|
|
510
|
+
discardLayers(pending)
|
|
485
511
|
releaseState(pending)
|
|
486
512
|
layer.remove(pending.root)
|
|
487
513
|
modals.rootKept()
|
|
@@ -124,18 +124,18 @@ internal class OverlayCoordinator(
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
/**
|
|
127
|
-
* `dismissOverlay`: the
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
* overlay`.
|
|
127
|
+
* `dismissOverlay`: the overlay [componentId] is in — its root or any screen inside it — goes with every overlay of
|
|
128
|
+
* the same root id: one that waits is cancelled, one that shows goes with its events (both, when a replacement of
|
|
129
|
+
* a shown one waits). [answer] resolves with the overlay's root id, as on iOS. An id no node has: `not shown`; a
|
|
130
|
+
* node in no overlay: `not in an overlay`.
|
|
131
131
|
*/
|
|
132
132
|
fun dismiss(componentId: String, answer: CommandAnswer) {
|
|
133
|
-
|
|
134
|
-
val
|
|
135
|
-
|
|
133
|
+
val node = host.find(componentId) ?: return answer.reject(ErrorTexts.screenNotShown(componentId))
|
|
134
|
+
val rootId = recordOf(node)?.rootId ?: return answer.reject(ErrorTexts.notInOverlay(componentId))
|
|
135
|
+
val matches = records.filter { it.rootId == rootId }
|
|
136
136
|
matches.filter { it.state == OverlayRecord.State.Waiting }.forEach(::cancel)
|
|
137
137
|
val shown = matches.filter { it.state == OverlayRecord.State.Shown }
|
|
138
|
-
if (shown.isEmpty()) return answer.resolve(
|
|
138
|
+
if (shown.isEmpty()) return answer.resolve(rootId)
|
|
139
139
|
shown.dropLast(1).forEach { remove(it, null) }
|
|
140
140
|
remove(shown.last(), answer)
|
|
141
141
|
}
|
|
@@ -185,6 +185,8 @@ internal class OverlayCoordinator(
|
|
|
185
185
|
|
|
186
186
|
private fun start(make: () -> ViewController<*>, answer: CommandAnswer?, chainDone: (() -> Unit)?): OverlayRecord {
|
|
187
187
|
val root = make()
|
|
188
|
+
// Before the root's view is made: its screens are drawn under the status bar from their first layout.
|
|
189
|
+
root.shownAsOverlay = true
|
|
188
190
|
val record = OverlayRecord(root)
|
|
189
191
|
// A waiting layer before its views join the window: what is in it isn't on screen from its first layout.
|
|
190
192
|
record.screensChanged = { screensChanged(record) }
|
package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/Capabilities.kt
CHANGED
|
@@ -41,11 +41,18 @@ interface KeepsStatusBarRoom
|
|
|
41
41
|
/** A node that shows screens in its columns (the split view): `showInColumn` and `setColumnShown` go to it. */
|
|
42
42
|
interface ShowsColumns {
|
|
43
43
|
/**
|
|
44
|
-
* Shows [screen] in
|
|
45
|
-
*
|
|
46
|
-
* (
|
|
44
|
+
* Shows [screen] in [column], in place of what it shows; [listener] once it shows, or with the error reason, which
|
|
45
|
+
* names [from], the screen the command comes from. [goesInStack] says whether [screen]'s layout is what a stack
|
|
46
|
+
* takes (a screen, a native screen, a pair), not a container. False when the node doesn't take it now (its compact
|
|
47
|
+
* layout shows): the core pushes the screen over [from] instead.
|
|
47
48
|
*/
|
|
48
|
-
fun showScreen(
|
|
49
|
+
fun showScreen(
|
|
50
|
+
screen: ViewController<*>,
|
|
51
|
+
column: String,
|
|
52
|
+
goesInStack: Boolean,
|
|
53
|
+
from: ViewController<*>,
|
|
54
|
+
listener: CommandListener,
|
|
55
|
+
): Boolean
|
|
49
56
|
|
|
50
57
|
/** Shows or hides [column]; [done] once the columns have stopped moving. */
|
|
51
58
|
fun setColumnShown(column: String, shown: Boolean, done: Runnable)
|
|
@@ -31,9 +31,9 @@ internal object ContainerBackground {
|
|
|
31
31
|
if (!colour.hasValue()) return null
|
|
32
32
|
val color = colour.get(node.activity, Color.TRANSPARENT) ?: Color.TRANSPARENT
|
|
33
33
|
// The screens' band rule (`ScreenSafeArea.backgroundBand`) for a layout, which keeps no room at its top: the
|
|
34
|
-
// status bar's height, but none when it is hidden or the layout is drawn under it
|
|
35
|
-
// a pair.
|
|
36
|
-
val full = options.statusBar.isHiddenOrDrawBehind || node.isInSideMenu || node.isInSheet ||
|
|
34
|
+
// status bar's height, but none when it is hidden or the layout is drawn under it (in an overlay by default),
|
|
35
|
+
// in a side menu, a sheet or a pair.
|
|
36
|
+
val full = options.statusBar.isHiddenOrDrawBehind(node.isInOverlay) || node.isInSideMenu || node.isInSheet ||
|
|
37
37
|
node.parentController is KeepsStatusBarRoom
|
|
38
38
|
val band = if (full) 0 else SystemUiUtils.getStatusBarHeight(node.activity)
|
|
39
39
|
if (band <= 0) return ColorDrawable(color)
|
package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ParentController.kt
CHANGED
|
@@ -8,6 +8,7 @@ import dev.apexnative.navigation.react.CommandListener
|
|
|
8
8
|
import dev.apexnative.navigation.viewcontrollers.bottomtabs.TabBarMotion
|
|
9
9
|
import dev.apexnative.navigation.viewcontrollers.child.ChildController
|
|
10
10
|
import dev.apexnative.navigation.viewcontrollers.child.ChildControllersRegistry
|
|
11
|
+
import dev.apexnative.navigation.viewcontrollers.stack.StackController
|
|
11
12
|
import dev.apexnative.navigation.viewcontrollers.stack.fab.FabPlacement
|
|
12
13
|
import dev.apexnative.navigation.viewcontrollers.viewcontroller.Presenter
|
|
13
14
|
import dev.apexnative.navigation.viewcontrollers.viewcontroller.ViewController
|
|
@@ -128,12 +129,9 @@ abstract class ParentController<V : ViewGroup>(
|
|
|
128
129
|
open fun leavesTopEdgeFree(child: ViewController<*>): Boolean =
|
|
129
130
|
parentController?.leavesTopEdgeFree(this) ?: false
|
|
130
131
|
|
|
131
|
-
/**
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
*/
|
|
135
|
-
open fun leavesBottomEdgeFree(child: ViewController<*>, screen: ViewController<*> = child): Boolean =
|
|
136
|
-
parentController?.leavesBottomEdgeFree(this, screen) ?: false
|
|
132
|
+
/** Whether a large title shows over [child]: its stack shows the bar with one. No by default. */
|
|
133
|
+
open fun showsLargeTitleOver(child: ViewController<*>): Boolean =
|
|
134
|
+
parentController?.showsLargeTitleOver(this) ?: false
|
|
137
135
|
|
|
138
136
|
/**
|
|
139
137
|
* The tab bar at rest under [child]: where a stack's FAB keeps clear of it, by the options of [screen], the stack's
|
|
@@ -210,6 +208,8 @@ abstract class ParentController<V : ViewGroup>(
|
|
|
210
208
|
|
|
211
209
|
override fun canHandleBack(): Boolean = getCurrentChild()?.canHandleBack() == true
|
|
212
210
|
|
|
211
|
+
override fun stackPoppedByBack(): StackController? = getCurrentChild()?.stackPoppedByBack()
|
|
212
|
+
|
|
213
213
|
override fun destroy() {
|
|
214
214
|
if (isDestroyed) return
|
|
215
215
|
getChildControllers().forEach { it.destroy() }
|
|
@@ -16,6 +16,7 @@ import dev.apexnative.navigation.viewcontrollers.navigator.Navigator
|
|
|
16
16
|
import dev.apexnative.navigation.viewcontrollers.parent.ChildOffsetFromRest
|
|
17
17
|
import dev.apexnative.navigation.viewcontrollers.parent.ParentController
|
|
18
18
|
import dev.apexnative.navigation.viewcontrollers.sidemenu.SideMenuMotion.Side
|
|
19
|
+
import dev.apexnative.navigation.viewcontrollers.stack.StackController
|
|
19
20
|
import dev.apexnative.navigation.viewcontrollers.viewcontroller.Presenter
|
|
20
21
|
import dev.apexnative.navigation.viewcontrollers.viewcontroller.ViewController
|
|
21
22
|
import dev.apexnative.navigation.views.sidemenu.SideMenuView
|
|
@@ -28,7 +29,8 @@ import dev.apexnative.navigation.views.sidemenu.SideMenuView
|
|
|
28
29
|
* - The current child is the open menu's node, else the center ([SideMenuMotion.openSide]: from the end of the
|
|
29
30
|
* opening to the end of the closing); the state, the options and back follow it.
|
|
30
31
|
* - The center and the open menu show with the side menu ([visibleChildren]); a wait for the side menu to render
|
|
31
|
-
* waits for the center ([waitedChildren]); the menus' views
|
|
32
|
+
* waits for the center ([waitedChildren]); the menus' views join the drawer as `sideMenu.menusAttachMode` says
|
|
33
|
+
* ([attached]): with the side menu's view, once it first appeared, or each as it first starts to show.
|
|
32
34
|
* - Its options ([SideMenuPresenter]): from the resolution of [resolveShownOptions] at creation, at every appearance
|
|
33
35
|
* of a screen inside, and for the fields a merge names; `sideMenu.<side>.visible` acts once, from a merge or from the
|
|
34
36
|
* layout at the first show. What goes on up goes without `sideMenu`: the nearest side menu acts.
|
|
@@ -63,6 +65,12 @@ internal class SideMenuController(
|
|
|
63
65
|
// From the end of its appearance's start until it disappears: the drawer's motion tells the menu screens then.
|
|
64
66
|
private var appeared = false
|
|
65
67
|
private var firstShown = false
|
|
68
|
+
private var firstAppeared = false
|
|
69
|
+
|
|
70
|
+
private val attachMode = SideMenuRules.attachModeOf(initialOptions.sideMenu, DefaultOptions.current.sideMenu)
|
|
71
|
+
|
|
72
|
+
/** The menus whose nodes' views are in the drawer, or join it as it is made. */
|
|
73
|
+
internal val attached = HashSet<Side>(2)
|
|
66
74
|
// Its children go first as it is destroyed: nothing reacts to them, nor to the drawer, from the start.
|
|
67
75
|
private var destroying = false
|
|
68
76
|
|
|
@@ -71,6 +79,7 @@ internal class SideMenuController(
|
|
|
71
79
|
|
|
72
80
|
init {
|
|
73
81
|
getChildControllers().forEach { it.parentController = this }
|
|
82
|
+
SideMenuRules.attachedAtCreation(attachMode).filter { childOf(it) != null }.forEach { attached += it }
|
|
74
83
|
}
|
|
75
84
|
|
|
76
85
|
override fun getChildControllers(): List<ViewController<*>> = listOfNotNull(center, left, right)
|
|
@@ -87,13 +96,16 @@ internal class SideMenuController(
|
|
|
87
96
|
|
|
88
97
|
private fun childOf(side: Side): ViewController<*>? = if (side == Side.Left) left else right
|
|
89
98
|
|
|
90
|
-
// The drawer and its parts, each node
|
|
91
|
-
// view existed is open in it from the start; the drawer is silent before its first layout.
|
|
99
|
+
// The drawer and its parts, the view of each node attached so far in its part; the creation's options. An open menu
|
|
100
|
+
// recorded before the view existed is open in it from the start; the drawer is silent before its first layout.
|
|
92
101
|
override fun createView(): SideMenuView {
|
|
93
102
|
val view = SideMenuView(activity)
|
|
94
103
|
view.setCenter(center.view)
|
|
95
|
-
|
|
96
|
-
|
|
104
|
+
for (side in Side.entries) {
|
|
105
|
+
val child = childOf(side) ?: continue
|
|
106
|
+
view.addPart(side)
|
|
107
|
+
if (side in attached) view.fillPart(side, child.view)
|
|
108
|
+
}
|
|
97
109
|
menus.applyOnCreation(view, resolveShownOptions(DefaultOptions.current))
|
|
98
110
|
motion.openSide?.let { view.open(it, false) }
|
|
99
111
|
view.follow(motion)
|
|
@@ -130,7 +142,7 @@ internal class SideMenuController(
|
|
|
130
142
|
|
|
131
143
|
// `mergeOptions` with the side menu's id: its own options, then what a merge does, then the layouts around.
|
|
132
144
|
override fun mergeOptions(options: Options) {
|
|
133
|
-
|
|
145
|
+
mergeOwnOptions(options)
|
|
134
146
|
applyMerge(options)
|
|
135
147
|
performOnParentController { it.mergeChildOptions(SideMenuRules.withoutSideMenu(options), this) }
|
|
136
148
|
}
|
|
@@ -171,6 +183,14 @@ internal class SideMenuController(
|
|
|
171
183
|
motion.containerAppeared()
|
|
172
184
|
}
|
|
173
185
|
|
|
186
|
+
// `afterCenter`: the menus join once the side menu first appeared with its center.
|
|
187
|
+
override fun onViewDidAppear() {
|
|
188
|
+
super.onViewDidAppear()
|
|
189
|
+
if (firstAppeared || destroying || isDestroyed) return
|
|
190
|
+
firstAppeared = true
|
|
191
|
+
SideMenuRules.attachedAfterAppearance(attachMode).forEach(::attach)
|
|
192
|
+
}
|
|
193
|
+
|
|
174
194
|
override fun onViewDisappear() {
|
|
175
195
|
appeared = false
|
|
176
196
|
motion.containerDisappeared()
|
|
@@ -183,6 +203,9 @@ internal class SideMenuController(
|
|
|
183
203
|
|
|
184
204
|
override fun canHandleBack(): Boolean = motion.canGoBack || center.canHandleBack()
|
|
185
205
|
|
|
206
|
+
// An open menu closes first: no preview of a pop then.
|
|
207
|
+
override fun stackPoppedByBack(): StackController? = if (motion.canGoBack) null else center.stackPoppedByBack()
|
|
208
|
+
|
|
186
209
|
// A button's press addressed to the side menu goes to the center.
|
|
187
210
|
override fun sendOnNavigationButtonPressed(buttonId: String) = center.sendOnNavigationButtonPressed(buttonId)
|
|
188
211
|
|
|
@@ -218,6 +241,16 @@ internal class SideMenuController(
|
|
|
218
241
|
if (child === currentChild) super.tabBarSettled(child)
|
|
219
242
|
}
|
|
220
243
|
|
|
244
|
+
// The view of the menu on [side] joins its part, once, before its screens hear that they appear: a stack lays out
|
|
245
|
+
// its bar as it appears in the window. The drawer's first movement may come while it draws (a peek settles in
|
|
246
|
+
// `computeScroll`, before the drawer draws its children): the view joins the part then, measured and laid out at the
|
|
247
|
+
// next frame.
|
|
248
|
+
private fun attach(side: Side) {
|
|
249
|
+
val child = childOf(side) ?: return
|
|
250
|
+
if (destroying || isDestroyed || !attached.add(side)) return
|
|
251
|
+
peekView()?.fillPart(side, child.view)
|
|
252
|
+
}
|
|
253
|
+
|
|
221
254
|
/** Destroys the side menu once: the drawer's callbacks stop first, then the children go. */
|
|
222
255
|
override fun destroy() {
|
|
223
256
|
if (isDestroyed) return
|
|
@@ -234,6 +267,8 @@ internal class SideMenuController(
|
|
|
234
267
|
|
|
235
268
|
override fun child(side: Side): ViewController<*>? = childOf(side)
|
|
236
269
|
|
|
270
|
+
override fun starts(side: Side) = attach(side)
|
|
271
|
+
|
|
237
272
|
override fun isEnabled(side: Side): Boolean =
|
|
238
273
|
SideMenuRules.isEnabled(resolveShownOptions(DefaultOptions.current).sideMenu, side)
|
|
239
274
|
|
|
@@ -255,9 +290,7 @@ internal class SideMenuController(
|
|
|
255
290
|
}
|
|
256
291
|
|
|
257
292
|
// The system UI follows the screen the user sees now, at rest: the open menu's, the center's once a close
|
|
258
|
-
// ends. The owner reads it before the next frame, when a menu that closed is hidden already.
|
|
259
|
-
// animation runs this inside `AppearanceDispatcher.withoutWillAppear`: what starts to appear from here would
|
|
260
|
-
// send no WillAppear.
|
|
293
|
+
// ends. The owner reads it before the next frame, when a menu that closed is hidden already.
|
|
261
294
|
override fun shownChanged() {
|
|
262
295
|
navigator?.shownScreensChanged(this@SideMenuController)
|
|
263
296
|
navigator?.systemUi?.invalidate()
|
package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuMotion.kt
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
package dev.apexnative.navigation.viewcontrollers.sidemenu
|
|
2
2
|
|
|
3
3
|
import dev.apexnative.navigation.react.events.AppearanceDispatcher
|
|
4
|
+
import dev.apexnative.navigation.utils.SystemAnimations
|
|
4
5
|
import dev.apexnative.navigation.viewcontrollers.viewcontroller.ViewController
|
|
5
6
|
|
|
6
7
|
/**
|
|
@@ -16,8 +17,8 @@ import dev.apexnative.navigation.viewcontrollers.viewcontroller.ViewController
|
|
|
16
17
|
* the drawer calls `onDrawerClosed` only for a drawer that had opened.
|
|
17
18
|
* - The menu screen's events: WillAppear at the side's first movement, DidAppear when it opened, DidDisappear when it
|
|
18
19
|
* rests closed; only while the side menu has appeared ([Host.appeared]) — otherwise they come with the side menu's
|
|
19
|
-
* own appearance (its visible children). An open without animation sends
|
|
20
|
-
*
|
|
20
|
+
* own appearance (its visible children). An open without animation sends both too, WillAppear first, as on iOS:
|
|
21
|
+
* the drawer jumps to its open offset before it calls the open.
|
|
21
22
|
* - At each rest: one state update after the menu's events, the back callback, and the layers that follow the shown
|
|
22
23
|
* screen.
|
|
23
24
|
* - A drawer that doesn't call back (not laid out since it joined the window, or not in one: `DrawerLayout` only
|
|
@@ -26,6 +27,8 @@ import dev.apexnative.navigation.viewcontrollers.viewcontroller.ViewController
|
|
|
26
27
|
internal class SideMenuMotion(
|
|
27
28
|
private val drawer: () -> Drawer,
|
|
28
29
|
private val host: Host,
|
|
30
|
+
/** The system's animations are off ([SystemAnimations]): a command or back moves the drawer at once. */
|
|
31
|
+
private val animationsOff: () -> Boolean = { SystemAnimations.areOff() },
|
|
29
32
|
) {
|
|
30
33
|
/** A side of the side menu: physical, `left` stays on the left in RTL too. */
|
|
31
34
|
enum class Side(
|
|
@@ -79,6 +82,12 @@ internal class SideMenuMotion(
|
|
|
79
82
|
/** `sideMenu.<side>.enabled` of the side menu's options now. */
|
|
80
83
|
fun isEnabled(side: Side): Boolean
|
|
81
84
|
|
|
85
|
+
/**
|
|
86
|
+
* The menu on [side] starts to show: the drawer's first movement, or a command that opens it. Before its
|
|
87
|
+
* screen hears that it appears.
|
|
88
|
+
*/
|
|
89
|
+
fun starts(side: Side)
|
|
90
|
+
|
|
82
91
|
/** `visible: true` for a side the layout doesn't have: a warning, nothing else. */
|
|
83
92
|
fun missingSide(side: Side)
|
|
84
93
|
|
|
@@ -119,6 +128,7 @@ internal class SideMenuMotion(
|
|
|
119
128
|
fun slid(side: Side, offset: Float) {
|
|
120
129
|
// Not more than 0 also takes a NaN: `DrawerLayout` divides by the drawer's width, which may be 0.
|
|
121
130
|
if (destroyed || !(offset > 0f)) return
|
|
131
|
+
if (!isOnScreen(side)) host.starts(side)
|
|
122
132
|
onScreen += side
|
|
123
133
|
if (side in appearing || !host.appeared) return
|
|
124
134
|
appearing += side
|
|
@@ -204,6 +214,7 @@ internal class SideMenuMotion(
|
|
|
204
214
|
}
|
|
205
215
|
// Never decided by where the other menu is: a side asked to open in the same merge hasn't moved yet.
|
|
206
216
|
if (drawer.has(side.other)) move(side.other, open = false, animate = animated)
|
|
217
|
+
if (!isOnScreen(side)) host.starts(side)
|
|
207
218
|
onScreen += side
|
|
208
219
|
// A locked menu opened from code can be dragged closed while it is open.
|
|
209
220
|
drawer.lock(side, locked = false)
|
|
@@ -242,15 +253,15 @@ internal class SideMenuMotion(
|
|
|
242
253
|
drawer.lock(side, locked = !isOnScreen(side) && !host.isEnabled(side))
|
|
243
254
|
}
|
|
244
255
|
|
|
245
|
-
// The drawer opens or closes [side]; one that doesn't call back has its result recorded here.
|
|
256
|
+
// The drawer opens or closes [side]; one that doesn't call back has its result recorded here. With the system's
|
|
257
|
+
// animations off it jumps, unless it moves: the drag and the settle aren't animators, and it can't jump while it
|
|
258
|
+
// settles.
|
|
246
259
|
private fun move(side: Side, open: Boolean, animate: Boolean) {
|
|
247
260
|
val drawer = drawer()
|
|
261
|
+
val animated = animate && (moving || !animationsOff())
|
|
248
262
|
val silent = !drawer.callsBack
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
if (silent) record(side, open)
|
|
252
|
-
}
|
|
253
|
-
if (open && !animate && host.appeared) AppearanceDispatcher.withoutWillAppear(run) else run()
|
|
263
|
+
if (open) drawer.open(side, animated) else drawer.close(side, animated)
|
|
264
|
+
if (silent) record(side, open)
|
|
254
265
|
}
|
|
255
266
|
|
|
256
267
|
private fun record(side: Side, open: Boolean) {
|
|
@@ -18,15 +18,14 @@ import dev.apexnative.navigation.views.sidemenu.SideMenuView
|
|
|
18
18
|
* `testID`s. Each moment applies its part, from the side menu's resolved options
|
|
19
19
|
* (`SideMenuController.resolveShownOptions`: the current part's chain, the center's `sideMenu` over an open menu's) —
|
|
20
20
|
* at creation everything with the heights, at every appearance of a screen inside everything but the heights, at a
|
|
21
|
-
* merge the fields it names
|
|
21
|
+
* merge the fields it names (a width or a height at once, an open menu too), at a repaint the background and the
|
|
22
|
+
* `testID`s. The locks of `enabled` and the command
|
|
22
23
|
* `visible` are the node's ([SideMenuMotion]). Main thread only.
|
|
23
24
|
*/
|
|
24
25
|
internal class SideMenuPresenter(activity: Activity) : Presenter(activity, Options()) {
|
|
25
|
-
/** The side menu's [view] is made, with [options], resolved: the heights,
|
|
26
|
+
/** The side menu's [view] is made, with [options], resolved: the heights too, which only a merge changes after. */
|
|
26
27
|
fun applyOnCreation(view: SideMenuView, options: Options) {
|
|
27
|
-
|
|
28
|
-
view.setPartHeight(side, SideMenuRules.height(SideMenuRules.sideOf(options.sideMenu, side), ::toPixels))
|
|
29
|
-
}
|
|
28
|
+
applyHeights(view, options.sideMenu)
|
|
30
29
|
applyWidths(view, options.sideMenu)
|
|
31
30
|
applyBackground(view, options)
|
|
32
31
|
applyTestIds(view, options.sideMenu)
|
|
@@ -46,14 +45,18 @@ internal class SideMenuPresenter(activity: Activity) : Presenter(activity, Optio
|
|
|
46
45
|
/**
|
|
47
46
|
* A merge reached the side menu, its own or through a screen inside (`mergeOptions` step 3): the fields [options]
|
|
48
47
|
* name, with the values of the side menu's resolution now, so a screen off what shows changes nothing until it
|
|
49
|
-
* appears. A width
|
|
48
|
+
* appears. A width or a height resizes its menu at once, open or closed, as on iOS.
|
|
50
49
|
*/
|
|
51
50
|
override fun mergeOptions(viewController: ViewController<*>, options: Options) {
|
|
52
51
|
val layout = viewController.peekView() as? SideMenuView ?: return
|
|
53
52
|
val touchesBackground = SideMenuRules.touchesBackground(options)
|
|
54
53
|
val touchesTestIds = SideMenuRules.touchesTestIds(options.sideMenu)
|
|
55
|
-
|
|
54
|
+
val touchesWidths = SideMenuRules.touchesWidths(options.sideMenu)
|
|
55
|
+
val touchesHeights = SideMenuRules.touchesHeights(options.sideMenu)
|
|
56
|
+
if (!touchesBackground && !touchesTestIds && !touchesWidths && !touchesHeights) return
|
|
56
57
|
val shown = viewController.resolveShownOptions(DefaultOptions.current)
|
|
58
|
+
if (touchesWidths) applyWidths(layout, shown.sideMenu)
|
|
59
|
+
if (touchesHeights) applyHeights(layout, shown.sideMenu)
|
|
57
60
|
if (touchesBackground) applyBackground(layout, shown)
|
|
58
61
|
if (touchesTestIds) applyTestIds(layout, shown.sideMenu)
|
|
59
62
|
}
|
|
@@ -71,6 +74,12 @@ internal class SideMenuPresenter(activity: Activity) : Presenter(activity, Optio
|
|
|
71
74
|
}
|
|
72
75
|
}
|
|
73
76
|
|
|
77
|
+
private fun applyHeights(view: SideMenuView, options: SideMenuOptions) {
|
|
78
|
+
for (side in Side.entries) {
|
|
79
|
+
view.setPartHeight(side, SideMenuRules.height(SideMenuRules.sideOf(options, side), ::toPixels))
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
74
83
|
// `layout.backgroundColor` on the drawer, its whole height, under the status bar; unset leaves the view as it is,
|
|
75
84
|
// `'NoColor'` clears it.
|
|
76
85
|
private fun applyBackground(view: View, options: Options) {
|
package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuRules.kt
CHANGED
|
@@ -11,11 +11,23 @@ import kotlin.math.min
|
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* What the options of a side menu do on Android (`sideMenu.*`), without views: the values of each moment, `visible` as
|
|
14
|
-
* a command, the sizes, the `testID`s. Android reads `enabled`, `width`, `height`,
|
|
15
|
-
* `testID`s of `sideMenu`; `openGestureMode`, `animationType`,
|
|
16
|
-
* and `glass` are iOS's.
|
|
14
|
+
* a command, the sizes, the `testID`s, when the menus join the drawer. Android reads `enabled`, `width`, `height`,
|
|
15
|
+
* `visible`, `animate`, `menusAttachMode` and the `testID`s of `sideMenu`; `openGestureMode`, `animationType`,
|
|
16
|
+
* `openMode`, `shouldStretchDrawer`, `animationVelocity` and `glass` are iOS's.
|
|
17
17
|
*/
|
|
18
18
|
internal object SideMenuRules {
|
|
19
|
+
/** When the views of the menus' nodes join the drawer (`sideMenu.menusAttachMode`): their content renders then. */
|
|
20
|
+
enum class AttachMode {
|
|
21
|
+
/** With the side menu's view. */
|
|
22
|
+
Together,
|
|
23
|
+
|
|
24
|
+
/** Once the side menu first appeared, with its center. */
|
|
25
|
+
AfterCenter,
|
|
26
|
+
|
|
27
|
+
/** Each as it first starts to show: the drawer's first movement, or a command that opens it. */
|
|
28
|
+
OnOpen,
|
|
29
|
+
}
|
|
30
|
+
|
|
19
31
|
/** A side's `visible` of one merge: open or close it, with its `animate`. */
|
|
20
32
|
data class Command(val side: Side, val visible: Boolean, val animate: Boolean)
|
|
21
33
|
|
|
@@ -43,6 +55,26 @@ internal object SideMenuRules {
|
|
|
43
55
|
*/
|
|
44
56
|
fun firstShow(layout: SideMenuOptions): List<Side> = Side.entries.filter { sideOf(layout, it).visible.isTrue }
|
|
45
57
|
|
|
58
|
+
/**
|
|
59
|
+
* The mode of `sideMenu.menusAttachMode`: the side menu's [own] options, else the [defaults]; `together` without
|
|
60
|
+
* either. Read once, as the side menu is made.
|
|
61
|
+
*/
|
|
62
|
+
fun attachModeOf(own: SideMenuOptions, defaults: SideMenuOptions): AttachMode {
|
|
63
|
+
val value = own.menusAttachMode.takeIf { it.hasValue() } ?: defaults.menusAttachMode
|
|
64
|
+
return when (value.get(null)) {
|
|
65
|
+
"afterCenter" -> AttachMode.AfterCenter
|
|
66
|
+
"onOpen" -> AttachMode.OnOpen
|
|
67
|
+
else -> AttachMode.Together
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** The menus that join as the side menu is made: both with `together`. */
|
|
72
|
+
fun attachedAtCreation(mode: AttachMode): List<Side> = if (mode == AttachMode.Together) Side.entries else emptyList()
|
|
73
|
+
|
|
74
|
+
/** The menus that join once the side menu first appeared: both with `afterCenter`. */
|
|
75
|
+
fun attachedAfterAppearance(mode: AttachMode): List<Side> =
|
|
76
|
+
if (mode == AttachMode.AfterCenter) Side.entries else emptyList()
|
|
77
|
+
|
|
46
78
|
/** `enabled` of [side]: true unless `false`, from the side menu's resolved options. */
|
|
47
79
|
fun isEnabled(options: SideMenuOptions, side: Side): Boolean = !sideOf(options, side).enabled.isFalse
|
|
48
80
|
|
|
@@ -54,6 +86,13 @@ internal object SideMenuRules {
|
|
|
54
86
|
fun touchesTestIds(merge: SideMenuOptions): Boolean =
|
|
55
87
|
merge.testID.hasValue() || merge.left.testID.hasValue() || merge.right.testID.hasValue()
|
|
56
88
|
|
|
89
|
+
/** A merge names `width` of a side: the menus take their widths again. */
|
|
90
|
+
fun touchesWidths(merge: SideMenuOptions): Boolean = merge.left.width.hasValue() || merge.right.width.hasValue()
|
|
91
|
+
|
|
92
|
+
/** A merge names `height` of a side: the menus take their heights again. */
|
|
93
|
+
fun touchesHeights(merge: SideMenuOptions): Boolean =
|
|
94
|
+
merge.left.height.hasValue() || merge.right.height.hasValue()
|
|
95
|
+
|
|
57
96
|
/** A merge names the background of the side menu (`layout.backgroundColor`). */
|
|
58
97
|
fun touchesBackground(merge: Options): Boolean = merge.layout.backgroundColor.hasValue()
|
|
59
98
|
|
|
@@ -64,7 +103,7 @@ internal object SideMenuRules {
|
|
|
64
103
|
fun wantedWidth(options: SideMenuSideOptions, toPixels: (Double) -> Int): Int? =
|
|
65
104
|
options.width.get(null)?.let { max(0, toPixels(it)) }
|
|
66
105
|
|
|
67
|
-
/** The height of a side, in pixels: `height` (dp) by [toPixels]
|
|
106
|
+
/** The height of a side, in pixels: `height` (dp) by [toPixels]; none: the whole height. */
|
|
68
107
|
fun height(options: SideMenuSideOptions, toPixels: (Double) -> Int): Int? =
|
|
69
108
|
options.height.get(null)?.let { max(0, toPixels(it)) }
|
|
70
109
|
|
package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitPanes.kt
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
package dev.apexnative.navigation.viewcontrollers.splitview
|
|
2
2
|
|
|
3
3
|
import android.content.Context
|
|
4
|
+
import android.view.View
|
|
5
|
+
import android.view.ViewGroup
|
|
4
6
|
import android.view.WindowInsets
|
|
5
7
|
import androidx.core.graphics.Insets
|
|
6
8
|
import androidx.core.view.WindowInsetsCompat
|
|
@@ -14,6 +16,27 @@ class SplitPanes(context: Context) : SlidingPaneLayout(context) {
|
|
|
14
16
|
/** The panes are side by side. */
|
|
15
17
|
var isSideBySide = false
|
|
16
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Puts [next] in the place of the pane [old], with the structure and the params [old] had. The library wraps the
|
|
21
|
+
* second view it is given in a view of its own that holds back touches (`addView` with one child there), and its
|
|
22
|
+
* `removeView` takes that wrapper away: a plain remove and add would wrap a new primary pane, or give a new
|
|
23
|
+
* secondary one the wrapper's params, and lose its width and weight. So the secondary pane's content changes
|
|
24
|
+
* inside the wrapper, and a new primary pane goes in before the old one leaves, while two children are there.
|
|
25
|
+
*/
|
|
26
|
+
internal fun replacePane(old: View, next: View) {
|
|
27
|
+
val holder = old.parent as? ViewGroup ?: return
|
|
28
|
+
val params = old.layoutParams
|
|
29
|
+
if (holder === this) {
|
|
30
|
+
// A copy: the width that `splitView.width` changes later is the new pane's own.
|
|
31
|
+
addView(next, indexOfChild(old), if (params is LayoutParams) LayoutParams(params) else params)
|
|
32
|
+
removeView(old)
|
|
33
|
+
} else {
|
|
34
|
+
val index = holder.indexOfChild(old)
|
|
35
|
+
holder.removeView(old)
|
|
36
|
+
holder.addView(next, index, params)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
17
40
|
override fun dispatchApplyWindowInsets(insets: WindowInsets): WindowInsets {
|
|
18
41
|
if (!isSideBySide) return super.dispatchApplyWindowInsets(insets)
|
|
19
42
|
val own = onApplyWindowInsets(insets)
|