@apexnative/navigation 1.0.0-alpha.5 → 1.0.0-alpha.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ApexNavigation.podspec +2 -1
- package/CHANGELOG.md +32 -0
- package/README.md +1 -1
- package/android/CLAUDE.md +31 -20
- package/android/CORE.md +12 -8
- package/android/consumer-rules.pro +6 -0
- package/android/src/main/java/dev/apexnative/navigation/NavigationActivity.kt +36 -5
- package/android/src/main/java/dev/apexnative/navigation/options/BottomTabOptions.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/BottomTabsOptions.kt +13 -8
- package/android/src/main/java/dev/apexnative/navigation/options/ButtonOptions.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/LargeTitleOptions.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/LayoutAnimation.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/OptionKey.kt +18 -0
- package/android/src/main/java/dev/apexnative/navigation/options/OptionPaths.kt +91 -0
- package/android/src/main/java/dev/apexnative/navigation/options/SheetOptions.kt +7 -4
- package/android/src/main/java/dev/apexnative/navigation/options/TitleOptions.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/options/TopBarAppearanceOptions.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/TopBarOptions.kt +16 -7
- package/android/src/main/java/dev/apexnative/navigation/react/ContentHeights.kt +95 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ContentMounts.kt +66 -0
- package/android/src/main/java/dev/apexnative/navigation/react/NavigationTurboModule.kt +7 -3
- package/android/src/main/java/dev/apexnative/navigation/react/OptionsCommands.kt +41 -3
- package/android/src/main/java/dev/apexnative/navigation/react/ReactView.kt +16 -1
- package/android/src/main/java/dev/apexnative/navigation/react/ReloadCoordinator.kt +0 -2
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenEnvironment.kt +177 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenRegions.kt +12 -49
- package/android/src/main/java/dev/apexnative/navigation/react/ScrollEvents.kt +49 -128
- package/android/src/main/java/dev/apexnative/navigation/safearea/SafeAreaView.kt +6 -6
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotScreenView.kt +27 -7
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotView.kt +12 -1
- package/android/src/main/java/dev/apexnative/navigation/utils/MaterialTheme.kt +5 -6
- package/android/src/main/java/dev/apexnative/navigation/utils/SystemAnimations.kt +36 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/ViewExtensions.kt +0 -13
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/ArrangementController.kt +9 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsCollapseBehavior.kt +5 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsController.kt +13 -10
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowGeometry.kt +22 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabsRoom.kt +0 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentViewController.kt +7 -8
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenSafeArea.kt +29 -11
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/externalcomponent/ExternalComponentViewController.kt +2 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalCoordinator.kt +20 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalSheet.kt +443 -58
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalViews.kt +33 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetBack.kt +42 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetStops.kt +60 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/Navigator.kt +4 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ParentController.kt +3 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuMotion.kt +8 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/BackPreview.kt +32 -4
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/PreparedFrame.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackCommands.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackController.kt +50 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackQueue.kt +15 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackViews.kt +10 -4
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabMotion.kt +142 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabPresenter.kt +215 -43
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/StackSearchPresenter.kt +25 -26
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/BarRowTransition.kt +3 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/ButtonPlaces.kt +11 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarPresenter.kt +36 -38
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ScrollEventListener.kt +6 -9
- package/android/src/main/java/dev/apexnative/navigation/views/animations/AnimationLayer.kt +73 -0
- package/android/src/main/java/dev/apexnative/navigation/views/animations/ValueInterpolation.kt +14 -0
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabsLayout.kt +61 -2
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomTabRow.kt +72 -10
- package/android/src/main/java/dev/apexnative/navigation/views/element/ElementTransitions.kt +129 -179
- package/android/src/main/java/dev/apexnative/navigation/views/element/TargetsWait.kt +8 -1
- package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionLayer.kt +37 -112
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ElementPictures.kt +67 -3
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/FlightGeometry.kt +346 -36
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMorph.kt +199 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/SharedAnimatorFactory.kt +55 -42
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextMorph.kt +176 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewMorph.kt +108 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabCopy.kt +85 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabMenu.kt +13 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TitleBar.kt +5 -24
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TopBar.kt +51 -34
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonComponentCell.kt +6 -6
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonView.kt +113 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarMenu.kt +219 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonBar.kt +121 -175
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonMenus.kt +34 -64
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonRow.kt +216 -0
- package/android/src/main/jni/ANNContentHeights.cpp +82 -0
- package/android/src/main/res/drawable/apex_navigation_ic_arrow_right.xml +14 -0
- package/android/src/main/res/layout/apex_navigation_menu_header.xml +19 -0
- package/android/src/main/res/layout/apex_navigation_menu_item.xml +68 -0
- package/android/src/main/res/values/styles.xml +1 -1
- package/android/src/main/res/values-night/styles.xml +1 -1
- package/cli/doctor/checks/app.js +16 -1
- package/cli/project.js +4 -0
- package/cli/setup/index.js +5 -0
- package/cli/setup/steps/metro.js +46 -0
- package/docs-md/architecture/native-screens.md +4 -0
- package/docs-md/architecture/theme-and-context.md +131 -12
- package/docs-md/architecture/transitions.md +46 -5
- package/docs-md/containers/modals.md +2 -0
- package/docs-md/containers/overlays.md +1 -1
- package/docs-md/containers/side-menu.md +1 -1
- package/docs-md/containers/tabs.md +2 -0
- package/docs-md/flows/bottom-sheets.md +4 -2
- package/docs-md/fundamentals/screens-and-props.md +9 -1
- package/docs-md/fundamentals/starting-the-app.md +1 -1
- package/docs-md/guides/cli.md +3 -1
- package/docs-md/help/glossary.md +2 -2
- package/docs-md/help/troubleshooting.md +22 -1
- package/docs-md/index.json +41 -1
- package/docs-md/migration/from-expo-router.md +1 -1
- package/docs-md/migration/from-react-native-navigation.md +1 -1
- package/docs-md/migration/from-react-navigation.md +2 -2
- package/docs-md/screen-ui/back-and-gestures.md +17 -1
- package/docs-md/screen-ui/bar-buttons.md +5 -5
- package/docs-md/screen-ui/search.md +1 -1
- package/docs-md/screen-ui/system-ui.md +16 -11
- package/docs-md/screen-ui/toolbar-and-fab.md +4 -2
- package/docs-md/screen-ui/top-bar.md +8 -4
- package/docs-md/start/installation.md +16 -1
- package/ios/Animations/ANNFrameDriver.h +55 -15
- package/ios/Animations/ANNFrameDriver.mm +216 -60
- package/ios/Animations/ANNTransitionAnimator.h +26 -5
- package/ios/Animations/ANNTransitionAnimator.mm +49 -3
- package/ios/Animations/ANNTransitionPlan.h +2 -2
- package/ios/Animations/ANNTransitionPlan.mm +10 -0
- package/ios/Animations/Elements/ANNElementFinder.h +2 -2
- package/ios/Animations/Elements/ANNElementFinder.mm +2 -2
- package/ios/Animations/Elements/ANNElementTransition.h +3 -3
- package/ios/Animations/Elements/ANNElementTransition.mm +2 -2
- package/ios/Animations/Elements/ANNSharedElementFlight.h +3 -3
- package/ios/Animations/Elements/ANNSharedElementFlight.mm +249 -45
- package/ios/Animations/Interpolators/ANNInterpolate.h +2 -30
- package/ios/Animations/Interpolators/ANNTransformParts.h +48 -0
- package/ios/Animations/Interpolators/ANNTransformParts.mm +507 -0
- package/ios/Animations/Interpolators/ANNViewTracks.h +9 -6
- package/ios/Animations/Interpolators/ANNViewTracks.mm +100 -30
- package/ios/CLAUDE.md +32 -22
- package/ios/CORE.md +25 -21
- package/ios/Contract/ANNCommandRunner.h +8 -7
- package/ios/Contract/ANNCommandRunner.mm +21 -27
- package/ios/Contract/ANNLayoutNode.h +3 -3
- package/ios/Contract/ANNLayoutReader.h +3 -3
- package/ios/Core/ANNAppDelegate.mm +0 -2
- package/ios/Core/ANNDeepLinkQueue.h +6 -5
- package/ios/Core/ANNDeepLinkQueue.mm +22 -10
- package/ios/Core/ANNJavaScriptCalls.h +11 -12
- package/ios/Core/ANNJavaScriptCalls.mm +7 -16
- package/ios/Core/ANNReloadCoordinator.mm +4 -8
- package/ios/Core/ANNSceneDelegate.mm +2 -2
- package/ios/Core/ApexNavigation+Internal.h +1 -1
- package/ios/Core/ApexNavigation.mm +6 -2
- package/ios/Layouts/Arrangement/ANNArrangementState.h +2 -17
- package/ios/Layouts/Arrangement/ANNArrangementState.mm +0 -38
- package/ios/Layouts/Arrangement/ANNArrangementViewController.mm +4 -4
- package/ios/Layouts/Root/ANNRootCoordinator.mm +45 -15
- package/ios/Layouts/Screen/ANNComponentViewController.h +2 -2
- package/ios/Layouts/Screen/ANNComponentViewController.mm +13 -23
- package/ios/Layouts/Screen/ANNPreviewInteraction.h +7 -4
- package/ios/Layouts/Screen/ANNPreviewInteraction.mm +72 -10
- package/ios/Layouts/Screen/ANNScreenEnvironment.h +63 -0
- package/ios/Layouts/Screen/ANNScreenEnvironment.mm +181 -0
- package/ios/Layouts/Screen/ANNScreenRegions.h +3 -18
- package/ios/Layouts/Screen/ANNScreenRegions.mm +0 -38
- package/ios/Layouts/Screen/ANNScreenSafeArea.h +4 -9
- package/ios/Layouts/Screen/ANNScreenSafeArea.mm +14 -16
- package/ios/Layouts/Stack/ANNPreviewPush.h +7 -6
- package/ios/Layouts/Stack/ANNPreviewPush.mm +57 -5
- package/ios/Layouts/Stack/ANNStackAnimatingDelegate.h +11 -2
- package/ios/Layouts/Stack/ANNStackAnimatingDelegate.mm +14 -7
- package/ios/Layouts/Stack/ANNStackController.h +8 -0
- package/ios/Layouts/Stack/ANNStackController.mm +153 -11
- package/ios/Layouts/Stack/ANNSwipePopInteraction.h +26 -0
- package/ios/Layouts/Stack/ANNSwipePopInteraction.mm +185 -0
- package/ios/Layouts/Stack/InteractivePopGestureDelegate.mm +28 -4
- package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.h +12 -1
- package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.mm +23 -0
- package/ios/Layouts/Tabs/ANNBottomTabsController.mm +2 -1
- package/ios/Layouts/Tabs/ANNBottomTabsCustomRow.mm +8 -3
- package/ios/Layouts/Tabs/ANNBottomTabsPresenter.h +4 -0
- package/ios/Layouts/Tabs/ANNBottomTabsPresenter.mm +123 -36
- package/ios/Layouts/Tabs/ANNTabsDesign.h +6 -5
- package/ios/Layouts/Tabs/ANNTabsDesign.mm +9 -1
- package/ios/Layouts/Tabs/UITabBar+utils.h +5 -5
- package/ios/Layouts/Tabs/UITabBar+utils.mm +32 -13
- package/ios/Options/ANNAnimationOptions.h +2 -1
- package/ios/Options/ANNAnimationOptions.mm +1 -1
- package/ios/Options/ANNBottomTabsOptions.h +2 -0
- package/ios/Options/ANNBottomTabsOptions.mm +1 -0
- package/ios/Options/ANNOptions.h +25 -0
- package/ios/Options/ANNOptions.mm +157 -1
- package/ios/Options/ANNOptionsReader.mm +108 -0
- package/ios/Options/ANNStackPopAnimationOptions.h +13 -0
- package/ios/Options/ANNStackPopAnimationOptions.mm +11 -0
- package/ios/Options/Params/ANNParam.h +15 -0
- package/ios/Options/Params/ANNParam.mm +61 -0
- package/ios/Options/Params/Color.h +3 -0
- package/ios/Options/Params/Color.mm +21 -0
- package/ios/Options/Params/ColorParser.h +4 -3
- package/ios/Options/Params/ColorParser.mm +22 -4
- package/ios/Options/Params/Image.h +4 -0
- package/ios/Options/Params/Image.mm +20 -0
- package/ios/React/ANNReactView.mm +6 -25
- package/ios/React/ANNSafeAreaViewComponentView.mm +26 -15
- package/ios/React/ANNSurfaceHostingView.h +14 -0
- package/ios/React/ANNSurfaceHostingView.mm +144 -1
- package/ios/React/Slots/ANNSlotScreenView.mm +8 -2
- package/ios/TopBar/ANNBackButtonPresenter.mm +6 -5
- package/ios/TopBar/ANNBarAppearance.h +2 -1
- package/ios/TopBar/ANNBarAppearance.mm +111 -30
- package/ios/TopBar/ANNBarBackgroundComponent.mm +16 -0
- package/ios/TopBar/ANNBarButtonComponentView.h +4 -4
- package/ios/TopBar/ANNBarButtonComponentView.mm +1 -1
- package/ios/TopBar/ANNBarButtons.h +5 -3
- package/ios/TopBar/ANNBarButtons.mm +186 -17
- package/ios/TopBar/ANNLargeTitlePresenter.mm +24 -4
- package/ios/TopBar/ANNMainList.h +3 -0
- package/ios/TopBar/ANNMainList.mm +4 -0
- package/ios/TopBar/ANNScrollEdgeEffects.h +22 -6
- package/ios/TopBar/ANNScrollEdgeEffects.mm +123 -16
- package/ios/TopBar/ANNSearchPresenter.mm +2 -2
- package/ios/TopBar/ANNSearchResultsViewController.mm +5 -5
- package/ios/TopBar/ANNTopBarPresenter.h +3 -2
- package/ios/TopBar/ANNTopBarPresenter.mm +95 -22
- package/ios/TurboModules/ANNTurboModule.mm +66 -16
- package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.cpp +20 -0
- package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.h +5 -14
- package/lib/module/ARCHITECTURE.md +17 -7
- package/lib/module/adapters/NativeANNTurboModule.js.map +1 -1
- package/lib/module/api/app/AppRegistry.js +14 -2
- package/lib/module/api/app/AppRegistry.js.map +1 -1
- package/lib/module/api/app/createNavigation.js +188 -66
- package/lib/module/api/app/createNavigation.js.map +1 -1
- package/lib/module/api/events/navigationEvents.js +6 -2
- package/lib/module/api/events/navigationEvents.js.map +1 -1
- package/lib/module/api/hooks/useSafeAreaInsets.js +4 -3
- package/lib/module/api/hooks/useSafeAreaInsets.js.map +1 -1
- package/lib/module/api/linking/linking.js +11 -0
- package/lib/module/api/linking/linking.js.map +1 -1
- package/lib/module/api/options/OptionsChain.js +2 -2
- package/lib/module/api/screens/defineScreen.js +45 -3
- package/lib/module/api/screens/defineScreen.js.map +1 -1
- package/lib/module/api/screens/nativeScreens.js +31 -6
- package/lib/module/api/screens/nativeScreens.js.map +1 -1
- package/lib/module/api/screens/registerScreens.js +172 -35
- package/lib/module/api/screens/registerScreens.js.map +1 -1
- package/lib/module/api/theme/theme.js +5 -0
- package/lib/module/api/theme/theme.js.map +1 -1
- package/lib/module/engine/commands.js +42 -2
- package/lib/module/engine/commands.js.map +1 -1
- package/lib/module/engine/layout.js +7 -2
- package/lib/module/engine/layout.js.map +1 -1
- package/lib/module/engine/nativeScreens.js +9 -0
- package/lib/module/engine/nativeScreens.js.map +1 -1
- package/lib/module/engine/options.js +5 -4
- package/lib/module/engine/options.js.map +1 -1
- package/lib/module/engine/optionsChange.js +102 -0
- package/lib/module/engine/optionsChange.js.map +1 -0
- package/lib/module/engine/refresh.js +85 -0
- package/lib/module/engine/refresh.js.map +1 -0
- package/lib/module/engine/rememberedOptions.js +60 -0
- package/lib/module/engine/rememberedOptions.js.map +1 -1
- package/lib/module/engine/screens.js +55 -4
- package/lib/module/engine/screens.js.map +1 -1
- package/lib/typescript/adapters/NativeANNTurboModule.d.ts +7 -0
- package/lib/typescript/adapters/NativeANNTurboModule.d.ts.map +1 -1
- package/lib/typescript/api/app/AppRegistry.d.ts.map +1 -1
- package/lib/typescript/api/app/createNavigation.d.ts +8 -3
- package/lib/typescript/api/app/createNavigation.d.ts.map +1 -1
- package/lib/typescript/api/events/navigationEvents.d.ts +2 -2
- package/lib/typescript/api/events/navigationEvents.d.ts.map +1 -1
- package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts +4 -3
- package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts.map +1 -1
- package/lib/typescript/api/index.d.ts +1 -1
- package/lib/typescript/api/index.d.ts.map +1 -1
- package/lib/typescript/api/linking/linking.d.ts +8 -0
- package/lib/typescript/api/linking/linking.d.ts.map +1 -1
- package/lib/typescript/api/options/OptionsChain.d.ts +2 -2
- package/lib/typescript/api/screens/defineScreen.d.ts +23 -4
- package/lib/typescript/api/screens/defineScreen.d.ts.map +1 -1
- package/lib/typescript/api/screens/nativeScreens.d.ts +8 -1
- package/lib/typescript/api/screens/nativeScreens.d.ts.map +1 -1
- package/lib/typescript/api/screens/registerScreens.d.ts.map +1 -1
- package/lib/typescript/api/theme/theme.d.ts +2 -0
- package/lib/typescript/api/theme/theme.d.ts.map +1 -1
- package/lib/typescript/engine/commands.d.ts +5 -0
- package/lib/typescript/engine/commands.d.ts.map +1 -1
- package/lib/typescript/engine/layout.d.ts.map +1 -1
- package/lib/typescript/engine/nativeScreens.d.ts +5 -0
- package/lib/typescript/engine/nativeScreens.d.ts.map +1 -1
- package/lib/typescript/engine/optionsChange.d.ts +28 -0
- package/lib/typescript/engine/optionsChange.d.ts.map +1 -0
- package/lib/typescript/engine/refresh.d.ts +35 -0
- package/lib/typescript/engine/refresh.d.ts.map +1 -0
- package/lib/typescript/engine/rememberedOptions.d.ts +13 -0
- package/lib/typescript/engine/rememberedOptions.d.ts.map +1 -1
- package/lib/typescript/engine/screens.d.ts +27 -6
- package/lib/typescript/engine/screens.d.ts.map +1 -1
- package/lib/typescript/interfaces/ComponentEvents.d.ts +2 -2
- package/lib/typescript/interfaces/options/animations.d.ts +44 -14
- package/lib/typescript/interfaces/options/animations.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/bottomTabs.d.ts +19 -6
- package/lib/typescript/interfaces/options/bottomTabs.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/buttons.d.ts +10 -10
- package/lib/typescript/interfaces/options/modals.d.ts +6 -7
- package/lib/typescript/interfaces/options/modals.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/stack.d.ts +8 -3
- package/lib/typescript/interfaces/options/stack.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/system.d.ts +8 -5
- package/lib/typescript/interfaces/options/system.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/toolbar.d.ts +2 -2
- package/lib/typescript/interfaces/options/topBar.d.ts +46 -29
- package/lib/typescript/interfaces/options/topBar.d.ts.map +1 -1
- package/metro/acceptPlugin.js +57 -0
- package/metro/babelTransformer.js +45 -0
- package/metro/index.js +36 -0
- package/package.json +3 -1
- package/src/ARCHITECTURE.md +17 -7
- package/src/adapters/NativeANNTurboModule.ts +7 -0
- package/src/api/app/AppRegistry.ts +16 -2
- package/src/api/app/createNavigation.ts +201 -69
- package/src/api/events/navigationEvents.ts +9 -3
- package/src/api/hooks/useSafeAreaInsets.ts +4 -3
- package/src/api/index.ts +1 -0
- package/src/api/linking/linking.ts +22 -1
- package/src/api/options/OptionsChain.ts +2 -2
- package/src/api/screens/defineScreen.ts +49 -5
- package/src/api/screens/nativeScreens.ts +40 -4
- package/src/api/screens/registerScreens.tsx +170 -42
- package/src/api/theme/theme.ts +5 -0
- package/src/engine/commands.ts +51 -6
- package/src/engine/layout.ts +11 -2
- package/src/engine/nativeScreens.ts +10 -1
- package/src/engine/options.ts +6 -8
- package/src/engine/optionsChange.ts +107 -0
- package/src/engine/refresh.ts +97 -0
- package/src/engine/rememberedOptions.ts +70 -0
- package/src/engine/screens.tsx +53 -8
- package/src/interfaces/ComponentEvents.ts +2 -2
- package/src/interfaces/options/animations.ts +44 -14
- package/src/interfaces/options/bottomTabs.ts +19 -6
- package/src/interfaces/options/buttons.ts +10 -10
- package/src/interfaces/options/modals.ts +6 -7
- package/src/interfaces/options/stack.ts +8 -3
- package/src/interfaces/options/system.ts +8 -5
- package/src/interfaces/options/toolbar.ts +2 -2
- package/src/interfaces/options/topBar.ts +46 -29
- package/android/src/main/java/dev/apexnative/navigation/react/ArrangementStates.kt +0 -42
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenInsets.kt +0 -70
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowPlacer.kt +0 -223
- package/android/src/main/java/dev/apexnative/navigation/views/element/ElementStub.kt +0 -31
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMatrixAnimator.kt +0 -136
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PlainViewAnimator.kt +0 -86
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PropertyAnimatorCreator.kt +0 -33
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ReactImageAnimator.kt +0 -64
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextChangeAnimator.kt +0 -177
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewChangeAnimator.kt +0 -137
- package/ios/Layouts/Screen/ANNScreenInsets.h +0 -30
- package/ios/Layouts/Screen/ANNScreenInsets.mm +0 -70
|
@@ -64,8 +64,8 @@ The look and the state of a button:
|
|
|
64
64
|
| --- | --- |
|
|
65
65
|
| `color` | The color of this button. |
|
|
66
66
|
| `enabled: false` | Dimmed; a press does nothing. |
|
|
67
|
-
| `style: 'prominent'` | (iOS) The main action, such as Done or Send.
|
|
68
|
-
| `group` | (iOS)
|
|
67
|
+
| `style: 'prominent'` | (iOS) The main action, such as Done or Send. With the glass design a filled capsule in the button's `color`; without it, a bold title. See [the glass design](./top-bar#glass-design). |
|
|
68
|
+
| `group` | (iOS) Glass design: buttons with the same group share one glass capsule; each other button has a capsule of its own. |
|
|
69
69
|
| `badge` | (iOS) 26: a number, a short text, or `true` for a dot. |
|
|
70
70
|
| `toggle`, `selected` | (iOS) A button that switches on and off at each tap; the press carries the new state as `selected`. |
|
|
71
71
|
|
|
@@ -148,7 +148,7 @@ useNavigationButton('sort-name', () => setSort('name'));
|
|
|
148
148
|
| Platform | The menu |
|
|
149
149
|
| --- | --- |
|
|
150
150
|
| (iOS) | The system menu, with SF Symbols, submenus and a check on the picked item. |
|
|
151
|
-
| (Android) | The Material popup menu under the button, with the same items, without the `title` of the menu. |
|
|
151
|
+
| (Android) | The Material popup menu under the button, with the same items, without the `title` of the menu. `topBar.menuBackgroundColor` and `topBar.menuTextColor` color it and "⋮"; without them it takes the bar's color and the title's color, in light and dark mode. |
|
|
152
152
|
|
|
153
153
|
## The overflow menu
|
|
154
154
|
|
|
@@ -248,7 +248,7 @@ s.rightButtons({
|
|
|
248
248
|
});
|
|
249
249
|
```
|
|
250
250
|
|
|
251
|
-
The bar sends no press for it: the component's own `onPress` is the press. On (iOS)
|
|
251
|
+
The bar sends no press for it: the component's own `onPress` is the press. On (iOS) with the glass design it has no glass capsule; `hideSharedBackground: false` puts it on one. On (Android) `component.width` and `height` size it.
|
|
252
252
|
|
|
253
253
|
## Buttons that change
|
|
254
254
|
|
|
@@ -273,7 +273,7 @@ function NewNote() {
|
|
|
273
273
|
|
|
274
274
|
The options are built on each render and applied before the screen paints when they changed, so the bar never lags behind the state. `onPress` sees the state of the same render. A full form in a modal, with Cancel and Save, is walked through in [Forms in a modal](../flows/forms-in-a-modal).
|
|
275
275
|
|
|
276
|
-
On (iOS) `animateRightButtons` and `animateLeftButtons` fade the new buttons in.
|
|
276
|
+
On (iOS) `animateRightButtons` and `animateLeftButtons` fade the new buttons in. With the glass design buttons that share a capsule (several with one `group`) change at once: UIKit has no animation for groups of buttons.
|
|
277
277
|
|
|
278
278
|
## Buttons on iPhone Duo
|
|
279
279
|
|
|
@@ -171,7 +171,7 @@ The component gets the search events itself, with `useSearchBar`, as a screen of
|
|
|
171
171
|
|
|
172
172
|
| Platform | The results screen |
|
|
173
173
|
| --- | --- |
|
|
174
|
-
| (iOS) | Covers the whole screen, under the search field and to the bottom edge, so its background fills it. It keeps its content clear of the bar itself: a list with `contentInsetAdjustmentBehavior="automatic"`, other content with `useSafeAreaInsets`. |
|
|
174
|
+
| (iOS) | Covers the whole screen, under the search field and to the bottom edge, so its background fills it. It keeps its content clear of the bar itself: a list with `contentInsetAdjustmentBehavior="automatic"`, other content with `useSafeAreaInsets`. The results screen has no padding of its own. |
|
|
175
175
|
| (Android) | The search opens over the whole screen, the field at the top and the component under it. |
|
|
176
176
|
|
|
177
177
|
## In the toolbar
|
|
@@ -29,12 +29,12 @@ The status bar sits at the top, with the camera cutout in it; the home indicator
|
|
|
29
29
|
|
|
30
30
|
## The safe area
|
|
31
31
|
|
|
32
|
-
The safe area is where nothing covers the content: not the bars of the navigation, not the status bar, not the cutout, not the home indicator. **The navigation keeps every screen in it by default**, so a screen doesn't need its own padding:
|
|
32
|
+
The safe area is where nothing covers the content: not the bars of the navigation, not the status bar, not the cutout, not the home indicator. **The navigation keeps every screen's top and sides in it by default**, so a screen doesn't need its own padding there. The bottom is not padded: the content goes down to the edge, under the home indicator, the navigation bar and a tab bar or toolbar, and a list adds `useSafeAreaInsets().bottom` to its own padding, as with `react-native-safe-area-context`.
|
|
33
33
|
|
|
34
34
|
| Platform | By default |
|
|
35
35
|
| --- | --- |
|
|
36
|
-
| (iOS) |
|
|
37
|
-
| (Android) |
|
|
36
|
+
| (iOS) | The top and the sides, but not the top under a top bar that shows: a list goes under the bar and keeps its rows clear itself, so the bar's glass shows the content scrolling under it. A screen with a large title leaves the top out too, and on iPhone Duo the side of the [vertical bar](#vertical-bar). The bottom goes under the home indicator and under a tab bar or toolbar. |
|
|
37
|
+
| (Android) | The top and the sides: under the status bar, out of the cutout. The top is free under a top bar that hides on scroll and under a large title. The bottom goes under the navigation bar, when the screen draws under it (not with an opaque bar), and under the tabs only with `bottomTabs.drawBehind` or `hideOnScroll`. |
|
|
38
38
|
|
|
39
39
|
> **Tip**
|
|
40
40
|
>
|
|
@@ -47,6 +47,12 @@ A screen that should go under the system, such as a photo or a map, says which e
|
|
|
47
47
|
```ts
|
|
48
48
|
s.safeArea('bottom'); // only the bottom: the photo goes under the top
|
|
49
49
|
s.safeArea(); // no edge: the content goes everywhere
|
|
50
|
+
s.safeArea('top', 'left', 'right', 'bottom'); // all four: a form above the home indicator
|
|
51
|
+
|
|
52
|
+
// listed edges replace the default: this one loses
|
|
53
|
+
// the sides; under a large title the top stays free,
|
|
54
|
+
// because the list keeps clear of the bar itself
|
|
55
|
+
s.safeArea('top', 'bottom');
|
|
50
56
|
```
|
|
51
57
|
|
|
52
58
|
The edges for every screen of the app go in `createNavigation`, and a screen's own `safeArea` wins over them:
|
|
@@ -54,11 +60,11 @@ The edges for every screen of the app go in `createNavigation`, and a screen's o
|
|
|
54
60
|
```ts
|
|
55
61
|
export const Navigation = createNavigation({
|
|
56
62
|
// …
|
|
57
|
-
safeArea: { edges: ['top', 'bottom'] },
|
|
63
|
+
safeArea: { edges: ['top', 'left', 'right', 'bottom'] },
|
|
58
64
|
});
|
|
59
65
|
```
|
|
60
66
|
|
|
61
|
-
Content that keeps clear of the system itself, such as a list that scrolls under the home indicator, reads what still covers it with `useSafeAreaInsets()`. The insets are **what is left after the screen's own padding**: 0 on an edge the screen keeps, all of what covers it on an edge its content goes under. So the content adds them to its own padding, and no edge is padded twice. Here the screen keeps the top
|
|
67
|
+
Content that keeps clear of the system itself, such as a list that scrolls under the home indicator, reads what still covers it with `useSafeAreaInsets()`. The insets are **what is left after the screen's own padding**: 0 on an edge the screen keeps, all of what covers it on an edge its content goes under. So the content adds them to its own padding, and no edge is padded twice. Here the screen keeps the top and the sides by default, and the list pads its own bottom:
|
|
62
68
|
|
|
63
69
|
```tsx
|
|
64
70
|
import { ScrollView } from 'react-native';
|
|
@@ -71,7 +77,7 @@ function Inbox() {
|
|
|
71
77
|
const insets = useSafeAreaInsets();
|
|
72
78
|
return (
|
|
73
79
|
<ScrollView
|
|
74
|
-
contentContainerStyle={{ paddingBottom: insets.bottom }}
|
|
80
|
+
contentContainerStyle={{ paddingBottom: 16 + insets.bottom }}
|
|
75
81
|
>
|
|
76
82
|
{/* the rows scroll under the home indicator,
|
|
77
83
|
and the last one ends above it */}
|
|
@@ -80,12 +86,11 @@ function Inbox() {
|
|
|
80
86
|
}
|
|
81
87
|
|
|
82
88
|
export const InboxScreen = defineScreen({
|
|
83
|
-
component: Inbox,
|
|
84
|
-
options: (s) => s.safeArea('top'),
|
|
89
|
+
component: Inbox, // the default edges: the top and the sides
|
|
85
90
|
});
|
|
86
91
|
```
|
|
87
92
|
|
|
88
|
-
On a screen that
|
|
93
|
+
On a screen that lists `'bottom'` in its edges, `insets.bottom` is 0, so the same code works there: the content is already above the home indicator. Below a top bar the top inset is 0; on a screen drawn behind the bars it is their height. On (iOS) a scroll view with `contentInsetAdjustmentBehavior="automatic"` keeps clear of the bars by itself: leave the inset out on those edges. More: [The insets and the safe area of the screen](/api/system-ui/useSafeAreaInsets#safe-area).
|
|
89
94
|
|
|
90
95
|
### The vertical bar of iPhone Duo
|
|
91
96
|
|
|
@@ -231,7 +236,7 @@ export const PhotoScreen = defineScreen({
|
|
|
231
236
|
| Platform | The bottom |
|
|
232
237
|
| --- | --- |
|
|
233
238
|
| (iOS) | The home indicator. `layout.autoHideHomeIndicator` fades it out while the screen isn't touched, as in a video. `layout.deferSystemGestures` makes the first swipe on those edges go to the app, for a game or a drawing; the second swipe goes home. |
|
|
234
|
-
| (Android) | The navigation bar: a handle, or three buttons. The screen goes under it, and
|
|
239
|
+
| (Android) | The navigation bar: a handle, or three buttons. The screen goes under it, and by default so does the content; a list adds `insets.bottom`. With an opaque bar or `drawBehind: false` the screen ends above it. `navigationBar` sets its `backgroundColor`, hides it with `visible: false`, or puts the screen above it with `drawBehind: false`. |
|
|
235
240
|
|
|
236
241
|
(Android) The screen goes edge to edge as the platform says: always on Android 16+ for apps targeting SDK 36, on Android 15 for SDK 35, and on every version with `edgeToEdgeEnabled=true` in `android/gradle.properties`, the default of new React Native apps.
|
|
237
242
|
|
|
@@ -274,7 +279,7 @@ export const Navigation = createNavigation({
|
|
|
274
279
|
s.scrollEdgeEffect({ top: { style: 'hard' } });
|
|
275
280
|
```
|
|
276
281
|
|
|
277
|
-
The effect
|
|
282
|
+
The effect applies to the vertical lists and text views of the screen when it shows, so a list that mounts after the screen shows gets it the next time the screen appears. A list nested very deep in the screen's views may not get it. A list inside another vertical list, like a horizontal carousel in a feed, gets none: UIKit draws no edge effect there. Render the list at once, and fill it when the data comes.
|
|
278
283
|
|
|
279
284
|
## Keyboard shortcuts
|
|
280
285
|
|
|
@@ -46,10 +46,10 @@ Filter sits at the leading edge and Compose at the trailing one. The buttons are
|
|
|
46
46
|
| Item | What it does |
|
|
47
47
|
| --- | --- |
|
|
48
48
|
| `{ systemItem: 'flexibleSpace' }` | Takes the free width, and pushes the next buttons to the far side. |
|
|
49
|
-
| `{ systemItem: 'fixedSpace' }` | A gap.
|
|
49
|
+
| `{ systemItem: 'fixedSpace' }` | A gap. With the glass design it also starts a new glass capsule. |
|
|
50
50
|
| `{ systemItem: 'searchField' }` | iOS 26: the search field of the screen, between the buttons. See [Search](./search#toolbar). |
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
With the glass design ([what it is](./top-bar#glass-design)) icons next to each other share one glass capsule; a text button has one of its own, and a `badge` doesn't show in the toolbar. `visible: false` hides the toolbar with its buttons.
|
|
53
53
|
|
|
54
54
|
On iPhone with iOS 26 the floating tab bar takes the same place at the bottom. A screen with a toolbar inside [tabs](../containers/tabs) hides the tab bar with `hideBottomTabs()`.
|
|
55
55
|
|
|
@@ -75,6 +75,8 @@ A round button with a pencil floats at the bottom right; a press opens Compose.
|
|
|
75
75
|
| `backgroundColor`, `iconColor` | Its colors. Without them, the colors of the app's Material 3 theme. |
|
|
76
76
|
| `visible: false` | Hides it. |
|
|
77
77
|
|
|
78
|
+
The FAB belongs to its screen. A push brings the new screen's FAB in with it and takes the old one out with the screen it covers; a pop does the same the other way, and the back gesture shows the FAB of the screen under the top with that screen. Two screens with the same `id` share one button: it stays in place while the screens move.
|
|
79
|
+
|
|
78
80
|
### Actions
|
|
79
81
|
|
|
80
82
|
A FAB with `actions` opens them above it on a press, each a small FAB with its own press:
|
|
@@ -31,6 +31,10 @@ The top bar belongs to **the stack, not to a screen**: one bar for all the scree
|
|
|
31
31
|
|
|
32
32
|
The platform draws the bar: `UINavigationBar` on (iOS), with Liquid Glass on iOS 26, and the Material 3 top app bar on (Android). Its colors come from the [theme](../architecture/theme-and-context) until a screen sets its own.
|
|
33
33
|
|
|
34
|
+
## The glass design and the compatibility mode
|
|
35
|
+
|
|
36
|
+
On (iOS) the look of iOS 26 (Liquid Glass) is *the glass design*, and this page and [the bar buttons](./bar-buttons) call it that. An app in the compatibility mode (`UIDesignRequiresCompatibility = YES` in Info.plist) doesn't get it: the mode applies on iOS 26, and on iOS 27 only to an app built with an SDK before iOS 27. There the bar looks and behaves as before iOS 26: a title with a subtitle as two lines only when no large title can show (with a large title the subtitle shows nowhere), no capsules (`title.glass`, `hideSharedBackground` and `group` do nothing), `style: 'prominent'` is a bold Done button, the back button shows the title of the screen below, `background.color` gives an opaque bar, and a large title is drawn in the bar. [The bottom tabs](../containers/tabs) follow the same mode.
|
|
37
|
+
|
|
34
38
|
## The title
|
|
35
39
|
|
|
36
40
|
The title is the name of the screen. The subtitle is a second line under it, such as a status or a count. Both can come from the props of the screen:
|
|
@@ -84,20 +88,20 @@ s.title('Details').largeTitle({ displayMode: 'never' });
|
|
|
84
88
|
|
|
85
89
|
## The background and the border
|
|
86
90
|
|
|
87
|
-
|
|
91
|
+
With the glass design the bar is Liquid Glass, and the content shows through it as it scrolls under. **A color takes the glass away**, so set one only when the design needs it:
|
|
88
92
|
|
|
89
93
|
```ts
|
|
90
94
|
s.topBar({ background: { color: '#F3E9D2' }, noBorder: true });
|
|
91
95
|
```
|
|
92
96
|
|
|
93
|
-
`background.color` colors the bar on both platforms. With a large title
|
|
97
|
+
`background.color` colors the bar on both platforms. With a large title and the glass design the color goes behind the title in the list, and fills the bar once the title collapses. Under a bar with a color the list has no edge effect at the top: see [The edge of the scroll](./system-ui#scroll-edge).
|
|
94
98
|
|
|
95
99
|
The other keys of the background are rarer:
|
|
96
100
|
|
|
97
101
|
| Option | What it does |
|
|
98
102
|
| --- | --- |
|
|
99
103
|
| `background.component` | A component of `screens` drawn behind the bar, such as a gradient. It is registered as the [title component](#title-component) is. |
|
|
100
|
-
| `background.translucent` | (iOS) `true`: the content shows through; Liquid Glass
|
|
104
|
+
| `background.translucent` | (iOS) `true`: the content shows through; Liquid Glass with the glass design, where it is the default. `false`: a solid bar, white in the light theme and black in the dark one. |
|
|
101
105
|
| `background.blur` | (iOS) The system's frosted blur, plainer than the glass. A `color` wins over it, and it wins over `translucent`. |
|
|
102
106
|
| `scrollEdgeAppearance` | (iOS) The look of the bar while the content is at its top, with `active: true`. The bar takes its usual look once the content scrolls under it. |
|
|
103
107
|
|
|
@@ -132,7 +136,7 @@ The bar can also hide and show by itself:
|
|
|
132
136
|
| `hideOnKeyboard` | (iOS) Hides while the keyboard shows. |
|
|
133
137
|
| `animate` | `false`: hides and shows at once, without the animation. |
|
|
134
138
|
|
|
135
|
-
With `hideOnScroll` the screen goes under the bar, so its rows show where the bar was. Its list keeps its first rows clear: on (iOS) with `contentInsetAdjustmentBehavior="automatic"`, on (Android) with `paddingTop: useSafeAreaInsets().top`.
|
|
139
|
+
With `hideOnScroll` the screen goes under the bar, so its rows show where the bar was. Its list keeps its first rows clear: on (iOS) with `contentInsetAdjustmentBehavior="automatic"`, on (Android) with `paddingTop: useSafeAreaInsets().top`. The bottom edge is not padded by default, so the list also adds `useSafeAreaInsets().bottom` to its bottom padding (an iOS list with `contentInsetAdjustmentBehavior="automatic"` does it itself).
|
|
136
140
|
|
|
137
141
|
`drawBehind: true` keeps the bar and puts the content under it, as a map or a photo under a glass bar.
|
|
138
142
|
|
|
@@ -129,7 +129,7 @@ In an app as the React Native template makes it, the window shows **one React vi
|
|
|
129
129
|
| `MainApplication.kt` | Extends `NavigationApplication`; keeps the template's `loadReactNative(this)` in `onCreate`, or adds it. | It keeps one React host for all screens, made after `loadReactNative(this)` loaded React Native. Native screens made by `codegen` are registered there, before JS opens them. |
|
|
130
130
|
| `MainActivity.kt` | Extends `NavigationActivity`. | The activity holds the containers of the navigation instead of one React view. It gets the back press, edge-to-edge and configuration changes first. |
|
|
131
131
|
| `AndroidManifest.xml` | Adds `android:enableOnBackInvokedCallback="true"` to `<application>`. | On the first screen the system plays its own animation back to the home screen as the user swipes back (predictive back). Android 16 turns it on for apps that target API 36; an app that targets less opts in here. A value the app set itself stays. See [Back to the home screen](../screen-ui/back-and-gestures#system-animation). |
|
|
132
|
-
| `styles.xml` | `AppTheme` inherits `Theme.ApexNavigation`. | The bars, tabs and search are Material 3 views and take their colors from the app's theme. This one is Material 3 in neutral grays, light and dark; change any color in the same file. A theme of the app's own stays as it is. See [Android's
|
|
132
|
+
| `styles.xml` | `AppTheme` inherits `Theme.ApexNavigation`. | The bars, tabs and search are Material 3 views and take their colors from the app's theme. This one is Material 3 in neutral grays, light and dark; change any color in the same file. A theme of the app's own stays as it is. See [Android's theme](../architecture/theme-and-context#android). |
|
|
133
133
|
|
|
134
134
|
The main activity keeps the template's `android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"`. Without `orientation`, `screenSize`, `smallestScreenSize`, `screenLayout` or `uiMode` Android recreates the activity on a rotation, a resize, a fold or a light/dark switch, and every screen goes with it; `doctor` warns about it under Config changes.
|
|
135
135
|
|
|
@@ -150,8 +150,23 @@ These files are the same on both platforms.
|
|
|
150
150
|
| `index.js` | Starts the app through the navigation. | `AppRegistry` of the package starts `createNavigation` instead of mounting one root component. |
|
|
151
151
|
| `Navigation.ts` | New: shows `App` as the first screen. | The app keeps working as it was, now as the first screen of a stack. |
|
|
152
152
|
| `App.tsx` | Takes out the template's ``. | React Native's `StatusBar` logs an error on iOS once the screens set the status bar. |
|
|
153
|
+
| `metro.config.js` | Wraps the exported config in `withApexNavigation`. | Fast Refresh: an edit of a screen updates the running app in place, with its state, instead of reloading it. See [Fast Refresh](#fast-refresh). |
|
|
153
154
|
| `navigation-env.d.ts` | New: ties the commands to the screens of `Navigation.ts`. | The commands come from the package and can't see the app's screens. This declaration links them, so names and props are checked. See [Typed commands](#typed-commands). |
|
|
154
155
|
|
|
156
|
+
### Fast Refresh
|
|
157
|
+
|
|
158
|
+
`setup` wraps your `metro.config.js` in `withApexNavigation`; in a new app `init` has done it. By hand:
|
|
159
|
+
|
|
160
|
+
```js
|
|
161
|
+
const { withApexNavigation } = require('@apexnative/navigation/metro');
|
|
162
|
+
|
|
163
|
+
module.exports = withApexNavigation(mergeConfig(getDefaultConfig(__dirname), config));
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
It does two things. React Native 0.87's transformer doesn't apply React Refresh's Babel plugin (Metro no longer passes it `hot`), and without the plugin a component that its module doesn't export loses its state at every edit. And it makes the module that imports `createNavigation` accept hot updates, so an edit of the `screens` map or of the app's config updates the running app without a reload: the screens, the default options (when `theme` or `options` changed), the roots, the listeners and the link routes. What only the start reads isn't run again: the first root, `willMount`, the splash and the context. The app's module itself runs again, as a component's module does in Fast Refresh: code at its top level (an SDK's `init`, a listener added there) runs again too, so keep such code in a module of its own that doesn't change, or make it safe to run twice. The same holds for a module the app's module imports that isn't a component, such as a store: its edit runs it and the app's module again instead of reloading the app, so a store made at the top of that module is made anew while the screens that didn't run again keep the old one. Reload the app (R) after such an edit.
|
|
167
|
+
|
|
168
|
+
`doctor` warns under Fast Refresh when the Metro config doesn't use it. What to write in a screen file so that its edits update in place: [Fast Refresh](../fundamentals/screens-and-props#fast-refresh).
|
|
169
|
+
|
|
155
170
|
### Typed commands
|
|
156
171
|
|
|
157
172
|
`navigation.push('Details', { props })` comes from the package, and the package doesn't know the screens of your app. One declaration links them: `setup` and `init` write it in `navigation-env.d.ts` at the root of the app.
|
|
@@ -1,27 +1,47 @@
|
|
|
1
|
+
#import <QuartzCore/QuartzCore.h>
|
|
1
2
|
#import <UIKit/UIKit.h>
|
|
2
3
|
|
|
3
4
|
NS_ASSUME_NONNULL_BEGIN
|
|
4
5
|
|
|
5
|
-
/// What a frame driver moves: a view's properties (`ANNViewTracks`), an element, a shared element's copy.
|
|
6
|
-
///
|
|
6
|
+
/// What a frame driver moves: a view's properties (`ANNViewTracks`), an element, a shared element's copy. It gives its
|
|
7
|
+
/// values for the whole transition at once, as Core Animation's animations on its layers (`ANNKeyframes`); past its end
|
|
8
|
+
/// they hold its end values.
|
|
7
9
|
@protocol ANNFrameClient <NSObject>
|
|
8
10
|
|
|
9
|
-
/// The
|
|
10
|
-
|
|
11
|
+
/// The client's animations for a transition of `length` seconds go onto its layers, all inside the driver's
|
|
12
|
+
/// transaction, so they start together.
|
|
13
|
+
- (void)addAnimationsWithLength:(NSTimeInterval)length;
|
|
11
14
|
|
|
12
15
|
/// The time from which the client holds its end values.
|
|
13
16
|
@property(nonatomic, readonly) NSTimeInterval endTime;
|
|
14
17
|
|
|
15
|
-
///
|
|
16
|
-
/// views of its own removes them. Once; later calls do nothing.
|
|
18
|
+
/// The client's animations go, every value it wrote goes back as it was read before the transition (also at a
|
|
19
|
+
/// cancel), and a client that made views of its own removes them. Once; later calls do nothing.
|
|
17
20
|
- (void)restore;
|
|
18
21
|
|
|
19
22
|
@end
|
|
20
23
|
|
|
21
|
-
/// The
|
|
22
|
-
/// a
|
|
23
|
-
///
|
|
24
|
-
///
|
|
24
|
+
/// The times a client samples its values at, in seconds from the start: 0, every 1/120 s up to `end` (wider apart for
|
|
25
|
+
/// a transition over 20 s, 2400 samples at most), each of `marks` within it (a track's start and end, a swap's), `end`
|
|
26
|
+
/// and `length`; ascending, without repeats. The values between two samples are linear, so a kink of a track falls on
|
|
27
|
+
/// a sample.
|
|
28
|
+
FOUNDATION_EXPORT NSArray<NSNumber *> *ANNSampleTimes(NSTimeInterval end, NSTimeInterval length,
|
|
29
|
+
NSArray<NSNumber *> *marks);
|
|
30
|
+
|
|
31
|
+
/// The animation of `keyPath` through `values` at `times` (from `ANNSampleTimes`) over `length` seconds: linear
|
|
32
|
+
/// between them, holding the first value before and the last after (until it is removed). Nil for no length, and for
|
|
33
|
+
/// values and times that don't pair up.
|
|
34
|
+
FOUNDATION_EXPORT CAKeyframeAnimation *_Nullable ANNKeyframes(NSString *keyPath, NSArray *values,
|
|
35
|
+
NSArray<NSNumber *> *times,
|
|
36
|
+
NSTimeInterval length);
|
|
37
|
+
|
|
38
|
+
/// The key of the core's animation of `keyPath` on a layer, for its `restore`.
|
|
39
|
+
FOUNDATION_EXPORT NSString *ANNAnimationKey(NSString *keyPath);
|
|
40
|
+
|
|
41
|
+
/// The frames of one running transition, in Core Animation: every client adds its animations in one transaction, which
|
|
42
|
+
/// starts them together at its commit; the render server plays them, so a busy main queue no longer stops the
|
|
43
|
+
/// transition. Once every animation ended (or was removed) and `length` passed, `done` runs once on the main queue.
|
|
44
|
+
/// Main queue.
|
|
25
45
|
@interface ANNFrameDriver : NSObject
|
|
26
46
|
|
|
27
47
|
- (instancetype)initWithClients:(NSArray<id<ANNFrameClient>> *)clients
|
|
@@ -30,17 +50,37 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
30
50
|
- (instancetype)init NS_UNAVAILABLE;
|
|
31
51
|
+ (instancetype)new NS_UNAVAILABLE;
|
|
32
52
|
|
|
33
|
-
/// The clients
|
|
34
|
-
///
|
|
53
|
+
/// The clients add their animations, which start at the commit of the current transaction (the first frame shows the
|
|
54
|
+
/// start values). `done` comes later, never inside this call.
|
|
35
55
|
- (void)startWithDone:(dispatch_block_t)done;
|
|
36
56
|
|
|
37
|
-
/// The
|
|
38
|
-
///
|
|
57
|
+
/// The start of a transition that follows a gesture: the clients add their animations as `startWithDone:` does, under
|
|
58
|
+
/// the time of `clock` (the transition's container), which stops. `setProgress:` shows them at a part of the length;
|
|
59
|
+
/// `finishWithSpeed:` plays the rest and `rewindWithSpeed:` plays them back to the start, both in Core Animation. The
|
|
60
|
+
/// other animations under `clock` stop with it. Before `done`, which comes once after either of them (never inside a
|
|
61
|
+
/// call) with whether the transition finished, `clock` gets its time back; the caller restores the clients inside
|
|
62
|
+
/// `done` (one commit with it), or they would show at the clock's time for a frame.
|
|
63
|
+
- (void)startPausedOn:(CALayer *)clock done:(void (^)(BOOL finished))done;
|
|
64
|
+
|
|
65
|
+
/// The animations show at `progress` (0 to 1) of the length. Nothing once the end plays.
|
|
66
|
+
- (void)setProgress:(CGFloat)progress;
|
|
67
|
+
|
|
68
|
+
/// The rest of the animations plays from where they show, `speed` times as fast as they would (1 or more).
|
|
69
|
+
- (void)finishWithSpeed:(CGFloat)speed;
|
|
70
|
+
|
|
71
|
+
/// The animations play back to their start, `speed` times as fast as they would (1 or more).
|
|
72
|
+
- (void)rewindWithSpeed:(CGFloat)speed;
|
|
73
|
+
|
|
74
|
+
/// The transition stops (a destroy, a reload, a newer `setRoot`): `done` never runs, and a stopped `clock` gets its
|
|
75
|
+
/// time back. The caller restores the clients, which removes their animations, in the same commit.
|
|
39
76
|
- (void)cancel;
|
|
40
77
|
|
|
41
|
-
/// The
|
|
78
|
+
/// The animations run.
|
|
42
79
|
@property(nonatomic, readonly) BOOL isRunning;
|
|
43
80
|
|
|
81
|
+
/// The seconds from the start to the end of the last client, the transition's own length at least.
|
|
82
|
+
@property(nonatomic, readonly) NSTimeInterval length;
|
|
83
|
+
|
|
44
84
|
@end
|
|
45
85
|
|
|
46
86
|
NS_ASSUME_NONNULL_END
|