react-native-screens 5.0.0-alpha.2 → 5.0.0-alpha.4
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/Package.swift +87 -0
- package/README.md +0 -11
- package/android/build.gradle +1 -0
- package/android/consumer-rules.pro +3 -0
- package/android/src/fabric/java/com/swmansion/rnscreens/legacy/FabricEnabledHeaderConfigViewGroup.kt +2 -0
- package/android/src/fabric/java/com/swmansion/rnscreens/legacy/FabricEnabledHeaderSubviewViewGroup.kt +2 -0
- package/android/src/fabric/java/com/swmansion/rnscreens/legacy/FabricEnabledViewGroup.kt +18 -3
- package/android/src/main/cpp/NativeProxy.cpp +30 -6
- package/android/src/main/cpp/NativeProxy.h +7 -1
- package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +2 -2
- package/android/src/main/java/com/swmansion/rnscreens/ScreensModule.kt +7 -3
- package/android/src/main/java/com/swmansion/rnscreens/common/colorscheme/ColorSchemeCoordinator.kt +11 -1
- package/android/src/main/java/com/swmansion/rnscreens/common/container/Container.kt +17 -0
- package/android/src/main/java/com/swmansion/rnscreens/common/container/ContainerItem.kt +13 -1
- package/android/src/main/java/com/swmansion/rnscreens/common/text/ReactTextAppearance.kt +62 -0
- package/android/src/main/java/com/swmansion/rnscreens/common/text/TextAppearance.kt +20 -0
- package/android/src/main/java/com/swmansion/rnscreens/common/text/TextAppearanceDefaults.kt +65 -0
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/coordinator/FormSheetAppearanceCoordinator.kt +2 -2
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/coordinator/FormSheetBehaviorController.kt +51 -20
- package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/coordinator/FormSheetDimensionsCoordinator.kt +159 -0
- package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/coordinator/FormSheetKeyboardCoordinator.kt +101 -0
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/coordinator/FormSheetNativeDismissCoordinator.kt +2 -8
- package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/dialog/FormSheetAvailableHeightProvider.kt +44 -0
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native/core → core/modals/formsheet/dialog}/FormSheetContainer.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native/core → core/modals/formsheet/dialog}/FormSheetDialog.kt +36 -4
- package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/dialog/FormSheetDialogManager.kt +107 -0
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/interfaces/FormSheetContentSizeChangeDelegate.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/interfaces/FormSheetContentSizeChangeProvider.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/interfaces/FormSheetDialogEventEmitter.kt +3 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/model/FormSheetConfig.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/model/FormSheetDetents.kt +152 -0
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/presentation/FormSheetAnimatorFactory.kt +9 -10
- package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/presentation/FormSheetDimmingManager.kt +103 -0
- package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/presentation/FormSheetDismissalOrigin.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/presentation/FormSheetPresentation.kt +173 -0
- package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/presentation/FormSheetPresentationManager.kt +290 -0
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/presentation/FormSheetPresentationState.kt +2 -2
- package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/presentation/FormSheetStackRegistry.kt +28 -0
- package/android/src/main/java/com/swmansion/rnscreens/ext/FragmentManagerExt.kt +6 -0
- package/android/src/main/java/com/swmansion/rnscreens/helpers/FragmentManagerHelper.kt +0 -3
- package/android/src/main/java/com/swmansion/rnscreens/helpers/NoTintDrawable.kt +31 -0
- package/android/src/main/java/com/swmansion/rnscreens/helpers/PropIconResolver.kt +17 -23
- package/android/src/main/java/com/swmansion/rnscreens/helpers/ViewFinder.kt +0 -17
- package/android/src/main/java/com/swmansion/rnscreens/legacy/Screen.kt +32 -3
- package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenContainer.kt +35 -3
- package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenStack.kt +15 -0
- package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenStackHeaderConfig.kt +7 -1
- package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenStackHeaderSubviewManager.kt +7 -0
- package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenStackViewManager.kt +6 -0
- package/android/src/main/java/com/swmansion/rnscreens/legacy/bottomsheet/DimmingView.kt +2 -0
- package/android/src/main/java/com/swmansion/rnscreens/legacy/stack/views/ScreensCoordinatorLayout.kt +2 -0
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/contentwrapper/FormSheetContentWrapper.kt +3 -3
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/contentwrapper/FormSheetContentWrapperViewManager.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetDetentChangedEvent.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetDidAppearEvent.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetDidDisappearEvent.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/react/modals/formsheet/event/FormSheetDismissEvent.kt +29 -0
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetNativeDismissEvent.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetNativeDismissPreventedEvent.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetSyncFlushEvent.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetWillAppearEvent.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetWillDisappearEvent.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/host/FormSheetContentView.kt +3 -3
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/host/FormSheetHost.kt +5 -3
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/host/FormSheetHostEventEmitter.kt +17 -10
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/host/FormSheetHostViewManager.kt +11 -9
- package/android/src/main/java/com/swmansion/rnscreens/safearea/OnInterfaceInsetsChangeListener.kt +15 -0
- package/android/src/main/java/com/swmansion/rnscreens/safearea/SafeAreaProvider.kt +8 -8
- package/android/src/main/java/com/swmansion/rnscreens/safearea/SafeAreaView.kt +3 -2
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderApplicator.kt +360 -101
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderBackPressHandler.kt +11 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderCoordinatorLayout.kt +211 -113
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/appbar/StackHeaderAppBarLayout.kt +156 -24
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/appbar/StackHeaderContentScrimDrawable.kt +36 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/appbar/StackHeaderToolbar.kt +74 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderCollapsedTitleGravityMode.kt +6 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfig.kt +162 -228
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigViewManager.kt +385 -12
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigurationObserver.kt +5 -6
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigurationProviding.kt +29 -6
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderDelegate.kt +0 -7
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderInvalidationFlags.kt +8 -7
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuApplicator.kt +27 -280
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuController.kt +448 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuDelegate.kt +10 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuMapper.kt +28 -20
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/model/StackHeaderToolbarMenuConfig.kt +3 -55
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/model/StackHeaderToolbarMenuGroupMetadata.kt +1 -10
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/model/StackHeaderToolbarMenuItemConfig.kt +1 -3
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/model/StackHeaderToolbarMenuModel.kt +180 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuElementOptions.kt +57 -6
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuElementRawUpdate.kt +3 -1
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuElementUpdate.kt +1 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuIconResolver.kt +4 -3
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuUpdateQueue.kt +23 -9
- package/android/src/main/java/com/swmansion/rnscreens/stack/host/FragmentOperation.kt +1 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/host/FragmentOperationExecutor.kt +2 -1
- package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackContainer.kt +159 -21
- package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackContainerDelegate.kt +7 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackContainerUpdateCoordinator.kt +5 -3
- package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackHost.kt +27 -5
- package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackHostViewManager.kt +14 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackUpdateBatchStateProviding.kt +10 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/screen/PreventNativeDismissCallback.kt +2 -2
- package/android/src/main/java/com/swmansion/rnscreens/stack/screen/StackScreen.kt +4 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/screen/StackScreenFragment.kt +50 -10
- package/android/src/main/java/com/swmansion/rnscreens/stack/screen/StackScreenFragmentDelegate.kt +12 -0
- package/android/src/main/java/com/swmansion/rnscreens/tabs/appearance/TabsAppearanceApplicator.kt +106 -10
- package/android/src/main/java/com/swmansion/rnscreens/tabs/appearance/TabsAppearanceCoordinator.kt +46 -7
- package/android/src/main/java/com/swmansion/rnscreens/tabs/appearance/TabsAppearanceModel.kt +3 -0
- package/android/src/main/java/com/swmansion/rnscreens/tabs/container/CustomBottomNavigationView.kt +21 -1
- package/android/src/main/java/com/swmansion/rnscreens/tabs/container/MenuHelpers.kt +5 -23
- package/android/src/main/java/com/swmansion/rnscreens/tabs/container/TabsContainer.kt +72 -36
- package/android/src/main/java/com/swmansion/rnscreens/tabs/container/TabsContainerDelegate.kt +11 -0
- package/android/src/main/java/com/swmansion/rnscreens/tabs/host/TabsHost.kt +22 -2
- package/android/src/main/java/com/swmansion/rnscreens/tabs/host/TabsHostA11yCoordinator.kt +23 -2
- package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreen.kt +58 -17
- package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreenDelegate.kt +6 -0
- package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreenFragment.kt +3 -0
- package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreenIcon.kt +82 -0
- package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreenIconTinting.kt +17 -0
- package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreenViewManager.kt +26 -19
- package/android/src/main/java/com/swmansion/rnscreens/utils/DimensionUtils.kt +20 -6
- package/android/src/main/java/com/swmansion/rnscreens/utils/RNSLog.kt +22 -6
- package/android/src/main/java/com/swmansion/rnscreens/utils/StyleUtils.kt +22 -0
- package/android/src/main/res/base/layout/rns_collapsing_toolbar_large_available_space.xml +8 -0
- package/android/src/main/res/base/layout/rns_collapsing_toolbar_large_entire_space.xml +8 -0
- package/android/src/main/res/base/layout/rns_collapsing_toolbar_medium_available_space.xml +8 -0
- package/android/src/main/res/base/layout/rns_collapsing_toolbar_medium_entire_space.xml +8 -0
- package/cpp/legacy/RNSScreenRemovalListener.cpp +31 -1
- package/cpp/legacy/RNSScreenRemovalListener.h +18 -3
- package/ios/RNSEnums.h +16 -1
- package/ios/conversion/RNSConversions.h +7 -108
- package/ios/helpers/image/RNSImageLoadingHelper.h +7 -0
- package/ios/helpers/image/RNSImageLoadingHelper.mm +9 -0
- package/ios/legacy/RNSBarButtonItem.mm +15 -0
- package/ios/legacy/RNSConvert.h +6 -0
- package/ios/legacy/RNSConvert.mm +17 -0
- package/ios/legacy/RNSFullWindowOverlay.mm +1 -1
- package/ios/legacy/RNSModalScreen.mm +1 -1
- package/ios/legacy/RNSNavigationBar.h +31 -0
- package/ios/legacy/RNSNavigationBar.mm +15 -0
- package/ios/legacy/RNSScreen.mm +130 -31
- package/ios/legacy/RNSScreenContentWrapper.mm +4 -1
- package/ios/legacy/RNSScreenStack.mm +202 -15
- package/ios/legacy/RNSScreenStackHeaderConfig.h +30 -0
- package/ios/legacy/RNSScreenStackHeaderConfig.mm +72 -17
- package/ios/legacy/RNSScreenStackHeaderSubview.mm +34 -1
- package/ios/legacy/RNSScreenWindowTraits.mm +5 -13
- package/ios/modals/form-sheet/RNSFormSheetConfigurationApplicator.h +1 -3
- package/ios/modals/form-sheet/RNSFormSheetConfigurationApplicator.mm +11 -22
- package/ios/modals/form-sheet/RNSFormSheetContentController.h +1 -1
- package/ios/modals/form-sheet/RNSFormSheetContentController.mm +7 -18
- package/ios/modals/form-sheet/RNSFormSheetHostComponentView.mm +4 -4
- package/ios/modals/form-sheet/RNSFormSheetHostShadowStateProxy.mm +2 -2
- package/ios/modals/form-sheet/RNSFormSheetUpdateFlags.h +3 -0
- package/ios/safe-area/RNSSafeAreaViewComponentView.mm +3 -14
- package/ios/{conversion → scroll-view-marker/conversion}/RNSConversions-ScrollViewMarker.mm +2 -3
- package/ios/split/RNSSplitAppearanceApplicator.h +4 -4
- package/ios/split/RNSSplitAppearanceApplicator.mm +53 -56
- package/ios/split/RNSSplitHostComponentEventEmitter.h +1 -0
- package/ios/split/RNSSplitHostComponentEventEmitter.mm +1 -1
- package/ios/split/RNSSplitHostComponentView.h +5 -15
- package/ios/split/RNSSplitHostComponentView.mm +55 -6
- package/ios/split/RNSSplitHostController.h +25 -6
- package/ios/split/RNSSplitHostController.mm +24 -92
- package/ios/split/RNSSplitHostProviders.h +67 -0
- package/ios/split/RNSSplitScreenComponentView.h +0 -39
- package/ios/split/RNSSplitScreenComponentView.mm +27 -10
- package/ios/split/RNSSplitScreenController.h +26 -3
- package/ios/split/RNSSplitScreenController.mm +13 -30
- package/ios/split/RNSSplitScreenShadowStateProxy.h +1 -40
- package/ios/split/RNSSplitScreenShadowStateProxy.mm +1 -26
- package/ios/split/conversion/RNSConversions-SplitView.h +56 -0
- package/ios/{conversion → split/conversion}/RNSConversions-SplitView.mm +4 -1
- package/ios/stack/conversion/RNSConversions-Stack.h +62 -0
- package/ios/stack/conversion/RNSConversions-Stack.mm +134 -0
- package/ios/stack/header/RNSHeaderItemVisibilityPriority.h +9 -0
- package/ios/stack/header/RNSStackHeaderAppearanceMapper.h +26 -0
- package/ios/stack/header/RNSStackHeaderAppearanceMapper.mm +88 -0
- package/ios/stack/header/RNSStackHeaderConfigComponentView.h +14 -1
- package/ios/stack/header/RNSStackHeaderConfigComponentView.mm +103 -37
- package/ios/stack/header/RNSStackHeaderConfigDataProviding.h +11 -0
- package/ios/stack/header/RNSStackHeaderConfigShadowStateProxy.mm +1 -1
- package/ios/stack/header/RNSStackHeaderContentFactory.mm +3 -0
- package/ios/stack/header/RNSStackHeaderIconResolver.mm +7 -0
- package/ios/stack/header/RNSStackHeaderItemComponentView.h +12 -3
- package/ios/stack/header/RNSStackHeaderItemComponentView.mm +72 -5
- package/ios/stack/header/RNSStackHeaderItemDataProviding.h +7 -0
- package/ios/stack/header/RNSStackHeaderItemShadowStateProxy.mm +1 -1
- package/ios/stack/header/RNSStackHeaderItemSpacerComponentView.mm +2 -1
- package/ios/stack/header/RNSStackHeaderMenuCoordinator.h +13 -0
- package/ios/stack/header/RNSStackHeaderMenuCoordinator.mm +24 -0
- package/ios/stack/header/RNSStackHeaderMenuFinder.h +8 -1
- package/ios/stack/header/RNSStackHeaderMenuFinder.mm +26 -9
- package/ios/stack/header/RNSStackHeaderMenuMapper.mm +4 -0
- package/ios/stack/host/RNSStackNavigationBar.h +25 -0
- package/ios/stack/host/RNSStackNavigationBar.mm +80 -0
- package/ios/stack/host/RNSStackNavigationBarCoordinator.h +8 -0
- package/ios/stack/host/RNSStackNavigationBarCoordinator.mm +11 -0
- package/ios/stack/host/RNSStackNavigationController.mm +13 -5
- package/ios/stack/host/RNSStackOperation.h +0 -2
- package/ios/stack/screen/RNSStackScreenComponentView.h +2 -1
- package/ios/stack/screen/RNSStackScreenComponentView.mm +32 -2
- package/ios/stack/screen/RNSStackScreenController.mm +12 -0
- package/ios/stack/screen/RNSStackScreenHeaderCoordinator.h +8 -0
- package/ios/stack/screen/RNSStackScreenHeaderCoordinator.mm +179 -24
- package/ios/tabs/RNSTabBarAppearanceCoordinator.mm +110 -16
- package/ios/tabs/RNSTabBarItemCoordinator.h +16 -0
- package/ios/tabs/RNSTabBarItemCoordinator.mm +143 -0
- package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryComponentView.h +1 -1
- package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryComponentView.mm +1 -1
- package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryContentComponentView.mm +1 -1
- package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryEventEmitter.mm +1 -1
- package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryShadowStateProxy.mm +1 -1
- package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryWrapperView.h +24 -0
- package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryWrapperView.mm +22 -0
- package/ios/tabs/conversion/RNSConversions-Tabs.h +100 -0
- package/ios/{conversion → tabs/conversion}/RNSConversions-Tabs.mm +105 -74
- package/ios/tabs/extensions/RNSTabsHostComponentView+RNSImageLoader.h +1 -1
- package/ios/tabs/host/RNSTabBarController.h +16 -0
- package/ios/tabs/host/RNSTabBarController.mm +516 -107
- package/ios/tabs/host/RNSTabsHostComponentView.h +4 -0
- package/ios/tabs/host/RNSTabsHostComponentView.mm +41 -4
- package/ios/tabs/host/RNSTabsHostEventEmitter.mm +1 -1
- package/ios/tabs/screen/RNSTabsScreenComponentView.h +21 -0
- package/ios/tabs/screen/RNSTabsScreenComponentView.mm +56 -56
- package/ios/tabs/screen/RNSTabsScreenViewController.mm +1 -0
- package/ios/utils/RNSDefines.h +15 -7
- package/lib/commonjs/components/stack/header/StackHeaderConfig.android.js +37 -21
- package/lib/commonjs/components/stack/header/StackHeaderConfig.android.js.map +1 -1
- package/lib/commonjs/components/stack/header/StackHeaderConfig.ios.js +41 -4
- package/lib/commonjs/components/stack/header/StackHeaderConfig.ios.js.map +1 -1
- package/lib/commonjs/components/stack/header/StackHeaderConfig.js +17 -0
- package/lib/commonjs/components/stack/header/StackHeaderConfig.js.map +1 -0
- package/lib/commonjs/components/stack/header/ios/StackHeaderItem.ios.js +4 -1
- package/lib/commonjs/components/stack/header/ios/StackHeaderItem.ios.js.map +1 -1
- package/lib/commonjs/components/stack/host/StackHost.js +17 -7
- package/lib/commonjs/components/stack/host/StackHost.js.map +1 -1
- package/lib/commonjs/components/stack/host/StackHost.web.js +0 -2
- package/lib/commonjs/components/stack/host/StackHost.web.js.map +1 -1
- package/lib/commonjs/components/stack/index.js.map +1 -1
- package/lib/commonjs/components/tabs/host/TabsHost.ios.js +3 -0
- package/lib/commonjs/components/tabs/host/TabsHost.ios.js.map +1 -1
- package/lib/commonjs/components/tabs/host/{TabsHost.web.js → TabsHost.js} +1 -1
- package/lib/commonjs/components/tabs/host/TabsHost.js.map +1 -0
- package/lib/commonjs/components/tabs/index.js.map +1 -1
- package/lib/commonjs/components/tabs/screen/TabsScreen.android.js +3 -1
- package/lib/commonjs/components/tabs/screen/TabsScreen.android.js.map +1 -1
- package/lib/commonjs/components/tabs/screen/TabsScreen.ios.js +10 -1
- package/lib/commonjs/components/tabs/screen/TabsScreen.ios.js.map +1 -1
- package/lib/commonjs/components/tabs/screen/{TabsScreen.web.js → TabsScreen.js} +1 -1
- package/lib/commonjs/components/tabs/screen/TabsScreen.js.map +1 -0
- package/lib/commonjs/components/{stack/header/StackHeaderConfig.d.js → tabs/screen/TabsScreenIcon.types.js} +1 -1
- package/lib/commonjs/components/{stack/header/StackHeaderConfig.d.js.map → tabs/screen/TabsScreenIcon.types.js.map} +1 -1
- package/lib/commonjs/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/legacy/ScreenStackNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/stack/StackHeaderConfigAndroidNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/stack/StackHeaderConfigIOSNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/stack/StackHeaderItemIOSNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/stack/StackHostNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/tabs/TabsHostIOSNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/tabs/TabsScreenAndroidNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/tabs/TabsScreenIOSNativeComponent.js +1 -1
- package/lib/commonjs/fabric/tabs/TabsScreenIOSNativeComponent.js.map +1 -1
- package/lib/commonjs/legacy/components/ScreenStackItem.js +31 -11
- package/lib/commonjs/legacy/components/ScreenStackItem.js.map +1 -1
- package/lib/module/components/stack/header/StackHeaderConfig.android.js +39 -23
- package/lib/module/components/stack/header/StackHeaderConfig.android.js.map +1 -1
- package/lib/module/components/stack/header/StackHeaderConfig.ios.js +43 -6
- package/lib/module/components/stack/header/StackHeaderConfig.ios.js.map +1 -1
- package/lib/module/components/stack/header/StackHeaderConfig.js +10 -0
- package/lib/module/components/stack/header/StackHeaderConfig.js.map +1 -0
- package/lib/module/components/stack/header/ios/StackHeaderItem.ios.js +4 -1
- package/lib/module/components/stack/header/ios/StackHeaderItem.ios.js.map +1 -1
- package/lib/module/components/stack/host/StackHost.js +18 -8
- package/lib/module/components/stack/host/StackHost.js.map +1 -1
- package/lib/module/components/stack/host/StackHost.web.js +0 -3
- package/lib/module/components/stack/host/StackHost.web.js.map +1 -1
- package/lib/module/components/stack/index.js.map +1 -1
- package/lib/module/components/tabs/host/TabsHost.ios.js +3 -0
- package/lib/module/components/tabs/host/TabsHost.ios.js.map +1 -1
- package/{src/components/tabs/host/TabsHost.web.tsx → lib/module/components/tabs/host/TabsHost.js} +1 -2
- package/lib/module/components/tabs/host/TabsHost.js.map +1 -0
- package/lib/module/components/tabs/index.js.map +1 -1
- package/lib/module/components/tabs/screen/TabsScreen.android.js +3 -1
- package/lib/module/components/tabs/screen/TabsScreen.android.js.map +1 -1
- package/lib/module/components/tabs/screen/TabsScreen.ios.js +10 -1
- package/lib/module/components/tabs/screen/TabsScreen.ios.js.map +1 -1
- package/{src/components/tabs/screen/TabsScreen.web.tsx → lib/module/components/tabs/screen/TabsScreen.js} +1 -2
- package/lib/module/components/tabs/screen/TabsScreen.js.map +1 -0
- package/lib/module/components/tabs/screen/TabsScreenIcon.types.js +2 -0
- package/lib/module/components/{stack/header/StackHeaderConfig.d.js.map → tabs/screen/TabsScreenIcon.types.js.map} +1 -1
- package/lib/module/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.js.map +1 -1
- package/lib/module/fabric/legacy/ScreenStackNativeComponent.js.map +1 -1
- package/lib/module/fabric/stack/StackHeaderConfigAndroidNativeComponent.js.map +1 -1
- package/lib/module/fabric/stack/StackHeaderConfigIOSNativeComponent.js.map +1 -1
- package/lib/module/fabric/stack/StackHeaderItemIOSNativeComponent.js.map +1 -1
- package/lib/module/fabric/stack/StackHostNativeComponent.js.map +1 -1
- package/lib/module/fabric/tabs/TabsHostIOSNativeComponent.js.map +1 -1
- package/lib/module/fabric/tabs/TabsScreenAndroidNativeComponent.js.map +1 -1
- package/lib/module/fabric/tabs/TabsScreenIOSNativeComponent.js +1 -1
- package/lib/module/fabric/tabs/TabsScreenIOSNativeComponent.js.map +1 -1
- package/lib/module/legacy/components/ScreenStackItem.js +31 -11
- package/lib/module/legacy/components/ScreenStackItem.js.map +1 -1
- package/lib/typescript/components/modals/form-sheet/FormSheet.types.d.ts +1 -1
- package/lib/typescript/components/stack/header/StackHeaderConfig.android.d.ts +6 -3
- package/lib/typescript/components/stack/header/StackHeaderConfig.android.d.ts.map +1 -1
- package/lib/typescript/components/stack/header/StackHeaderConfig.android.types.d.ts +620 -24
- package/lib/typescript/components/stack/header/StackHeaderConfig.android.types.d.ts.map +1 -1
- package/lib/typescript/components/stack/header/StackHeaderConfig.d.ts +8 -0
- package/lib/typescript/components/stack/header/StackHeaderConfig.d.ts.map +1 -0
- package/lib/typescript/components/stack/header/StackHeaderConfig.ios.d.ts +6 -3
- package/lib/typescript/components/stack/header/StackHeaderConfig.ios.d.ts.map +1 -1
- package/lib/typescript/components/stack/header/StackHeaderConfig.ios.types.d.ts +361 -2
- package/lib/typescript/components/stack/header/StackHeaderConfig.ios.types.d.ts.map +1 -1
- package/lib/typescript/components/stack/header/StackHeaderConfig.types.d.ts +4 -2
- package/lib/typescript/components/stack/header/StackHeaderConfig.types.d.ts.map +1 -1
- package/lib/typescript/components/stack/header/ios/StackHeaderItem.ios.d.ts.map +1 -1
- package/lib/typescript/components/stack/header/ios/StackHeaderItem.ios.types.d.ts +7 -0
- package/lib/typescript/components/stack/header/ios/StackHeaderItem.ios.types.d.ts.map +1 -1
- package/lib/typescript/components/stack/host/StackHost.d.ts +1 -1
- package/lib/typescript/components/stack/host/StackHost.d.ts.map +1 -1
- package/lib/typescript/components/stack/host/StackHost.types.d.ts +47 -0
- package/lib/typescript/components/stack/host/StackHost.types.d.ts.map +1 -1
- package/lib/typescript/components/stack/host/StackHost.web.d.ts +1 -3
- package/lib/typescript/components/stack/host/StackHost.web.d.ts.map +1 -1
- package/lib/typescript/components/stack/index.d.ts +4 -3
- package/lib/typescript/components/stack/index.d.ts.map +1 -1
- package/lib/typescript/components/tabs/host/TabsHost.d.ts +5 -0
- package/lib/typescript/components/tabs/host/TabsHost.d.ts.map +1 -0
- package/lib/typescript/components/tabs/host/TabsHost.ios.d.ts.map +1 -1
- package/lib/typescript/components/tabs/host/TabsHost.ios.types.d.ts +72 -0
- package/lib/typescript/components/tabs/host/TabsHost.ios.types.d.ts.map +1 -1
- package/lib/typescript/components/tabs/host/TabsHost.types.d.ts +3 -0
- package/lib/typescript/components/tabs/host/TabsHost.types.d.ts.map +1 -1
- package/lib/typescript/components/tabs/index.d.ts +4 -6
- package/lib/typescript/components/tabs/index.d.ts.map +1 -1
- package/lib/typescript/components/tabs/screen/TabsScreen.android.d.ts.map +1 -1
- package/lib/typescript/components/tabs/screen/TabsScreen.android.types.d.ts +42 -7
- package/lib/typescript/components/tabs/screen/TabsScreen.android.types.d.ts.map +1 -1
- package/lib/typescript/components/tabs/screen/TabsScreen.d.ts +5 -0
- package/lib/typescript/components/tabs/screen/TabsScreen.d.ts.map +1 -0
- package/lib/typescript/components/tabs/screen/TabsScreen.ios.d.ts.map +1 -1
- package/lib/typescript/components/tabs/screen/TabsScreen.ios.types.d.ts +78 -13
- package/lib/typescript/components/tabs/screen/TabsScreen.ios.types.d.ts.map +1 -1
- package/lib/typescript/components/tabs/screen/TabsScreenIcon.types.d.ts +91 -0
- package/lib/typescript/components/tabs/screen/TabsScreenIcon.types.d.ts.map +1 -0
- package/lib/typescript/components/tabs/screen/index.d.ts +1 -0
- package/lib/typescript/components/tabs/screen/index.d.ts.map +1 -1
- package/lib/typescript/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.d.ts +2 -0
- package/lib/typescript/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/legacy/ScreenStackNativeComponent.d.ts +1 -0
- package/lib/typescript/fabric/legacy/ScreenStackNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/stack/StackHeaderConfigAndroidNativeComponent.d.ts +52 -0
- package/lib/typescript/fabric/stack/StackHeaderConfigAndroidNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/stack/StackHeaderConfigIOSNativeComponent.d.ts +29 -1
- package/lib/typescript/fabric/stack/StackHeaderConfigIOSNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/stack/StackHeaderItemIOSNativeComponent.d.ts +8 -0
- package/lib/typescript/fabric/stack/StackHeaderItemIOSNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/stack/StackHostNativeComponent.d.ts +3 -1
- package/lib/typescript/fabric/stack/StackHostNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/tabs/TabsHostIOSNativeComponent.d.ts +4 -0
- package/lib/typescript/fabric/tabs/TabsHostIOSNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/tabs/TabsScreenAndroidNativeComponent.d.ts +6 -0
- package/lib/typescript/fabric/tabs/TabsScreenAndroidNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/tabs/TabsScreenIOSNativeComponent.d.ts +10 -1
- package/lib/typescript/fabric/tabs/TabsScreenIOSNativeComponent.d.ts.map +1 -1
- package/lib/typescript/legacy/components/ScreenStackItem.d.ts +25 -0
- package/lib/typescript/legacy/components/ScreenStackItem.d.ts.map +1 -1
- package/lib/typescript/legacy/components/helpers/prepareHeaderBarButtonItems.d.ts +4 -0
- package/lib/typescript/legacy/components/helpers/prepareHeaderBarButtonItems.d.ts.map +1 -1
- package/lib/typescript/legacy/types.d.ts +30 -0
- package/lib/typescript/legacy/types.d.ts.map +1 -1
- package/package.json +11 -8
- package/react-native.config.js +3 -0
- package/src/components/modals/form-sheet/FormSheet.types.ts +1 -1
- package/src/components/stack/header/StackHeaderConfig.android.tsx +54 -43
- package/src/components/stack/header/StackHeaderConfig.android.types.ts +641 -24
- package/src/components/stack/header/StackHeaderConfig.ios.tsx +55 -17
- package/src/components/stack/header/StackHeaderConfig.ios.types.ts +384 -2
- package/src/components/stack/header/StackHeaderConfig.tsx +12 -0
- package/src/components/stack/header/StackHeaderConfig.types.ts +4 -2
- package/src/components/stack/header/ios/StackHeaderItem.ios.tsx +9 -1
- package/src/components/stack/header/ios/StackHeaderItem.ios.types.ts +7 -0
- package/src/components/stack/host/StackHost.tsx +12 -3
- package/src/components/stack/host/StackHost.types.ts +50 -0
- package/src/components/stack/host/StackHost.web.tsx +1 -4
- package/src/components/stack/index.ts +14 -1
- package/src/components/tabs/host/TabsHost.ios.tsx +3 -0
- package/src/components/tabs/host/TabsHost.ios.types.ts +76 -0
- package/src/components/tabs/host/TabsHost.tsx +7 -0
- package/src/components/tabs/host/TabsHost.types.ts +3 -0
- package/src/components/tabs/index.ts +9 -0
- package/src/components/tabs/screen/TabsScreen.android.tsx +8 -3
- package/src/components/tabs/screen/TabsScreen.android.types.ts +42 -7
- package/src/components/tabs/screen/TabsScreen.ios.tsx +22 -5
- package/src/components/tabs/screen/TabsScreen.ios.types.ts +79 -17
- package/src/components/tabs/screen/TabsScreen.tsx +7 -0
- package/src/components/tabs/screen/TabsScreenIcon.types.ts +117 -0
- package/src/components/tabs/screen/index.ts +1 -0
- package/src/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.ts +6 -0
- package/src/fabric/legacy/ScreenStackNativeComponent.ts +2 -0
- package/src/fabric/stack/StackHeaderConfigAndroidNativeComponent.ts +78 -0
- package/src/fabric/stack/StackHeaderConfigIOSNativeComponent.ts +43 -0
- package/src/fabric/stack/StackHeaderItemIOSNativeComponent.ts +13 -0
- package/src/fabric/stack/StackHostNativeComponent.ts +11 -2
- package/src/fabric/tabs/TabsHostIOSNativeComponent.ts +8 -0
- package/src/fabric/tabs/TabsScreenAndroidNativeComponent.ts +9 -0
- package/src/fabric/tabs/TabsScreenIOSNativeComponent.ts +20 -2
- package/src/legacy/components/ScreenStackItem.tsx +59 -12
- package/src/legacy/types.ts +31 -0
- package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenModalFragment.kt +0 -281
- package/android/src/main/java/com/swmansion/rnscreens/legacy/bottomsheet/BottomSheetDialogRootView.kt +0 -104
- package/android/src/main/java/com/swmansion/rnscreens/legacy/bottomsheet/BottomSheetDialogScreen.kt +0 -26
- package/android/src/main/java/com/swmansion/rnscreens/modals/dimmingview/DimmingView.kt +0 -83
- package/android/src/main/java/com/swmansion/rnscreens/modals/dimmingview/DimmingViewManager.kt +0 -89
- package/android/src/main/java/com/swmansion/rnscreens/modals/dimmingview/DimmingViewPointerEvents.kt +0 -18
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/coordinator/FormSheetDimensionsCoordinator.kt +0 -134
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/core/FormSheetDialogManager.kt +0 -162
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/model/FormSheetDetents.kt +0 -106
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/presentation/FormSheetPresentationManager.kt +0 -198
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuSelectionController.kt +0 -83
- package/ios/conversion/RNSConversions-Stack.h +0 -32
- package/ios/conversion/RNSConversions-Stack.mm +0 -41
- package/ios/conversion/always_false.h +0 -31
- package/lib/commonjs/components/stack/header/StackHeaderConfig.web.js +0 -10
- package/lib/commonjs/components/stack/header/StackHeaderConfig.web.js.map +0 -1
- package/lib/commonjs/components/tabs/host/TabsHost.d.js +0 -2
- package/lib/commonjs/components/tabs/host/TabsHost.d.js.map +0 -1
- package/lib/commonjs/components/tabs/host/TabsHost.web.js.map +0 -1
- package/lib/commonjs/components/tabs/screen/TabsScreen.d.js +0 -2
- package/lib/commonjs/components/tabs/screen/TabsScreen.d.js.map +0 -1
- package/lib/commonjs/components/tabs/screen/TabsScreen.web.js.map +0 -1
- package/lib/module/components/stack/header/StackHeaderConfig.d.js +0 -2
- package/lib/module/components/stack/header/StackHeaderConfig.web.js +0 -4
- package/lib/module/components/stack/header/StackHeaderConfig.web.js.map +0 -1
- package/lib/module/components/tabs/host/TabsHost.d.js +0 -2
- package/lib/module/components/tabs/host/TabsHost.d.js.map +0 -1
- package/lib/module/components/tabs/host/TabsHost.web.js +0 -4
- package/lib/module/components/tabs/host/TabsHost.web.js.map +0 -1
- package/lib/module/components/tabs/screen/TabsScreen.d.js +0 -2
- package/lib/module/components/tabs/screen/TabsScreen.d.js.map +0 -1
- package/lib/module/components/tabs/screen/TabsScreen.web.js +0 -4
- package/lib/module/components/tabs/screen/TabsScreen.web.js.map +0 -1
- package/lib/typescript/components/stack/header/StackHeaderConfig.web.d.ts +0 -7
- package/lib/typescript/components/stack/header/StackHeaderConfig.web.d.ts.map +0 -1
- package/lib/typescript/components/tabs/host/TabsHost.web.d.ts +0 -7
- package/lib/typescript/components/tabs/host/TabsHost.web.d.ts.map +0 -1
- package/lib/typescript/components/tabs/screen/TabsScreen.web.d.ts +0 -7
- package/lib/typescript/components/tabs/screen/TabsScreen.web.d.ts.map +0 -1
- package/src/components/stack/header/StackHeaderConfig.d.ts +0 -22
- package/src/components/stack/header/StackHeaderConfig.web.tsx +0 -5
- package/src/components/tabs/host/TabsHost.d.ts +0 -12
- package/src/components/tabs/screen/TabsScreen.d.ts +0 -12
- /package/ios/{conversion → scroll-view-marker/conversion}/RNSConversions-ScrollViewMarker.h +0 -0
package/android/src/main/java/com/swmansion/rnscreens/tabs/appearance/TabsAppearanceApplicator.kt
CHANGED
|
@@ -3,6 +3,8 @@ package com.swmansion.rnscreens.tabs.appearance
|
|
|
3
3
|
import android.annotation.SuppressLint
|
|
4
4
|
import android.content.Context
|
|
5
5
|
import android.content.res.ColorStateList
|
|
6
|
+
import android.graphics.drawable.Drawable
|
|
7
|
+
import android.graphics.drawable.InsetDrawable
|
|
6
8
|
import android.graphics.drawable.StateListDrawable
|
|
7
9
|
import android.util.TypedValue
|
|
8
10
|
import android.view.MenuItem
|
|
@@ -14,14 +16,99 @@ import com.facebook.react.common.assets.ReactFontManager
|
|
|
14
16
|
import com.facebook.react.uimanager.PixelUtil
|
|
15
17
|
import com.google.android.material.R
|
|
16
18
|
import com.google.android.material.bottomnavigation.BottomNavigationView
|
|
19
|
+
import com.google.android.material.navigation.NavigationBarItemView
|
|
17
20
|
import com.google.android.material.navigation.NavigationBarView
|
|
18
21
|
import com.swmansion.rnscreens.tabs.screen.TabsScreen
|
|
22
|
+
import com.swmansion.rnscreens.utils.dpToPx
|
|
23
|
+
import com.swmansion.rnscreens.utils.pxToDp
|
|
19
24
|
import com.swmansion.rnscreens.utils.resolveColorAttr
|
|
20
25
|
|
|
21
26
|
@SuppressLint("PrivateResource") // We want to use variables from material design for default values
|
|
22
27
|
internal class TabsAppearanceApplicator(
|
|
23
28
|
private val bottomNavigationView: BottomNavigationView,
|
|
24
29
|
) {
|
|
30
|
+
// Resolved on each access: tracks the display density of the current configuration.
|
|
31
|
+
internal val defaultIconSizeDp: Float
|
|
32
|
+
get() =
|
|
33
|
+
bottomNavigationView.pxToDp(
|
|
34
|
+
bottomNavigationView.resources.getDimension(R.dimen.mtrl_navigation_bar_item_default_icon_size),
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
internal fun effectiveIconSizeDp(tabsScreen: TabsScreen): Float =
|
|
38
|
+
tabsScreen.appearance?.tabBarItemIconSize?.takeIf { it > 0f } ?: defaultIconSizeDp
|
|
39
|
+
|
|
40
|
+
// Material allows only one icon size for all items; iconBoxDp is the largest effective per-tab size.
|
|
41
|
+
fun applyIconBox(iconBoxDp: Float) {
|
|
42
|
+
val iconBoxPx = bottomNavigationView.dpToPx(iconBoxDp).toInt()
|
|
43
|
+
if (bottomNavigationView.itemIconSize != iconBoxPx) {
|
|
44
|
+
bottomNavigationView.itemIconSize = iconBoxPx
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Resolved on each access: tracks the material library version and the display density.
|
|
49
|
+
private val defaultIndicatorWidthPx: Int
|
|
50
|
+
get() = bottomNavigationView.resources.getDimensionPixelSize(R.dimen.m3_bottom_nav_item_active_indicator_width)
|
|
51
|
+
|
|
52
|
+
private val defaultIndicatorHeightPx: Int
|
|
53
|
+
get() = bottomNavigationView.resources.getDimensionPixelSize(R.dimen.m3_bottom_nav_item_active_indicator_height)
|
|
54
|
+
|
|
55
|
+
// Auto-scale preserves the themed default padding around the icon: default indicator minus default icon size.
|
|
56
|
+
private val autoIndicatorHorizontalPaddingDp: Float
|
|
57
|
+
get() = bottomNavigationView.pxToDp(defaultIndicatorWidthPx.toFloat()) - defaultIconSizeDp
|
|
58
|
+
|
|
59
|
+
private val autoIndicatorVerticalPaddingDp: Float
|
|
60
|
+
get() = bottomNavigationView.pxToDp(defaultIndicatorHeightPx.toFloat()) - defaultIconSizeDp
|
|
61
|
+
|
|
62
|
+
internal fun effectiveIndicatorWidthDp(tabsScreen: TabsScreen): Float =
|
|
63
|
+
tabsScreen.appearance?.tabBarItemActiveIndicatorWidth?.takeIf { it > 0f }
|
|
64
|
+
?: (effectiveIconSizeDp(tabsScreen) + autoIndicatorHorizontalPaddingDp)
|
|
65
|
+
|
|
66
|
+
internal fun effectiveIndicatorHeightDp(tabsScreen: TabsScreen): Float =
|
|
67
|
+
tabsScreen.appearance?.tabBarItemActiveIndicatorHeight?.takeIf { it > 0f }
|
|
68
|
+
?: (effectiveIconSizeDp(tabsScreen) + autoIndicatorVerticalPaddingDp)
|
|
69
|
+
|
|
70
|
+
@SuppressLint("RestrictedApi")
|
|
71
|
+
private fun applyActiveIndicatorSize(
|
|
72
|
+
menuItem: MenuItem,
|
|
73
|
+
tabsScreen: TabsScreen,
|
|
74
|
+
): Boolean {
|
|
75
|
+
val widthPx = bottomNavigationView.dpToPx(effectiveIndicatorWidthDp(tabsScreen)).toInt()
|
|
76
|
+
val heightPx = bottomNavigationView.dpToPx(effectiveIndicatorHeightDp(tabsScreen)).toInt()
|
|
77
|
+
val isAlreadyApplied =
|
|
78
|
+
widthPx == (tabsScreen.appliedActiveIndicatorWidthPx ?: defaultIndicatorWidthPx) &&
|
|
79
|
+
heightPx == (tabsScreen.appliedActiveIndicatorHeightPx ?: defaultIndicatorHeightPx)
|
|
80
|
+
if (isAlreadyApplied) {
|
|
81
|
+
return true
|
|
82
|
+
}
|
|
83
|
+
val itemView =
|
|
84
|
+
bottomNavigationView.menuViewGroup.children.firstOrNull { it.id == menuItem.itemId } as? NavigationBarItemView
|
|
85
|
+
?: return false
|
|
86
|
+
// NavigationBarItemView is restricted Material API. Without it, Material only offers one active
|
|
87
|
+
// indicator size for the whole tab bar (BottomNavigationView.itemActiveIndicatorWidth/Height).
|
|
88
|
+
itemView.setActiveIndicatorWidth(widthPx)
|
|
89
|
+
itemView.setActiveIndicatorHeight(heightPx)
|
|
90
|
+
|
|
91
|
+
tabsScreen.appliedActiveIndicatorWidthPx = widthPx
|
|
92
|
+
tabsScreen.appliedActiveIndicatorHeightPx = heightPx
|
|
93
|
+
|
|
94
|
+
return true
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Inset the icon so it renders at effectiveDp, centered within iconBoxDp.
|
|
98
|
+
// Intrinsic-relative on purpose: Material FIT_CENTER-scales the drawable to the icon box,
|
|
99
|
+
// so the intrinsic factor cancels and the glyph lands at effectiveDp/iconBoxDp of the box.
|
|
100
|
+
private fun sizeIcon(
|
|
101
|
+
icon: Drawable?,
|
|
102
|
+
effectiveDp: Float,
|
|
103
|
+
iconBoxDp: Float,
|
|
104
|
+
): Drawable? {
|
|
105
|
+
if (icon == null || effectiveDp >= iconBoxDp) return icon
|
|
106
|
+
val larger = maxOf(icon.intrinsicWidth, icon.intrinsicHeight)
|
|
107
|
+
if (larger <= 0) return icon
|
|
108
|
+
val insetPx = (larger * (iconBoxDp - effectiveDp) / (2f * effectiveDp)).toInt()
|
|
109
|
+
return if (insetPx > 0) InsetDrawable(icon, insetPx) else icon
|
|
110
|
+
}
|
|
111
|
+
|
|
25
112
|
private val states =
|
|
26
113
|
arrayOf(
|
|
27
114
|
intArrayOf(-android.R.attr.state_enabled), // disabled
|
|
@@ -174,23 +261,32 @@ internal class TabsAppearanceApplicator(
|
|
|
174
261
|
fun updateMenuItemAppearance(
|
|
175
262
|
menuItem: MenuItem,
|
|
176
263
|
tabsScreen: TabsScreen,
|
|
264
|
+
iconBoxDp: Float,
|
|
177
265
|
) {
|
|
178
266
|
if (menuItem.title != tabsScreen.tabTitle) {
|
|
179
267
|
menuItem.title = tabsScreen.tabTitle
|
|
180
268
|
}
|
|
181
269
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
270
|
+
if (tabsScreen.isMenuItemIconInvalidated) {
|
|
271
|
+
tabsScreen.isMenuItemIconInvalidated = false
|
|
272
|
+
// Sized per slot: a StateListDrawable's intrinsic size follows its current state, so a
|
|
273
|
+
// single inset computed from one child would mis-size the other when their resolutions differ.
|
|
274
|
+
val effectiveDp = effectiveIconSizeDp(tabsScreen)
|
|
275
|
+
val iconDrawable = sizeIcon(tabsScreen.icon.drawable, effectiveDp, iconBoxDp)
|
|
276
|
+
val selectedIconDrawable = sizeIcon(tabsScreen.selectedIcon.drawable, effectiveDp, iconBoxDp)
|
|
277
|
+
menuItem.icon =
|
|
278
|
+
if (selectedIconDrawable != null && iconDrawable != null) {
|
|
279
|
+
StateListDrawable().apply {
|
|
280
|
+
addState(intArrayOf(android.R.attr.state_checked), selectedIconDrawable.mutate())
|
|
281
|
+
addState(intArrayOf(), iconDrawable.mutate())
|
|
282
|
+
}
|
|
283
|
+
} else {
|
|
284
|
+
iconDrawable
|
|
187
285
|
}
|
|
188
|
-
|
|
189
|
-
tabsScreen.icon
|
|
190
|
-
}
|
|
286
|
+
}
|
|
191
287
|
|
|
192
|
-
if (
|
|
193
|
-
|
|
288
|
+
if (tabsScreen.isMenuItemActiveIndicatorInvalidated && applyActiveIndicatorSize(menuItem, tabsScreen)) {
|
|
289
|
+
tabsScreen.isMenuItemActiveIndicatorInvalidated = false
|
|
194
290
|
}
|
|
195
291
|
}
|
|
196
292
|
|
package/android/src/main/java/com/swmansion/rnscreens/tabs/appearance/TabsAppearanceCoordinator.kt
CHANGED
|
@@ -4,7 +4,6 @@ import android.content.Context
|
|
|
4
4
|
import android.view.MenuItem
|
|
5
5
|
import com.google.android.material.bottomnavigation.BottomNavigationView
|
|
6
6
|
import com.swmansion.rnscreens.tabs.container.TabsContainer
|
|
7
|
-
import com.swmansion.rnscreens.tabs.container.menuItemIdForFragmentAtIndex
|
|
8
7
|
import com.swmansion.rnscreens.tabs.screen.TabsScreen
|
|
9
8
|
import com.swmansion.rnscreens.tabs.screen.TabsScreenFragment
|
|
10
9
|
|
|
@@ -14,28 +13,67 @@ internal class TabsAppearanceCoordinator(
|
|
|
14
13
|
) {
|
|
15
14
|
private val appearanceApplicator = TabsAppearanceApplicator(bottomNavigationView)
|
|
16
15
|
|
|
16
|
+
private var appliedIconBoxDp: Float? = null
|
|
17
|
+
|
|
18
|
+
// Icon box is bar-wide: the largest effective size across tabs.
|
|
19
|
+
internal fun resolveIconBoxDp(): Float {
|
|
20
|
+
if (tabsScreenFragments.isEmpty()) {
|
|
21
|
+
return appearanceApplicator.defaultIconSizeDp
|
|
22
|
+
}
|
|
23
|
+
var largestIconDp = 0f
|
|
24
|
+
var tallestIndicatorDp = 0f
|
|
25
|
+
var shortestIndicatorDp = Float.MAX_VALUE
|
|
26
|
+
tabsScreenFragments.forEach {
|
|
27
|
+
largestIconDp = maxOf(largestIconDp, appearanceApplicator.effectiveIconSizeDp(it.tabsScreen))
|
|
28
|
+
val indicatorHeightDp = appearanceApplicator.effectiveIndicatorHeightDp(it.tabsScreen)
|
|
29
|
+
tallestIndicatorDp = maxOf(tallestIndicatorDp, indicatorHeightDp)
|
|
30
|
+
shortestIndicatorDp = minOf(shortestIndicatorDp, indicatorHeightDp)
|
|
31
|
+
}
|
|
32
|
+
val unevenIndicatorsOutgrowIcons = tallestIndicatorDp > largestIconDp && tallestIndicatorDp != shortestIndicatorDp
|
|
33
|
+
return if (unevenIndicatorsOutgrowIcons) tallestIndicatorDp else largestIconDp
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
internal fun invalidateMenuItemIcons() {
|
|
37
|
+
tabsScreenFragments.forEach { it.tabsScreen.isMenuItemIconInvalidated = true }
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
internal fun invalidateRebuiltMenuItems() {
|
|
41
|
+
invalidateMenuItemIcons()
|
|
42
|
+
tabsScreenFragments.forEach {
|
|
43
|
+
it.tabsScreen.isMenuItemActiveIndicatorInvalidated = true
|
|
44
|
+
it.tabsScreen.appliedActiveIndicatorWidthPx = null
|
|
45
|
+
it.tabsScreen.appliedActiveIndicatorHeightPx = null
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
17
49
|
fun updateTabAppearance(
|
|
18
50
|
context: Context,
|
|
19
51
|
tabsContainer: TabsContainer,
|
|
20
52
|
) {
|
|
21
53
|
val selectedTabAppearance = tabsContainer.selectedTab.tabsScreen.appearance
|
|
54
|
+
val iconBoxDp = resolveIconBoxDp()
|
|
55
|
+
if (iconBoxDp != appliedIconBoxDp) {
|
|
56
|
+
appliedIconBoxDp = iconBoxDp
|
|
57
|
+
invalidateMenuItemIcons()
|
|
58
|
+
}
|
|
59
|
+
appearanceApplicator.applyIconBox(iconBoxDp)
|
|
22
60
|
appearanceApplicator.updateSharedAppearance(context, selectedTabAppearance, tabsContainer.tabBarHidden)
|
|
23
|
-
updateMenuItems(context, selectedTabAppearance)
|
|
61
|
+
updateMenuItems(context, selectedTabAppearance, iconBoxDp)
|
|
24
62
|
appearanceApplicator.updateFontStyles(context, selectedTabAppearance) // It needs to be updated after updateMenuItems
|
|
25
63
|
}
|
|
26
64
|
|
|
27
65
|
private fun updateMenuItems(
|
|
28
66
|
context: Context,
|
|
29
67
|
tabsAppearance: TabsAppearance?,
|
|
68
|
+
iconBoxDp: Float,
|
|
30
69
|
) {
|
|
31
|
-
tabsScreenFragments.
|
|
32
|
-
val menuItemId =
|
|
70
|
+
tabsScreenFragments.forEach { fragment ->
|
|
71
|
+
val menuItemId = fragment.menuItemId
|
|
33
72
|
val menuItem =
|
|
34
73
|
checkNotNull(bottomNavigationView.menu.findItem(menuItemId)) {
|
|
35
74
|
"[RNScreens] Missing MenuItem for id: $menuItemId"
|
|
36
75
|
}
|
|
37
|
-
|
|
38
|
-
updateMenuItemAppearance(context, menuItem, fragment.tabsScreen, tabsAppearance)
|
|
76
|
+
updateMenuItemAppearance(context, menuItem, fragment.tabsScreen, tabsAppearance, iconBoxDp)
|
|
39
77
|
}
|
|
40
78
|
}
|
|
41
79
|
|
|
@@ -44,8 +82,9 @@ internal class TabsAppearanceCoordinator(
|
|
|
44
82
|
menuItem: MenuItem,
|
|
45
83
|
tabsScreen: TabsScreen,
|
|
46
84
|
appearance: TabsAppearance?,
|
|
85
|
+
iconBoxDp: Float,
|
|
47
86
|
) {
|
|
48
|
-
appearanceApplicator.updateMenuItemAppearance(menuItem, tabsScreen)
|
|
87
|
+
appearanceApplicator.updateMenuItemAppearance(menuItem, tabsScreen, iconBoxDp)
|
|
49
88
|
appearanceApplicator.updateBadgeAppearance(context, menuItem, tabsScreen, appearance)
|
|
50
89
|
}
|
|
51
90
|
}
|
package/android/src/main/java/com/swmansion/rnscreens/tabs/appearance/TabsAppearanceModel.kt
CHANGED
|
@@ -8,8 +8,11 @@ internal data class TabsAppearance(
|
|
|
8
8
|
val selected: ItemStateAppearance? = null,
|
|
9
9
|
val focused: ItemStateAppearance? = null,
|
|
10
10
|
val disabled: ItemStateAppearance? = null,
|
|
11
|
+
val tabBarItemIconSize: Float? = null,
|
|
11
12
|
val tabBarItemActiveIndicatorColor: Int? = null,
|
|
12
13
|
val tabBarItemActiveIndicatorEnabled: Boolean? = null,
|
|
14
|
+
val tabBarItemActiveIndicatorWidth: Float? = null,
|
|
15
|
+
val tabBarItemActiveIndicatorHeight: Float? = null,
|
|
13
16
|
val tabBarItemTitleFontFamily: String? = null,
|
|
14
17
|
val tabBarItemTitleSmallLabelFontSize: Float? = null,
|
|
15
18
|
val tabBarItemTitleLargeLabelFontSize: Float? = null,
|
package/android/src/main/java/com/swmansion/rnscreens/tabs/container/CustomBottomNavigationView.kt
CHANGED
|
@@ -2,15 +2,35 @@ package com.swmansion.rnscreens.tabs.container
|
|
|
2
2
|
|
|
3
3
|
import android.annotation.SuppressLint
|
|
4
4
|
import android.content.Context
|
|
5
|
+
import androidx.core.view.isVisible
|
|
6
|
+
import com.facebook.react.uimanager.PointerEvents
|
|
7
|
+
import com.facebook.react.uimanager.ReactPointerEventsView
|
|
5
8
|
import com.google.android.material.bottomnavigation.BottomNavigationView
|
|
6
9
|
|
|
7
10
|
@SuppressLint("ViewConstructor") // Should not be restored & should only be constructed by us.
|
|
8
11
|
class CustomBottomNavigationView(
|
|
9
12
|
context: Context,
|
|
10
13
|
val container: TabsContainer,
|
|
11
|
-
) : BottomNavigationView(context)
|
|
14
|
+
) : BottomNavigationView(context),
|
|
15
|
+
ReactPointerEventsView {
|
|
12
16
|
private var actionOrigin: TabsActionOrigin? = null
|
|
13
17
|
|
|
18
|
+
/**
|
|
19
|
+
* The tab bar is hidden by setting its visibility to `GONE`. A `GONE` view is skipped by its
|
|
20
|
+
* parent's layout pass, so it keeps the bounds it was last laid out with, and Android's own
|
|
21
|
+
* touch dispatch ignores it (`ViewGroup.canViewReceivePointerEvents` requires `VISIBLE`).
|
|
22
|
+
*
|
|
23
|
+
* React Native does not go through Android's dispatch to pick a touch target - it runs its own
|
|
24
|
+
* hit-test over the native view tree in `TouchTargetHelper`, which only checks bounds. The
|
|
25
|
+
* retained bounds of the hidden bar therefore keep capturing every touch aimed at the content
|
|
26
|
+
* laid out underneath it. Declaring [PointerEvents.NONE] while hidden is how a native view opts
|
|
27
|
+
* out of that hit-test, which brings it back in line with Android's dispatch.
|
|
28
|
+
*
|
|
29
|
+
* See https://github.com/software-mansion/react-native-screens/issues/4132.
|
|
30
|
+
*/
|
|
31
|
+
override val pointerEvents: PointerEvents
|
|
32
|
+
get() = if (isVisible) PointerEvents.AUTO else PointerEvents.NONE
|
|
33
|
+
|
|
14
34
|
internal fun setSelectedItemIdWithActionOrigin(
|
|
15
35
|
itemId: Int,
|
|
16
36
|
actionOrigin: TabsActionOrigin,
|
|
@@ -2,30 +2,12 @@ package com.swmansion.rnscreens.tabs.container
|
|
|
2
2
|
|
|
3
3
|
import android.view.Menu
|
|
4
4
|
import android.view.MenuItem
|
|
5
|
-
import com.swmansion.rnscreens.tabs.screen.
|
|
5
|
+
import com.swmansion.rnscreens.tabs.screen.TabsScreenFragment
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Compute MenuItem id for a fragment at given index in "tabsModel" of TabsContainer
|
|
11
|
-
*/
|
|
12
|
-
internal fun menuItemIdForFragmentAtIndex(fragmentIndex: Int): Int = fragmentIndex + 1
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Compute fragment index in "tabsModel" of TabsContainer for a MenuItem with given id.
|
|
16
|
-
*/
|
|
17
|
-
internal fun fragmentIndexForMenuItemId(menuItemId: Int): Int {
|
|
18
|
-
check(menuItemId >= 1) { "[RNScreens] MenuItem id must not be less than 1" }
|
|
19
|
-
return menuItemId - 1
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
internal fun Menu.getOrCreateMenuItemForFragmentAt(
|
|
23
|
-
index: Int,
|
|
24
|
-
tabsScreen: TabsScreen,
|
|
25
|
-
): MenuItem =
|
|
26
|
-
this.findItem(menuItemIdForFragmentAtIndex(index)) ?: this.add(
|
|
7
|
+
internal fun Menu.getOrCreateMenuItemForFragment(fragment: TabsScreenFragment): MenuItem =
|
|
8
|
+
this.findItem(fragment.menuItemId) ?: this.add(
|
|
27
9
|
Menu.NONE,
|
|
28
|
-
|
|
10
|
+
fragment.menuItemId,
|
|
29
11
|
Menu.NONE,
|
|
30
|
-
tabsScreen.tabTitle,
|
|
12
|
+
fragment.tabsScreen.tabTitle,
|
|
31
13
|
)
|
|
@@ -24,14 +24,13 @@ import com.swmansion.rnscreens.common.colorscheme.ColorSchemeCoordinator
|
|
|
24
24
|
import com.swmansion.rnscreens.common.colorscheme.ColorSchemeListener
|
|
25
25
|
import com.swmansion.rnscreens.common.colorscheme.ColorSchemeProviding
|
|
26
26
|
import com.swmansion.rnscreens.common.container.Container
|
|
27
|
+
import com.swmansion.rnscreens.common.container.ContainerItem
|
|
27
28
|
import com.swmansion.rnscreens.common.container.ParentContainerItemRegistry
|
|
28
|
-
import com.swmansion.rnscreens.
|
|
29
|
-
import com.swmansion.rnscreens.helpers.ViewFinder
|
|
29
|
+
import com.swmansion.rnscreens.ext.createTransactionWithReordering
|
|
30
30
|
import com.swmansion.rnscreens.helpers.ViewIdGenerator
|
|
31
|
-
import com.swmansion.rnscreens.helpers.createTransactionWithReordering
|
|
32
31
|
import com.swmansion.rnscreens.safearea.EdgeInsets
|
|
32
|
+
import com.swmansion.rnscreens.safearea.OnInterfaceInsetsChangeListener
|
|
33
33
|
import com.swmansion.rnscreens.safearea.SafeAreaProvider
|
|
34
|
-
import com.swmansion.rnscreens.safearea.SafeAreaView
|
|
35
34
|
import com.swmansion.rnscreens.tabs.appearance.TabsAppearanceCoordinator
|
|
36
35
|
import com.swmansion.rnscreens.tabs.host.TabsHost
|
|
37
36
|
import com.swmansion.rnscreens.tabs.host.TabsHostA11yCoordinator
|
|
@@ -39,6 +38,7 @@ import com.swmansion.rnscreens.tabs.screen.TabsScreen
|
|
|
39
38
|
import com.swmansion.rnscreens.tabs.screen.TabsScreenDelegate
|
|
40
39
|
import com.swmansion.rnscreens.tabs.screen.TabsScreenFragment
|
|
41
40
|
import com.swmansion.rnscreens.utils.RNSLog
|
|
41
|
+
import java.lang.ref.WeakReference
|
|
42
42
|
import kotlin.properties.Delegates
|
|
43
43
|
|
|
44
44
|
/**
|
|
@@ -52,6 +52,7 @@ import kotlin.properties.Delegates
|
|
|
52
52
|
@SuppressLint("ViewConstructor") // Created only by us. Should never be restored.
|
|
53
53
|
class TabsContainer internal constructor(
|
|
54
54
|
private val context: Context,
|
|
55
|
+
private val delegate: WeakReference<TabsContainerDelegate>,
|
|
55
56
|
) : FrameLayout(context),
|
|
56
57
|
Container,
|
|
57
58
|
ColorSchemeProviding,
|
|
@@ -67,8 +68,7 @@ class TabsContainer internal constructor(
|
|
|
67
68
|
val selectedTabScreen = this@TabsContainer.selectedTab.tabsScreen
|
|
68
69
|
|
|
69
70
|
if (selectedTabScreen.shouldUseRepeatedTabSelectionPopToRootSpecialEffect) {
|
|
70
|
-
|
|
71
|
-
if (screenStack != null && screenStack.popToRoot()) {
|
|
71
|
+
if (selectedTabScreen.resolveNestedContainer()?.requestPopToRoot() == true) {
|
|
72
72
|
return true
|
|
73
73
|
}
|
|
74
74
|
}
|
|
@@ -160,7 +160,7 @@ class TabsContainer internal constructor(
|
|
|
160
160
|
|
|
161
161
|
private val a11yCoordinator = TabsHostA11yCoordinator(bottomNavigationView, tabsModel)
|
|
162
162
|
|
|
163
|
-
private var interfaceInsetsChangeListener:
|
|
163
|
+
private var interfaceInsetsChangeListener: OnInterfaceInsetsChangeListener? = null
|
|
164
164
|
|
|
165
165
|
internal var tabBarHidden: Boolean by Delegates.observable(false) { _, oldValue, newValue ->
|
|
166
166
|
if (newValue != oldValue) {
|
|
@@ -255,9 +255,9 @@ class TabsContainer internal constructor(
|
|
|
255
255
|
|
|
256
256
|
internal fun setupFragmentManager() {
|
|
257
257
|
fragmentManager =
|
|
258
|
-
checkNotNull(
|
|
259
|
-
"[RNScreens]
|
|
260
|
-
}
|
|
258
|
+
checkNotNull(delegate.get()) {
|
|
259
|
+
"[RNScreens] TabsContainer has no delegate to resolve the fragment manager from"
|
|
260
|
+
}.resolveFragmentManager()
|
|
261
261
|
}
|
|
262
262
|
|
|
263
263
|
internal fun teardownFragmentManager() {
|
|
@@ -372,14 +372,14 @@ class TabsContainer internal constructor(
|
|
|
372
372
|
}
|
|
373
373
|
}
|
|
374
374
|
|
|
375
|
-
override fun setOnInterfaceInsetsChangeListener(listener:
|
|
375
|
+
override fun setOnInterfaceInsetsChangeListener(listener: OnInterfaceInsetsChangeListener) {
|
|
376
376
|
if (interfaceInsetsChangeListener == null) {
|
|
377
377
|
bottomNavigationView.addOnLayoutChangeListener(this)
|
|
378
378
|
}
|
|
379
379
|
interfaceInsetsChangeListener = listener
|
|
380
380
|
}
|
|
381
381
|
|
|
382
|
-
override fun removeOnInterfaceInsetsChangeListener(listener:
|
|
382
|
+
override fun removeOnInterfaceInsetsChangeListener(listener: OnInterfaceInsetsChangeListener) {
|
|
383
383
|
if (interfaceInsetsChangeListener == listener) {
|
|
384
384
|
interfaceInsetsChangeListener = null
|
|
385
385
|
bottomNavigationView.removeOnLayoutChangeListener(this)
|
|
@@ -415,11 +415,23 @@ class TabsContainer internal constructor(
|
|
|
415
415
|
menuItem,
|
|
416
416
|
tabsScreen,
|
|
417
417
|
appearance,
|
|
418
|
+
appearanceCoordinator.resolveIconBoxDp(),
|
|
418
419
|
)
|
|
419
420
|
a11yCoordinator.setA11yPropertiesToTabItem(menuItem, tabsScreen)
|
|
420
421
|
}
|
|
421
422
|
}
|
|
422
423
|
|
|
424
|
+
override fun onItemSizeChange(tabsScreen: TabsScreen) {
|
|
425
|
+
// Icon box is bar-wide, so this must run even when the changed tab is not selected.
|
|
426
|
+
// Skip when detached; reattachment reapplies the full appearance anyway.
|
|
427
|
+
if (isAttachedToWindow) {
|
|
428
|
+
invalidationFlags.isNavigationMenuAppearanceInvalidated = true
|
|
429
|
+
post {
|
|
430
|
+
this.flushPendingUpdates()
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
423
435
|
override fun getFragmentForTabsScreen(tabsScreen: TabsScreen): TabsScreenFragment? =
|
|
424
436
|
tabsModel.find {
|
|
425
437
|
it.tabsScreen ===
|
|
@@ -492,7 +504,10 @@ class TabsContainer internal constructor(
|
|
|
492
504
|
|
|
493
505
|
private fun performSelectedTabUpdate() {
|
|
494
506
|
if (pendingStateUpdateRequest == null) {
|
|
495
|
-
RNSLog.w(
|
|
507
|
+
RNSLog.w(
|
|
508
|
+
TAG,
|
|
509
|
+
"TabsContainer::performSelectedTabUpdate called w/o pending operation; skipping update",
|
|
510
|
+
)
|
|
496
511
|
return
|
|
497
512
|
}
|
|
498
513
|
|
|
@@ -516,7 +531,10 @@ class TabsContainer internal constructor(
|
|
|
516
531
|
if (bottomNavigationView.selectedItemId != nextSelectedMenuItemId || navState.isEmpty()) {
|
|
517
532
|
isInExternalOperationContext = true
|
|
518
533
|
// This triggers on OnMenuItemClicked callback, where we perform actual update from
|
|
519
|
-
bottomNavigationView.setSelectedItemIdWithActionOrigin(
|
|
534
|
+
bottomNavigationView.setSelectedItemIdWithActionOrigin(
|
|
535
|
+
nextSelectedMenuItemId,
|
|
536
|
+
stateUpdateRequest.actionOrigin,
|
|
537
|
+
)
|
|
520
538
|
isInExternalOperationContext = false
|
|
521
539
|
} else {
|
|
522
540
|
observerRegistry.emitOnNavigationStateUpdateRejected(
|
|
@@ -530,18 +548,21 @@ class TabsContainer internal constructor(
|
|
|
530
548
|
}
|
|
531
549
|
|
|
532
550
|
private fun updateNavigationMenuStructure() {
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
551
|
+
val menu = bottomNavigationView.menu
|
|
552
|
+
val isMenuInSync =
|
|
553
|
+
menu.size == tabsModel.size &&
|
|
554
|
+
tabsModel.withIndex().all { (index, fragment) ->
|
|
555
|
+
menu.getItem(index).itemId == fragment.menuItemId
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
if (isMenuInSync) {
|
|
559
|
+
return
|
|
560
|
+
}
|
|
561
|
+
menu.clear()
|
|
562
|
+
tabsModel.forEach { fragment ->
|
|
563
|
+
menu.getOrCreateMenuItemForFragment(fragment)
|
|
544
564
|
}
|
|
565
|
+
appearanceCoordinator.invalidateRebuiltMenuItems()
|
|
545
566
|
}
|
|
546
567
|
|
|
547
568
|
private fun updateBottomNavigationViewAppearance() {
|
|
@@ -573,7 +594,10 @@ class TabsContainer internal constructor(
|
|
|
573
594
|
}
|
|
574
595
|
|
|
575
596
|
progressNavigationState(nextSelectedFragment.requireScreenKey, actionOrigin)
|
|
576
|
-
applyNextSelectedFragmentToFragmentManagerSync(
|
|
597
|
+
applyNextSelectedFragmentToFragmentManagerSync(
|
|
598
|
+
currentSelectedFragment,
|
|
599
|
+
nextSelectedFragment,
|
|
600
|
+
)
|
|
577
601
|
return true
|
|
578
602
|
}
|
|
579
603
|
|
|
@@ -643,7 +667,8 @@ class TabsContainer internal constructor(
|
|
|
643
667
|
return false
|
|
644
668
|
}
|
|
645
669
|
|
|
646
|
-
val stateChanged =
|
|
670
|
+
val stateChanged =
|
|
671
|
+
updateNavigationStateAndSelectedFragment(nextSelectedFragment, actionOrigin)
|
|
647
672
|
|
|
648
673
|
val hasTriggeredSpecialEffect =
|
|
649
674
|
if (isRepeated) specialEffectsHandler.handleRepeatedTabSelection() else false
|
|
@@ -688,7 +713,8 @@ class TabsContainer internal constructor(
|
|
|
688
713
|
|
|
689
714
|
// We expect at most a single fragment added (detached fragments are not returned from
|
|
690
715
|
// FragmentManager.getFragments call) and it being the currently selected tab.
|
|
691
|
-
val isInUpToDateState =
|
|
716
|
+
val isInUpToDateState =
|
|
717
|
+
currentFragments.size == 1 && currentFragments.first() === selectedTab
|
|
692
718
|
if (isInUpToDateState) {
|
|
693
719
|
return
|
|
694
720
|
} else if (currentFragments.isEmpty()) {
|
|
@@ -717,12 +743,10 @@ class TabsContainer internal constructor(
|
|
|
717
743
|
appearanceCoordinator.updateTabAppearance(themedContext, this)
|
|
718
744
|
}
|
|
719
745
|
|
|
720
|
-
private fun getFragmentForMenuItemId(itemId: Int): TabsScreenFragment? = tabsModel.
|
|
746
|
+
private fun getFragmentForMenuItemId(itemId: Int): TabsScreenFragment? = tabsModel.find { it.menuItemId == itemId }
|
|
721
747
|
|
|
722
748
|
private fun getMenuItemIdForFragment(tabsScreenFragment: TabsScreenFragment): Int? =
|
|
723
|
-
tabsModel.
|
|
724
|
-
menuItemIdForFragmentAtIndex(it)
|
|
725
|
-
}
|
|
749
|
+
tabsScreenFragment.menuItemId.takeIf { tabsModel.any { it === tabsScreenFragment } }
|
|
726
750
|
|
|
727
751
|
private fun getSelectedTabsScreenFragmentId(): Int? =
|
|
728
752
|
tabsModel
|
|
@@ -731,10 +755,9 @@ class TabsContainer internal constructor(
|
|
|
731
755
|
|
|
732
756
|
private fun getMenuItemForTabsScreen(tabsScreen: TabsScreen): MenuItem? =
|
|
733
757
|
tabsModel
|
|
734
|
-
.
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
bottomNavigationView.menu.findItem(menuItemIdForFragmentAtIndex(index))
|
|
758
|
+
.find { it.tabsScreen === tabsScreen }
|
|
759
|
+
?.let { fragment ->
|
|
760
|
+
bottomNavigationView.menu.findItem(fragment.menuItemId)
|
|
738
761
|
}
|
|
739
762
|
|
|
740
763
|
private fun getFragmentForScreenKey(screenKey: String): TabsScreenFragment? = tabsModel.find { it.requireScreenKey == screenKey }
|
|
@@ -780,6 +803,19 @@ class TabsContainer internal constructor(
|
|
|
780
803
|
return selectedTab.tabsScreen.findContentScrollView()
|
|
781
804
|
}
|
|
782
805
|
|
|
806
|
+
// Only the active item is consulted - a preventing screen inside an inactive tab
|
|
807
|
+
// does not veto the dismissal.
|
|
808
|
+
override fun wantsToPreventStackNativeDismiss(): ContainerItem? =
|
|
809
|
+
if (navState.isNotEmpty()) {
|
|
810
|
+
selectedTab.tabsScreen.wantsToPreventStackNativeDismiss()
|
|
811
|
+
} else {
|
|
812
|
+
null
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
// Tabs have no stack of their own - the request goes to the selected tab's nested container.
|
|
816
|
+
override fun requestPopToRoot(): Boolean =
|
|
817
|
+
navState.isNotEmpty() && selectedTab.tabsScreen.resolveNestedContainer()?.requestPopToRoot() == true
|
|
818
|
+
|
|
783
819
|
// endregion
|
|
784
820
|
|
|
785
821
|
companion object {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
package com.swmansion.rnscreens.tabs.container
|
|
2
|
+
|
|
3
|
+
import androidx.fragment.app.FragmentManager
|
|
4
|
+
|
|
5
|
+
internal interface TabsContainerDelegate {
|
|
6
|
+
/**
|
|
7
|
+
* Resolves the fragment manager the container should run its operations on. Called every time the container
|
|
8
|
+
* is attached to a window, as the result may differ between attachments.
|
|
9
|
+
*/
|
|
10
|
+
fun resolveFragmentManager(): FragmentManager
|
|
11
|
+
}
|
|
@@ -4,21 +4,25 @@ import android.annotation.SuppressLint
|
|
|
4
4
|
import android.view.ViewTreeObserver
|
|
5
5
|
import android.widget.FrameLayout
|
|
6
6
|
import androidx.core.graphics.drawable.toDrawable
|
|
7
|
+
import androidx.fragment.app.FragmentManager
|
|
7
8
|
import com.facebook.react.bridge.UIManager
|
|
8
9
|
import com.facebook.react.bridge.UIManagerListener
|
|
9
10
|
import com.facebook.react.common.annotations.UnstableReactNativeAPI
|
|
10
11
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
11
12
|
import com.facebook.react.uimanager.UIManagerHelper
|
|
12
13
|
import com.swmansion.rnscreens.common.colorscheme.ColorScheme
|
|
14
|
+
import com.swmansion.rnscreens.helpers.FragmentManagerHelper
|
|
13
15
|
import com.swmansion.rnscreens.helpers.getFabricUIManagerNotNull
|
|
14
16
|
import com.swmansion.rnscreens.tabs.container.TabsActionOrigin
|
|
15
17
|
import com.swmansion.rnscreens.tabs.container.TabsContainer
|
|
18
|
+
import com.swmansion.rnscreens.tabs.container.TabsContainerDelegate
|
|
16
19
|
import com.swmansion.rnscreens.tabs.container.TabsNavigationState
|
|
17
20
|
import com.swmansion.rnscreens.tabs.container.TabsNavigationStateObserver
|
|
18
21
|
import com.swmansion.rnscreens.tabs.container.TabsNavigationStateRejectionReason
|
|
19
22
|
import com.swmansion.rnscreens.tabs.container.TabsNavigationStateUpdateRequest
|
|
20
23
|
import com.swmansion.rnscreens.tabs.screen.TabsScreen
|
|
21
24
|
import com.swmansion.rnscreens.utils.RNSLog
|
|
25
|
+
import java.lang.ref.WeakReference
|
|
22
26
|
import kotlin.properties.Delegates
|
|
23
27
|
|
|
24
28
|
@SuppressLint("ViewConstructor") // Only created by us. Should never be restored
|
|
@@ -28,7 +32,8 @@ class TabsHost(
|
|
|
28
32
|
) : FrameLayout(reactContext),
|
|
29
33
|
TabsNavigationStateObserver,
|
|
30
34
|
ViewTreeObserver.OnPreDrawListener,
|
|
31
|
-
UIManagerListener
|
|
35
|
+
UIManagerListener,
|
|
36
|
+
TabsContainerDelegate {
|
|
32
37
|
private val renderedScreens: ArrayList<TabsScreen> = arrayListOf()
|
|
33
38
|
private var jsNavStateRequest: TabsNavigationStateUpdateRequest? = null
|
|
34
39
|
private val layoutCoordinator: TabsHostLayoutCoordinator =
|
|
@@ -37,7 +42,7 @@ class TabsHost(
|
|
|
37
42
|
private var hasFirstLayoutWithInsets: Boolean = false
|
|
38
43
|
|
|
39
44
|
private val container: TabsContainer =
|
|
40
|
-
TabsContainer(reactContext).apply {
|
|
45
|
+
TabsContainer(reactContext, WeakReference(this)).apply {
|
|
41
46
|
layoutParams =
|
|
42
47
|
LayoutParams(
|
|
43
48
|
LayoutParams.MATCH_PARENT,
|
|
@@ -82,6 +87,11 @@ class TabsHost(
|
|
|
82
87
|
super.onDetachedFromWindow()
|
|
83
88
|
}
|
|
84
89
|
|
|
90
|
+
override fun resolveFragmentManager(): FragmentManager =
|
|
91
|
+
checkNotNull(FragmentManagerHelper.findFragmentManagerForView(this)) {
|
|
92
|
+
"[RNScreens] Nullish fragment manager - can't run container operations"
|
|
93
|
+
}
|
|
94
|
+
|
|
85
95
|
internal fun mountReactSubviewAt(
|
|
86
96
|
tabsScreen: TabsScreen,
|
|
87
97
|
index: Int,
|
|
@@ -161,6 +171,16 @@ class TabsHost(
|
|
|
161
171
|
refreshLayout()
|
|
162
172
|
}
|
|
163
173
|
|
|
174
|
+
// On window configuration changes ViewRootImpl calls forceLayout() recursively on every view
|
|
175
|
+
// in the hierarchy, bypassing requestLayout(). React views never lay out their children during
|
|
176
|
+
// framework traversals, so nothing would clear the force-layout flags in our subtree — and once
|
|
177
|
+
// they are set, any subsequent requestLayout() from a descendant short-circuits before reaching
|
|
178
|
+
// the override above, permanently disabling the manual pass. Schedule it from here as well.
|
|
179
|
+
override fun forceLayout() {
|
|
180
|
+
super.forceLayout()
|
|
181
|
+
refreshLayout()
|
|
182
|
+
}
|
|
183
|
+
|
|
164
184
|
private fun forceSubtreeMeasureAndLayoutPass() {
|
|
165
185
|
measure(
|
|
166
186
|
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
|