@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
|
@@ -68,8 +68,8 @@ export abstract class OptionsChain {
|
|
|
68
68
|
|
|
69
69
|
/**
|
|
70
70
|
* The edges on which the screen keeps its content out of its safe area (bars, status bar, home indicator, cutout);
|
|
71
|
-
* none with no edge. Without it:
|
|
72
|
-
* a
|
|
71
|
+
* none with no edge. Without it: the top and the sides, but those where the content goes under a bar; the bottom is
|
|
72
|
+
* free, and a list keeps clear of it with `useSafeAreaInsets()`. A large title leaves the top out by itself.
|
|
73
73
|
*/
|
|
74
74
|
safeArea(...edges: SafeAreaEdge[]): this {
|
|
75
75
|
return this.layout({ safeAreaEdges: edges });
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ComponentType, createElement } from 'react';
|
|
2
2
|
import type { Options } from '../../interfaces/Options';
|
|
3
|
+
import { keepStateOf, newestType, redefined } from '../../engine/refresh';
|
|
3
4
|
import { getAppContext } from '../context/appContext';
|
|
4
5
|
import { readScreenOptions, ScreenOptions } from '../options/ScreenOptions';
|
|
5
6
|
import { getTheme, type NavigationTheme } from '../theme/theme';
|
|
@@ -38,12 +39,55 @@ export interface ScreenDefinition<Props = any> {
|
|
|
38
39
|
arrangement?: ScreenArrangement<Props & object>;
|
|
39
40
|
}
|
|
40
41
|
|
|
42
|
+
const SCREEN_DEFINITION = Symbol('apexnative.navigation.screenDefinition');
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* A screen of `defineScreen`: a component of its own, which renders the screen's component and carries the screen's
|
|
46
|
+
* definition. It goes right into `screens` of createNavigation, and rendered on its own (a test) it renders the screen.
|
|
47
|
+
*/
|
|
48
|
+
export type DefinedScreen<Props> = ComponentType<Props> & {
|
|
49
|
+
readonly [SCREEN_DEFINITION]: ScreenDefinition<Props>;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Describes a screen next to its component, so its registration stays one line. It gives a component that renders the
|
|
54
|
+
* screen and goes right into `screens` of createNavigation: a file that exports only its screens stays a boundary of
|
|
55
|
+
* Fast Refresh, so an edit of the screen, its options too, updates it in place instead of reloading the app.
|
|
56
|
+
*/
|
|
57
|
+
export function defineScreen<Props>(definition: ScreenDefinition<Props>): DefinedScreen<Props> {
|
|
58
|
+
const { component } = definition;
|
|
59
|
+
// A component of each definition, so the app's own component stays as it is for any other use of it.
|
|
60
|
+
const Component = component as ComponentType<object>;
|
|
61
|
+
function Screen(props: Props) {
|
|
62
|
+
return createElement(Component, props as object);
|
|
63
|
+
}
|
|
64
|
+
Screen.displayName = component.displayName ?? component.name;
|
|
65
|
+
Object.defineProperty(Screen, SCREEN_DEFINITION, { value: definition });
|
|
66
|
+
keepStateOf(Screen, component);
|
|
67
|
+
redefined(Screen);
|
|
68
|
+
return Screen as DefinedScreen<Props>;
|
|
69
|
+
}
|
|
70
|
+
|
|
41
71
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
72
|
+
* The definition a screen of `defineScreen` carries, the newest one after Fast Refresh ran the screen's module again;
|
|
73
|
+
* undefined for anything else.
|
|
44
74
|
*/
|
|
45
|
-
export function
|
|
46
|
-
return
|
|
75
|
+
export function definitionOf(value: unknown): ScreenDefinition | undefined {
|
|
76
|
+
return isDefinedScreen(value) ? ownDefinitionOf(newestType(value)) : undefined;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** The definition a screen of `defineScreen` carries itself, not a newer one; undefined for anything else. */
|
|
80
|
+
export function ownDefinitionOf(value: unknown): ScreenDefinition | undefined {
|
|
81
|
+
return isDefinedScreen(value) ? value[SCREEN_DEFINITION] : undefined;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Whether the value is a screen of `defineScreen`. */
|
|
85
|
+
export function isDefinedScreen(value: unknown): value is DefinedScreen<any> {
|
|
86
|
+
return (
|
|
87
|
+
(typeof value === 'function' || typeof value === 'object') &&
|
|
88
|
+
value !== null &&
|
|
89
|
+
SCREEN_DEFINITION in value
|
|
90
|
+
);
|
|
47
91
|
}
|
|
48
92
|
|
|
49
93
|
export function buildScreenOptions<Props>(
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import { redefined, resetOnEdit } from '../../engine/refresh';
|
|
1
3
|
import type { ScreenArrangement } from './arrangement';
|
|
2
4
|
import type { ScreenOptionsInput } from './defineScreen';
|
|
3
5
|
|
|
@@ -30,7 +32,9 @@ export interface NativeScreenDefinition<Props extends object> {
|
|
|
30
32
|
|
|
31
33
|
/**
|
|
32
34
|
* A native screen for `screens`: commands and layouts name it like any other screen, and its props go to the native
|
|
33
|
-
* creator. `nativeName` is the name it is registered under natively (`ApexNavigation.registerNativeScreen`).
|
|
35
|
+
* creator. `nativeName` is the name it is registered under natively (`ApexNavigation.registerNativeScreen`). It is a
|
|
36
|
+
* component that runs `useProps`, so a file that exports only its screens updates by Fast Refresh, the hook and the
|
|
37
|
+
* options too.
|
|
34
38
|
*
|
|
35
39
|
* @example
|
|
36
40
|
* const Settings = nativeScreen('Settings', {
|
|
@@ -49,10 +53,42 @@ export function nativeScreen<Props extends object = {}>(
|
|
|
49
53
|
nativeName: string,
|
|
50
54
|
definition: NativeScreenDefinition<Props> = {}
|
|
51
55
|
): NativeScreen<Props> {
|
|
52
|
-
const { options, useProps, arrangement } = definition;
|
|
53
|
-
|
|
56
|
+
const { options, useProps = noProps, arrangement } = definition;
|
|
57
|
+
// A component that runs the hook, so that a file exporting only its screens stays a boundary of Fast Refresh: React
|
|
58
|
+
// Refresh puts the new version in place, with the edited hook.
|
|
59
|
+
function NativeScreen({ props, onProps }: NativeScreenHookProps<Props>) {
|
|
60
|
+
const result = useProps(props);
|
|
61
|
+
// After each render React committed, so the native side never shows what the app did not.
|
|
62
|
+
useEffect(() => onProps(result));
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
const screen = Object.assign(NativeScreen, {
|
|
66
|
+
[NATIVE_SCREEN]: true as const,
|
|
67
|
+
nativeName,
|
|
68
|
+
options,
|
|
69
|
+
useProps: definition.useProps,
|
|
70
|
+
arrangement,
|
|
71
|
+
});
|
|
72
|
+
// The hook is the app's and may have other hooks after an edit: its new version mounts anew.
|
|
73
|
+
resetOnEdit(screen);
|
|
74
|
+
redefined(screen);
|
|
75
|
+
return screen;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function noProps(): object {
|
|
79
|
+
return {};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** What the component of a native screen renders with: the props of the command, and where the hook's result goes. */
|
|
83
|
+
export interface NativeScreenHookProps<Props> {
|
|
84
|
+
props: Props;
|
|
85
|
+
onProps(result: object): void;
|
|
54
86
|
}
|
|
55
87
|
|
|
56
88
|
export function isNativeScreen(value: unknown): value is NativeScreen<any> {
|
|
57
|
-
return
|
|
89
|
+
return (
|
|
90
|
+
(typeof value === 'function' || typeof value === 'object') &&
|
|
91
|
+
value !== null &&
|
|
92
|
+
NATIVE_SCREEN in value
|
|
93
|
+
);
|
|
58
94
|
}
|
|
@@ -6,32 +6,39 @@ import React, {
|
|
|
6
6
|
lazy,
|
|
7
7
|
type ReactNode,
|
|
8
8
|
Suspense,
|
|
9
|
-
useEffect,
|
|
10
9
|
useMemo,
|
|
11
10
|
useState,
|
|
12
11
|
} from 'react';
|
|
13
|
-
import { Platform, StyleSheet } from 'react-native';
|
|
12
|
+
import { DevSettings, Platform, StyleSheet } from 'react-native';
|
|
14
13
|
import ANNTurboModule from '../../adapters/NativeANNTurboModule';
|
|
15
14
|
import type { NativeControllerProps } from '../../engine/nativeScreens';
|
|
16
15
|
import { isButtonRoot } from '../../engine/props';
|
|
17
16
|
import {
|
|
18
17
|
checkArrangements,
|
|
19
|
-
type EngineArrangement,
|
|
20
18
|
onScreenUnmounted,
|
|
21
19
|
registerScreen as registerEngineScreen,
|
|
22
20
|
type ScreenRootProps,
|
|
21
|
+
shownScreens,
|
|
23
22
|
} from '../../engine/screens';
|
|
24
23
|
import { screenUnmounted } from '../events/screenLifecycle';
|
|
25
24
|
import { mergeOptions } from '../../engine/mergeOptions';
|
|
26
25
|
import { preparedPadding } from '../../engine/slots';
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
26
|
+
import { clearOptions, mergeOptions as sendMergeOptions } from '../../engine/commands';
|
|
27
|
+
import { changeOverOwn, optionsChange } from '../../engine/optionsChange';
|
|
28
|
+
import { notedScreens, ownOptionsOf } from '../../engine/rememberedOptions';
|
|
29
|
+
import { openNativeScreens } from '../../engine/nativeScreens';
|
|
30
|
+
import { placeOf } from '../../engine/places';
|
|
31
|
+
import { propsOf } from '../../engine/props';
|
|
32
|
+
import { familyOf, newestType, onRedefined } from '../../engine/refresh';
|
|
29
33
|
import {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
buildScreenOptions,
|
|
35
|
+
definitionOf,
|
|
36
|
+
ownDefinitionOf,
|
|
37
|
+
type ScreenDefinition,
|
|
38
|
+
type ScreenOptionsInput,
|
|
39
|
+
} from './defineScreen';
|
|
40
|
+
import { isNativeScreen, type NativeScreen, type NativeScreenHookProps } from './nativeScreens';
|
|
41
|
+
import { type Arrangement, isArrangement, toEngineArrangement } from './arrangement';
|
|
35
42
|
import { type ErrorFallbackProps, ScreenBoundary } from './ScreenBoundary';
|
|
36
43
|
import ANNSafeAreaView from '../safeArea/ANNSafeAreaViewNativeComponent';
|
|
37
44
|
|
|
@@ -98,6 +105,125 @@ export interface ScreenSet {
|
|
|
98
105
|
// The root of a screen tells when it unmounts: what the screen left behind goes.
|
|
99
106
|
onScreenUnmounted(screenUnmounted);
|
|
100
107
|
|
|
108
|
+
// The screens of defineScreen by name, in development: what `screens` gives (a lazy screen's module once loaded) and
|
|
109
|
+
// the options of its group.
|
|
110
|
+
const editable = new Map<
|
|
111
|
+
string,
|
|
112
|
+
{ screen: () => unknown; groupOptions: ScreenOptionsInput<object> | undefined }
|
|
113
|
+
>();
|
|
114
|
+
|
|
115
|
+
onRedefined(applyEdit);
|
|
116
|
+
|
|
117
|
+
// Fast Refresh ran the module of a screen again: the screens of it that show take what the edit changed in their
|
|
118
|
+
// options, as a command would have shown them. The family's newest is still the version before the edit here, as React
|
|
119
|
+
// Refresh moves it on only after the update.
|
|
120
|
+
function applyEdit(next: object) {
|
|
121
|
+
const family = familyOf(next);
|
|
122
|
+
const edited = ownDefinitionOf(next) ?? (isNativeScreen(next) ? next : undefined);
|
|
123
|
+
if (!family || !edited) return;
|
|
124
|
+
for (const [name, { screen, groupOptions }] of editable) {
|
|
125
|
+
const current = screen();
|
|
126
|
+
if (current === undefined || familyOf(current) !== family) continue;
|
|
127
|
+
const native = isNativeScreen(current);
|
|
128
|
+
const before = native ? newestType(current) : definitionOf(current);
|
|
129
|
+
// The screen as it was registered: its own module running, nothing edited yet.
|
|
130
|
+
if (before === edited) continue;
|
|
131
|
+
// What a native screen is made of goes to the native side when it is registered and shown: a change of it starts
|
|
132
|
+
// the app again.
|
|
133
|
+
if (native && isNativeScreen(edited) && madeOtherwise(newestType(current), edited)) {
|
|
134
|
+
DevSettings.reload('[navigation] A native screen changed its name or its useProps');
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
applyChange(
|
|
138
|
+
name,
|
|
139
|
+
native,
|
|
140
|
+
{ group: groupOptions, definition: before },
|
|
141
|
+
{ group: groupOptions, definition: edited }
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** The options a screen is shown with: those of its group, and those of its definition over them. */
|
|
147
|
+
interface ShownOptions {
|
|
148
|
+
group: ScreenOptionsInput<object> | undefined;
|
|
149
|
+
definition: { options?: ScreenOptionsInput<any> } | undefined;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// What an edit changed in a screen's options goes to every screen of it the native side has, a screen React hasn't
|
|
153
|
+
// mounted yet too (a tab not selected yet), as a command would have shown it; only where the screen still has what
|
|
154
|
+
// the definition before gave.
|
|
155
|
+
function applyChange(name: string, native: boolean, before: ShownOptions, after: ShownOptions) {
|
|
156
|
+
const shown = native
|
|
157
|
+
? openNativeScreens(name)
|
|
158
|
+
: [...new Set([...shownScreens(name), ...notedScreens(name).filter(isPlaced)])].map((id) => ({
|
|
159
|
+
id,
|
|
160
|
+
props: propsOf(id),
|
|
161
|
+
}));
|
|
162
|
+
for (const { id, props } of shown) {
|
|
163
|
+
const options = ({ group, definition }: ShownOptions) =>
|
|
164
|
+
mergeOptions(
|
|
165
|
+
buildScreenOptions(group, props),
|
|
166
|
+
buildScreenOptions(definition?.options, props)
|
|
167
|
+
);
|
|
168
|
+
const shownWith = options(before);
|
|
169
|
+
const change = optionsChange(shownWith, options(after));
|
|
170
|
+
const { merge, removed } = changeOverOwn(change, shownWith, ownOptionsOf(id) ?? shownWith);
|
|
171
|
+
if (removed.length > 0) clearOptions(id, removed);
|
|
172
|
+
if (merge) sendMergeOptions(id, merge);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// The screens map registered again (Fast Refresh ran the module of the app): a screen written in the map itself, a
|
|
177
|
+
// definition no module exports, has no family to tell its edit, so its definition before and after are compared here.
|
|
178
|
+
// The options of its group too: a group is written in the app's module, and an edit of them leaves the screen as it was.
|
|
179
|
+
function applyRegisteredAgain(
|
|
180
|
+
name: string,
|
|
181
|
+
entry: unknown,
|
|
182
|
+
group: ScreenOptionsInput<object> | undefined
|
|
183
|
+
) {
|
|
184
|
+
const previous = editable.get(name);
|
|
185
|
+
const before = previous?.screen();
|
|
186
|
+
if (before === undefined) return;
|
|
187
|
+
if (before === entry) {
|
|
188
|
+
if (previous!.groupOptions === group) return;
|
|
189
|
+
const native = isNativeScreen(entry);
|
|
190
|
+
const definition = native ? newestType(entry) : definitionOf(entry);
|
|
191
|
+
applyChange(name, native, { group: previous!.groupOptions, definition }, { group, definition });
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (isNativeScreen(before) && isNativeScreen(entry)) {
|
|
195
|
+
if (madeOtherwise(newestType(before), entry)) {
|
|
196
|
+
DevSettings.reload('[navigation] A native screen changed its name or its useProps');
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
applyChange(
|
|
200
|
+
name,
|
|
201
|
+
true,
|
|
202
|
+
{ group: previous!.groupOptions, definition: newestType(before) },
|
|
203
|
+
{ group, definition: entry }
|
|
204
|
+
);
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
const was = definitionOf(before);
|
|
208
|
+
const now = definitionOf(entry);
|
|
209
|
+
if (!was && !now && previous!.groupOptions === group) return;
|
|
210
|
+
applyChange(
|
|
211
|
+
name,
|
|
212
|
+
false,
|
|
213
|
+
{ group: previous!.groupOptions, definition: was },
|
|
214
|
+
{ group, definition: now }
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// A screen the engine knows the place of: one whose command failed after its layout was built has none.
|
|
219
|
+
function isPlaced(id: string): boolean {
|
|
220
|
+
return placeOf(id) !== undefined;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function madeOtherwise(before: NativeScreen<any>, after: NativeScreen<any>): boolean {
|
|
224
|
+
return before.nativeName !== after.nativeName || !before.useProps !== !after.useProps;
|
|
225
|
+
}
|
|
226
|
+
|
|
101
227
|
export function registerScreens(sets: ScreenSet[], wrapper: ScreenWrapper = {}) {
|
|
102
228
|
// The screens of every set are in one namespace: a command names a screen without its group.
|
|
103
229
|
const sources = new Map<string, string>();
|
|
@@ -131,21 +257,38 @@ function registerScreen(
|
|
|
131
257
|
return;
|
|
132
258
|
}
|
|
133
259
|
if (isNativeScreen(entry)) {
|
|
260
|
+
// Read on every show, the newest after Fast Refresh, as for a screen of defineScreen.
|
|
261
|
+
const screen = () => newestType(entry);
|
|
262
|
+
if (__DEV__) {
|
|
263
|
+
applyRegisteredAgain(name, entry, groupOptions);
|
|
264
|
+
editable.set(name, { screen: () => entry, groupOptions });
|
|
265
|
+
}
|
|
134
266
|
registerEngineScreen(name, {
|
|
135
267
|
nativeName: entry.nativeName,
|
|
136
268
|
options: (props) =>
|
|
137
269
|
mergeOptions(
|
|
138
270
|
buildScreenOptions(groupOptions, props),
|
|
139
|
-
buildScreenOptions(
|
|
271
|
+
buildScreenOptions(screen().options, props)
|
|
140
272
|
),
|
|
141
|
-
controller: entry.useProps && wrapNativeScreen(name, entry
|
|
142
|
-
arrangement:
|
|
273
|
+
controller: entry.useProps && wrapNativeScreen(name, entry, wrapper),
|
|
274
|
+
arrangement: () => {
|
|
275
|
+
const arrangement = screen().arrangement;
|
|
276
|
+
return arrangement && toEngineArrangement(name, arrangement);
|
|
277
|
+
},
|
|
143
278
|
});
|
|
144
279
|
return;
|
|
145
280
|
}
|
|
146
281
|
// React.memo and forwardRef components are objects, so the kind of entry is told by its keys.
|
|
147
282
|
if (isObject(entry) && 'load' in entry) {
|
|
148
283
|
const screen = lazyScreen(entry.load);
|
|
284
|
+
if (__DEV__) {
|
|
285
|
+
// A lazy screen registered again loads its module on its next show: until then the one loaded before stands for
|
|
286
|
+
// it, so the screens of it that show take an edit of their group's options, and of their module, as before.
|
|
287
|
+
const before = editable.get(name)?.screen();
|
|
288
|
+
const loaded = () => screen.loaded() ?? before;
|
|
289
|
+
applyRegisteredAgain(name, loaded(), groupOptions);
|
|
290
|
+
editable.set(name, { screen: loaded, groupOptions });
|
|
291
|
+
}
|
|
149
292
|
registerEngineScreen(name, {
|
|
150
293
|
component: () => wrapScreen(name, screen.component, wrapper),
|
|
151
294
|
// A command loads the screen before it reads its options.
|
|
@@ -164,32 +307,34 @@ function registerScreen(
|
|
|
164
307
|
});
|
|
165
308
|
return;
|
|
166
309
|
}
|
|
167
|
-
|
|
310
|
+
// Read on every show: after Fast Refresh a screen of defineScreen gives its new options, key and pair.
|
|
311
|
+
const definition = () => toDefinition(entry);
|
|
312
|
+
if (__DEV__) {
|
|
313
|
+
applyRegisteredAgain(name, entry, groupOptions);
|
|
314
|
+
editable.set(name, { screen: () => entry, groupOptions });
|
|
315
|
+
}
|
|
168
316
|
registerEngineScreen(name, {
|
|
169
|
-
component: () => wrapScreen(name, definition.component, wrapper),
|
|
317
|
+
component: () => wrapScreen(name, definition().component, wrapper),
|
|
170
318
|
options: (props) =>
|
|
171
319
|
mergeOptions(
|
|
172
320
|
buildScreenOptions(groupOptions, props),
|
|
173
|
-
buildScreenOptions(definition.options, props)
|
|
321
|
+
buildScreenOptions(definition().options, props)
|
|
174
322
|
),
|
|
175
|
-
key:
|
|
323
|
+
key: (props) => definition().key?.(props),
|
|
176
324
|
ownRoot,
|
|
177
|
-
arrangement:
|
|
325
|
+
arrangement: () => {
|
|
326
|
+
const arrangement = definition().arrangement;
|
|
327
|
+
return arrangement && toEngineArrangement(name, arrangement);
|
|
328
|
+
},
|
|
178
329
|
});
|
|
179
330
|
}
|
|
180
331
|
|
|
181
|
-
// The pair of a screen whose `arrangement` is known at registration: checked and filled in once.
|
|
182
|
-
function pairOf(
|
|
183
|
-
name: string,
|
|
184
|
-
arrangement: ScreenArrangement<any> | undefined
|
|
185
|
-
): (() => EngineArrangement) | undefined {
|
|
186
|
-
if (!arrangement) return undefined;
|
|
187
|
-
const pair = toEngineArrangement(name, arrangement);
|
|
188
|
-
return () => pair;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
332
|
function toDefinition(value: ScreenComponent | ScreenDefinition): ScreenDefinition {
|
|
192
|
-
|
|
333
|
+
// A screen of defineScreen renders as itself: React Refresh knows it by its module's export, and the version of the
|
|
334
|
+
// newest definition renders in its place.
|
|
335
|
+
const defined = definitionOf(value);
|
|
336
|
+
if (defined) return { ...defined, component: value as ScreenComponent };
|
|
337
|
+
return isObject(value) && 'component' in value ? value : { component: value as ScreenComponent };
|
|
193
338
|
}
|
|
194
339
|
|
|
195
340
|
/**
|
|
@@ -198,15 +343,17 @@ function toDefinition(value: ScreenComponent | ScreenDefinition): ScreenDefiniti
|
|
|
198
343
|
* screen) waits for it in Suspense.
|
|
199
344
|
*/
|
|
200
345
|
function lazyScreen(loadModule: () => ScreenModule | PromiseLike<ScreenModule>) {
|
|
201
|
-
|
|
346
|
+
// The screen the module gives; its definition is read from it each time, the newest after Fast Refresh.
|
|
347
|
+
let loaded: ScreenComponent | ScreenDefinition | undefined;
|
|
202
348
|
let loading: Promise<void> | undefined;
|
|
349
|
+
const definition = () => (loaded ? toDefinition(loaded) : undefined);
|
|
203
350
|
const load = (): Promise<void> | undefined => {
|
|
204
|
-
if (
|
|
351
|
+
if (loaded) return undefined;
|
|
205
352
|
if (!loading) {
|
|
206
353
|
loading = Promise.resolve()
|
|
207
354
|
.then(loadModule)
|
|
208
355
|
.then((module) => {
|
|
209
|
-
|
|
356
|
+
loaded = unwrapModule(module);
|
|
210
357
|
});
|
|
211
358
|
loading.catch(() => {
|
|
212
359
|
loading = undefined;
|
|
@@ -216,14 +363,14 @@ function lazyScreen(loadModule: () => ScreenModule | PromiseLike<ScreenModule>)
|
|
|
216
363
|
};
|
|
217
364
|
const Loaded = lazy(async () => {
|
|
218
365
|
await load();
|
|
219
|
-
return { default: definition!.component };
|
|
366
|
+
return { default: definition()!.component };
|
|
220
367
|
});
|
|
221
368
|
function LazyScreen(props: object) {
|
|
222
369
|
// The same component for the life of the view, so that the load doesn't mount it again.
|
|
223
|
-
const [Screen] = useState(() => definition?.component ?? Loaded);
|
|
370
|
+
const [Screen] = useState(() => definition()?.component ?? Loaded);
|
|
224
371
|
return <Screen {...props} />;
|
|
225
372
|
}
|
|
226
|
-
return { load, definition: () =>
|
|
373
|
+
return { load, definition, loaded: () => loaded, component: LazyScreen };
|
|
227
374
|
}
|
|
228
375
|
|
|
229
376
|
function unwrapModule(loaded: ScreenModule): ScreenComponent | ScreenDefinition {
|
|
@@ -297,15 +444,11 @@ function wrapScreen(name: string, Screen: ScreenComponent, wrapper: ScreenWrappe
|
|
|
297
444
|
*/
|
|
298
445
|
function wrapNativeScreen(
|
|
299
446
|
name: string,
|
|
300
|
-
|
|
447
|
+
entry: NativeScreen<any>,
|
|
301
448
|
{ provider: Provider, onError }: ScreenWrapper
|
|
302
449
|
): ComponentType<NativeControllerProps> {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
// After each render React committed, so the native side never shows what the app did not.
|
|
306
|
-
useEffect(() => onProps(result));
|
|
307
|
-
return null;
|
|
308
|
-
}
|
|
450
|
+
// The screen's own component runs the hook: Fast Refresh puts a new version of it in place.
|
|
451
|
+
const Hook = entry as unknown as ComponentType<NativeScreenHookProps<object>>;
|
|
309
452
|
function NativeScreenProps({
|
|
310
453
|
componentId,
|
|
311
454
|
props,
|
package/src/api/theme/theme.ts
CHANGED
|
@@ -135,6 +135,11 @@ export function setTheme(next: NavigationTheme) {
|
|
|
135
135
|
listeners.forEach((listener) => listener());
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
+
/** The direction of the app now: the config's, or the one `setDirection` gave since. */
|
|
139
|
+
export function getDirection(): NavigationDirection | undefined {
|
|
140
|
+
return direction;
|
|
141
|
+
}
|
|
142
|
+
|
|
138
143
|
/** Changes the direction of the app: the bars, the transitions and the swipe back follow at once. */
|
|
139
144
|
export function setDirection(next: NavigationDirection) {
|
|
140
145
|
direction = next;
|
package/src/engine/commands.ts
CHANGED
|
@@ -9,15 +9,17 @@ import { whenNativeScreensReady } from './nativeScreens';
|
|
|
9
9
|
import { commands as native } from './native';
|
|
10
10
|
import { toNativeOptions } from './options';
|
|
11
11
|
import { dropReactRenderMeasures } from './reactMeasures';
|
|
12
|
-
import { columnOf, forgetPlace, notePlaces, placeOf, stackOfColumn } from './places';
|
|
12
|
+
import { columnOf, forgetPlace, layoutsOf, notePlaces, placeOf, stackOfColumn } from './places';
|
|
13
13
|
import { forgetProps } from './props';
|
|
14
14
|
import {
|
|
15
15
|
forgetMergedOptions,
|
|
16
|
+
forgetMergedPaths,
|
|
17
|
+
noteMergedOwnOptions,
|
|
16
18
|
rememberMergedOptions,
|
|
17
19
|
rootGoesOut,
|
|
18
20
|
sentRoot,
|
|
19
21
|
} from './rememberedOptions';
|
|
20
|
-
import { afterLoading } from './screens';
|
|
22
|
+
import { afterLoading, hasRoot, isReactScreen } from './screens';
|
|
21
23
|
import { holdSlot, isSlotName, removeSlots, showSlot, type SlotFrame } from './slots';
|
|
22
24
|
import { forgetTabsScreen, showScreensFrom } from './tabs';
|
|
23
25
|
|
|
@@ -122,7 +124,7 @@ export function setRoot(root: LayoutRoot): Promise<string> {
|
|
|
122
124
|
|
|
123
125
|
export function setDefaultOptions(options: Options): void {
|
|
124
126
|
rememberDefaultOptions(options);
|
|
125
|
-
native.setDefaultOptions(toNativeOptions(options));
|
|
127
|
+
native.setDefaultOptions(toNativeOptions(options, 'defaultOptions'));
|
|
126
128
|
}
|
|
127
129
|
|
|
128
130
|
// The show commands that wait in JS, by number: for lazy screens to load, for the first props of native screens, for a
|
|
@@ -141,9 +143,10 @@ const preparedScreens = new Set<string>();
|
|
|
141
143
|
* engine remembers them by the node's id, so the root set again for a new launch of the native side shows them too.
|
|
142
144
|
*/
|
|
143
145
|
export function mergeOptions(componentId: string, options: Options): void {
|
|
144
|
-
const nativeOptions = toNativeOptions(options);
|
|
146
|
+
const nativeOptions = toNativeOptions(options, componentId);
|
|
145
147
|
const send = () => {
|
|
146
148
|
rememberMergedOptions(componentId, options);
|
|
149
|
+
noteMergedOwnOptions(componentId, options);
|
|
147
150
|
native.mergeOptions(componentId, nativeOptions);
|
|
148
151
|
};
|
|
149
152
|
const prepared =
|
|
@@ -152,6 +155,24 @@ export function mergeOptions(componentId: string, options: Options): void {
|
|
|
152
155
|
else heldMerges.push({ id: componentId, after: shows, send });
|
|
153
156
|
}
|
|
154
157
|
|
|
158
|
+
/**
|
|
159
|
+
* Takes the options at the paths, such as `['topBar', 'subtitle']`, out of the own options of a node, so it shows what
|
|
160
|
+
* the layouts around it and the defaults give there (Fast Refresh, development). It waits for the shows as a merge does.
|
|
161
|
+
*/
|
|
162
|
+
export function clearOptions(componentId: string, paths: readonly string[][]): void {
|
|
163
|
+
const send = () => {
|
|
164
|
+
forgetMergedPaths(componentId, paths);
|
|
165
|
+
native.clearOptions(
|
|
166
|
+
componentId,
|
|
167
|
+
paths.map((path) => path.join('.'))
|
|
168
|
+
);
|
|
169
|
+
};
|
|
170
|
+
const prepared =
|
|
171
|
+
preparedScreens.has(componentId) && !heldMerges.some(({ id }) => id === componentId);
|
|
172
|
+
if (waitingShows.size === 0 || prepared) send();
|
|
173
|
+
else heldMerges.push({ id: componentId, after: shows, send });
|
|
174
|
+
}
|
|
175
|
+
|
|
155
176
|
// Runs a show command; the function `run` gets lets the mergeOptions made after the show go, once it went out. It is
|
|
156
177
|
// called again when the command ends, so a command that fails before it goes out lets them go too.
|
|
157
178
|
function show<Result>(run: (goneOut: () => void) => Promise<Result>): Promise<Result> {
|
|
@@ -225,19 +246,44 @@ export function push(
|
|
|
225
246
|
from?.stack ?? null,
|
|
226
247
|
(from?.index ?? 0) + 1,
|
|
227
248
|
from?.menu,
|
|
228
|
-
from?.layer
|
|
249
|
+
from?.layer,
|
|
250
|
+
layoutsOf(componentId)
|
|
229
251
|
);
|
|
230
252
|
return whenNativeScreensReady([node], () =>
|
|
231
|
-
sendPush(commandId, componentId, node, prepares, wanted, goneOut).then(
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
253
|
+
sendPush(commandId, componentId, node, prepares, wanted, goneOut).then(
|
|
254
|
+
(shownId) => {
|
|
255
|
+
// A screen with a key went back to the one with the same key: the new screen never shows.
|
|
256
|
+
if (shownId !== node.id) forgetNeverShown(node.id);
|
|
257
|
+
return shownId;
|
|
258
|
+
},
|
|
259
|
+
(error: unknown) => {
|
|
260
|
+
if (rendersAtPress(node)) forgetUnmountedPreview(node.id);
|
|
261
|
+
throw error;
|
|
262
|
+
}
|
|
263
|
+
)
|
|
236
264
|
);
|
|
237
265
|
})
|
|
238
266
|
);
|
|
239
267
|
}
|
|
240
268
|
|
|
269
|
+
// A preview's React screen with a root of its own renders only once the view is pressed (iOS): one whose preview went
|
|
270
|
+
// before that never mounts. A screen of the one tree mounts with its slot, a native screen has no root.
|
|
271
|
+
function rendersAtPress(node: LayoutNode): boolean {
|
|
272
|
+
return node.data.options?.preview?.nativeID !== undefined && isReactScreen(node.data.name ?? '');
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// A root started at a press that came just before the preview went can reach JavaScript after its push failed: without
|
|
276
|
+
// its props it would render the screen with none. Its notes go after this time, when no root of it has mounted by
|
|
277
|
+
// then; one that has clears them as it unmounts.
|
|
278
|
+
const PREVIEW_FORGET_DELAY = 1000;
|
|
279
|
+
|
|
280
|
+
function forgetUnmountedPreview(screenId: string): void {
|
|
281
|
+
if (hasRoot(screenId)) return;
|
|
282
|
+
setTimeout(() => {
|
|
283
|
+
if (!hasRoot(screenId)) forgetNeverShown(screenId);
|
|
284
|
+
}, PREVIEW_FORGET_DELAY);
|
|
285
|
+
}
|
|
286
|
+
|
|
241
287
|
// Everything a push noted for a screen that never mounts, which an unmount would clear.
|
|
242
288
|
function forgetNeverShown(screenId: string): void {
|
|
243
289
|
forgetProps(screenId);
|
|
@@ -363,7 +409,8 @@ export function setStackRoot(componentId: string, children: Layout[]): Promise<s
|
|
|
363
409
|
from?.stack ?? null,
|
|
364
410
|
index,
|
|
365
411
|
from?.menu,
|
|
366
|
-
from?.layer
|
|
412
|
+
from?.layer,
|
|
413
|
+
layoutsOf(componentId)
|
|
367
414
|
)
|
|
368
415
|
);
|
|
369
416
|
return whenNativeScreensReady(nodes, () =>
|
|
@@ -383,7 +430,17 @@ export function showInColumn(componentId: string, column: string, layout: Layout
|
|
|
383
430
|
showScreensFrom(componentId, node);
|
|
384
431
|
const from = placeOf(componentId);
|
|
385
432
|
const at = columnPlace(componentId, column);
|
|
386
|
-
|
|
433
|
+
// In the split view of the screen it comes from, and in the column's stack.
|
|
434
|
+
const within = at.stack ? [...layoutsOf(componentId), at.stack] : layoutsOf(componentId);
|
|
435
|
+
notePlaces(
|
|
436
|
+
node,
|
|
437
|
+
from?.container ?? 'root',
|
|
438
|
+
at.stack,
|
|
439
|
+
at.index,
|
|
440
|
+
from?.menu,
|
|
441
|
+
from?.layer,
|
|
442
|
+
within
|
|
443
|
+
);
|
|
387
444
|
return whenNativeScreensReady([node], () =>
|
|
388
445
|
inOrder(() =>
|
|
389
446
|
sendShow(goneOut, () => native.showInColumn(commandId, componentId, column, node))
|
|
@@ -431,7 +488,7 @@ export function dismissModal(componentId: string, options?: Options): Promise<st
|
|
|
431
488
|
dropReactRenderMeasures();
|
|
432
489
|
const commandId = nextId('dismissModal');
|
|
433
490
|
return inOrder(() =>
|
|
434
|
-
native.dismissModal(commandId, componentId, options && toNativeOptions(options))
|
|
491
|
+
native.dismissModal(commandId, componentId, options && toNativeOptions(options, componentId))
|
|
435
492
|
);
|
|
436
493
|
}
|
|
437
494
|
|