@apexnative/navigation 1.0.0-alpha.5 → 1.0.0-alpha.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ApexNavigation.podspec +2 -1
- package/CHANGELOG.md +32 -0
- package/README.md +1 -1
- package/android/CLAUDE.md +31 -20
- package/android/CORE.md +12 -8
- package/android/consumer-rules.pro +6 -0
- package/android/src/main/java/dev/apexnative/navigation/NavigationActivity.kt +36 -5
- package/android/src/main/java/dev/apexnative/navigation/options/BottomTabOptions.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/BottomTabsOptions.kt +13 -8
- package/android/src/main/java/dev/apexnative/navigation/options/ButtonOptions.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/LargeTitleOptions.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/LayoutAnimation.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/OptionKey.kt +18 -0
- package/android/src/main/java/dev/apexnative/navigation/options/OptionPaths.kt +91 -0
- package/android/src/main/java/dev/apexnative/navigation/options/SheetOptions.kt +7 -4
- package/android/src/main/java/dev/apexnative/navigation/options/TitleOptions.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/options/TopBarAppearanceOptions.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/TopBarOptions.kt +16 -7
- package/android/src/main/java/dev/apexnative/navigation/react/ContentHeights.kt +95 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ContentMounts.kt +66 -0
- package/android/src/main/java/dev/apexnative/navigation/react/NavigationTurboModule.kt +7 -3
- package/android/src/main/java/dev/apexnative/navigation/react/OptionsCommands.kt +41 -3
- package/android/src/main/java/dev/apexnative/navigation/react/ReactView.kt +16 -1
- package/android/src/main/java/dev/apexnative/navigation/react/ReloadCoordinator.kt +0 -2
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenEnvironment.kt +177 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenRegions.kt +12 -49
- package/android/src/main/java/dev/apexnative/navigation/react/ScrollEvents.kt +49 -128
- package/android/src/main/java/dev/apexnative/navigation/safearea/SafeAreaView.kt +6 -6
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotScreenView.kt +27 -7
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotView.kt +12 -1
- package/android/src/main/java/dev/apexnative/navigation/utils/MaterialTheme.kt +5 -6
- package/android/src/main/java/dev/apexnative/navigation/utils/SystemAnimations.kt +36 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/ViewExtensions.kt +0 -13
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/ArrangementController.kt +9 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsCollapseBehavior.kt +5 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsController.kt +13 -10
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowGeometry.kt +22 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabsRoom.kt +0 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentViewController.kt +7 -8
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenSafeArea.kt +29 -11
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/externalcomponent/ExternalComponentViewController.kt +2 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalCoordinator.kt +20 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalSheet.kt +443 -58
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalViews.kt +33 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetBack.kt +42 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetStops.kt +60 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/Navigator.kt +4 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ParentController.kt +3 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuMotion.kt +8 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/BackPreview.kt +32 -4
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/PreparedFrame.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackCommands.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackController.kt +50 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackQueue.kt +15 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackViews.kt +10 -4
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabMotion.kt +142 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabPresenter.kt +215 -43
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/StackSearchPresenter.kt +25 -26
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/BarRowTransition.kt +3 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/ButtonPlaces.kt +11 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarPresenter.kt +36 -38
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ScrollEventListener.kt +6 -9
- package/android/src/main/java/dev/apexnative/navigation/views/animations/AnimationLayer.kt +73 -0
- package/android/src/main/java/dev/apexnative/navigation/views/animations/ValueInterpolation.kt +14 -0
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabsLayout.kt +61 -2
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomTabRow.kt +72 -10
- package/android/src/main/java/dev/apexnative/navigation/views/element/ElementTransitions.kt +129 -179
- package/android/src/main/java/dev/apexnative/navigation/views/element/TargetsWait.kt +8 -1
- package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionLayer.kt +37 -112
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ElementPictures.kt +67 -3
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/FlightGeometry.kt +346 -36
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMorph.kt +199 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/SharedAnimatorFactory.kt +55 -42
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextMorph.kt +176 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewMorph.kt +108 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabCopy.kt +85 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabMenu.kt +13 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TitleBar.kt +5 -24
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TopBar.kt +51 -34
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonComponentCell.kt +6 -6
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonView.kt +113 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarMenu.kt +219 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonBar.kt +121 -175
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonMenus.kt +34 -64
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonRow.kt +216 -0
- package/android/src/main/jni/ANNContentHeights.cpp +82 -0
- package/android/src/main/res/drawable/apex_navigation_ic_arrow_right.xml +14 -0
- package/android/src/main/res/layout/apex_navigation_menu_header.xml +19 -0
- package/android/src/main/res/layout/apex_navigation_menu_item.xml +68 -0
- package/android/src/main/res/values/styles.xml +1 -1
- package/android/src/main/res/values-night/styles.xml +1 -1
- package/cli/doctor/checks/app.js +16 -1
- package/cli/project.js +4 -0
- package/cli/setup/index.js +5 -0
- package/cli/setup/steps/metro.js +46 -0
- package/docs-md/architecture/native-screens.md +4 -0
- package/docs-md/architecture/theme-and-context.md +131 -12
- package/docs-md/architecture/transitions.md +46 -5
- package/docs-md/containers/modals.md +2 -0
- package/docs-md/containers/overlays.md +1 -1
- package/docs-md/containers/side-menu.md +1 -1
- package/docs-md/containers/tabs.md +2 -0
- package/docs-md/flows/bottom-sheets.md +4 -2
- package/docs-md/fundamentals/screens-and-props.md +9 -1
- package/docs-md/fundamentals/starting-the-app.md +1 -1
- package/docs-md/guides/cli.md +3 -1
- package/docs-md/help/glossary.md +2 -2
- package/docs-md/help/troubleshooting.md +22 -1
- package/docs-md/index.json +41 -1
- package/docs-md/migration/from-expo-router.md +1 -1
- package/docs-md/migration/from-react-native-navigation.md +1 -1
- package/docs-md/migration/from-react-navigation.md +2 -2
- package/docs-md/screen-ui/back-and-gestures.md +17 -1
- package/docs-md/screen-ui/bar-buttons.md +5 -5
- package/docs-md/screen-ui/search.md +1 -1
- package/docs-md/screen-ui/system-ui.md +16 -11
- package/docs-md/screen-ui/toolbar-and-fab.md +4 -2
- package/docs-md/screen-ui/top-bar.md +8 -4
- package/docs-md/start/installation.md +16 -1
- package/ios/Animations/ANNFrameDriver.h +55 -15
- package/ios/Animations/ANNFrameDriver.mm +216 -60
- package/ios/Animations/ANNTransitionAnimator.h +26 -5
- package/ios/Animations/ANNTransitionAnimator.mm +49 -3
- package/ios/Animations/ANNTransitionPlan.h +2 -2
- package/ios/Animations/ANNTransitionPlan.mm +10 -0
- package/ios/Animations/Elements/ANNElementFinder.h +2 -2
- package/ios/Animations/Elements/ANNElementFinder.mm +2 -2
- package/ios/Animations/Elements/ANNElementTransition.h +3 -3
- package/ios/Animations/Elements/ANNElementTransition.mm +2 -2
- package/ios/Animations/Elements/ANNSharedElementFlight.h +3 -3
- package/ios/Animations/Elements/ANNSharedElementFlight.mm +249 -45
- package/ios/Animations/Interpolators/ANNInterpolate.h +2 -30
- package/ios/Animations/Interpolators/ANNTransformParts.h +48 -0
- package/ios/Animations/Interpolators/ANNTransformParts.mm +507 -0
- package/ios/Animations/Interpolators/ANNViewTracks.h +9 -6
- package/ios/Animations/Interpolators/ANNViewTracks.mm +100 -30
- package/ios/CLAUDE.md +32 -22
- package/ios/CORE.md +25 -21
- package/ios/Contract/ANNCommandRunner.h +8 -7
- package/ios/Contract/ANNCommandRunner.mm +21 -27
- package/ios/Contract/ANNLayoutNode.h +3 -3
- package/ios/Contract/ANNLayoutReader.h +3 -3
- package/ios/Core/ANNAppDelegate.mm +0 -2
- package/ios/Core/ANNDeepLinkQueue.h +6 -5
- package/ios/Core/ANNDeepLinkQueue.mm +22 -10
- package/ios/Core/ANNJavaScriptCalls.h +11 -12
- package/ios/Core/ANNJavaScriptCalls.mm +7 -16
- package/ios/Core/ANNReloadCoordinator.mm +4 -8
- package/ios/Core/ANNSceneDelegate.mm +2 -2
- package/ios/Core/ApexNavigation+Internal.h +1 -1
- package/ios/Core/ApexNavigation.mm +6 -2
- package/ios/Layouts/Arrangement/ANNArrangementState.h +2 -17
- package/ios/Layouts/Arrangement/ANNArrangementState.mm +0 -38
- package/ios/Layouts/Arrangement/ANNArrangementViewController.mm +4 -4
- package/ios/Layouts/Root/ANNRootCoordinator.mm +45 -15
- package/ios/Layouts/Screen/ANNComponentViewController.h +2 -2
- package/ios/Layouts/Screen/ANNComponentViewController.mm +13 -23
- package/ios/Layouts/Screen/ANNPreviewInteraction.h +7 -4
- package/ios/Layouts/Screen/ANNPreviewInteraction.mm +72 -10
- package/ios/Layouts/Screen/ANNScreenEnvironment.h +63 -0
- package/ios/Layouts/Screen/ANNScreenEnvironment.mm +181 -0
- package/ios/Layouts/Screen/ANNScreenRegions.h +3 -18
- package/ios/Layouts/Screen/ANNScreenRegions.mm +0 -38
- package/ios/Layouts/Screen/ANNScreenSafeArea.h +4 -9
- package/ios/Layouts/Screen/ANNScreenSafeArea.mm +14 -16
- package/ios/Layouts/Stack/ANNPreviewPush.h +7 -6
- package/ios/Layouts/Stack/ANNPreviewPush.mm +57 -5
- package/ios/Layouts/Stack/ANNStackAnimatingDelegate.h +11 -2
- package/ios/Layouts/Stack/ANNStackAnimatingDelegate.mm +14 -7
- package/ios/Layouts/Stack/ANNStackController.h +8 -0
- package/ios/Layouts/Stack/ANNStackController.mm +153 -11
- package/ios/Layouts/Stack/ANNSwipePopInteraction.h +26 -0
- package/ios/Layouts/Stack/ANNSwipePopInteraction.mm +185 -0
- package/ios/Layouts/Stack/InteractivePopGestureDelegate.mm +28 -4
- package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.h +12 -1
- package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.mm +23 -0
- package/ios/Layouts/Tabs/ANNBottomTabsController.mm +2 -1
- package/ios/Layouts/Tabs/ANNBottomTabsCustomRow.mm +8 -3
- package/ios/Layouts/Tabs/ANNBottomTabsPresenter.h +4 -0
- package/ios/Layouts/Tabs/ANNBottomTabsPresenter.mm +123 -36
- package/ios/Layouts/Tabs/ANNTabsDesign.h +6 -5
- package/ios/Layouts/Tabs/ANNTabsDesign.mm +9 -1
- package/ios/Layouts/Tabs/UITabBar+utils.h +5 -5
- package/ios/Layouts/Tabs/UITabBar+utils.mm +32 -13
- package/ios/Options/ANNAnimationOptions.h +2 -1
- package/ios/Options/ANNAnimationOptions.mm +1 -1
- package/ios/Options/ANNBottomTabsOptions.h +2 -0
- package/ios/Options/ANNBottomTabsOptions.mm +1 -0
- package/ios/Options/ANNOptions.h +25 -0
- package/ios/Options/ANNOptions.mm +157 -1
- package/ios/Options/ANNOptionsReader.mm +108 -0
- package/ios/Options/ANNStackPopAnimationOptions.h +13 -0
- package/ios/Options/ANNStackPopAnimationOptions.mm +11 -0
- package/ios/Options/Params/ANNParam.h +15 -0
- package/ios/Options/Params/ANNParam.mm +61 -0
- package/ios/Options/Params/Color.h +3 -0
- package/ios/Options/Params/Color.mm +21 -0
- package/ios/Options/Params/ColorParser.h +4 -3
- package/ios/Options/Params/ColorParser.mm +22 -4
- package/ios/Options/Params/Image.h +4 -0
- package/ios/Options/Params/Image.mm +20 -0
- package/ios/React/ANNReactView.mm +6 -25
- package/ios/React/ANNSafeAreaViewComponentView.mm +26 -15
- package/ios/React/ANNSurfaceHostingView.h +14 -0
- package/ios/React/ANNSurfaceHostingView.mm +144 -1
- package/ios/React/Slots/ANNSlotScreenView.mm +8 -2
- package/ios/TopBar/ANNBackButtonPresenter.mm +6 -5
- package/ios/TopBar/ANNBarAppearance.h +2 -1
- package/ios/TopBar/ANNBarAppearance.mm +111 -30
- package/ios/TopBar/ANNBarBackgroundComponent.mm +16 -0
- package/ios/TopBar/ANNBarButtonComponentView.h +4 -4
- package/ios/TopBar/ANNBarButtonComponentView.mm +1 -1
- package/ios/TopBar/ANNBarButtons.h +5 -3
- package/ios/TopBar/ANNBarButtons.mm +186 -17
- package/ios/TopBar/ANNLargeTitlePresenter.mm +24 -4
- package/ios/TopBar/ANNMainList.h +3 -0
- package/ios/TopBar/ANNMainList.mm +4 -0
- package/ios/TopBar/ANNScrollEdgeEffects.h +22 -6
- package/ios/TopBar/ANNScrollEdgeEffects.mm +123 -16
- package/ios/TopBar/ANNSearchPresenter.mm +2 -2
- package/ios/TopBar/ANNSearchResultsViewController.mm +5 -5
- package/ios/TopBar/ANNTopBarPresenter.h +3 -2
- package/ios/TopBar/ANNTopBarPresenter.mm +95 -22
- package/ios/TurboModules/ANNTurboModule.mm +66 -16
- package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.cpp +20 -0
- package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.h +5 -14
- package/lib/module/ARCHITECTURE.md +17 -7
- package/lib/module/adapters/NativeANNTurboModule.js.map +1 -1
- package/lib/module/api/app/AppRegistry.js +14 -2
- package/lib/module/api/app/AppRegistry.js.map +1 -1
- package/lib/module/api/app/createNavigation.js +188 -66
- package/lib/module/api/app/createNavigation.js.map +1 -1
- package/lib/module/api/events/navigationEvents.js +6 -2
- package/lib/module/api/events/navigationEvents.js.map +1 -1
- package/lib/module/api/hooks/useSafeAreaInsets.js +4 -3
- package/lib/module/api/hooks/useSafeAreaInsets.js.map +1 -1
- package/lib/module/api/linking/linking.js +11 -0
- package/lib/module/api/linking/linking.js.map +1 -1
- package/lib/module/api/options/OptionsChain.js +2 -2
- package/lib/module/api/screens/defineScreen.js +45 -3
- package/lib/module/api/screens/defineScreen.js.map +1 -1
- package/lib/module/api/screens/nativeScreens.js +31 -6
- package/lib/module/api/screens/nativeScreens.js.map +1 -1
- package/lib/module/api/screens/registerScreens.js +172 -35
- package/lib/module/api/screens/registerScreens.js.map +1 -1
- package/lib/module/api/theme/theme.js +5 -0
- package/lib/module/api/theme/theme.js.map +1 -1
- package/lib/module/engine/commands.js +42 -2
- package/lib/module/engine/commands.js.map +1 -1
- package/lib/module/engine/layout.js +7 -2
- package/lib/module/engine/layout.js.map +1 -1
- package/lib/module/engine/nativeScreens.js +9 -0
- package/lib/module/engine/nativeScreens.js.map +1 -1
- package/lib/module/engine/options.js +5 -4
- package/lib/module/engine/options.js.map +1 -1
- package/lib/module/engine/optionsChange.js +102 -0
- package/lib/module/engine/optionsChange.js.map +1 -0
- package/lib/module/engine/refresh.js +85 -0
- package/lib/module/engine/refresh.js.map +1 -0
- package/lib/module/engine/rememberedOptions.js +60 -0
- package/lib/module/engine/rememberedOptions.js.map +1 -1
- package/lib/module/engine/screens.js +55 -4
- package/lib/module/engine/screens.js.map +1 -1
- package/lib/typescript/adapters/NativeANNTurboModule.d.ts +7 -0
- package/lib/typescript/adapters/NativeANNTurboModule.d.ts.map +1 -1
- package/lib/typescript/api/app/AppRegistry.d.ts.map +1 -1
- package/lib/typescript/api/app/createNavigation.d.ts +8 -3
- package/lib/typescript/api/app/createNavigation.d.ts.map +1 -1
- package/lib/typescript/api/events/navigationEvents.d.ts +2 -2
- package/lib/typescript/api/events/navigationEvents.d.ts.map +1 -1
- package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts +4 -3
- package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts.map +1 -1
- package/lib/typescript/api/index.d.ts +1 -1
- package/lib/typescript/api/index.d.ts.map +1 -1
- package/lib/typescript/api/linking/linking.d.ts +8 -0
- package/lib/typescript/api/linking/linking.d.ts.map +1 -1
- package/lib/typescript/api/options/OptionsChain.d.ts +2 -2
- package/lib/typescript/api/screens/defineScreen.d.ts +23 -4
- package/lib/typescript/api/screens/defineScreen.d.ts.map +1 -1
- package/lib/typescript/api/screens/nativeScreens.d.ts +8 -1
- package/lib/typescript/api/screens/nativeScreens.d.ts.map +1 -1
- package/lib/typescript/api/screens/registerScreens.d.ts.map +1 -1
- package/lib/typescript/api/theme/theme.d.ts +2 -0
- package/lib/typescript/api/theme/theme.d.ts.map +1 -1
- package/lib/typescript/engine/commands.d.ts +5 -0
- package/lib/typescript/engine/commands.d.ts.map +1 -1
- package/lib/typescript/engine/layout.d.ts.map +1 -1
- package/lib/typescript/engine/nativeScreens.d.ts +5 -0
- package/lib/typescript/engine/nativeScreens.d.ts.map +1 -1
- package/lib/typescript/engine/optionsChange.d.ts +28 -0
- package/lib/typescript/engine/optionsChange.d.ts.map +1 -0
- package/lib/typescript/engine/refresh.d.ts +35 -0
- package/lib/typescript/engine/refresh.d.ts.map +1 -0
- package/lib/typescript/engine/rememberedOptions.d.ts +13 -0
- package/lib/typescript/engine/rememberedOptions.d.ts.map +1 -1
- package/lib/typescript/engine/screens.d.ts +27 -6
- package/lib/typescript/engine/screens.d.ts.map +1 -1
- package/lib/typescript/interfaces/ComponentEvents.d.ts +2 -2
- package/lib/typescript/interfaces/options/animations.d.ts +44 -14
- package/lib/typescript/interfaces/options/animations.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/bottomTabs.d.ts +19 -6
- package/lib/typescript/interfaces/options/bottomTabs.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/buttons.d.ts +10 -10
- package/lib/typescript/interfaces/options/modals.d.ts +6 -7
- package/lib/typescript/interfaces/options/modals.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/stack.d.ts +8 -3
- package/lib/typescript/interfaces/options/stack.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/system.d.ts +8 -5
- package/lib/typescript/interfaces/options/system.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/toolbar.d.ts +2 -2
- package/lib/typescript/interfaces/options/topBar.d.ts +46 -29
- package/lib/typescript/interfaces/options/topBar.d.ts.map +1 -1
- package/metro/acceptPlugin.js +57 -0
- package/metro/babelTransformer.js +45 -0
- package/metro/index.js +36 -0
- package/package.json +3 -1
- package/src/ARCHITECTURE.md +17 -7
- package/src/adapters/NativeANNTurboModule.ts +7 -0
- package/src/api/app/AppRegistry.ts +16 -2
- package/src/api/app/createNavigation.ts +201 -69
- package/src/api/events/navigationEvents.ts +9 -3
- package/src/api/hooks/useSafeAreaInsets.ts +4 -3
- package/src/api/index.ts +1 -0
- package/src/api/linking/linking.ts +22 -1
- package/src/api/options/OptionsChain.ts +2 -2
- package/src/api/screens/defineScreen.ts +49 -5
- package/src/api/screens/nativeScreens.ts +40 -4
- package/src/api/screens/registerScreens.tsx +170 -42
- package/src/api/theme/theme.ts +5 -0
- package/src/engine/commands.ts +51 -6
- package/src/engine/layout.ts +11 -2
- package/src/engine/nativeScreens.ts +10 -1
- package/src/engine/options.ts +6 -8
- package/src/engine/optionsChange.ts +107 -0
- package/src/engine/refresh.ts +97 -0
- package/src/engine/rememberedOptions.ts +70 -0
- package/src/engine/screens.tsx +53 -8
- package/src/interfaces/ComponentEvents.ts +2 -2
- package/src/interfaces/options/animations.ts +44 -14
- package/src/interfaces/options/bottomTabs.ts +19 -6
- package/src/interfaces/options/buttons.ts +10 -10
- package/src/interfaces/options/modals.ts +6 -7
- package/src/interfaces/options/stack.ts +8 -3
- package/src/interfaces/options/system.ts +8 -5
- package/src/interfaces/options/toolbar.ts +2 -2
- package/src/interfaces/options/topBar.ts +46 -29
- package/android/src/main/java/dev/apexnative/navigation/react/ArrangementStates.kt +0 -42
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenInsets.kt +0 -70
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowPlacer.kt +0 -223
- package/android/src/main/java/dev/apexnative/navigation/views/element/ElementStub.kt +0 -31
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMatrixAnimator.kt +0 -136
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PlainViewAnimator.kt +0 -86
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PropertyAnimatorCreator.kt +0 -33
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ReactImageAnimator.kt +0 -64
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextChangeAnimator.kt +0 -177
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewChangeAnimator.kt +0 -137
- package/ios/Layouts/Screen/ANNScreenInsets.h +0 -30
- package/ios/Layouts/Screen/ANNScreenInsets.mm +0 -70
package/ApexNavigation.podspec
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
# ApexNavigation): the Objective-C++ core and modules under ios/, with the public headers of ios/Public/ApexNavigation
|
|
3
3
|
# (<ApexNavigation/ApexNavigation.h>, <ApexNavigation/ANNAppDelegate.h>, <ApexNavigation/ANNSceneDelegate.h>). Other
|
|
4
4
|
# headers stay private to the pod and are imported by bare name. The C++ of the Fabric components ANNSlot and
|
|
5
|
-
# ANNSafeAreaView is
|
|
5
|
+
# ANNSafeAreaView is under ios/cpp, next to the code React Native's codegen makes from src/: headers, and one source
|
|
6
|
+
# file with the store of the slots' measured heights.
|
|
6
7
|
require "json"
|
|
7
8
|
|
|
8
9
|
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.0.0-alpha.7](https://github.com/apexnative/navigation/compare/v1.0.0-alpha.6...v1.0.0-alpha.7) (2026-10-29)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* own android sheet and bar row, ios transitions in core animation, fast refresh of screens ([#56](https://github.com/apexnative/navigation/issues/56)) ([3113b42](https://github.com/apexnative/navigation/commit/3113b42a466f59490faaca181178a7840dab2826))
|
|
9
|
+
|
|
10
|
+
## [1.0.0-alpha.6](https://github.com/apexnative/navigation/compare/v1.0.0-alpha.5...v1.0.0-alpha.6) (2026-10-25)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### ⚠ BREAKING CHANGES
|
|
14
|
+
|
|
15
|
+
* leave the bottom edge of a screen free by default ([#49](https://github.com/apexnative/navigation/issues/49))
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* a sheet's back preview on android, lighter tabs and top bar, the compatibility mode on ios 27 ([#46](https://github.com/apexnative/navigation/issues/46)) ([24d333d](https://github.com/apexnative/navigation/commit/24d333dd43fc5e056786f22dc8d7f1a0ff82a1ad))
|
|
20
|
+
* leave the bottom edge of a screen free by default ([#49](https://github.com/apexnative/navigation/issues/49)) ([b6bb165](https://github.com/apexnative/navigation/commit/b6bb165152114fb2886bd3c4ee55560c418f0cbe))
|
|
21
|
+
* **tabs:** choose whether a tab switch animates with bottomTabs.switchAnimation ([#52](https://github.com/apexnative/navigation/issues/52)) ([c6185b6](https://github.com/apexnative/navigation/commit/c6185b6b42574cff671def1ebdf8aa4f5e4be681))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### Bug Fixes
|
|
25
|
+
|
|
26
|
+
* an explicit top edge stays free under a large title ([#53](https://github.com/apexnative/navigation/issues/53)) ([188a89e](https://github.com/apexnative/navigation/commit/188a89e8d160c071f91cc010ed43ccc0683e12b3))
|
|
27
|
+
* shared elements fly turned and scaled views the same way on ios and android ([#50](https://github.com/apexnative/navigation/issues/50)) ([bf63ab6](https://github.com/apexnative/navigation/commit/bf63ab624d33ff9295af297ce6506206b1bfa0e6))
|
|
28
|
+
* the custom tab row moves with its tabs on android, and tab cells get selected and badge ([#51](https://github.com/apexnative/navigation/issues/51)) ([fd8f41d](https://github.com/apexnative/navigation/commit/fd8f41d2efd108741672220c54253a86704929a5))
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
### Performance Improvements
|
|
32
|
+
|
|
33
|
+
* **ios:** render a preview's screen when a press on its view starts ([#48](https://github.com/apexnative/navigation/issues/48)) ([4a57d1a](https://github.com/apexnative/navigation/commit/4a57d1aee1df7690dbde4c7d08dca2a70773d1f5))
|
|
34
|
+
|
|
3
35
|
## [1.0.0-alpha.5](https://github.com/apexnative/navigation/compare/v1.0.0-alpha.4...v1.0.0-alpha.5) (2026-10-23)
|
|
4
36
|
|
|
5
37
|
|
package/README.md
CHANGED
|
@@ -97,7 +97,7 @@ navigation.push('Details', { props: { title: 'Order 42' } });
|
|
|
97
97
|
each other: tabs of stacks, a stack in a modal, tabs in a side menu.
|
|
98
98
|
- **Screen UI as options:** the top bar, bar buttons, search, the toolbar and the floating action button, the status
|
|
99
99
|
bar and the system bars.
|
|
100
|
-
- **No safe area code:** every screen keeps its
|
|
100
|
+
- **No safe area code:** every screen keeps its top and sides clear of the bars and the cutout by itself; the bottom is free, and a list adds `useSafeAreaInsets().bottom`.
|
|
101
101
|
- **Native screens:** SwiftUI, UIKit and Compose screens are pushed, presented and put in tabs the same way as React
|
|
102
102
|
screens.
|
|
103
103
|
- **One React tree when you want it:** each screen is its own React root by default; with `appProvider` all screens
|
package/android/CLAUDE.md
CHANGED
|
@@ -22,8 +22,9 @@ top-level folder. Main thread only, unless a line says otherwise.
|
|
|
22
22
|
`Variant`, `ThemeColour`); `parsers/` reads them tolerantly from React Native data.
|
|
23
23
|
- `react/`: the way in and out: `NavigationTurboModule`, `CommandRunner`, `CommandAnswer`, `ErrorTexts`,
|
|
24
24
|
`OptionsCommands`, `PendingCalls` (a task behind the calls JavaScript made), `ReloadCoordinator`, `ReactGateway`,
|
|
25
|
-
`ReactView` (a React root),
|
|
26
|
-
`
|
|
25
|
+
`ReactView` (a React root), `ContentHeights` (content measured without a height limit, through JNI), the stores
|
|
26
|
+
(`ScreenEnvironment`: a screen's insets, padding, regions and pair state; `Hinge`, `StartInfo`), `ScreenRegions`
|
|
27
|
+
(measures a screen's regions), `LaunchLink`, `ScrollEvents`.
|
|
27
28
|
- `react/events/`: `AppearanceDispatcher`, `ScreenAppearance`, `EventEmitter`, `EventContract` (made by
|
|
28
29
|
`scripts/contract.mjs`), `NavigationState`, `ComponentType`.
|
|
29
30
|
- `viewcontrollers/viewcontroller/`: `ViewController` (the base of every node), `Presenter`, `IReactView` (what a
|
|
@@ -44,7 +45,7 @@ top-level folder. Main thread only, unless a line says otherwise.
|
|
|
44
45
|
- `viewcontrollers/sidemenu/`: `SideMenuController`, `SideMenuMotion`, `SideMenuPresenter`, `SideMenuRules`.
|
|
45
46
|
- `viewcontrollers/splitview/`, `arrangement/`: the split view and the pair (modules, plus the core's
|
|
46
47
|
`SplitViewPresenter`).
|
|
47
|
-
- `viewcontrollers/modal/`, `overlay/`: `ModalCoordinator`, `ModalRecord`, `ModalViews`, `ModalSheet`;
|
|
48
|
+
- `viewcontrollers/modal/`, `overlay/`: `ModalCoordinator`, `ModalRecord`, `ModalViews`, `ModalSheet`, `SheetBack`;
|
|
48
49
|
`OverlayCoordinator`, `OverlayRecord`, `OverlayViews`, `OverlayTouches`.
|
|
49
50
|
- `views/`: Android views and animators, no rules: `component/`, `externalcomponent/`, `stack/` (`StackLayout`,
|
|
50
51
|
`topbar/`, `fab/`), `bottomtabs/`, `sidemenu/`, `animations/` (curves, `SideAnimator`, `AnimationRules`), `element/`
|
|
@@ -58,7 +59,8 @@ top-level folder. Main thread only, unless a line says otherwise.
|
|
|
58
59
|
`DevelopmentLog`).
|
|
59
60
|
- `android/src/main/jni/`: `CMakeLists.txt` builds the codegen target with the C++ of `ios/cpp` (the slot's and the
|
|
60
61
|
safe area view's shadow nodes); `ApexNavigationSpec.h` replaces the generated header so autolinking sees their
|
|
61
|
-
descriptors.
|
|
62
|
+
descriptors; `ANNContentHeights.cpp` measures React content without a height limit for `react/ContentHeights.kt`
|
|
63
|
+
(a sheet's `'content'` detent).
|
|
62
64
|
- `android/src/main/res/`: theme `Theme.ApexNavigation` (and `values-night`), `attrs.xml` (splash attributes),
|
|
63
65
|
`ids.xml`, `dimens*.xml`, text colors, icons.
|
|
64
66
|
- `android/src/test/java/…`: unit tests, one package per main package; fakes beside them (`Fakes.kt`,
|
|
@@ -78,16 +80,21 @@ top-level folder. Main thread only, unless a line says otherwise.
|
|
|
78
80
|
`StackViews.kt`, `StackTransitions.kt`, `PreparedPushes.kt`; `views/stack/StackLayout.kt`, `ScreenEdge.kt` (the edge
|
|
79
81
|
a moving screen extends); back: `NavigationActivity.kt`, `viewcontrollers/navigator/BackCallbackState.kt`; the
|
|
80
82
|
preview of a pop during the back gesture (Android 14+): `StackController.BackGesture`, `BackPreview.kt`,
|
|
81
|
-
`stackPoppedByBack` of the layouts.
|
|
82
|
-
|
|
83
|
+
`stackPoppedByBack` of the layouts; of a sheet's dismissal: `viewcontrollers/modal/SheetBack.kt`,
|
|
84
|
+
`ModalCoordinator.backTargetSheet`, `ModalSheet.BackPreview`.
|
|
85
|
+
- Stack FAB: `viewcontrollers/stack/fab/FabPresenter.kt`, `FabPlan.kt`, `FabPlacement.kt`, `FabMotion.kt` (how it goes
|
|
86
|
+
with a transition); `views/stack/fab/` (`FabCopy`: the picture of a FAB that leaves).
|
|
83
87
|
- Top bar (title, buttons, menus, large title): `viewcontrollers/stack/topbar/TopBarPresenter.kt`, `TopBarRoom.kt`,
|
|
84
88
|
`TopBarVisibility.kt`, `BarComponents.kt`, `ButtonPlaces.kt`, `LargeTitleCollapse.kt`, `BarRowTransition.kt`;
|
|
85
|
-
`views/stack/topbar/TopBar.kt`, `TitleBar.kt`, `titlebar/
|
|
89
|
+
`views/stack/topbar/TopBar.kt`, `TitleBar.kt`, `titlebar/ButtonRow.kt` (the views of a side: back, buttons,
|
|
90
|
+
magnifier, "⋮"), `titlebar/ButtonBar.kt` (the buttons from the options, "⋮"'s popup), `titlebar/BarButtonView.kt`,
|
|
91
|
+
`titlebar/BarMenu.kt` (the bar's menus: a `ListPopupWindow` with the theme's popup style and the options' colors),
|
|
92
|
+
`titlebar/ButtonMenus.kt` (menu options to its items).
|
|
86
93
|
- Search: `viewcontrollers/stack/search/StackSearchPresenter.kt`, `ScreenSearch.kt`, `SearchPanel.kt`;
|
|
87
94
|
`views/stack/topbar/search/`.
|
|
88
95
|
- Tabs: `viewcontrollers/bottomtabs/BottomTabsController.kt`, `BottomTabsPresenter.kt`, `TabSelection.kt`,
|
|
89
96
|
`TabItems.kt`, `TabsRoom.kt`; `views/bottomtabs/`; `customrow/BottomTabsCustomRowOptions.kt`,
|
|
90
|
-
`viewcontrollers/bottomtabs/
|
|
97
|
+
`viewcontrollers/bottomtabs/CustomTabRowGeometry.kt`.
|
|
91
98
|
- Modals and sheets: `viewcontrollers/modal/ModalCoordinator.kt`, `ModalRecord.kt`, `ModalViews.kt`, `ModalSheet.kt`,
|
|
92
99
|
`ModalAnimations.kt`; `options/SheetOptions.kt`.
|
|
93
100
|
- Overlays: `viewcontrollers/overlay/OverlayCoordinator.kt`, `OverlayViews.kt`, `OverlayTouches.kt`.
|
|
@@ -96,12 +103,13 @@ top-level folder. Main thread only, unless a line says otherwise.
|
|
|
96
103
|
- Split view: `viewcontrollers/splitview/SplitViewController.kt`, `SplitViewLayout.kt`, `SplitPanes.kt`,
|
|
97
104
|
`SplitViewPresenter.kt`; `StackCommands.showInColumn`.
|
|
98
105
|
- Pair (arrangement): `viewcontrollers/arrangement/ArrangementController.kt`, `ArrangementPlanner.kt`,
|
|
99
|
-
`ArrangementLayout.kt`, `ArrangementDefinition.kt`; `react/
|
|
106
|
+
`ArrangementLayout.kt`, `ArrangementDefinition.kt`; the pair's state in `react/ScreenEnvironment.kt`.
|
|
100
107
|
- Preview, key commands: iOS only. The options are parsed and merged (`options/PreviewOptions.kt`,
|
|
101
108
|
`options/KeyCommandOptions.kt`) and not applied; `dismissPreview` does nothing.
|
|
102
109
|
- Animations and transitions: `views/animations/` (`AnimationRules`, `Curves`, `SideAnimator`, `ValueInterpolation`,
|
|
103
|
-
`FadeThrough`, `SystemTransition`); `views/element/`
|
|
104
|
-
`animators/`); `options/StackAnimationOptions.kt`,
|
|
110
|
+
`FadeThrough`, `SystemTransition`, `AnimationLayer`: the hardware layer of a fade); `views/element/`
|
|
111
|
+
(`ElementTransitions`, `TransitionLayer`, `TargetsWait`, `animators/`); `options/StackAnimationOptions.kt`,
|
|
112
|
+
`ViewAnimationOptions.kt`.
|
|
105
113
|
- System bars: `system/SystemUiOwner.kt`, `SystemUiLayers.kt`, `SystemUiRules.kt`, `SystemUiWindow.kt`,
|
|
106
114
|
`AppDirection.kt`; `viewcontrollers/parent/ContainerBackground.kt`.
|
|
107
115
|
- Events and state: `react/events/AppearanceDispatcher.kt`, `ScreenAppearance.kt`, `EventEmitter.kt`,
|
|
@@ -111,21 +119,21 @@ top-level folder. Main thread only, unless a line says otherwise.
|
|
|
111
119
|
- Error texts and answers: `react/ErrorTexts.kt` and `react/CommandContract.kt`, made by `scripts/contract.mjs` from
|
|
112
120
|
`src/interfaces/contract/errors.json` and `commands.json`.
|
|
113
121
|
- Links: `react/LaunchLink.kt`, `NavigationActivity.kt` (`onNewIntent`); `react/StartInfo.kt`.
|
|
114
|
-
- Hinge and regions: `react/Hinge.kt`, `react/ScreenRegions.kt`, `react/
|
|
122
|
+
- Hinge and regions: `react/Hinge.kt`, `react/ScreenRegions.kt`, `react/ScreenEnvironment.kt`, `utils/WindowFolds.kt`.
|
|
115
123
|
- Native screens: `nativescreen/NativeScreenContext.kt`, `NativeScreenCalls.kt`, `NativeScreenCreator.kt`;
|
|
116
124
|
`viewcontrollers/externalcomponent/`.
|
|
117
125
|
- Slots: `slots/SlotHost.kt`, `SlotView.kt`, `SlotScreenView.kt`, `SlotContainers.kt` (containers and slot views by
|
|
118
126
|
slot id: a change goes straight to the views of its id, `SlotViews.kt`), `SlotViewManager.kt`.
|
|
119
127
|
- Safe area: `safearea/SafeAreaView.kt`, `SafeAreaViewManager.kt`; `viewcontrollers/component/ScreenReadiness.kt`;
|
|
120
|
-
`react/
|
|
128
|
+
`react/ScreenEnvironment.kt`.
|
|
121
129
|
- The C++ of `ANNSlot`, `ANNSafeAreaView`: `android/src/main/jni/CMakeLists.txt`, `ApexNavigationSpec.h`; sources in
|
|
122
130
|
`ios/cpp/`.
|
|
123
131
|
|
|
124
132
|
## Threads
|
|
125
133
|
|
|
126
134
|
- **JS thread.** The sync getters `getScreenInsets`, `getScreenRegions`, `getArrangementState`, `getHinge`,
|
|
127
|
-
`getStartInfo` read stores (`ConcurrentHashMap`
|
|
128
|
-
|
|
135
|
+
`getStartInfo` read stores (one `ConcurrentHashMap` of immutable records in `ScreenEnvironment`; `@Volatile` in
|
|
136
|
+
`Hinge`). They never touch a node.
|
|
129
137
|
- **Module thread.** The `check` of every command with a promise: `LayoutReader` and, through it, `OptionsReader` (also
|
|
130
138
|
for `setDefaultOptions`, `mergeOptions` and the options of `dismissModal`, in the runner's `prepare` step);
|
|
131
139
|
`ReadableJson` for native-screen props. The registry of native screens is read under its lock. Images are not loaded
|
|
@@ -156,9 +164,9 @@ top-level folder. Main thread only, unless a line says otherwise.
|
|
|
156
164
|
- Native code never touches React Native's views (their children, their layout): Fabric owns and recycles them. Move
|
|
157
165
|
content through `SlotContainers` and `SlotView`, and find views by `nativeID` only through React Native's own search
|
|
158
166
|
or its tag (`ReactR.id.view_tag_native_id`); a transition's elements in one walk per screen (`TransitionViews`).
|
|
159
|
-
- Each step of a transition's element (its
|
|
160
|
-
|
|
161
|
-
too, or one bad element takes the whole transition down.
|
|
167
|
+
- Each step of a transition's element (its start, its animator, a flight's start and frames in `MoveAnimator`) runs
|
|
168
|
+
in `elementStep`, and the layer draws each copy on its own: an exception skips that element only. A new step of an
|
|
169
|
+
element goes there too, or one bad element takes the whole transition down.
|
|
162
170
|
- Every change of a stack's children goes through its `StackQueue`; a direct change of `shown` or of the container
|
|
163
171
|
skips the table that decides interrupts and answers.
|
|
164
172
|
- Every event of an appearance goes through `AppearanceDispatcher`. A container with its own loop of
|
|
@@ -198,8 +206,11 @@ top-level folder. Main thread only, unless a line says otherwise.
|
|
|
198
206
|
- The bar measures to its children: a picture laid into it for a transition that is taller than the bar the incoming
|
|
199
207
|
screen gives holds the bar at that height to the end (the row's picture of a pop from a large title). What doesn't
|
|
200
208
|
stay in the bar rides with the leaving screen (`TopBarPresenter.pictureUnderRow`).
|
|
201
|
-
-
|
|
202
|
-
|
|
209
|
+
- The bar's buttons are plain views of the row (`ButtonRow`), not a toolbar's menu: a button keeps its view while its id
|
|
210
|
+
stays, and its `testID` is set when it is bound. They copy a Material 3 toolbar's look through the theme's
|
|
211
|
+
attributes (`actionButtonStyle`, `actionMenuTextAppearance`, `actionOverflowButtonStyle`,
|
|
212
|
+
`toolbarNavigationButtonStyle`) and its `maxButtonHeight` of 56 dp; the count of places is AppCompat's
|
|
213
|
+
(`ButtonPlaces.maxActionButtons`).
|
|
203
214
|
- A screen's overlay is clipped to the screen, and a screen without a large title is laid out under the bar (its `top`
|
|
204
215
|
is the bar's height): a picture of the bar in its overlay doesn't show. The bar's picture in a transition of the
|
|
205
216
|
stack's own is drawn by the stack's view with the screen's transform (`StackLayout.barTravels`).
|
package/android/CORE.md
CHANGED
|
@@ -10,7 +10,7 @@ otherwise.
|
|
|
10
10
|
```
|
|
11
11
|
JS ─ ANNTurboModule (codegen NativeANNTurboModuleSpec)
|
|
12
12
|
│ sync getters answer on the JS thread from stores the main thread fills
|
|
13
|
-
│ (
|
|
13
|
+
│ (ScreenEnvironment, Hinge, StartInfo)
|
|
14
14
|
▼ module thread
|
|
15
15
|
react/NavigationTurboModule one override per method
|
|
16
16
|
│ layout/LayoutReader ► options/OptionsReader the whole layout read and checked, its options read
|
|
@@ -188,7 +188,7 @@ Each rule has one owner. Change the owner, not a caller; if a new feature needs
|
|
|
188
188
|
- **Room for the bars.** A screen's room at the top and bottom is `ScreenFrame` with `ScreenSafeArea` and the
|
|
189
189
|
`ParentController` room hooks (`getTopInset`, `keepsStatusBarRoomOf`, …). A screen in a pair forwards its room to
|
|
190
190
|
the pair (`ScreenFrame.applyRoom`), and the pair's `getTopInset` uses the screens' rule (`ScreenFrame.topRoomOf`)
|
|
191
|
-
with the options it shows with. A view's place in the window for the safe area (the React root, the stack's header
|
|
191
|
+
with the options it shows with. The bottom edge is not padded by default (only `'bottom'` in the edges pads it); `roomPadding` still shrinks the view for an opaque navigation bar and the keyboard. A view's place in the window for the safe area (the React root, the stack's header
|
|
192
192
|
bottom in `headerBottomOf`, the tabs' top in `tabsTopOf`) is `RestPlace`: from layout, without translations, a sheet
|
|
193
193
|
at rest.
|
|
194
194
|
- **A container's own move.** A container that moves children in or out of the window without a command (the split
|
|
@@ -207,11 +207,12 @@ Modules are the feature classes that plug into the core through its contract (th
|
|
|
207
207
|
custom row (`BottomTabsCustomRowOptions`).
|
|
208
208
|
- **Views and helpers:** tabs bar (`BottomTabs`, `BottomTabItem`, `BottomTabsCollapseBehavior`, `scrollToTop`), slots
|
|
209
209
|
(`SlotHost`, `SlotView`, `SlotContainers`), safe area (`SafeAreaView`), native screens (`nativescreen/`), splash
|
|
210
|
-
(`splash/`), animations (`FadeThrough`, `SystemTransition`, `TransitionTargets`,
|
|
211
|
-
(`MaterialTheme`, `NavigationLog`, `awaitBarComponents`,
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
210
|
+
(`splash/`), animations (`FadeThrough`, `SystemTransition`, `TransitionTargets`, the copies of shared elements:
|
|
211
|
+
`TextMorph`, `ViewMorph`, `ImageMorph`), utils (`MaterialTheme`, `NavigationLog`, `awaitBarComponents`,
|
|
212
|
+
`whenDrawn`).
|
|
213
|
+
- **Stores and singletons:** a screen's environment (`ScreenEnvironment`: its insets and padding, its regions as
|
|
214
|
+
`ScreenRegions` measures them, its pair state), the window (`Hinge`, `WindowFolds`), links (`LaunchLink`,
|
|
215
|
+
`StartInfo`), events (`NavigationState`), commands (`BackCallbackState`), stack (`PreparedFrame`).
|
|
215
216
|
|
|
216
217
|
How they plug in:
|
|
217
218
|
|
|
@@ -235,5 +236,8 @@ How they plug in:
|
|
|
235
236
|
- **Core code in a module's folder:** `viewcontrollers/splitview/SplitViewPresenter.kt`, `slots/SlotScreenView.kt`,
|
|
236
237
|
and in `views/animations/` and `views/element/` everything except the files named above.
|
|
237
238
|
- **Stores** are written on the main thread by the core and read from any thread; they are cleared with their nodes and on
|
|
238
|
-
reload.
|
|
239
|
+
reload. A screen's environment is one immutable record per id in `ScreenEnvironment` (insets for JavaScript, padding,
|
|
240
|
+
regions, pair state), replaced at once; the screen's node clears it with one `remove` when it is destroyed, unless a
|
|
241
|
+
later node has its id; the padding listeners of its safe area views stay until the views stop. Their events, and
|
|
242
|
+
the search's, go through the emitter of the JavaScript the screen was made for
|
|
239
243
|
(`EventEmitter.of(node.jsGeneration)`); the hinge keeps the `EventEmitter.current()` of the call that turned it on.
|
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
# The native screens `npx apex-navigation codegen` lists in the app: the navigation finds the list by its name.
|
|
2
2
|
-keep class dev.apexnative.navigation.generated.ApexNavigationGeneratedScreens { *; }
|
|
3
|
+
|
|
4
|
+
# The library's C++ measures a React root's content through the surface's handler, which it reads by this getter's
|
|
5
|
+
# name (`android/src/main/jni/ANNContentHeights.cpp`).
|
|
6
|
+
-keepclassmembers class com.facebook.react.runtime.ReactSurfaceImpl {
|
|
7
|
+
com.facebook.react.fabric.SurfaceHandlerBinding getSurfaceHandler();
|
|
8
|
+
}
|
|
@@ -35,6 +35,7 @@ import dev.apexnative.navigation.splash.SplashTheme
|
|
|
35
35
|
import dev.apexnative.navigation.splash.SplashView
|
|
36
36
|
import dev.apexnative.navigation.system.SystemUiWindow
|
|
37
37
|
import dev.apexnative.navigation.utils.MaterialTheme
|
|
38
|
+
import dev.apexnative.navigation.viewcontrollers.modal.SheetBack
|
|
38
39
|
import dev.apexnative.navigation.viewcontrollers.navigator.BackCallbackCheck
|
|
39
40
|
import dev.apexnative.navigation.viewcontrollers.navigator.BackCallbackState
|
|
40
41
|
import dev.apexnative.navigation.viewcontrollers.navigator.Navigator
|
|
@@ -72,23 +73,33 @@ open class NavigationActivity : AppCompatActivity(), DefaultHardwareBackBtnHandl
|
|
|
72
73
|
// Enabled while back has something to do in the app (BackCallbackState); otherwise the system does its own back.
|
|
73
74
|
// From Android 14, where the app hears the progress of the back gesture, a gesture that would pop a stack with the
|
|
74
75
|
// default transition previews the pop as the system previews back between activities (`StackController
|
|
75
|
-
// .BackGesture`)
|
|
76
|
+
// .BackGesture`), and one that would dismiss a sheet previews its hide as Material's sheets do (`SheetBack`), its
|
|
77
|
+
// release closing it as a drag down does; JavaScript's listeners hear back first, so with them there is no preview.
|
|
76
78
|
private val backCallback = object : OnBackPressedCallback(false) {
|
|
77
79
|
override fun handleOnBackStarted(backEvent: BackEventCompat) {
|
|
78
80
|
backGesture = null
|
|
79
|
-
|
|
81
|
+
sheetGesture = null
|
|
82
|
+
val navigator = navigator ?: return
|
|
83
|
+
backCheck?.atBack(navigator)
|
|
80
84
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE || BackCallbackState.hasJsListeners) return
|
|
81
|
-
val stack = navigator
|
|
82
|
-
|
|
85
|
+
val stack = navigator.stackPoppedByBack()
|
|
86
|
+
if (stack != null) {
|
|
87
|
+
backGesture = stack.startBackGesture(backEvent.swipeEdge == BackEventCompat.EDGE_LEFT, backEvent.touchY)
|
|
88
|
+
return
|
|
89
|
+
}
|
|
90
|
+
sheetGesture = navigator.sheetDismissedByBack()?.startBackPreview(backEvent)
|
|
83
91
|
}
|
|
84
92
|
|
|
85
93
|
override fun handleOnBackProgressed(backEvent: BackEventCompat) {
|
|
86
94
|
backGesture?.progress(backEvent.progress, backEvent.touchY)
|
|
95
|
+
sheetGesture?.progress(backEvent)
|
|
87
96
|
}
|
|
88
97
|
|
|
89
98
|
override fun handleOnBackCancelled() {
|
|
90
99
|
backGesture?.cancel()
|
|
91
100
|
backGesture = null
|
|
101
|
+
sheetGesture?.cancel()
|
|
102
|
+
sheetGesture = null
|
|
92
103
|
navigator?.let(BackCallbackState::update)
|
|
93
104
|
}
|
|
94
105
|
|
|
@@ -96,13 +107,33 @@ open class NavigationActivity : AppCompatActivity(), DefaultHardwareBackBtnHandl
|
|
|
96
107
|
navigator?.let { backCheck?.atBack(it) }
|
|
97
108
|
val gesture = backGesture
|
|
98
109
|
backGesture = null
|
|
99
|
-
|
|
110
|
+
val sheet = sheetGesture
|
|
111
|
+
sheetGesture = null
|
|
112
|
+
when {
|
|
113
|
+
gesture?.commit() == true -> BackCallbackState.update()
|
|
114
|
+
sheet != null && commitSheet(sheet) -> BackCallbackState.update()
|
|
115
|
+
else -> passBack()
|
|
116
|
+
}
|
|
100
117
|
}
|
|
101
118
|
}
|
|
102
119
|
|
|
103
120
|
// The back gesture that previews a pop now; none.
|
|
104
121
|
private var backGesture: StackController.BackGesture? = null
|
|
105
122
|
|
|
123
|
+
// The back gesture that previews a sheet's hide now; none.
|
|
124
|
+
private var sheetGesture: SheetBack.Gesture? = null
|
|
125
|
+
|
|
126
|
+
// A sheet's preview released: the sheet goes as the user's drag down closes it, and back doesn't go on (no
|
|
127
|
+
// `passBack`, which would dismiss it a second time). A command that changed what back does since the gesture
|
|
128
|
+
// started (a push in the sheet, a modal over it, a hold) leaves it to the usual back, the sheet back in place.
|
|
129
|
+
private fun commitSheet(gesture: SheetBack.Gesture): Boolean {
|
|
130
|
+
if (navigator?.sheetDismissedByBack() !== gesture.sheet) {
|
|
131
|
+
gesture.cancel()
|
|
132
|
+
return false
|
|
133
|
+
}
|
|
134
|
+
return gesture.commit()
|
|
135
|
+
}
|
|
136
|
+
|
|
106
137
|
// Debug builds only: the check that what back does never changes without its trigger (BackCallbackState), sampled
|
|
107
138
|
// before frames and at back events. It only logs; release builds have neither the check nor the listener.
|
|
108
139
|
private val backCheck = if (BuildConfig.DEBUG) BackCallbackCheck() else null
|
|
@@ -105,7 +105,7 @@ class BottomTabOptions {
|
|
|
105
105
|
@JvmField var textColor: ThemeColour = NullThemeColour()
|
|
106
106
|
@JvmField var selectedIconColor: ThemeColour = NullThemeColour()
|
|
107
107
|
@JvmField var selectedTextColor: ThemeColour = NullThemeColour()
|
|
108
|
-
@JvmField var font = FontOptions()
|
|
108
|
+
@ReadFromParent @JvmField var font = FontOptions()
|
|
109
109
|
@JvmField var fontSize: Fraction = NullFraction()
|
|
110
110
|
@JvmField var selectedFontSize: Fraction = NullFraction()
|
|
111
111
|
@JvmField var iconInsets = IconInsetsOptions()
|
|
@@ -95,6 +95,7 @@ class BottomTabsAccessoryOptions {
|
|
|
95
95
|
class BottomTabsOptions {
|
|
96
96
|
@JvmField var visible: Bool = NullBool()
|
|
97
97
|
@JvmField var animate: Bool = NullBool()
|
|
98
|
+
@JvmField var switchAnimation: Text = NullText()
|
|
98
99
|
/** Selects a tab once; a whole number, truncated where it is read. */
|
|
99
100
|
@JvmField var currentTabIndex: Fraction = NullFraction()
|
|
100
101
|
/** Selects a tab once. */
|
|
@@ -124,18 +125,19 @@ class BottomTabsOptions {
|
|
|
124
125
|
@JvmField var minimizeBehavior: Text = NullText()
|
|
125
126
|
@JvmField var bottomAccessory = BottomTabsAccessoryOptions()
|
|
126
127
|
|
|
127
|
-
fun hasValue(): Boolean = visible.hasValue() || animate.hasValue() ||
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
bottomAccessory.hasValue()
|
|
128
|
+
fun hasValue(): Boolean = visible.hasValue() || animate.hasValue() || switchAnimation.hasValue() ||
|
|
129
|
+
currentTabIndex.hasValue() || currentTabId.hasValue() || testID.hasValue() || accessibilityLabel.hasValue() ||
|
|
130
|
+
moreTestID.hasValue() || drawBehind.hasValue() || backgroundColor.hasValue() || tabsAttachMode.hasValue() ||
|
|
131
|
+
barStyle.hasValue() || layoutStyle.hasValue() || cornerRadius.hasValue() || bottomMargin.hasValue() ||
|
|
132
|
+
translucent.hasValue() || hideShadow.hasValue() || titleDisplayMode.hasValue() || elevation.hasValue() ||
|
|
133
|
+
hideOnScroll.hasValue() || borderColor.hasValue() || borderWidth.hasValue() || shadow.hasValue() ||
|
|
134
|
+
customRow.hasValue() || sidebar.hasValue() || sidebarLayout.hasValue() || customizationId.hasValue() ||
|
|
135
|
+
minimizeBehavior.hasValue() || bottomAccessory.hasValue()
|
|
135
136
|
|
|
136
137
|
fun mergeWith(other: BottomTabsOptions) {
|
|
137
138
|
if (other.visible.hasValue()) visible = other.visible
|
|
138
139
|
if (other.animate.hasValue()) animate = other.animate
|
|
140
|
+
if (other.switchAnimation.hasValue()) switchAnimation = other.switchAnimation
|
|
139
141
|
if (other.currentTabIndex.hasValue()) currentTabIndex = other.currentTabIndex
|
|
140
142
|
if (other.currentTabId.hasValue()) currentTabId = other.currentTabId
|
|
141
143
|
if (other.testID.hasValue()) testID = other.testID
|
|
@@ -167,6 +169,7 @@ class BottomTabsOptions {
|
|
|
167
169
|
fun mergeWithDefault(defaults: BottomTabsOptions) {
|
|
168
170
|
if (!visible.hasValue()) visible = defaults.visible
|
|
169
171
|
if (!animate.hasValue()) animate = defaults.animate
|
|
172
|
+
if (!switchAnimation.hasValue()) switchAnimation = defaults.switchAnimation
|
|
170
173
|
if (!currentTabIndex.hasValue()) currentTabIndex = defaults.currentTabIndex
|
|
171
174
|
if (!currentTabId.hasValue()) currentTabId = defaults.currentTabId
|
|
172
175
|
if (!testID.hasValue()) testID = defaults.testID
|
|
@@ -198,6 +201,7 @@ class BottomTabsOptions {
|
|
|
198
201
|
fun copy() = BottomTabsOptions().also { it.mergeWith(this) }
|
|
199
202
|
|
|
200
203
|
companion object {
|
|
204
|
+
private val SWITCH_ANIMATIONS = setOf("platform", "none")
|
|
201
205
|
private val TABS_ATTACH_MODES = setOf("together", "afterInitialTab", "onSwitchToTab")
|
|
202
206
|
private val BAR_STYLES = setOf("default", "black")
|
|
203
207
|
private val LAYOUT_STYLES = setOf("stretch", "compact")
|
|
@@ -212,6 +216,7 @@ class BottomTabsOptions {
|
|
|
212
216
|
if (map == null) return options
|
|
213
217
|
options.visible = BoolParser.parse(map, "visible")
|
|
214
218
|
options.animate = BoolParser.parse(map, "animate")
|
|
219
|
+
options.switchAnimation = TextParser.parse(map, "switchAnimation", SWITCH_ANIMATIONS)
|
|
215
220
|
options.currentTabIndex = FractionParser.parse(map, "currentTabIndex")
|
|
216
221
|
options.currentTabId = TextParser.parse(map, "currentTabId")
|
|
217
222
|
options.testID = TextParser.parse(map, "testID")
|
|
@@ -31,7 +31,7 @@ class ButtonOptions(@JvmField var id: Text = NullText()) {
|
|
|
31
31
|
@JvmField var systemItem: Text = NullText()
|
|
32
32
|
@JvmField var text: Text = NullText()
|
|
33
33
|
@JvmField var accessibilityLabel: Text = NullText()
|
|
34
|
-
@JvmField var font = FontOptions()
|
|
34
|
+
@ReadFromParent @JvmField var font = FontOptions()
|
|
35
35
|
@JvmField var fontSize: Fraction = NullFraction()
|
|
36
36
|
@JvmField var enabled: Bool = NullBool()
|
|
37
37
|
@JvmField var disableIconTint: Bool = NullBool()
|
|
@@ -22,7 +22,7 @@ class LargeTitleOptions {
|
|
|
22
22
|
@JvmField var collapseOnScroll: Bool = NullBool()
|
|
23
23
|
@JvmField var fontSize: Fraction = NullFraction()
|
|
24
24
|
@JvmField var color: ThemeColour = NullThemeColour()
|
|
25
|
-
@JvmField var font = FontOptions()
|
|
25
|
+
@ReadFromParent @JvmField var font = FontOptions()
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* When the large title shows: [ALWAYS], [NEVER] or [AUTOMATIC], as on the screen below. `displayMode` over
|
|
@@ -9,7 +9,7 @@ import com.facebook.react.bridge.ReadableMap
|
|
|
9
9
|
* first).
|
|
10
10
|
*/
|
|
11
11
|
open class LayoutAnimation(
|
|
12
|
-
@JvmField var sharedElements: SharedElements = SharedElements(),
|
|
12
|
+
@OptionKey("sharedElementTransitions") @JvmField var sharedElements: SharedElements = SharedElements(),
|
|
13
13
|
@JvmField var elementTransitions: ElementTransitions = ElementTransitions(),
|
|
14
14
|
) {
|
|
15
15
|
open fun hasValue(): Boolean = sharedElements.hasValue() || elementTransitions.hasValue()
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
package dev.apexnative.navigation.options
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The JSON key of an option field whose name is not that key (`topBar.backButton` is `TopBarButtons.back`), for the
|
|
5
|
+
* paths of [OptionPaths]; also the flag that tells a value is given, which goes with it. A field without it answers to
|
|
6
|
+
* its own name.
|
|
7
|
+
*/
|
|
8
|
+
@Target(AnnotationTarget.FIELD)
|
|
9
|
+
@Retention(AnnotationRetention.RUNTIME)
|
|
10
|
+
annotation class OptionKey(val name: String)
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A group the reader takes from the object of the group that holds it, not from a key of its own (the font of a text,
|
|
14
|
+
* the top bar's buttons): for the paths of [OptionPaths] its fields answer to the keys of that object.
|
|
15
|
+
*/
|
|
16
|
+
@Target(AnnotationTarget.FIELD)
|
|
17
|
+
@Retention(AnnotationRetention.RUNTIME)
|
|
18
|
+
annotation class ReadFromParent
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
package dev.apexnative.navigation.options
|
|
2
|
+
|
|
3
|
+
import dev.apexnative.navigation.options.params.Param
|
|
4
|
+
import dev.apexnative.navigation.options.params.ThemeColour
|
|
5
|
+
import java.lang.reflect.Field
|
|
6
|
+
import java.lang.reflect.Modifier
|
|
7
|
+
import java.util.concurrent.ConcurrentHashMap
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The options at a JSON key path, the keys of the options joined with dots (`topBar.subtitle`, `bottomTab.badge`), as
|
|
11
|
+
* the readers parse them: `clearOptions` takes them out of a node's own options. Generic over the whole tree, by
|
|
12
|
+
* reflection on the fields of the groups: a field answers to the key of its name, or of its [OptionKey]; a group the
|
|
13
|
+
* reader takes from the object of its parent ([ReadFromParent]: the font of a text, the top bar's buttons) answers with
|
|
14
|
+
* its fields to the keys of that object. A group is a class with a `mergeWith` of its own class; anything else (a
|
|
15
|
+
* value, a color, a list, a button menu) ends a path.
|
|
16
|
+
*/
|
|
17
|
+
internal object OptionPaths {
|
|
18
|
+
/**
|
|
19
|
+
* What a path names: the fields of [group] that answer to its last key, [members] (one, or a value and the flag
|
|
20
|
+
* that tells it is given, as `modal.sheet.largestUndimmedDetent`).
|
|
21
|
+
*/
|
|
22
|
+
class Place(val group: Any, val members: List<Field>) {
|
|
23
|
+
/** The value at the path, of the first field. */
|
|
24
|
+
val value: Any? get() = members.first().get(group)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// The fields of each class walked, its superclasses' first.
|
|
28
|
+
private val fieldsOfType = ConcurrentHashMap<Class<*>, List<Field>>()
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Takes the value at [path] out of [options], which it changes in place: the field gets the value a freshly made
|
|
32
|
+
* group has for it (unset; a group, an empty one). Whether the path names a field; an empty or unknown path, or
|
|
33
|
+
* one that goes on inside a value (a side of a color), changes nothing.
|
|
34
|
+
*/
|
|
35
|
+
fun clear(options: Options, path: String): Boolean {
|
|
36
|
+
val place = find(options, path) ?: return false
|
|
37
|
+
val fresh = newGroup(place.group.javaClass) ?: return false
|
|
38
|
+
place.members.forEach { it.set(place.group, it.get(fresh)) }
|
|
39
|
+
return true
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** The fields [path] names in [options]; none for an empty or unknown path or one inside a value. */
|
|
43
|
+
fun find(options: Options, path: String): Place? {
|
|
44
|
+
val keys = path.split('.')
|
|
45
|
+
if (keys.any(String::isEmpty)) return null
|
|
46
|
+
var group: Any = options
|
|
47
|
+
for (key in keys.dropLast(1)) {
|
|
48
|
+
group = fieldOf(group, key)?.value?.takeIf(::isGroup) ?: return null
|
|
49
|
+
}
|
|
50
|
+
return fieldOf(group, keys.last())?.takeIf { newGroup(it.group.javaClass) != null }
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// The fields of [group] that answer to [key]: its own, else those of a group read from the same object.
|
|
54
|
+
private fun fieldOf(group: Any, key: String): Place? {
|
|
55
|
+
val fields = fieldsOf(group.javaClass)
|
|
56
|
+
fields.filter { !it.isAnnotationPresent(ReadFromParent::class.java) && keyOf(it) == key }
|
|
57
|
+
.takeIf { it.isNotEmpty() }
|
|
58
|
+
?.let { return Place(group, it) }
|
|
59
|
+
for (field in fields) {
|
|
60
|
+
if (!field.isAnnotationPresent(ReadFromParent::class.java)) continue
|
|
61
|
+
val inner = field.get(group)?.takeIf(::isGroup) ?: continue
|
|
62
|
+
fieldOf(inner, key)?.let { return it }
|
|
63
|
+
}
|
|
64
|
+
return null
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private fun keyOf(field: Field): String = field.getAnnotation(OptionKey::class.java)?.name ?: field.name
|
|
68
|
+
|
|
69
|
+
private fun fieldsOf(type: Class<*>): List<Field> = fieldsOfType.getOrPut(type) {
|
|
70
|
+
generateSequence(type) { it.superclass }
|
|
71
|
+
.takeWhile { it != Any::class.java }
|
|
72
|
+
.toList()
|
|
73
|
+
.asReversed()
|
|
74
|
+
.flatMap { it.declaredFields.asList() }
|
|
75
|
+
.filter { !Modifier.isStatic(it.modifiers) && !it.isSynthetic }
|
|
76
|
+
.onEach { it.isAccessible = true }
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private fun isGroup(value: Any): Boolean {
|
|
80
|
+
if (value is Param<*> || value is ThemeColour) return false
|
|
81
|
+
val type = value.javaClass
|
|
82
|
+
return type.declaredMethods.any { it.name == "mergeWith" && it.parameterTypes.contentEquals(arrayOf(type)) }
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// A group as its class makes it, every field unset; none for a class without a constructor of no arguments.
|
|
86
|
+
private fun newGroup(type: Class<*>): Any? = try {
|
|
87
|
+
type.getDeclaredConstructor().newInstance()
|
|
88
|
+
} catch (_: ReflectiveOperationException) {
|
|
89
|
+
null
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -12,25 +12,28 @@ import dev.apexnative.navigation.options.parsers.FractionParser
|
|
|
12
12
|
import dev.apexnative.navigation.options.parsers.TextParser
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
* A height a sheet stops at: about half the screen, the full height,
|
|
16
|
-
*
|
|
15
|
+
* A height a sheet stops at: about half the screen, the full height, the height of the screen's content, or a height in
|
|
16
|
+
* dp.
|
|
17
17
|
*/
|
|
18
18
|
sealed class SheetDetent {
|
|
19
19
|
object Medium : SheetDetent()
|
|
20
20
|
object Large : SheetDetent()
|
|
21
|
+
object Content : SheetDetent()
|
|
21
22
|
data class Height(val dp: Double) : SheetDetent()
|
|
22
23
|
|
|
23
24
|
/** The detent as the app names it, in `sheetDetentChanged`. */
|
|
24
25
|
fun toValue(): Any = when (this) {
|
|
25
26
|
Medium -> "medium"
|
|
26
27
|
Large -> "large"
|
|
28
|
+
Content -> "content"
|
|
27
29
|
is Height -> dp
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
companion object {
|
|
31
33
|
fun parse(value: Any?): SheetDetent? = when (value) {
|
|
32
|
-
"medium"
|
|
34
|
+
"medium" -> Medium
|
|
33
35
|
"large" -> Large
|
|
36
|
+
"content" -> Content
|
|
34
37
|
// A number is a height only when it is finite and positive.
|
|
35
38
|
is Number -> value.toDouble().takeIf { it.isFinite() && it > 0 }?.let { Height(it) }
|
|
36
39
|
else -> null
|
|
@@ -47,7 +50,7 @@ class SheetOptions {
|
|
|
47
50
|
@JvmField var selectedDetent: SheetDetent? = null
|
|
48
51
|
@JvmField var largestUndimmedDetent: SheetDetent? = null
|
|
49
52
|
/** The options give `largestUndimmedDetent`, `null` included. */
|
|
50
|
-
@JvmField var hasLargestUndimmedDetent = false
|
|
53
|
+
@OptionKey("largestUndimmedDetent") @JvmField var hasLargestUndimmedDetent = false
|
|
51
54
|
@JvmField var grabber: Bool = NullBool()
|
|
52
55
|
@JvmField var expandsOnScroll: Bool = NullBool()
|
|
53
56
|
@JvmField var cornerRadius: Fraction = NullFraction()
|
|
@@ -22,7 +22,7 @@ class TitleOptions {
|
|
|
22
22
|
@JvmField var text: Text = NullText()
|
|
23
23
|
@JvmField var fontSize: Fraction = NullFraction()
|
|
24
24
|
@JvmField var color: ThemeColour = NullThemeColour()
|
|
25
|
-
@JvmField var font = FontOptions()
|
|
25
|
+
@ReadFromParent @JvmField var font = FontOptions()
|
|
26
26
|
@JvmField var component = TitleComponentOptions()
|
|
27
27
|
/** Shared between copies, as its module wants. */
|
|
28
28
|
@JvmField var menu: ButtonMenuOptions? = null
|
|
@@ -98,7 +98,7 @@ class SubtitleOptions {
|
|
|
98
98
|
@JvmField var text: Text = NullText()
|
|
99
99
|
@JvmField var fontSize: Fraction = NullFraction()
|
|
100
100
|
@JvmField var color: ThemeColour = NullThemeColour()
|
|
101
|
-
@JvmField var font = FontOptions()
|
|
101
|
+
@ReadFromParent @JvmField var font = FontOptions()
|
|
102
102
|
@JvmField var alignment: Text = NullText()
|
|
103
103
|
|
|
104
104
|
fun hasValue(): Boolean =
|
|
@@ -109,7 +109,7 @@ class TopBarBackgroundOptions {
|
|
|
109
109
|
*/
|
|
110
110
|
class ScrollEdgeAppearanceTitleOptions {
|
|
111
111
|
@JvmField var color: ThemeColour = NullThemeColour()
|
|
112
|
-
@JvmField var font = FontOptions()
|
|
112
|
+
@ReadFromParent @JvmField var font = FontOptions()
|
|
113
113
|
@JvmField var fontSize: Fraction = NullFraction()
|
|
114
114
|
|
|
115
115
|
fun hasValue(): Boolean = color.hasValue() || font.hasValue() || fontSize.hasValue()
|