@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
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
package dev.apexnative.navigation.viewcontrollers.bottomtabs
|
|
2
|
+
|
|
3
|
+
import dev.apexnative.navigation.utils.ImageKey
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The last call of each kind for each item of the bar, by which [BottomTabsPresenter.run] skips a call equal to it: an
|
|
7
|
+
* icon isn't loaded and set again as a screen appears. The badge and the font always go (their defaults are read at
|
|
8
|
+
* each set). An icon whose load gave no image goes again ([failed]); a `file:` icon compares by its [ImageKey] (the
|
|
9
|
+
* file's modification time and size, read by [fileKey]), so a file written again at the same path shows. Main thread.
|
|
10
|
+
*/
|
|
11
|
+
internal class AppliedTabCalls(private val fileKey: (String) -> ImageKey) {
|
|
12
|
+
/** A call that runs: [isChange], the item had a call of its kind before; [image], the key of a `file:` icon. */
|
|
13
|
+
class Next(val isChange: Boolean, val image: ImageKey?)
|
|
14
|
+
|
|
15
|
+
private class Applied(val call: TabItems.Call, val image: ImageKey?, var failed: Boolean = false)
|
|
16
|
+
|
|
17
|
+
private val last = HashMap<Pair<Int, Class<*>>, Applied>()
|
|
18
|
+
|
|
19
|
+
/** How [call] runs, and it is the last of its kind for its item from now on; none when it is skipped. */
|
|
20
|
+
fun next(call: TabItems.Call): Next? {
|
|
21
|
+
val key = call.index to call.javaClass
|
|
22
|
+
val before = last[key]
|
|
23
|
+
val image = uriOf(call)?.takeIf { it.startsWith(FILE_SCHEME) }?.let(fileKey)
|
|
24
|
+
val always = call is TabItems.Call.Badge || call is TabItems.Call.Font
|
|
25
|
+
if (!always && before != null && before.call == call && !before.failed && before.image == image) return null
|
|
26
|
+
last[key] = Applied(call, image)
|
|
27
|
+
return Next(isChange = before != null, image = image)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** The icon of [call] didn't load: the same call goes again. */
|
|
31
|
+
fun failed(call: TabItems.Call) {
|
|
32
|
+
last[call.index to call.javaClass]?.takeIf { it.call == call }?.failed = true
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** The bar goes: every call goes again. */
|
|
36
|
+
fun clear() {
|
|
37
|
+
last.clear()
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
private fun uriOf(call: TabItems.Call): String? = when (call) {
|
|
41
|
+
is TabItems.Call.Icon -> call.uri
|
|
42
|
+
is TabItems.Call.SelectedIcon -> call.uri
|
|
43
|
+
else -> null
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private companion object {
|
|
47
|
+
const val FILE_SCHEME = "file:"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -2,6 +2,7 @@ package dev.apexnative.navigation.viewcontrollers.bottomtabs
|
|
|
2
2
|
|
|
3
3
|
import android.view.View
|
|
4
4
|
import dev.apexnative.navigation.viewcontrollers.viewcontroller.ScrollEventListener
|
|
5
|
+
import dev.apexnative.navigation.views.bottomtabs.BottomTabsLayout
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* bottomTabs.hideOnScroll: the tabs hide after a drag that scrolls the screen's content down and come back after one
|
|
@@ -43,9 +44,10 @@ class BottomTabsCollapseBehavior(private val container: () -> View?) :
|
|
|
43
44
|
override fun onHide() {
|
|
44
45
|
val view = container() ?: return
|
|
45
46
|
hiddenByScroll = true
|
|
46
|
-
// Out of the screen with what is under it
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
// Out of the screen with what is under it (a compact bar floats over its bottom margin and the navigation bar)
|
|
48
|
+
// and the custom row that rises above it.
|
|
49
|
+
val distance = (view.parent as? BottomTabsLayout)?.hideDistance ?: view.height
|
|
50
|
+
view.animate().translationY(distance.toFloat()).setDuration(DURATION).start()
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
private companion object {
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
package dev.apexnative.navigation.viewcontrollers.bottomtabs
|
|
2
2
|
|
|
3
|
+
import android.animation.Animator
|
|
4
|
+
import android.animation.AnimatorListenerAdapter
|
|
5
|
+
import android.animation.AnimatorSet
|
|
3
6
|
import android.app.Activity
|
|
4
7
|
import android.graphics.Color
|
|
5
8
|
import android.util.Log
|
|
@@ -23,16 +26,16 @@ import dev.apexnative.navigation.utils.scrollToTop
|
|
|
23
26
|
import dev.apexnative.navigation.viewcontrollers.child.ChildControllersRegistry
|
|
24
27
|
import dev.apexnative.navigation.viewcontrollers.component.ComponentViewController
|
|
25
28
|
import dev.apexnative.navigation.viewcontrollers.component.RestPlace
|
|
26
|
-
import dev.apexnative.navigation.viewcontrollers.component.ScreenReadiness
|
|
27
29
|
import dev.apexnative.navigation.viewcontrollers.navigator.BackCallbackState
|
|
28
30
|
import dev.apexnative.navigation.viewcontrollers.navigator.Navigator
|
|
29
31
|
import dev.apexnative.navigation.viewcontrollers.parent.ContainerBackground
|
|
30
32
|
import dev.apexnative.navigation.viewcontrollers.parent.ParentController
|
|
31
33
|
import dev.apexnative.navigation.viewcontrollers.stack.StackController
|
|
32
34
|
import dev.apexnative.navigation.viewcontrollers.stack.fab.FabPlacement
|
|
33
|
-
import dev.apexnative.navigation.viewcontrollers.stack.topbar.BarComponents
|
|
34
35
|
import dev.apexnative.navigation.viewcontrollers.viewcontroller.Presenter
|
|
35
36
|
import dev.apexnative.navigation.viewcontrollers.viewcontroller.ViewController
|
|
37
|
+
import dev.apexnative.navigation.views.animations.AnimationLayer
|
|
38
|
+
import dev.apexnative.navigation.views.animations.FadeThrough
|
|
36
39
|
import dev.apexnative.navigation.views.bottomtabs.BottomTabItem
|
|
37
40
|
import dev.apexnative.navigation.views.bottomtabs.BottomTabsLayout
|
|
38
41
|
import dev.apexnative.navigation.views.bottomtabs.CustomBottomTabItemView
|
|
@@ -68,6 +71,12 @@ class BottomTabsController(
|
|
|
68
71
|
private var cells: List<CustomBottomTabItemView> = emptyList()
|
|
69
72
|
// `ANN.BottomTabSelected` of a press that waits for the new tab's screen to appear.
|
|
70
73
|
private var pendingSelected: (() -> Unit)? = null
|
|
74
|
+
// Ends the fade through of a switch still running, with its events.
|
|
75
|
+
private var endSwitch: (() -> Unit)? = null
|
|
76
|
+
|
|
77
|
+
// The made tabs that didn't show at the last repaint (new default options, a light/dark switch): each is repainted
|
|
78
|
+
// as it is selected, not while hidden.
|
|
79
|
+
private val staleTabs = mutableSetOf<ViewController<*>>()
|
|
71
80
|
// The bar goes with a stack's transition: the options of the new top don't move it themselves.
|
|
72
81
|
private var riding = false
|
|
73
82
|
private var restAttached = false
|
|
@@ -150,8 +159,11 @@ class BottomTabsController(
|
|
|
150
159
|
/** The view of [tab] joins, or is there already: [visible], or invisible but laid out. */
|
|
151
160
|
fun attach(tab: ViewController<*>, visible: Boolean)
|
|
152
161
|
|
|
153
|
-
/**
|
|
154
|
-
|
|
162
|
+
/**
|
|
163
|
+
* The view of [shown] becomes visible and that of [hidden] invisible: at once, or with Material's fade through
|
|
164
|
+
* when [animated]; then [onEnd]. The function returned ends a switch still running at once, [onEnd] included.
|
|
165
|
+
*/
|
|
166
|
+
fun switch(shown: ViewController<*>, hidden: ViewController<*>, animated: Boolean, onEnd: () -> Unit): () -> Unit
|
|
155
167
|
}
|
|
156
168
|
|
|
157
169
|
/** The views of the tabs; none before the tabs' view is made. */
|
|
@@ -166,9 +178,45 @@ class BottomTabsController(
|
|
|
166
178
|
tab.view.visibility = if (visible) View.VISIBLE else View.INVISIBLE
|
|
167
179
|
}
|
|
168
180
|
|
|
169
|
-
override fun switch(
|
|
170
|
-
shown
|
|
171
|
-
hidden
|
|
181
|
+
override fun switch(
|
|
182
|
+
shown: ViewController<*>,
|
|
183
|
+
hidden: ViewController<*>,
|
|
184
|
+
animated: Boolean,
|
|
185
|
+
onEnd: () -> Unit,
|
|
186
|
+
): () -> Unit {
|
|
187
|
+
val coming = shown.view
|
|
188
|
+
coming.visibility = View.VISIBLE
|
|
189
|
+
val going = hidden.peekView()
|
|
190
|
+
if (!animated || going == null) {
|
|
191
|
+
going?.visibility = View.INVISIBLE
|
|
192
|
+
onEnd()
|
|
193
|
+
return {}
|
|
194
|
+
}
|
|
195
|
+
val exit = FadeThrough.exit(going)
|
|
196
|
+
// Faded out, the tab that goes takes no more touches and no accessibility focus.
|
|
197
|
+
exit.addListener(object : AnimatorListenerAdapter() {
|
|
198
|
+
override fun onAnimationEnd(animation: Animator) {
|
|
199
|
+
going.visibility = View.INVISIBLE
|
|
200
|
+
}
|
|
201
|
+
})
|
|
202
|
+
val set = AnimatorSet()
|
|
203
|
+
// Each tab fades whole through a hardware layer; a switch ended early ([set]'s end) gives them back too.
|
|
204
|
+
val enter = FadeThrough.enter(coming)
|
|
205
|
+
set.playTogether(AnimationLayer.during(going, exit), AnimationLayer.during(coming, enter))
|
|
206
|
+
set.addListener(object : AnimatorListenerAdapter() {
|
|
207
|
+
override fun onAnimationEnd(animation: Animator) {
|
|
208
|
+
set.removeAllListeners()
|
|
209
|
+
// The tab that went keeps its look for its next selection; only its visibility hides it.
|
|
210
|
+
going.visibility = View.INVISIBLE
|
|
211
|
+
going.alpha = 1f
|
|
212
|
+
coming.alpha = 1f
|
|
213
|
+
coming.scaleX = 1f
|
|
214
|
+
coming.scaleY = 1f
|
|
215
|
+
onEnd()
|
|
216
|
+
}
|
|
217
|
+
})
|
|
218
|
+
set.start()
|
|
219
|
+
return set::end
|
|
172
220
|
}
|
|
173
221
|
}
|
|
174
222
|
|
|
@@ -204,7 +252,7 @@ class BottomTabsController(
|
|
|
204
252
|
// `mergeOptions` with the tabs' id: their own options, then what they show, then the layouts around without
|
|
205
253
|
// `bottomTabs`; the one-shot options act once, also while the view isn't shown.
|
|
206
254
|
override fun mergeOptions(options: Options) {
|
|
207
|
-
|
|
255
|
+
mergeOwnOptions(options)
|
|
208
256
|
applyMerge(options, null)
|
|
209
257
|
performOnParentController { it.mergeChildOptions(withoutBottomTabs(options), this) }
|
|
210
258
|
}
|
|
@@ -268,8 +316,10 @@ class BottomTabsController(
|
|
|
268
316
|
private enum class How { Press, Code, Back }
|
|
269
317
|
|
|
270
318
|
/**
|
|
271
|
-
* A tap on the tab at [index], on the bar or on its cell of the custom row:
|
|
272
|
-
*
|
|
319
|
+
* A tap on the tab at [index], on the bar or on its cell of the custom row, the one path of both: a switch still
|
|
320
|
+
* running ends first, with its `ANN.BottomTabSelected`; then this press's `ANN.BottomTabPressed`, then the
|
|
321
|
+
* selection (`ANN.BottomTabSelected` after the new screen's DidAppear), the repeat (the pop's own events), or
|
|
322
|
+
* nothing, as its resolved options say. The same order as `-[ANNBottomTabsController pressTabAtIndex:source:]`.
|
|
273
323
|
*/
|
|
274
324
|
internal fun onTabPressed(index: Int) {
|
|
275
325
|
if (isDestroyed || index !in tabs.indices) return
|
|
@@ -302,10 +352,9 @@ class BottomTabsController(
|
|
|
302
352
|
}
|
|
303
353
|
|
|
304
354
|
/**
|
|
305
|
-
* Selects the tab at [index]:
|
|
306
|
-
*
|
|
307
|
-
*
|
|
308
|
-
* and the state at once. The history of back follows.
|
|
355
|
+
* Selects the tab at [index]: the bar shows it at once; on screen the tab it left fades through to it (Material's
|
|
356
|
+
* fade through); off screen, or when the new tab's `bottomTabs.switchAnimation` is `'none'`, one container becomes
|
|
357
|
+
* invisible and the other visible at once; then [switched]. The history of back follows.
|
|
309
358
|
*/
|
|
310
359
|
private fun select(index: Int, how: How) {
|
|
311
360
|
if (index == selectedIndex || index !in tabs.indices || isDestroyed) return
|
|
@@ -321,6 +370,9 @@ class BottomTabsController(
|
|
|
321
370
|
}
|
|
322
371
|
selectedIndex = index
|
|
323
372
|
attach(index)
|
|
373
|
+
// A tab hidden at a repaint takes it now, before its screens appear: its bar's parts, its search's and its
|
|
374
|
+
// FAB's colors follow the theme and the defaults only through a repaint.
|
|
375
|
+
if (staleTabs.remove(shown)) Navigator.repaintLayer(shown)
|
|
324
376
|
peekView()?.bar?.let {
|
|
325
377
|
it.setCurrentItem(index, false)
|
|
326
378
|
it.onCustomItemViewSelectionChanged(index)
|
|
@@ -328,10 +380,30 @@ class BottomTabsController(
|
|
|
328
380
|
// A layer that waits for the tabs waits for the tab they show now.
|
|
329
381
|
navigator?.shownScreensChanged(this)
|
|
330
382
|
if (onScreen) AppearanceDispatcher.beginTransition(listOf(shown))
|
|
331
|
-
|
|
383
|
+
// From code and by back the state goes at once, as on iOS: `selectTab` resolves on it, and the command after
|
|
384
|
+
// it must act in this tab, not in the one still fading out.
|
|
385
|
+
if (how != How.Press) AppearanceDispatcher.reportState()
|
|
386
|
+
if (views == null) return switched(index, previous, how, onScreen, hasViews = false)
|
|
387
|
+
endSwitch = views.switch(shown, left, animated = onScreen && fadesThrough(shown)) {
|
|
388
|
+
endSwitch = null
|
|
389
|
+
if (!isDestroyed) switched(index, previous, how, onScreen, hasViews = true)
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* The switch to the tab at [index] from [previous] ended: what went disappears, what came appears — unless the tabs
|
|
395
|
+
* stopped showing during the fade (a modal over them): it appears when they show again; then for a press
|
|
396
|
+
* `ANN.BottomTabSelected` right after the new screen's DidAppear and the left tab's `popToRootOnBlur`, with the state
|
|
397
|
+
* as one update after them; from code and by back, `popToRootOnBlur` and the state, which went at the start too
|
|
398
|
+
* ([select]). [onScreen]: the switch started on screen.
|
|
399
|
+
*/
|
|
400
|
+
private fun switched(index: Int, previous: Int, how: How, onScreen: Boolean, hasViews: Boolean) {
|
|
401
|
+
val left = tabs[previous]
|
|
402
|
+
val shown = tabs[index]
|
|
332
403
|
if (onScreen) {
|
|
333
|
-
|
|
334
|
-
|
|
404
|
+
val showing = if (isOnScreen) listOf(shown) else emptyList()
|
|
405
|
+
AppearanceDispatcher.endTransition(listOf(left), showing, null, null, null, reportsState = false)
|
|
406
|
+
} else if (hasViews) {
|
|
335
407
|
// Not on screen: the bar takes the new tab's options as they are, without appearance events.
|
|
336
408
|
val options = resolveShownOptions(DefaultOptions.current)
|
|
337
409
|
bar.applyBar(options.bottomTabs, directionOf(options))
|
|
@@ -358,8 +430,15 @@ class BottomTabsController(
|
|
|
358
430
|
if (screen == null) finish() else AppearanceDispatcher.afterDidAppear(screen, finish)
|
|
359
431
|
}
|
|
360
432
|
|
|
361
|
-
//
|
|
433
|
+
// `bottomTabs.switchAnimation` of the tab that shows, its shown screen's over its own, the tabs' and the defaults:
|
|
434
|
+
// `'platform'`, the default, fades through; `'none'` switches at once.
|
|
435
|
+
private fun fadesThrough(tab: ViewController<*>): Boolean =
|
|
436
|
+
tab.resolveShownOptions(DefaultOptions.current).bottomTabs.switchAnimation.get(null) != "none"
|
|
437
|
+
|
|
438
|
+
// A switch still running ends at once and a press's `ANN.BottomTabSelected` still waiting goes, before anything
|
|
439
|
+
// newer on these tabs.
|
|
362
440
|
private fun flushPendingSelected() {
|
|
441
|
+
endSwitch?.invoke()
|
|
363
442
|
pendingSelected?.invoke()
|
|
364
443
|
}
|
|
365
444
|
|
|
@@ -477,9 +556,6 @@ class BottomTabsController(
|
|
|
477
556
|
return TabsRoom.tabsTop(room(), screenOptions(screen), bottom)
|
|
478
557
|
}
|
|
479
558
|
|
|
480
|
-
override fun leavesBottomEdgeFree(child: ViewController<*>, screen: ViewController<*>): Boolean =
|
|
481
|
-
TabsRoom.leavesBottomEdgeFree(screenOptions(screen)) || super.leavesBottomEdgeFree(child, screen)
|
|
482
|
-
|
|
483
559
|
override fun tabsAtRestOf(child: ViewController<*>, screen: ViewController<*>): FabPlacement.Tabs? {
|
|
484
560
|
if (peekView() == null) return super.tabsAtRestOf(child, screen)
|
|
485
561
|
return TabsRoom.fabTabs(room(), screenOptions(screen))
|
|
@@ -531,8 +607,8 @@ class BottomTabsController(
|
|
|
531
607
|
}
|
|
532
608
|
}
|
|
533
609
|
|
|
534
|
-
// The repaint: the bar, the items of every tab, the row
|
|
535
|
-
//
|
|
610
|
+
// The repaint: the bar, the items of every tab, the row. Only what shows is repainted (the pass over what shows
|
|
611
|
+
// reaches the selected tab); a made tab that doesn't show is repainted when it is selected ([staleTabs]).
|
|
536
612
|
internal fun repaint(options: Options) {
|
|
537
613
|
if (isDestroyed) return
|
|
538
614
|
ContainerBackground.apply(this, options)
|
|
@@ -542,7 +618,7 @@ class BottomTabsController(
|
|
|
542
618
|
if (usesRow) layout.bar.customRowOptions = options.bottomTabs.customRow.copy()
|
|
543
619
|
}
|
|
544
620
|
cells.forEachIndexed { index, cell -> cell.update(cellState(index)) }
|
|
545
|
-
tabs.forEach { if (it !== currentChild && it.isViewCreated)
|
|
621
|
+
tabs.forEach { if (it !== currentChild && it.isViewCreated) staleTabs += it }
|
|
546
622
|
}
|
|
547
623
|
|
|
548
624
|
// The custom row: the cells first into the bar's external host, then the row holds them; its look follows the tabs'
|
|
@@ -560,7 +636,6 @@ class BottomTabsController(
|
|
|
560
636
|
layout.row = row
|
|
561
637
|
layout.bar.customRowOptionsListener = { applyRow(row, it) }
|
|
562
638
|
layout.bar.customRowOptions = resolveShownOptions(DefaultOptions.current).bottomTabs.customRow.copy()
|
|
563
|
-
CustomTabRowPlacer.track(activity)
|
|
564
639
|
}
|
|
565
640
|
|
|
566
641
|
private fun applyRow(row: CustomTabRow, options: BottomTabsCustomRowOptions) {
|
|
@@ -590,15 +665,12 @@ class BottomTabsController(
|
|
|
590
665
|
private fun makeCell(index: Int): CustomBottomTabItemView {
|
|
591
666
|
val component = itemOptions(index).component
|
|
592
667
|
val componentId = component.componentId.get(null) ?: "$id.$index"
|
|
593
|
-
ScreenReadiness.setRendersAtOnce(componentId, true)
|
|
594
|
-
// Another live root has the id (the same layout set again before the old one went): what it rendered isn't
|
|
595
|
-
// this one's; the id's readiness goes only with its last root (as the bar's roots).
|
|
596
|
-
if (BarComponents.isLive(componentId)) ScreenReadiness.forgetRender(componentId)
|
|
597
|
-
BarComponents.rootMade(componentId)
|
|
598
668
|
val cell = CustomBottomTabItemView(activity)
|
|
599
669
|
val state = cellState(index)
|
|
600
|
-
|
|
601
|
-
|
|
670
|
+
// Another live root may have the id (the same layout set again before the old one went): each answers by the
|
|
671
|
+
// render of its own surface, and the id's readiness goes with its last root.
|
|
672
|
+
val root = ReactView(activity, componentId, component.name.get(""), cell.bundleOf(state), rendersAtOnce = true)
|
|
673
|
+
cell.show(root, state)
|
|
602
674
|
return cell
|
|
603
675
|
}
|
|
604
676
|
|
|
@@ -615,15 +687,17 @@ class BottomTabsController(
|
|
|
615
687
|
|
|
616
688
|
/**
|
|
617
689
|
* Destroys the tabs once: every tab and the registry first, then the cells (each stops its root once), the row out
|
|
618
|
-
* of the
|
|
690
|
+
* of the tabs' view, the scroll it followed. A press's event still waiting goes with them.
|
|
619
691
|
*/
|
|
620
692
|
override fun destroy() {
|
|
621
693
|
if (isDestroyed) return
|
|
622
694
|
pendingSelected = null
|
|
695
|
+
staleTabs.clear()
|
|
623
696
|
super.destroy()
|
|
697
|
+
// A switch still running ends with its views at rest, without events: the tabs are gone.
|
|
698
|
+
endSwitch?.invoke()
|
|
624
699
|
peekView()?.let { layout ->
|
|
625
700
|
layout.bar.destroyCustomItemViews()
|
|
626
|
-
layout.row?.let(CustomTabRowPlacer::forget)
|
|
627
701
|
layout.row = null
|
|
628
702
|
}
|
|
629
703
|
cells = emptyList()
|
|
@@ -6,7 +6,6 @@ import android.animation.AnimatorSet
|
|
|
6
6
|
import android.animation.ObjectAnimator
|
|
7
7
|
import android.app.Activity
|
|
8
8
|
import android.graphics.Color
|
|
9
|
-
import android.graphics.drawable.Drawable
|
|
10
9
|
import android.view.View
|
|
11
10
|
import android.view.animation.LinearInterpolator
|
|
12
11
|
import android.view.animation.PathInterpolator
|
|
@@ -20,8 +19,8 @@ import dev.apexnative.navigation.options.params.LayoutDirection
|
|
|
20
19
|
import dev.apexnative.navigation.options.params.ThemeColour
|
|
21
20
|
import dev.apexnative.navigation.options.parsers.TypefaceLoader
|
|
22
21
|
import dev.apexnative.navigation.system.SystemUiOwner
|
|
23
|
-
import dev.apexnative.navigation.utils.
|
|
24
|
-
import dev.apexnative.navigation.utils.
|
|
22
|
+
import dev.apexnative.navigation.utils.ImageRequests
|
|
23
|
+
import dev.apexnative.navigation.utils.OptionImages
|
|
25
24
|
import dev.apexnative.navigation.utils.TestIds
|
|
26
25
|
import dev.apexnative.navigation.utils.UiUtils
|
|
27
26
|
import dev.apexnative.navigation.viewcontrollers.viewcontroller.Presenter
|
|
@@ -67,8 +66,9 @@ internal open class BottomTabsPresenter(activity: Activity) : Presenter(activity
|
|
|
67
66
|
|
|
68
67
|
private var layout: BottomTabsLayout? = null
|
|
69
68
|
private val typefaces = TypefaceLoader(activity)
|
|
70
|
-
|
|
71
|
-
private val
|
|
69
|
+
// The icons of the items by item and kind (selected or not): those of the cache at once, the others as below.
|
|
70
|
+
private val icons = ImageRequests<Pair<Int, Boolean>>(OptionImages.source(activity))
|
|
71
|
+
private val applied = AppliedTabCalls(icons::key)
|
|
72
72
|
private var motion: Animator? = null
|
|
73
73
|
private var anyIcon = false
|
|
74
74
|
private var testId: String? = null
|
|
@@ -100,25 +100,24 @@ internal open class BottomTabsPresenter(activity: Activity) : Presenter(activity
|
|
|
100
100
|
|
|
101
101
|
/**
|
|
102
102
|
* Runs [calls] on the bar's items; a call equal to the last of its kind for its item is skipped (an icon isn't
|
|
103
|
-
* loaded and set again as a screen appears)
|
|
103
|
+
* loaded and set again as a screen appears), except the badge and the font, an icon that didn't load and a `file:`
|
|
104
|
+
* icon whose file changed ([AppliedTabCalls]).
|
|
104
105
|
*/
|
|
105
106
|
open fun run(calls: List<TabItems.Call>) {
|
|
106
107
|
val bar = layout?.bar ?: return
|
|
107
108
|
for (call in calls) {
|
|
108
109
|
if (call is TabItems.Call.TestId && !itemTestIds) continue
|
|
109
|
-
val
|
|
110
|
-
|
|
111
|
-
applied[key] = call
|
|
112
|
-
run(bar, call)
|
|
110
|
+
val next = applied.next(call) ?: continue
|
|
111
|
+
run(bar, call, next)
|
|
113
112
|
}
|
|
114
113
|
}
|
|
115
114
|
|
|
116
|
-
private fun run(bar: BottomTabs, call: TabItems.Call) {
|
|
115
|
+
private fun run(bar: BottomTabs, call: TabItems.Call, next: AppliedTabCalls.Next) {
|
|
117
116
|
val index = call.index
|
|
118
117
|
when (call) {
|
|
119
118
|
is TabItems.Call.Title -> bar.setText(index, call.text)
|
|
120
|
-
is TabItems.Call.Icon ->
|
|
121
|
-
is TabItems.Call.SelectedIcon ->
|
|
119
|
+
is TabItems.Call.Icon -> icon(bar, call, call.uri, false, next)
|
|
120
|
+
is TabItems.Call.SelectedIcon -> icon(bar, call, call.uri, true, next)
|
|
122
121
|
is TabItems.Call.Colors -> {
|
|
123
122
|
bar.setIconActiveColor(index, call.iconActive)
|
|
124
123
|
bar.setIconInactiveColor(index, call.iconInactive)
|
|
@@ -344,17 +343,19 @@ internal open class BottomTabsPresenter(activity: Activity) : Presenter(activity
|
|
|
344
343
|
|
|
345
344
|
private fun colorOf(colour: ThemeColour): Int? = colour.get(activity, null)
|
|
346
345
|
|
|
347
|
-
// Icons
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
346
|
+
// Icons never throw: one that doesn't load leaves the item without it (without its selected icon, the item shows
|
|
347
|
+
// its icon when selected). An item's first icon loads at once, its tab's first frame shows it; a change of it on
|
|
348
|
+
// the bar that shows loads off the main thread when it can, and the item takes it when ready, unless a newer icon
|
|
349
|
+
// of the item came first.
|
|
350
|
+
// The key of a `file:` icon was built for the comparison: the request takes it, its file read once.
|
|
351
|
+
private fun icon(bar: BottomTabs, call: TabItems.Call, uri: String, selected: Boolean, next: AppliedTabCalls.Next) {
|
|
352
|
+
val index = call.index
|
|
353
|
+
val key = next.image ?: icons.key(uri)
|
|
354
|
+
icons.request(index to selected, key, mayWait = next.isChange && bar.isAttachedToWindow) { icon ->
|
|
355
|
+
if (icon == null) applied.failed(call)
|
|
356
|
+
val shown = layout?.bar ?: return@request
|
|
357
|
+
if (selected) shown.setSelectedIcon(index, icon) else shown.setIcon(index, icon)
|
|
358
|
+
}
|
|
358
359
|
}
|
|
359
360
|
|
|
360
361
|
private companion object {
|
|
@@ -49,6 +49,22 @@ internal object CustomTabRowGeometry {
|
|
|
49
49
|
content = content,
|
|
50
50
|
)
|
|
51
51
|
|
|
52
|
+
/**
|
|
53
|
+
* The row over the bar as the tabs' view lays it out: the bar's [barLeft], [barRight] and [barBottom] in that
|
|
54
|
+
* view, whose height is [tabsHeight] and whose bottom [navigationBar] pixels lie under the navigation bar — the
|
|
55
|
+
* row's bottom never goes over them —, with [margin], [content] and [bottomMargin] as [place] takes them.
|
|
56
|
+
*/
|
|
57
|
+
fun inTabs(
|
|
58
|
+
barLeft: Int,
|
|
59
|
+
barRight: Int,
|
|
60
|
+
barBottom: Int,
|
|
61
|
+
tabsHeight: Int,
|
|
62
|
+
navigationBar: Int,
|
|
63
|
+
margin: Int,
|
|
64
|
+
content: Int,
|
|
65
|
+
bottomMargin: Int,
|
|
66
|
+
): Place = place(barLeft, barRight, minOf(barBottom, tabsHeight - navigationBar), margin, content, bottomMargin)
|
|
67
|
+
|
|
52
68
|
/**
|
|
53
69
|
* The part of the row's frame at [place] below its visible part, in pixels: `bottomMargin`. The row draws and takes
|
|
54
70
|
* touches only above it.
|
|
@@ -61,6 +77,12 @@ internal object CustomTabRowGeometry {
|
|
|
61
77
|
*/
|
|
62
78
|
fun needsPlacing(last: Place?, next: Place): Boolean = last != next
|
|
63
79
|
|
|
80
|
+
/**
|
|
81
|
+
* The row's own lift over its [elevation] while the bar's container stands at [barZ]: as high as the container, so
|
|
82
|
+
* the row, after it in the tabs' view, draws over it and takes the touches first even under a raised bar.
|
|
83
|
+
*/
|
|
84
|
+
fun lift(barZ: Float, elevation: Float): Float = (barZ - elevation).coerceAtLeast(0f)
|
|
85
|
+
|
|
64
86
|
/**
|
|
65
87
|
* The row's background: `customRow.backgroundColor` ([color]; `null` and `'NoColor'` are none); without it
|
|
66
88
|
* `backgroundEffect: 'none'` ([effect]) is clear, any other effect or none the theme's `android:colorBackground`
|
package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabItems.kt
CHANGED
|
@@ -36,7 +36,7 @@ internal class TabItems(private val color: (ThemeColour) -> Int?) {
|
|
|
36
36
|
) : Call()
|
|
37
37
|
|
|
38
38
|
/** The icon's size in dp, width over height. */
|
|
39
|
-
data class IconSize(override val index: Int, val width:
|
|
39
|
+
data class IconSize(override val index: Int, val width: Double?, val height: Double?) : Call()
|
|
40
40
|
|
|
41
41
|
data class Font(override val index: Int, val font: FontOptions) : Call()
|
|
42
42
|
|
|
@@ -86,7 +86,7 @@ internal class TabItems(private val color: (ThemeColour) -> Int?) {
|
|
|
86
86
|
options.icon.get(null)?.let { Call.Icon(index, it) },
|
|
87
87
|
options.selectedIcon.get(null)?.let { Call.SelectedIcon(index, it) },
|
|
88
88
|
colors(index, options),
|
|
89
|
-
Call.IconSize(index, options.iconWidth.get(null)
|
|
89
|
+
Call.IconSize(index, options.iconWidth.get(null), options.iconHeight.get(null)),
|
|
90
90
|
Call.Font(index, options.font.copy()),
|
|
91
91
|
Call.FontSizes(index, options.selectedFontSize.get(null)?.toFloat(), options.fontSize.get(null)?.toFloat()),
|
|
92
92
|
Call.TestId(index, options.testID.get(null)),
|
|
@@ -110,7 +110,7 @@ internal class TabItems(private val color: (ThemeColour) -> Int?) {
|
|
|
110
110
|
calls += colors(index, resolved)
|
|
111
111
|
}
|
|
112
112
|
if (merge.iconWidth.hasValue() || merge.iconHeight.hasValue()) {
|
|
113
|
-
calls += Call.IconSize(index, resolved.iconWidth.get(null)
|
|
113
|
+
calls += Call.IconSize(index, resolved.iconWidth.get(null), resolved.iconHeight.get(null))
|
|
114
114
|
}
|
|
115
115
|
if (merge.font.hasValue()) calls += Call.Font(index, resolved.font.copy())
|
|
116
116
|
if (merge.fontSize.hasValue() || merge.selectedFontSize.hasValue()) {
|
package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabsRoom.kt
CHANGED
|
@@ -58,11 +58,6 @@ internal object TabsRoom {
|
|
|
58
58
|
fun tabsTop(bar: Bar, screen: Screen, tabsBottom: Int): Int? =
|
|
59
59
|
if (screen.hidden) null else tabsBottom - bar.reach - bar.rowOvershoot
|
|
60
60
|
|
|
61
|
-
/**
|
|
62
|
-
* The safe area of the screen leaves its bottom edge free: the bar hides on scroll and shows for it.
|
|
63
|
-
*/
|
|
64
|
-
fun leavesBottomEdgeFree(screen: Screen): Boolean = screen.hideOnScroll && !screen.hidden
|
|
65
|
-
|
|
66
61
|
/**
|
|
67
62
|
* The bar at rest under a stack's FAB: also when the screen is under it (`drawBehind`, `hideOnScroll`); none when
|
|
68
63
|
* the screen hides it.
|
|
@@ -6,6 +6,7 @@ import android.graphics.drawable.ColorDrawable
|
|
|
6
6
|
import android.graphics.drawable.Drawable
|
|
7
7
|
import android.graphics.drawable.LayerDrawable
|
|
8
8
|
import android.view.View
|
|
9
|
+
import com.google.android.material.color.MaterialColors
|
|
9
10
|
import dev.apexnative.navigation.options.DefaultOptions
|
|
10
11
|
import dev.apexnative.navigation.options.Options
|
|
11
12
|
import dev.apexnative.navigation.options.params.ThemeColour
|
|
@@ -15,9 +16,9 @@ import dev.apexnative.navigation.viewcontrollers.viewcontroller.Presenter
|
|
|
15
16
|
import dev.apexnative.navigation.viewcontrollers.viewcontroller.ViewController
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
|
-
* The presenter of a screen, React or native: its background — the screen's view takes `layout.backgroundColor
|
|
19
|
-
* out of the status bar's height where the status bar shows over
|
|
20
|
-
* `layout.componentBackgroundColor` over it —, its room for the bars, and its safe area again on `mergeOptions`
|
|
19
|
+
* The presenter of a screen, React or native: its background — the screen's view takes `layout.backgroundColor` (a
|
|
20
|
+
* React screen without it the theme's background), kept out of the status bar's height where the status bar shows over
|
|
21
|
+
* it, and the React content takes `layout.componentBackgroundColor` over it —, its room for the bars, and its safe area again on `mergeOptions`
|
|
21
22
|
* (`mergeOptions` step 4). It applies as the screen appears, on `mergeOptions` of what it covers, and again with new
|
|
22
23
|
* default options or after a light/dark switch from the resolved options it is given, which it never writes. Each
|
|
23
24
|
* appearance tells the activity's system UI owner, which follows the screen on top. Main thread only.
|
|
@@ -49,8 +50,8 @@ open class ComponentPresenter(activity: Activity) : Presenter(activity, DefaultO
|
|
|
49
50
|
applyBackground(controller, options)
|
|
50
51
|
|
|
51
52
|
/**
|
|
52
|
-
* The colors of [screen] from its resolved [options]: `layout.backgroundColor` on the screen's view,
|
|
53
|
-
*
|
|
53
|
+
* The colors of [screen] from its resolved [options]: `layout.backgroundColor` on the screen's view, without it the
|
|
54
|
+
* theme's background for a React screen ([defaultColorOf]); `layout.componentBackgroundColor` on its React content.
|
|
54
55
|
*/
|
|
55
56
|
fun applyBackground(screen: ViewController<*>, options: Options) {
|
|
56
57
|
val view = screen.peekView() ?: return
|
|
@@ -59,11 +60,11 @@ open class ComponentPresenter(activity: Activity) : Presenter(activity, DefaultO
|
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
private fun screenBackground(screen: ViewController<*>, options: Options): Drawable? {
|
|
62
|
-
val color = colorOf(options.layout.backgroundColor) ?: return null
|
|
63
|
+
val color = colorOf(options.layout.backgroundColor) ?: defaultColorOf(screen) ?: return null
|
|
63
64
|
val frame = frameOf(screen) ?: return ColorDrawable(color)
|
|
64
65
|
val band = ScreenSafeArea.backgroundBand(
|
|
65
66
|
statusBarHeight = frame.statusBarHeight,
|
|
66
|
-
hiddenOrDrawBehind = options.statusBar.isHiddenOrDrawBehind,
|
|
67
|
+
hiddenOrDrawBehind = options.statusBar.isHiddenOrDrawBehind(screen.isInOverlay),
|
|
67
68
|
inSideMenu = screen.isInSideMenu,
|
|
68
69
|
inSheet = screen.isInSheet,
|
|
69
70
|
inPair = frame.isInPair,
|
|
@@ -79,6 +80,15 @@ open class ComponentPresenter(activity: Activity) : Presenter(activity, DefaultO
|
|
|
79
80
|
private fun colorOf(colour: ThemeColour): Int? =
|
|
80
81
|
if (colour.hasValue()) colour.get(activity, Color.TRANSPARENT) ?: Color.TRANSPARENT else null
|
|
81
82
|
|
|
83
|
+
// A React screen is opaque without a color of its own, as iOS gives it the system background: the screen under it
|
|
84
|
+
// never shows through, also while a push slides it aside. The app theme's `android:colorBackground`, read now, so a
|
|
85
|
+
// light/dark switch takes the new mode's. A screen of a sheet shows the sheet's surface; a native screen paints its
|
|
86
|
+
// own view.
|
|
87
|
+
private fun defaultColorOf(screen: ViewController<*>): Int? {
|
|
88
|
+
if (screen !is ComponentViewController || screen.isInSheet) return null
|
|
89
|
+
return themeBackgroundOf(activity)
|
|
90
|
+
}
|
|
91
|
+
|
|
82
92
|
private fun frameOf(screen: ViewController<*>): ScreenFrame? = when (screen) {
|
|
83
93
|
is ComponentViewController -> screen.frame
|
|
84
94
|
is ExternalComponentViewController -> screen.frame
|
|
@@ -87,4 +97,15 @@ open class ComponentPresenter(activity: Activity) : Presenter(activity, DefaultO
|
|
|
87
97
|
|
|
88
98
|
// The view under the React content: the React root, or the container of a slot screen. A native screen has none.
|
|
89
99
|
private fun contentOf(screen: ViewController<*>): View? = (screen as? ComponentViewController)?.content?.asView()
|
|
100
|
+
|
|
101
|
+
internal companion object {
|
|
102
|
+
/**
|
|
103
|
+
* The background of a React screen without `layout.backgroundColor`: `android:colorBackground` of [activity]'s
|
|
104
|
+
* theme now. None for an activity without a theme (the unit tests' fakes).
|
|
105
|
+
*/
|
|
106
|
+
fun themeBackgroundOf(activity: Activity): Int? {
|
|
107
|
+
if (activity.theme == null) return null
|
|
108
|
+
return MaterialColors.getColor(activity, android.R.attr.colorBackground, Color.WHITE)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
90
111
|
}
|