react-native-screens 5.0.0-alpha.1 → 5.0.0-alpha.2
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/README.md +1 -2
- package/RNScreens.podspec +2 -6
- package/android/build.gradle +26 -1
- package/android/src/fabric/java/com/swmansion/rnscreens/NativeProxy.kt +5 -0
- package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +2 -2
- package/android/src/main/java/com/swmansion/rnscreens/legacy/Screen.kt +22 -6
- package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenStackFragment.kt +39 -10
- package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenViewManager.kt +5 -0
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetAppearanceCoordinator.kt → native/coordinator/FormSheetAppearanceCoordinator.kt} +2 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetBehaviorController.kt → native/coordinator/FormSheetBehaviorController.kt} +25 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetDimensionsCoordinator.kt → native/coordinator/FormSheetDimensionsCoordinator.kt} +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/coordinator/FormSheetNativeDismissCoordinator.kt +50 -0
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetContainer.kt → native/core/FormSheetContainer.kt} +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetDialog.kt → native/core/FormSheetDialog.kt} +24 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetDialogManager.kt → native/core/FormSheetDialogManager.kt} +25 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetContentSizeChangeDelegate.kt → native/interfaces/FormSheetContentSizeChangeDelegate.kt} +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetContentSizeChangeProvider.kt → native/interfaces/FormSheetContentSizeChangeProvider.kt} +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetDialogEventEmitter.kt → native/interfaces/FormSheetDialogEventEmitter.kt} +3 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetConfig.kt → native/model/FormSheetConfig.kt} +5 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetDetents.kt → native/model/FormSheetDetents.kt} +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetAnimatorFactory.kt → native/presentation/FormSheetAnimatorFactory.kt} +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetPresentationManager.kt → native/presentation/FormSheetPresentationManager.kt} +3 -12
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetPresentationState.kt → native/presentation/FormSheetPresentationState.kt} +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetContentWrapper.kt → react/contentwrapper/FormSheetContentWrapper.kt} +3 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetContentWrapperViewManager.kt → react/contentwrapper/FormSheetContentWrapperViewManager.kt} +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetDetentChangedEvent.kt → react/event/FormSheetDetentChangedEvent.kt} +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetDidAppearEvent.kt → react/event/FormSheetDidAppearEvent.kt} +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetDidDisappearEvent.kt → react/event/FormSheetDidDisappearEvent.kt} +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetNativeDismissEvent.kt → react/event/FormSheetNativeDismissEvent.kt} +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/react/event/FormSheetNativeDismissPreventedEvent.kt +29 -0
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetSyncFlushEvent.kt → react/event/FormSheetSyncFlushEvent.kt} +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetWillAppearEvent.kt → react/event/FormSheetWillAppearEvent.kt} +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetWillDisappearEvent.kt → react/event/FormSheetWillDisappearEvent.kt} +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetContentView.kt → react/host/FormSheetContentView.kt} +3 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetHost.kt → react/host/FormSheetHost.kt} +6 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetHostEventEmitter.kt → react/host/FormSheetHostEventEmitter.kt} +16 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/{FormSheetHostViewManager.kt → react/host/FormSheetHostViewManager.kt} +11 -2
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderApplicator.kt +30 -418
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderCoordinatorLayout.kt +36 -113
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderFrameSynchronizer.kt +63 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/{StackHeaderAppBarLayout.kt → appbar/StackHeaderAppBarLayout.kt} +1 -6
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/{StackHeaderAppBarLayoutBehavior.kt → appbar/StackHeaderAppBarLayoutBehavior.kt} +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/{StackHeaderScrollingViewBehavior.kt → appbar/StackHeaderScrollingViewBehavior.kt} +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfig.kt +28 -6
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigViewManager.kt +8 -1
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigurationObserver.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigurationProviding.kt +2 -1
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderInvalidationFlags.kt +2 -1
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuApplicator.kt +448 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuMapper.kt +17 -3
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuSelectionController.kt +83 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/{StackHeaderToolbarMenuConfig.kt → model/StackHeaderToolbarMenuConfig.kt} +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/{StackHeaderToolbarMenuElementConfig.kt → model/StackHeaderToolbarMenuElementConfig.kt} +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/{StackHeaderToolbarMenuGroupConfig.kt → model/StackHeaderToolbarMenuGroupConfig.kt} +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/{StackHeaderToolbarMenuGroupMetadata.kt → model/StackHeaderToolbarMenuGroupMetadata.kt} +5 -1
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/{StackHeaderToolbarMenuItemConfig.kt → model/StackHeaderToolbarMenuItemConfig.kt} +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/{StackHeaderToolbarMenuItemDefaults.kt → model/StackHeaderToolbarMenuItemDefaults.kt} +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/{StackHeaderToolbarMenuItemIconSource.kt → model/StackHeaderToolbarMenuItemIconSource.kt} +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/{StackHeaderToolbarMenuItemShowAsAction.kt → model/StackHeaderToolbarMenuItemShowAsAction.kt} +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/{StackHeaderToolbarMenuItemType.kt → model/StackHeaderToolbarMenuItemType.kt} +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/{StackHeaderToolbarFieldUpdate.kt → update/StackHeaderToolbarFieldUpdate.kt} +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/{StackHeaderToolbarMenuElementOptions.kt → update/StackHeaderToolbarMenuElementOptions.kt} +2 -1
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuElementRawUpdate.kt +13 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuElementUpdate.kt +10 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuIconResolver.kt +17 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/{StackHeaderToolbarMenuUpdateQueue.kt → update/StackHeaderToolbarMenuUpdateQueue.kt} +1 -43
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuUpdateQueueDelegate.kt +9 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/screen/StackScreen.kt +1 -0
- package/common/cpp/react/renderer/components/rnscreens/legacy/RNSScreenShadowNode.cpp +10 -5
- package/ios/RNSEnums.h +0 -2
- package/ios/RNSOrientationProviding.h +0 -2
- package/ios/RNSReactMountingTransactionObserving.h +15 -0
- package/ios/legacy/RNSBarButtonItem.mm +12 -5
- package/ios/legacy/RNSScreen.h +8 -1
- package/ios/legacy/RNSScreen.mm +39 -17
- package/ios/legacy/RNSScreenContentWrapper.mm +9 -0
- package/ios/legacy/RNSScreenFooter.mm +2 -0
- package/ios/legacy/RNSScreenStack.mm +9 -4
- package/ios/modals/form-sheet/RNSFormSheetContentWrapperComponentView.mm +9 -0
- package/ios/scroll-to-top-guard/RNSScrollToTopGuard.h +17 -0
- package/ios/scroll-to-top-guard/RNSScrollToTopGuard.mm +57 -0
- package/ios/scroll-to-top-guard/RNSScrollToTopGuardGestureRecognizer.h +28 -0
- package/ios/scroll-to-top-guard/RNSScrollToTopGuardGestureRecognizer.mm +64 -0
- package/ios/split/RNSSplitAppearanceApplicator.h +36 -0
- package/ios/split/RNSSplitAppearanceApplicator.mm +185 -0
- package/ios/split/RNSSplitAppearanceCoordinator.h +26 -0
- package/ios/split/RNSSplitAppearanceCoordinator.mm +27 -0
- package/ios/split/RNSSplitAppearanceUpdateFlags.h +14 -0
- package/ios/split/RNSSplitHostComponentView.mm +1 -1
- package/ios/split/RNSSplitHostController.h +86 -0
- package/ios/split/RNSSplitHostController.mm +560 -0
- package/ios/split/RNSSplitNavigationController.h +31 -0
- package/ios/split/RNSSplitNavigationController.mm +44 -0
- package/ios/split/RNSSplitNavigationControllerFrameObserver.h +32 -0
- package/ios/split/RNSSplitNavigationControllerFrameObserver.mm +80 -0
- package/ios/split/RNSSplitNavigationControllerFrameOriginChangeDelegate.h +15 -0
- package/ios/split/RNSSplitScreenComponentView.mm +8 -9
- package/ios/split/RNSSplitScreenController.h +45 -0
- package/ios/split/RNSSplitScreenController.mm +130 -0
- package/ios/stack/header/RNSStackHeaderConfigComponentView.h +1 -0
- package/ios/stack/header/RNSStackHeaderConfigComponentView.mm +47 -9
- package/ios/stack/header/RNSStackHeaderConfigDataProviding.h +3 -0
- package/ios/stack/header/RNSStackHeaderMenuCoordinator.h +9 -0
- package/ios/stack/header/RNSStackHeaderMenuCoordinator.mm +15 -0
- package/ios/stack/header/RNSStackHeaderMenuFinder.h +18 -3
- package/ios/stack/header/RNSStackHeaderMenuFinder.mm +21 -3
- package/ios/stack/host/RNSStackHostComponentView.mm +3 -1
- package/ios/stack/host/RNSStackNavigationController.mm +1 -1
- package/ios/stack/screen/RNSStackScreenComponentView.mm +0 -2
- package/ios/stack/screen/RNSStackScreenHeaderCoordinator.h +6 -1
- package/ios/stack/screen/RNSStackScreenHeaderCoordinator.mm +61 -12
- package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryComponentView.mm +3 -0
- package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryContentComponentView.mm +4 -1
- package/ios/tabs/host/RNSTabBarController.h +5 -12
- package/ios/tabs/host/RNSTabBarController.mm +1 -1
- package/lib/commonjs/components/scroll-to-top-guard/ScrollToTopGuard.ios.js +25 -0
- package/lib/commonjs/components/scroll-to-top-guard/ScrollToTopGuard.ios.js.map +1 -0
- package/lib/commonjs/components/scroll-to-top-guard/ScrollToTopGuard.js +24 -0
- package/lib/commonjs/components/scroll-to-top-guard/ScrollToTopGuard.js.map +1 -0
- package/lib/commonjs/components/scroll-to-top-guard/index.js +13 -0
- package/lib/commonjs/components/scroll-to-top-guard/index.js.map +1 -0
- package/lib/commonjs/components/stack/header/StackHeaderConfig.ios.js +11 -12
- package/lib/commonjs/components/stack/header/StackHeaderConfig.ios.js.map +1 -1
- package/lib/commonjs/components/stack/header/ios/StackHeaderItem.ios.js +1 -22
- package/lib/commonjs/components/stack/header/ios/StackHeaderItem.ios.js.map +1 -1
- package/lib/commonjs/components/stack/header/ios/iconUtils.ios.js +33 -2
- package/lib/commonjs/components/stack/header/ios/iconUtils.ios.js.map +1 -1
- package/lib/commonjs/components/stack/header/utils.js +6 -9
- package/lib/commonjs/components/stack/header/utils.js.map +1 -1
- package/lib/commonjs/experimental/index.js +11 -0
- package/lib/commonjs/experimental/index.js.map +1 -1
- package/lib/commonjs/fabric/ScrollViewMarkerNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/legacy/FullWindowOverlayNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/legacy/ModalScreenNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/legacy/ScreenContainerNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/legacy/ScreenFooterNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/legacy/ScreenNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/legacy/ScreenStackHeaderConfigNativeComponent.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/legacy/SearchBarNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/modals/form-sheet/FormSheetHostNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/safe-area/SafeAreaViewNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/scroll-to-top-guard/ScrollToTopGuardNativeComponent.js +12 -0
- package/lib/commonjs/fabric/scroll-to-top-guard/ScrollToTopGuardNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/split/SplitHostNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/split/SplitScreenNativeComponent.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/StackHeaderItemSpacerIOSNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/stack/StackHeaderSubviewAndroidNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/stack/StackHostNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/stack/StackScreenNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/tabs/TabsBottomAccessoryContentNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/tabs/TabsBottomAccessoryNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/tabs/TabsHostAndroidNativeComponent.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.map +1 -1
- package/lib/commonjs/flags.js +22 -1
- package/lib/commonjs/flags.js.map +1 -1
- package/lib/commonjs/legacy/components/Screen.js +6 -1
- package/lib/commonjs/legacy/components/Screen.js.map +1 -1
- package/lib/commonjs/legacy/components/ScreenStackHeaderConfig.js +5 -0
- package/lib/commonjs/legacy/components/ScreenStackHeaderConfig.js.map +1 -1
- package/lib/commonjs/legacy/components/ScreenStackItem.js.map +1 -1
- package/lib/commonjs/legacy/components/SearchBar.js +16 -16
- package/lib/commonjs/legacy/components/SearchBar.js.map +1 -1
- package/lib/commonjs/legacy/components/helpers/prepareHeaderBarButtonItems.js +3 -0
- package/lib/commonjs/legacy/components/helpers/prepareHeaderBarButtonItems.js.map +1 -1
- package/lib/commonjs/legacy/gesture-handler/fabricUtils.js.map +1 -1
- package/lib/commonjs/legacy/useTransitionProgress.js.map +1 -1
- package/lib/module/components/scroll-to-top-guard/ScrollToTopGuard.ios.js +20 -0
- package/lib/module/components/scroll-to-top-guard/ScrollToTopGuard.ios.js.map +1 -0
- package/lib/module/components/scroll-to-top-guard/ScrollToTopGuard.js +18 -0
- package/lib/module/components/scroll-to-top-guard/ScrollToTopGuard.js.map +1 -0
- package/lib/module/components/scroll-to-top-guard/index.js +2 -0
- package/lib/module/components/scroll-to-top-guard/index.js.map +1 -0
- package/lib/module/components/stack/header/StackHeaderConfig.ios.js +14 -15
- package/lib/module/components/stack/header/StackHeaderConfig.ios.js.map +1 -1
- package/lib/module/components/stack/header/ios/StackHeaderItem.ios.js +1 -22
- package/lib/module/components/stack/header/ios/StackHeaderItem.ios.js.map +1 -1
- package/lib/module/components/stack/header/ios/iconUtils.ios.js +31 -2
- package/lib/module/components/stack/header/ios/iconUtils.ios.js.map +1 -1
- package/lib/module/components/stack/header/utils.js +5 -8
- package/lib/module/components/stack/header/utils.js.map +1 -1
- package/lib/module/experimental/index.js +1 -0
- package/lib/module/experimental/index.js.map +1 -1
- package/lib/module/fabric/ScrollViewMarkerNativeComponent.js.map +1 -1
- package/lib/module/fabric/legacy/FullWindowOverlayNativeComponent.js.map +1 -1
- package/lib/module/fabric/legacy/ModalScreenNativeComponent.js.map +1 -1
- package/lib/module/fabric/legacy/ScreenContainerNativeComponent.js.map +1 -1
- package/lib/module/fabric/legacy/ScreenFooterNativeComponent.js.map +1 -1
- package/lib/module/fabric/legacy/ScreenNativeComponent.js.map +1 -1
- package/lib/module/fabric/legacy/ScreenStackHeaderConfigNativeComponent.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/legacy/SearchBarNativeComponent.js.map +1 -1
- package/lib/module/fabric/modals/form-sheet/FormSheetHostNativeComponent.js.map +1 -1
- package/lib/module/fabric/safe-area/SafeAreaViewNativeComponent.js.map +1 -1
- package/lib/module/fabric/scroll-to-top-guard/ScrollToTopGuardNativeComponent.js +7 -0
- package/lib/module/fabric/scroll-to-top-guard/ScrollToTopGuardNativeComponent.js.map +1 -0
- package/lib/module/fabric/split/SplitHostNativeComponent.js.map +1 -1
- package/lib/module/fabric/split/SplitScreenNativeComponent.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/StackHeaderItemSpacerIOSNativeComponent.js.map +1 -1
- package/lib/module/fabric/stack/StackHeaderSubviewAndroidNativeComponent.js.map +1 -1
- package/lib/module/fabric/stack/StackHostNativeComponent.js.map +1 -1
- package/lib/module/fabric/stack/StackScreenNativeComponent.js.map +1 -1
- package/lib/module/fabric/tabs/TabsBottomAccessoryContentNativeComponent.js.map +1 -1
- package/lib/module/fabric/tabs/TabsBottomAccessoryNativeComponent.js.map +1 -1
- package/lib/module/fabric/tabs/TabsHostAndroidNativeComponent.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.map +1 -1
- package/lib/module/flags.js +22 -1
- package/lib/module/flags.js.map +1 -1
- package/lib/module/legacy/components/Screen.js +6 -1
- package/lib/module/legacy/components/Screen.js.map +1 -1
- package/lib/module/legacy/components/ScreenStackHeaderConfig.js +5 -0
- package/lib/module/legacy/components/ScreenStackHeaderConfig.js.map +1 -1
- package/lib/module/legacy/components/ScreenStackItem.js.map +1 -1
- package/lib/module/legacy/components/SearchBar.js +17 -17
- package/lib/module/legacy/components/SearchBar.js.map +1 -1
- package/lib/module/legacy/components/helpers/prepareHeaderBarButtonItems.js +4 -0
- package/lib/module/legacy/components/helpers/prepareHeaderBarButtonItems.js.map +1 -1
- package/lib/module/legacy/gesture-handler/fabricUtils.js.map +1 -1
- package/lib/module/legacy/useTransitionProgress.js.map +1 -1
- package/lib/module/private/hooks/useRenderDebugInfo.js.map +1 -1
- package/lib/typescript/components/modals/form-sheet/FormSheet.types.d.ts +2 -2
- package/lib/typescript/components/safe-area/SafeAreaView.web.d.ts +5 -2
- package/lib/typescript/components/safe-area/SafeAreaView.web.d.ts.map +1 -1
- package/lib/typescript/components/scroll-to-top-guard/ScrollToTopGuard.d.ts +15 -0
- package/lib/typescript/components/scroll-to-top-guard/ScrollToTopGuard.d.ts.map +1 -0
- package/lib/typescript/components/scroll-to-top-guard/ScrollToTopGuard.ios.d.ts +12 -0
- package/lib/typescript/components/scroll-to-top-guard/ScrollToTopGuard.ios.d.ts.map +1 -0
- package/lib/typescript/components/scroll-to-top-guard/index.d.ts +2 -0
- package/lib/typescript/components/scroll-to-top-guard/index.d.ts.map +1 -0
- package/lib/typescript/components/stack/header/StackHeaderConfig.android.types.d.ts +24 -0
- package/lib/typescript/components/stack/header/StackHeaderConfig.android.types.d.ts.map +1 -1
- package/lib/typescript/components/stack/header/StackHeaderConfig.ios.d.ts.map +1 -1
- package/lib/typescript/components/stack/header/StackHeaderConfig.ios.types.d.ts +13 -0
- package/lib/typescript/components/stack/header/StackHeaderConfig.ios.types.d.ts.map +1 -1
- package/lib/typescript/components/stack/header/StackHeaderConfig.web.d.ts +5 -2
- package/lib/typescript/components/stack/header/StackHeaderConfig.web.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/iconUtils.ios.d.ts +3 -0
- package/lib/typescript/components/stack/header/ios/iconUtils.ios.d.ts.map +1 -1
- package/lib/typescript/components/stack/header/utils.d.ts +1 -2
- package/lib/typescript/components/stack/header/utils.d.ts.map +1 -1
- package/lib/typescript/components/stack/host/StackHost.types.d.ts +2 -2
- package/lib/typescript/components/stack/host/StackHost.types.d.ts.map +1 -1
- package/lib/typescript/components/stack/host/StackHost.web.d.ts +6 -2
- package/lib/typescript/components/stack/host/StackHost.web.d.ts.map +1 -1
- package/lib/typescript/components/stack/screen/StackScreen.web.d.ts +5 -2
- package/lib/typescript/components/stack/screen/StackScreen.web.d.ts.map +1 -1
- package/lib/typescript/components/tabs/host/TabsHost.web.d.ts +5 -2
- package/lib/typescript/components/tabs/host/TabsHost.web.d.ts.map +1 -1
- package/lib/typescript/components/tabs/screen/TabsScreen.types.d.ts +7 -3
- package/lib/typescript/components/tabs/screen/TabsScreen.types.d.ts.map +1 -1
- package/lib/typescript/components/tabs/screen/TabsScreen.web.d.ts +5 -2
- package/lib/typescript/components/tabs/screen/TabsScreen.web.d.ts.map +1 -1
- package/lib/typescript/experimental/index.d.ts +1 -0
- package/lib/typescript/experimental/index.d.ts.map +1 -1
- package/lib/typescript/fabric/NativeScreensModule.d.ts +1 -1
- package/lib/typescript/fabric/ScrollViewMarkerNativeComponent.d.ts +2 -2
- package/lib/typescript/fabric/ScrollViewMarkerNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/legacy/FullWindowOverlayNativeComponent.d.ts +2 -2
- package/lib/typescript/fabric/legacy/FullWindowOverlayNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/legacy/ModalScreenNativeComponent.d.ts +3 -2
- package/lib/typescript/fabric/legacy/ModalScreenNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/legacy/ScreenContainerNativeComponent.d.ts +2 -2
- package/lib/typescript/fabric/legacy/ScreenContainerNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/legacy/ScreenContentWrapperNativeComponent.d.ts +2 -2
- package/lib/typescript/fabric/legacy/ScreenContentWrapperNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/legacy/ScreenFooterNativeComponent.d.ts +2 -2
- package/lib/typescript/fabric/legacy/ScreenFooterNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/legacy/ScreenNativeComponent.d.ts +3 -2
- package/lib/typescript/fabric/legacy/ScreenNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/legacy/ScreenNavigationContainerNativeComponent.d.ts +2 -2
- package/lib/typescript/fabric/legacy/ScreenNavigationContainerNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/legacy/ScreenStackHeaderConfigNativeComponent.d.ts +3 -3
- package/lib/typescript/fabric/legacy/ScreenStackHeaderConfigNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.d.ts +2 -2
- package/lib/typescript/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/legacy/ScreenStackNativeComponent.d.ts +2 -2
- package/lib/typescript/fabric/legacy/ScreenStackNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/legacy/SearchBarNativeComponent.d.ts +6 -6
- package/lib/typescript/fabric/legacy/SearchBarNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/modals/form-sheet/FormSheetContentWrapperNativeComponent.d.ts +2 -2
- package/lib/typescript/fabric/modals/form-sheet/FormSheetContentWrapperNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/modals/form-sheet/FormSheetHostNativeComponent.d.ts +2 -2
- package/lib/typescript/fabric/modals/form-sheet/FormSheetHostNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/safe-area/SafeAreaViewNativeComponent.d.ts +2 -2
- package/lib/typescript/fabric/safe-area/SafeAreaViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/scroll-to-top-guard/ScrollToTopGuardNativeComponent.d.ts +6 -0
- package/lib/typescript/fabric/scroll-to-top-guard/ScrollToTopGuardNativeComponent.d.ts.map +1 -0
- package/lib/typescript/fabric/split/SplitHostNativeComponent.d.ts +1 -1
- package/lib/typescript/fabric/split/SplitHostNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/split/SplitScreenNativeComponent.d.ts +2 -2
- package/lib/typescript/fabric/split/SplitScreenNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/stack/StackHeaderConfigAndroidNativeComponent.d.ts +1 -0
- package/lib/typescript/fabric/stack/StackHeaderConfigAndroidNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/stack/StackHeaderConfigIOSNativeComponent.d.ts +2 -1
- package/lib/typescript/fabric/stack/StackHeaderConfigIOSNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/stack/StackHeaderItemIOSNativeComponent.d.ts +2 -2
- package/lib/typescript/fabric/stack/StackHeaderItemIOSNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/stack/StackHeaderItemSpacerIOSNativeComponent.d.ts +2 -2
- package/lib/typescript/fabric/stack/StackHeaderItemSpacerIOSNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/stack/StackHeaderSubviewAndroidNativeComponent.d.ts +2 -2
- package/lib/typescript/fabric/stack/StackHeaderSubviewAndroidNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/stack/StackHostNativeComponent.d.ts +2 -2
- package/lib/typescript/fabric/stack/StackHostNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/stack/StackScreenNativeComponent.d.ts +2 -2
- package/lib/typescript/fabric/stack/StackScreenNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/tabs/TabsBottomAccessoryContentNativeComponent.d.ts +2 -2
- package/lib/typescript/fabric/tabs/TabsBottomAccessoryContentNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/tabs/TabsBottomAccessoryNativeComponent.d.ts +2 -2
- package/lib/typescript/fabric/tabs/TabsBottomAccessoryNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/tabs/TabsHostAndroidNativeComponent.d.ts +2 -2
- package/lib/typescript/fabric/tabs/TabsHostAndroidNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/tabs/TabsHostIOSNativeComponent.d.ts +2 -2
- package/lib/typescript/fabric/tabs/TabsHostIOSNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/tabs/TabsScreenAndroidNativeComponent.d.ts +2 -2
- package/lib/typescript/fabric/tabs/TabsScreenAndroidNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/tabs/TabsScreenIOSNativeComponent.d.ts +2 -2
- package/lib/typescript/fabric/tabs/TabsScreenIOSNativeComponent.d.ts.map +1 -1
- package/lib/typescript/flags.d.ts +13 -0
- package/lib/typescript/flags.d.ts.map +1 -1
- package/lib/typescript/legacy/TransitionProgressContext.d.ts +1 -1
- package/lib/typescript/legacy/TransitionProgressContext.d.ts.map +1 -1
- package/lib/typescript/legacy/components/Screen.d.ts +5 -3
- package/lib/typescript/legacy/components/Screen.d.ts.map +1 -1
- package/lib/typescript/legacy/components/Screen.web.d.ts +10 -2
- package/lib/typescript/legacy/components/Screen.web.d.ts.map +1 -1
- package/lib/typescript/legacy/components/ScreenContainer.web.d.ts +5 -2
- package/lib/typescript/legacy/components/ScreenContainer.web.d.ts.map +1 -1
- package/lib/typescript/legacy/components/ScreenContentWrapper.web.d.ts +5 -2
- package/lib/typescript/legacy/components/ScreenContentWrapper.web.d.ts.map +1 -1
- package/lib/typescript/legacy/components/ScreenContentWrapper.windows.d.ts +5 -2
- package/lib/typescript/legacy/components/ScreenContentWrapper.windows.d.ts.map +1 -1
- package/lib/typescript/legacy/components/ScreenFooter.web.d.ts +10 -3
- package/lib/typescript/legacy/components/ScreenFooter.web.d.ts.map +1 -1
- package/lib/typescript/legacy/components/ScreenFooter.windows.d.ts +10 -3
- package/lib/typescript/legacy/components/ScreenFooter.windows.d.ts.map +1 -1
- package/lib/typescript/legacy/components/ScreenStack.web.d.ts +5 -2
- package/lib/typescript/legacy/components/ScreenStack.web.d.ts.map +1 -1
- package/lib/typescript/legacy/components/ScreenStackHeaderConfig.d.ts +3 -1
- package/lib/typescript/legacy/components/ScreenStackHeaderConfig.d.ts.map +1 -1
- package/lib/typescript/legacy/components/ScreenStackItem.d.ts +3 -2
- package/lib/typescript/legacy/components/ScreenStackItem.d.ts.map +1 -1
- package/lib/typescript/legacy/components/SearchBar.d.ts +3 -3
- package/lib/typescript/legacy/components/SearchBar.d.ts.map +1 -1
- package/lib/typescript/legacy/components/SearchBar.web.d.ts +5 -2
- package/lib/typescript/legacy/components/SearchBar.web.d.ts.map +1 -1
- package/lib/typescript/legacy/components/helpers/prepareHeaderBarButtonItems.d.ts +15 -12
- package/lib/typescript/legacy/components/helpers/prepareHeaderBarButtonItems.d.ts.map +1 -1
- package/lib/typescript/legacy/gesture-handler/fabricUtils.d.ts +3 -2
- package/lib/typescript/legacy/gesture-handler/fabricUtils.d.ts.map +1 -1
- package/lib/typescript/legacy/types.d.ts +25 -5
- package/lib/typescript/legacy/types.d.ts.map +1 -1
- package/lib/typescript/legacy/useTransitionProgress.d.ts +2 -5
- package/lib/typescript/legacy/useTransitionProgress.d.ts.map +1 -1
- package/lib/typescript/private/hooks/useRenderDebugInfo.d.ts +2 -2
- package/lib/typescript/private/hooks/useRenderDebugInfo.d.ts.map +1 -1
- package/package.json +17 -17
- package/src/components/modals/form-sheet/FormSheet.types.ts +2 -2
- package/src/components/scroll-to-top-guard/ScrollToTopGuard.ios.tsx +17 -0
- package/src/components/scroll-to-top-guard/ScrollToTopGuard.tsx +18 -0
- package/src/components/scroll-to-top-guard/index.ts +1 -0
- package/src/components/stack/header/StackHeaderConfig.android.types.ts +24 -0
- package/src/components/stack/header/StackHeaderConfig.ios.tsx +32 -22
- package/src/components/stack/header/StackHeaderConfig.ios.types.ts +13 -0
- package/src/components/stack/header/ios/StackHeaderItem.ios.tsx +1 -23
- package/src/components/stack/header/ios/iconUtils.ios.ts +38 -2
- package/src/components/stack/header/utils.ts +6 -11
- package/src/components/stack/host/StackHost.types.ts +2 -4
- package/src/components/tabs/screen/TabsScreen.types.ts +7 -3
- package/src/experimental/index.ts +1 -0
- package/src/fabric/ScrollViewMarkerNativeComponent.ts +8 -2
- package/src/fabric/legacy/FullWindowOverlayNativeComponent.ts +6 -2
- package/src/fabric/legacy/ModalScreenNativeComponent.ts +8 -2
- package/src/fabric/legacy/ScreenContainerNativeComponent.ts +5 -2
- package/src/fabric/legacy/ScreenContentWrapperNativeComponent.ts +2 -2
- package/src/fabric/legacy/ScreenFooterNativeComponent.ts +5 -2
- package/src/fabric/legacy/ScreenNativeComponent.ts +8 -2
- package/src/fabric/legacy/ScreenNavigationContainerNativeComponent.ts +2 -2
- package/src/fabric/legacy/ScreenStackHeaderConfigNativeComponent.ts +8 -3
- package/src/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.ts +6 -2
- package/src/fabric/legacy/ScreenStackNativeComponent.ts +10 -2
- package/src/fabric/legacy/SearchBarNativeComponent.ts +10 -7
- package/src/fabric/modals/form-sheet/FormSheetContentWrapperNativeComponent.ts +2 -2
- package/src/fabric/modals/form-sheet/FormSheetHostNativeComponent.ts +7 -2
- package/src/fabric/safe-area/SafeAreaViewNativeComponent.ts +6 -2
- package/src/fabric/scroll-to-top-guard/ScrollToTopGuardNativeComponent.ts +10 -0
- package/src/fabric/split/SplitHostNativeComponent.ts +5 -2
- package/src/fabric/split/SplitScreenNativeComponent.ts +6 -2
- package/src/fabric/stack/StackHeaderConfigAndroidNativeComponent.ts +3 -1
- package/src/fabric/stack/StackHeaderConfigIOSNativeComponent.ts +7 -2
- package/src/fabric/stack/StackHeaderItemIOSNativeComponent.ts +2 -1
- package/src/fabric/stack/StackHeaderItemSpacerIOSNativeComponent.ts +6 -2
- package/src/fabric/stack/StackHeaderSubviewAndroidNativeComponent.ts +6 -2
- package/src/fabric/stack/StackHostNativeComponent.ts +5 -2
- package/src/fabric/stack/StackScreenNativeComponent.ts +6 -2
- package/src/fabric/tabs/TabsBottomAccessoryContentNativeComponent.ts +6 -2
- package/src/fabric/tabs/TabsBottomAccessoryNativeComponent.ts +6 -2
- package/src/fabric/tabs/TabsHostAndroidNativeComponent.ts +7 -2
- package/src/fabric/tabs/TabsHostIOSNativeComponent.ts +7 -2
- package/src/fabric/tabs/TabsScreenAndroidNativeComponent.ts +2 -1
- package/src/fabric/tabs/TabsScreenIOSNativeComponent.ts +2 -1
- package/src/flags.ts +26 -0
- package/src/legacy/TransitionProgressContext.tsx +1 -1
- package/src/legacy/components/Screen.tsx +14 -6
- package/src/legacy/components/ScreenStackHeaderConfig.tsx +7 -1
- package/src/legacy/components/ScreenStackItem.tsx +3 -4
- package/src/legacy/components/SearchBar.tsx +34 -44
- package/src/legacy/components/helpers/prepareHeaderBarButtonItems.ts +7 -1
- package/src/legacy/gesture-handler/fabricUtils.ts +5 -2
- package/src/legacy/types.ts +28 -5
- package/src/legacy/useTransitionProgress.tsx +4 -2
- package/src/private/hooks/useRenderDebugInfo.tsx +2 -2
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/FormSheetNativeDismissCoordinator.kt +0 -25
- package/ios/ReactMountingTransactionObserving.swift +0 -7
- package/ios/bridging/Swift-Bridging.h +0 -7
- package/ios/orientation/RNSOrientationProviding.swift +0 -6
- package/ios/orientation/RNSOrientationSwift.swift +0 -14
- package/ios/split/RNSSplitAppearanceApplicator.swift +0 -199
- package/ios/split/RNSSplitAppearanceCoordinator.swift +0 -26
- package/ios/split/RNSSplitAppearanceUpdateFlags.swift +0 -11
- package/ios/split/RNSSplitHostController.swift +0 -570
- package/ios/split/RNSSplitNavigationController.swift +0 -46
- package/ios/split/RNSSplitScreenController.swift +0 -133
- package/ios/utils/RNSLog.swift +0 -6
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
package com.swmansion.rnscreens.stack.header.toolbar
|
|
2
|
+
|
|
3
|
+
import android.content.res.ColorStateList
|
|
4
|
+
import android.graphics.drawable.Drawable
|
|
5
|
+
import android.os.Build
|
|
6
|
+
import android.util.Log
|
|
7
|
+
import android.view.Menu
|
|
8
|
+
import android.view.MenuItem
|
|
9
|
+
import androidx.core.view.MenuItemCompat
|
|
10
|
+
import com.google.android.material.appbar.MaterialToolbar
|
|
11
|
+
import com.swmansion.rnscreens.stack.header.getResizedDrawable
|
|
12
|
+
import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuConfig
|
|
13
|
+
import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuElementConfig
|
|
14
|
+
import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuGroupConfig
|
|
15
|
+
import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuGroupMetadata
|
|
16
|
+
import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuItemConfig
|
|
17
|
+
import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuItemType
|
|
18
|
+
import com.swmansion.rnscreens.stack.header.toolbar.update.StackHeaderToolbarFieldUpdate
|
|
19
|
+
import com.swmansion.rnscreens.stack.header.toolbar.update.StackHeaderToolbarMenuElementOptions
|
|
20
|
+
import com.swmansion.rnscreens.stack.header.toolbar.update.valueOrNull
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Builds the toolbar menu from its config and applies in-place element updates
|
|
24
|
+
* (options, checkability, icon tint).
|
|
25
|
+
*/
|
|
26
|
+
internal object StackHeaderToolbarMenuApplicator {
|
|
27
|
+
// region Mappings & metadata
|
|
28
|
+
|
|
29
|
+
internal fun generateToolbarMenuItemMappings(menuConfig: StackHeaderToolbarMenuConfig): Pair<Map<String, Int>, Map<Int, String>> {
|
|
30
|
+
val forwardIdMap = mutableMapOf<String, Int>()
|
|
31
|
+
val reverseIdMap = mutableMapOf<Int, String>()
|
|
32
|
+
var counter = 1
|
|
33
|
+
assignElementIds(menuConfig.children, forwardIdMap, reverseIdMap) { counter++ }
|
|
34
|
+
return Pair(forwardIdMap.toMap(), reverseIdMap.toMap())
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
internal fun generateToolbarMenuGroupMappings(menuConfig: StackHeaderToolbarMenuConfig): Map<String, Int> {
|
|
38
|
+
val forwardGroupIdMap = mutableMapOf<String, Int>()
|
|
39
|
+
var counter = 1
|
|
40
|
+
assignGroupIds(menuConfig, forwardGroupIdMap) { counter++ }
|
|
41
|
+
return forwardGroupIdMap.toMap()
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
internal fun computeGroupMetadata(menuConfig: StackHeaderToolbarMenuConfig): StackHeaderToolbarMenuGroupMetadata {
|
|
45
|
+
val itemGroupMap = mutableMapOf<String, String>()
|
|
46
|
+
val groupSingleSelection = mutableMapOf<String, Boolean>()
|
|
47
|
+
val groupMemberItems = mutableMapOf<String, MutableList<String>>()
|
|
48
|
+
collectGroupMetadata(menuConfig, itemGroupMap, groupSingleSelection, groupMemberItems)
|
|
49
|
+
return StackHeaderToolbarMenuGroupMetadata(
|
|
50
|
+
itemGroupMap,
|
|
51
|
+
groupSingleSelection,
|
|
52
|
+
groupMemberItems.mapValues { it.value.toList() },
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
internal fun validateRadioInitialSelection(menuConfig: StackHeaderToolbarMenuConfig) {
|
|
57
|
+
for (group in menuConfig.groups) {
|
|
58
|
+
if (!group.singleSelection) continue
|
|
59
|
+
var count = 0
|
|
60
|
+
for (element in menuConfig.children) {
|
|
61
|
+
if (element.item.groupId == group.groupId && element.item.initialToggleState) {
|
|
62
|
+
count++
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
require(count <= 1) {
|
|
66
|
+
"[RNScreens] Radio group '${group.groupId}' has $count items with " +
|
|
67
|
+
"initialToggleState=true. At most 1 is allowed for single-selection groups."
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
for (element in menuConfig.children) {
|
|
71
|
+
if (element is StackHeaderToolbarMenuElementConfig.Submenu) {
|
|
72
|
+
validateRadioInitialSelection(element.menu)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Recursively traverses menu elements and maps user-friendly string item IDs to integers
|
|
79
|
+
* expected by Android.
|
|
80
|
+
*
|
|
81
|
+
* @param elements List of menu elements.
|
|
82
|
+
* @param forwardIdMap Reference to String->Int ID map to which ID entries will be added.
|
|
83
|
+
* @param reverseIdMap Reference to Int->String ID map to which ID entries will be added.
|
|
84
|
+
* @param nextId Function that returns next ID integer. New unique integer should be returned
|
|
85
|
+
* each time the function is called. The function is used to handle recursive
|
|
86
|
+
* element traversal.
|
|
87
|
+
*/
|
|
88
|
+
private fun assignElementIds(
|
|
89
|
+
elements: List<StackHeaderToolbarMenuElementConfig>,
|
|
90
|
+
forwardIdMap: MutableMap<String, Int>,
|
|
91
|
+
reverseIdMap: MutableMap<Int, String>,
|
|
92
|
+
nextId: () -> Int,
|
|
93
|
+
) {
|
|
94
|
+
for (element in elements) {
|
|
95
|
+
require(element.item.id !in forwardIdMap) {
|
|
96
|
+
"[RNScreens] Duplicate toolbar menu item id: '${element.item.id}'. Item IDs must be unique across the entire menu."
|
|
97
|
+
}
|
|
98
|
+
val nativeId = nextId()
|
|
99
|
+
forwardIdMap[element.item.id] = nativeId
|
|
100
|
+
reverseIdMap[nativeId] = element.item.id
|
|
101
|
+
if (element is StackHeaderToolbarMenuElementConfig.Submenu) {
|
|
102
|
+
assignElementIds(element.menu.children, forwardIdMap, reverseIdMap, nextId)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Recursively traverses menu groups and maps user-friendly string group IDs to integers
|
|
109
|
+
* expected by Android.
|
|
110
|
+
*
|
|
111
|
+
* @param menuConfig Menu whose groups — and those of its submenus — will be mapped.
|
|
112
|
+
* @param forwardMap Reference to String->Int group ID map to which entries will be added.
|
|
113
|
+
* @param nextId Function that returns next ID integer. New unique integer should be returned
|
|
114
|
+
* each time the function is called. The function is used to handle recursive
|
|
115
|
+
* element traversal.
|
|
116
|
+
*/
|
|
117
|
+
private fun assignGroupIds(
|
|
118
|
+
menuConfig: StackHeaderToolbarMenuConfig,
|
|
119
|
+
forwardMap: MutableMap<String, Int>,
|
|
120
|
+
nextId: () -> Int,
|
|
121
|
+
) {
|
|
122
|
+
for (group in menuConfig.groups) {
|
|
123
|
+
require(group.groupId !in forwardMap) {
|
|
124
|
+
"[RNScreens] Duplicate toolbar menu group id: '${group.groupId}'. Group IDs must be unique across the entire menu."
|
|
125
|
+
}
|
|
126
|
+
forwardMap[group.groupId] = nextId()
|
|
127
|
+
}
|
|
128
|
+
for (element in menuConfig.children) {
|
|
129
|
+
if (element is StackHeaderToolbarMenuElementConfig.Submenu) {
|
|
130
|
+
assignGroupIds(element.menu, forwardMap, nextId)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
private fun collectGroupMetadata(
|
|
136
|
+
config: StackHeaderToolbarMenuConfig,
|
|
137
|
+
itemGroupMap: MutableMap<String, String>,
|
|
138
|
+
groupSingleSelection: MutableMap<String, Boolean>,
|
|
139
|
+
groupMemberItems: MutableMap<String, MutableList<String>>,
|
|
140
|
+
) {
|
|
141
|
+
val localGroupIds = config.groups.map { it.groupId }.toSet()
|
|
142
|
+
for (group in config.groups) {
|
|
143
|
+
groupSingleSelection[group.groupId] = group.singleSelection
|
|
144
|
+
groupMemberItems.getOrPut(group.groupId) { mutableListOf() }
|
|
145
|
+
}
|
|
146
|
+
for (element in config.children) {
|
|
147
|
+
element.item.groupId?.let { gid ->
|
|
148
|
+
require(gid in localGroupIds) {
|
|
149
|
+
"[RNScreens] Menu item '${element.item.id}' references group '$gid' " +
|
|
150
|
+
"which is not defined at the same menu level. " +
|
|
151
|
+
"Groups cannot span submenus."
|
|
152
|
+
}
|
|
153
|
+
itemGroupMap[element.item.id] = gid
|
|
154
|
+
groupMemberItems[gid]!!.add(element.item.id)
|
|
155
|
+
}
|
|
156
|
+
if (element is StackHeaderToolbarMenuElementConfig.Submenu) {
|
|
157
|
+
collectGroupMetadata(element.menu, itemGroupMap, groupSingleSelection, groupMemberItems)
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// endregion
|
|
163
|
+
|
|
164
|
+
// region Menu build
|
|
165
|
+
|
|
166
|
+
internal fun rebuildToolbarMenu(
|
|
167
|
+
toolbar: MaterialToolbar,
|
|
168
|
+
menuConfig: StackHeaderToolbarMenuConfig,
|
|
169
|
+
forwardIdMap: Map<String, Int>,
|
|
170
|
+
reverseIdMap: Map<Int, String>,
|
|
171
|
+
forwardGroupIdMap: Map<String, Int>,
|
|
172
|
+
groupDividerEnabled: Boolean,
|
|
173
|
+
onItemClicked: (id: String, menuItem: MenuItem) -> Unit,
|
|
174
|
+
) {
|
|
175
|
+
toolbar.menu.clear()
|
|
176
|
+
addElements(toolbar, toolbar.menu, menuConfig, forwardIdMap, forwardGroupIdMap)
|
|
177
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
|
178
|
+
toolbar.menu.setGroupDividerEnabled(groupDividerEnabled)
|
|
179
|
+
}
|
|
180
|
+
toolbar.setOnMenuItemClickListener { menuItem ->
|
|
181
|
+
val stringId = reverseIdMap[menuItem.itemId]
|
|
182
|
+
if (stringId != null) {
|
|
183
|
+
onItemClicked(stringId, menuItem)
|
|
184
|
+
}
|
|
185
|
+
true
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
private fun addElements(
|
|
190
|
+
toolbar: MaterialToolbar,
|
|
191
|
+
menu: Menu,
|
|
192
|
+
menuConfig: StackHeaderToolbarMenuConfig,
|
|
193
|
+
forwardIdMap: Map<String, Int>,
|
|
194
|
+
forwardGroupIdMap: Map<String, Int>,
|
|
195
|
+
) {
|
|
196
|
+
menuConfig.children.forEachIndexed { index, element ->
|
|
197
|
+
val itemId =
|
|
198
|
+
requireNotNull(forwardIdMap[element.item.id]) {
|
|
199
|
+
"[RNScreens] Invalid forwardIdMap received. Missing item: ${element.item}."
|
|
200
|
+
}
|
|
201
|
+
val groupIntId =
|
|
202
|
+
element.item.groupId
|
|
203
|
+
?.let { forwardGroupIdMap[it] ?: Menu.NONE }
|
|
204
|
+
?: Menu.NONE
|
|
205
|
+
when (element) {
|
|
206
|
+
is StackHeaderToolbarMenuElementConfig.MenuItem -> {
|
|
207
|
+
val menuItem = menu.add(groupIntId, itemId, index, null)
|
|
208
|
+
applyMenuElementOptions(toolbar, menuItem, element.item.toOptions())
|
|
209
|
+
applyCheckability(menuItem, element.item)
|
|
210
|
+
}
|
|
211
|
+
is StackHeaderToolbarMenuElementConfig.Submenu -> {
|
|
212
|
+
val subMenu = menu.addSubMenu(groupIntId, itemId, index, null)
|
|
213
|
+
applyMenuElementOptions(toolbar, subMenu.item, element.item.toOptions())
|
|
214
|
+
element.menuTitle?.let { subMenu.setHeaderTitle(it) }
|
|
215
|
+
addElements(toolbar, subMenu, element.menu, forwardIdMap, forwardGroupIdMap)
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
configureGroupCheckability(menu, menuConfig.groups, forwardGroupIdMap)
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
private fun configureGroupCheckability(
|
|
223
|
+
menu: Menu,
|
|
224
|
+
groups: List<StackHeaderToolbarMenuGroupConfig>,
|
|
225
|
+
forwardGroupIdMap: Map<String, Int>,
|
|
226
|
+
) {
|
|
227
|
+
for (group in groups) {
|
|
228
|
+
val groupIntId = forwardGroupIdMap[group.groupId] ?: continue
|
|
229
|
+
menu.setGroupCheckable(groupIntId, true, group.singleSelection)
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
private fun applyCheckability(
|
|
234
|
+
menuItem: MenuItem,
|
|
235
|
+
itemConfig: StackHeaderToolbarMenuItemConfig,
|
|
236
|
+
) {
|
|
237
|
+
val shouldBeCheckable =
|
|
238
|
+
when (itemConfig.itemType) {
|
|
239
|
+
StackHeaderToolbarMenuItemType.TOGGLE -> {
|
|
240
|
+
require(itemConfig.groupId != null) {
|
|
241
|
+
"[RNScreens] Menu item '${itemConfig.id}' has itemType=TOGGLE but no groupId. " +
|
|
242
|
+
"Toggle items must belong to a group."
|
|
243
|
+
}
|
|
244
|
+
true
|
|
245
|
+
}
|
|
246
|
+
StackHeaderToolbarMenuItemType.AUTOMATIC -> itemConfig.groupId != null
|
|
247
|
+
StackHeaderToolbarMenuItemType.ACTION -> {
|
|
248
|
+
require(itemConfig.groupId == null) {
|
|
249
|
+
"[RNScreens] Menu item '${itemConfig.id}' has itemType=ACTION " +
|
|
250
|
+
"and belongs to a group. Action items cannot belong to groups."
|
|
251
|
+
}
|
|
252
|
+
false
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
if (shouldBeCheckable) {
|
|
256
|
+
menuItem.isCheckable = true
|
|
257
|
+
menuItem.isChecked = itemConfig.initialToggleState
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// endregion
|
|
262
|
+
|
|
263
|
+
// region Element updates
|
|
264
|
+
|
|
265
|
+
internal fun updateToolbarMenuElement(
|
|
266
|
+
toolbar: MaterialToolbar,
|
|
267
|
+
forwardIdMap: Map<String, Int>,
|
|
268
|
+
id: String,
|
|
269
|
+
options: StackHeaderToolbarMenuElementOptions,
|
|
270
|
+
) {
|
|
271
|
+
val item =
|
|
272
|
+
forwardIdMap[id]?.let { toolbar.menu.findItem(it) } ?: run {
|
|
273
|
+
Log.e(TAG, "[RNScreens] Unable to find menu element with id '$id'.")
|
|
274
|
+
return
|
|
275
|
+
}
|
|
276
|
+
applyMenuElementOptions(toolbar, item, options)
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
private fun applyMenuElementOptions(
|
|
280
|
+
toolbar: MaterialToolbar,
|
|
281
|
+
menuItem: MenuItem,
|
|
282
|
+
options: StackHeaderToolbarMenuElementOptions,
|
|
283
|
+
) {
|
|
284
|
+
options.title?.let { menuItem.title = it.valueOrNull() }
|
|
285
|
+
options.titleCondensed?.let { menuItem.titleCondensed = it.valueOrNull() }
|
|
286
|
+
options.tooltipText?.let { MenuItemCompat.setTooltipText(menuItem, it.valueOrNull()) }
|
|
287
|
+
options.accessibilityLabel?.let {
|
|
288
|
+
// Setting `null` will restore Android's default (`title` for items
|
|
289
|
+
// in toolbar, `null` otherwise).
|
|
290
|
+
MenuItemCompat.setContentDescription(menuItem, it.valueOrNull())
|
|
291
|
+
}
|
|
292
|
+
options.hidden?.let { menuItem.isVisible = !it }
|
|
293
|
+
options.disabled?.let { menuItem.isEnabled = !it }
|
|
294
|
+
options.showAsAction?.let { menuItem.setShowAsAction(it.toNativeShowAsAction()) }
|
|
295
|
+
|
|
296
|
+
// checked is intentionally not handled here. The coordinator layout manages it in
|
|
297
|
+
// applyGroupItemStateChange because toggling checked state requires group metadata
|
|
298
|
+
// (radio vs checkbox) and may emit onGroupSelectionChanged events.
|
|
299
|
+
|
|
300
|
+
options.icon?.let {
|
|
301
|
+
when (it) {
|
|
302
|
+
StackHeaderToolbarFieldUpdate.Reset -> menuItem.icon = null
|
|
303
|
+
is StackHeaderToolbarFieldUpdate.Set<Drawable> ->
|
|
304
|
+
menuItem.icon = getResizedDrawable(toolbar, it.value)
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (options.requiresIconTintColorUpdate || options.icon != null) {
|
|
309
|
+
MenuItemCompat.setIconTintList(menuItem, getResolvedIconTintList(menuItem, options))
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
options.menuTitle?.let { update ->
|
|
313
|
+
val subMenu = menuItem.subMenu
|
|
314
|
+
if (subMenu != null) {
|
|
315
|
+
// In order to match native behavior, we need to clear the header first and then use
|
|
316
|
+
// regular title if menuTitle is not provided. If title is also null, there will be
|
|
317
|
+
// no submenu header at all.
|
|
318
|
+
subMenu.clearHeader()
|
|
319
|
+
subMenu.setHeaderTitle(update.valueOrNull() ?: menuItem.title)
|
|
320
|
+
} else {
|
|
321
|
+
Log.w(TAG, "[RNScreens] menuTitle ignored: target is not a submenu.")
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
private fun StackHeaderToolbarMenuItemConfig.toOptions() =
|
|
327
|
+
StackHeaderToolbarMenuElementOptions(
|
|
328
|
+
title = StackHeaderToolbarFieldUpdate.from(title),
|
|
329
|
+
titleCondensed = StackHeaderToolbarFieldUpdate.from(titleCondensed),
|
|
330
|
+
tooltipText = StackHeaderToolbarFieldUpdate.from(tooltipText),
|
|
331
|
+
accessibilityLabel = StackHeaderToolbarFieldUpdate.from(accessibilityLabel),
|
|
332
|
+
hidden = hidden,
|
|
333
|
+
disabled = disabled,
|
|
334
|
+
showAsAction = showAsAction,
|
|
335
|
+
icon = StackHeaderToolbarFieldUpdate.from(icon),
|
|
336
|
+
iconTintColorNormal = StackHeaderToolbarFieldUpdate.from(iconTintColorNormal),
|
|
337
|
+
iconTintColorPressed = StackHeaderToolbarFieldUpdate.from(iconTintColorPressed),
|
|
338
|
+
iconTintColorFocused = StackHeaderToolbarFieldUpdate.from(iconTintColorFocused),
|
|
339
|
+
iconTintColorDisabled = StackHeaderToolbarFieldUpdate.from(iconTintColorDisabled),
|
|
340
|
+
)
|
|
341
|
+
|
|
342
|
+
// endregion
|
|
343
|
+
|
|
344
|
+
// region Icon tint
|
|
345
|
+
|
|
346
|
+
private fun getResolvedIconTintList(
|
|
347
|
+
menuItem: MenuItem,
|
|
348
|
+
options: StackHeaderToolbarMenuElementOptions,
|
|
349
|
+
): ColorStateList? {
|
|
350
|
+
val currentTintList = MenuItemCompat.getIconTintList(menuItem)
|
|
351
|
+
// The currently-applied normal (catch-all) color, if any. Used both as the "leave
|
|
352
|
+
// unchanged" value for normal and to dedup read-back overrides: when a normal entry
|
|
353
|
+
// exists every override probe also matches it, so an override equal to the current
|
|
354
|
+
// normal is the catch-all leaking through rather than an explicit override.
|
|
355
|
+
val currentNormal = currentTintList?.resolvedColorOrNull(intArrayOf(android.R.attr.state_enabled))
|
|
356
|
+
|
|
357
|
+
val finalNormal =
|
|
358
|
+
when (val update = options.iconTintColorNormal) {
|
|
359
|
+
StackHeaderToolbarFieldUpdate.Reset -> null
|
|
360
|
+
is StackHeaderToolbarFieldUpdate.Set -> update.value
|
|
361
|
+
null -> currentNormal
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
val finalDisabled =
|
|
365
|
+
when (val update = options.iconTintColorDisabled) {
|
|
366
|
+
StackHeaderToolbarFieldUpdate.Reset -> null
|
|
367
|
+
is StackHeaderToolbarFieldUpdate.Set -> update.value
|
|
368
|
+
null ->
|
|
369
|
+
currentTintList
|
|
370
|
+
?.resolvedColorOrNull(intArrayOf(-android.R.attr.state_enabled))
|
|
371
|
+
?.takeIf { it != currentNormal }
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
val finalPressed =
|
|
375
|
+
when (val update = options.iconTintColorPressed) {
|
|
376
|
+
StackHeaderToolbarFieldUpdate.Reset -> null
|
|
377
|
+
is StackHeaderToolbarFieldUpdate.Set -> update.value
|
|
378
|
+
null ->
|
|
379
|
+
currentTintList
|
|
380
|
+
?.resolvedColorOrNull(intArrayOf(android.R.attr.state_enabled, android.R.attr.state_pressed))
|
|
381
|
+
?.takeIf { it != currentNormal }
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
val finalFocused =
|
|
385
|
+
when (val update = options.iconTintColorFocused) {
|
|
386
|
+
StackHeaderToolbarFieldUpdate.Reset -> null
|
|
387
|
+
is StackHeaderToolbarFieldUpdate.Set -> update.value
|
|
388
|
+
null ->
|
|
389
|
+
currentTintList
|
|
390
|
+
?.resolvedColorOrNull(intArrayOf(android.R.attr.state_enabled, android.R.attr.state_focused))
|
|
391
|
+
?.takeIf { it != currentNormal }
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
val states = mutableListOf<IntArray>()
|
|
395
|
+
val colors = mutableListOf<Int>()
|
|
396
|
+
|
|
397
|
+
finalDisabled?.let {
|
|
398
|
+
states.add(intArrayOf(-android.R.attr.state_enabled))
|
|
399
|
+
colors.add(it)
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
finalPressed?.let {
|
|
403
|
+
states.add(intArrayOf(android.R.attr.state_pressed))
|
|
404
|
+
colors.add(it)
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
finalFocused?.let {
|
|
408
|
+
states.add(intArrayOf(android.R.attr.state_focused))
|
|
409
|
+
colors.add(it)
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
finalNormal?.let {
|
|
413
|
+
states.add(intArrayOf())
|
|
414
|
+
colors.add(it)
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
return if (states.isNotEmpty()) {
|
|
418
|
+
ColorStateList(states.toTypedArray(), colors.toIntArray())
|
|
419
|
+
} else {
|
|
420
|
+
null
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* Resolves the color the receiver applies to [stateSet], or `null` when no state spec
|
|
426
|
+
* matches it.
|
|
427
|
+
*
|
|
428
|
+
* `getColorForState` returns the caller-supplied fallback when nothing matches, so we
|
|
429
|
+
* probe twice with two distinct sentinels: equal results mean a real spec matched (the
|
|
430
|
+
* actual color), differing results mean the slot is absent. This is robust for any color
|
|
431
|
+
* value and keeps the read-back stateless — see [getResolvedIconTintList].
|
|
432
|
+
*/
|
|
433
|
+
private fun ColorStateList.resolvedColorOrNull(stateSet: IntArray): Int? {
|
|
434
|
+
val a = getColorForState(stateSet, SENTINEL_A)
|
|
435
|
+
val b = getColorForState(stateSet, SENTINEL_B)
|
|
436
|
+
return if (a == b) a else null
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// endregion
|
|
440
|
+
|
|
441
|
+
private const val TAG = "StackHeaderToolbarMenuApplicator"
|
|
442
|
+
|
|
443
|
+
// Two distinct sentinel fallbacks used to detect whether a ColorStateList actually
|
|
444
|
+
// defines a color for a given state. Their concrete values are irrelevant as long as
|
|
445
|
+
// they differ — see resolvedColorOrNull.
|
|
446
|
+
private const val SENTINEL_A = 0x00000001
|
|
447
|
+
private const val SENTINEL_B = 0x00000002
|
|
448
|
+
}
|
|
@@ -11,11 +11,25 @@ import com.swmansion.rnscreens.helpers.readColor
|
|
|
11
11
|
import com.swmansion.rnscreens.helpers.readImageUri
|
|
12
12
|
import com.swmansion.rnscreens.helpers.readOptionalString
|
|
13
13
|
import com.swmansion.rnscreens.helpers.requireNotNullString
|
|
14
|
+
import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuConfig
|
|
15
|
+
import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuElementConfig
|
|
16
|
+
import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuGroupConfig
|
|
17
|
+
import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuItemConfig
|
|
18
|
+
import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuItemDefaults
|
|
19
|
+
import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuItemIconSource
|
|
20
|
+
import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuItemShowAsAction
|
|
21
|
+
import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuItemType
|
|
22
|
+
import com.swmansion.rnscreens.stack.header.toolbar.update.StackHeaderToolbarFieldUpdate
|
|
23
|
+
import com.swmansion.rnscreens.stack.header.toolbar.update.StackHeaderToolbarMenuElementOptions
|
|
14
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Parses React toolbar-menu props (Dynamic / ReadableMap) into the native menu
|
|
27
|
+
* config and element-update models.
|
|
28
|
+
*/
|
|
15
29
|
internal object StackHeaderToolbarMenuMapper {
|
|
16
30
|
// region Menu prop parsing
|
|
17
31
|
|
|
18
|
-
fun parseMenu(
|
|
32
|
+
internal fun parseMenu(
|
|
19
33
|
context: Context,
|
|
20
34
|
value: Dynamic,
|
|
21
35
|
): Pair<StackHeaderToolbarMenuConfig, Map<String, StackHeaderToolbarMenuItemIconSource>> {
|
|
@@ -34,7 +48,7 @@ internal object StackHeaderToolbarMenuMapper {
|
|
|
34
48
|
|
|
35
49
|
// region Menu element command parsing
|
|
36
50
|
|
|
37
|
-
fun parseMenuElementOptions(
|
|
51
|
+
internal fun parseMenuElementOptions(
|
|
38
52
|
context: Context,
|
|
39
53
|
map: ReadableMap,
|
|
40
54
|
): StackHeaderToolbarMenuElementOptions =
|
|
@@ -63,7 +77,7 @@ internal object StackHeaderToolbarMenuMapper {
|
|
|
63
77
|
menuTitle = map.readNullableStringUpdate("menuTitle"),
|
|
64
78
|
)
|
|
65
79
|
|
|
66
|
-
fun parseMenuElementIconSource(map: ReadableMap): StackHeaderToolbarMenuItemIconSource? {
|
|
80
|
+
internal fun parseMenuElementIconSource(map: ReadableMap): StackHeaderToolbarMenuItemIconSource? {
|
|
67
81
|
if (!map.hasKey("drawableIconResourceName") && !map.hasKey("imageIconResource")) {
|
|
68
82
|
return null
|
|
69
83
|
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
package com.swmansion.rnscreens.stack.header.toolbar
|
|
2
|
+
|
|
3
|
+
import android.util.Log
|
|
4
|
+
import com.google.android.material.appbar.MaterialToolbar
|
|
5
|
+
import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuGroupMetadata
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Owns toolbar-menu selection state (id map + group metadata) and applies
|
|
9
|
+
* group-item checked-state changes.
|
|
10
|
+
*/
|
|
11
|
+
internal class StackHeaderToolbarMenuSelectionController {
|
|
12
|
+
internal var forwardIdMap: Map<String, Int> = emptyMap()
|
|
13
|
+
private set
|
|
14
|
+
|
|
15
|
+
private var groupMetadata: StackHeaderToolbarMenuGroupMetadata = StackHeaderToolbarMenuGroupMetadata.EMPTY
|
|
16
|
+
|
|
17
|
+
internal fun setMenuMaps(
|
|
18
|
+
forwardIdMap: Map<String, Int>,
|
|
19
|
+
groupMetadata: StackHeaderToolbarMenuGroupMetadata,
|
|
20
|
+
) {
|
|
21
|
+
this.forwardIdMap = forwardIdMap
|
|
22
|
+
this.groupMetadata = groupMetadata
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
internal fun clear() {
|
|
26
|
+
forwardIdMap = emptyMap()
|
|
27
|
+
groupMetadata = StackHeaderToolbarMenuGroupMetadata.EMPTY
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Mutates the checked state of [itemId] within its group and returns the id of the group
|
|
32
|
+
* whose selection changed, or `null` when nothing changed (the item is not in a group, an
|
|
33
|
+
* invalid attempt to uncheck a single-selection item, or the item was already in the
|
|
34
|
+
* target state). Does not emit — callers decide when to emit so that batched updates can
|
|
35
|
+
* coalesce into one event per group.
|
|
36
|
+
*/
|
|
37
|
+
internal fun applyGroupItemStateChange(
|
|
38
|
+
toolbar: MaterialToolbar,
|
|
39
|
+
itemId: String,
|
|
40
|
+
explicitCheckedValue: Boolean? = null,
|
|
41
|
+
): String? {
|
|
42
|
+
val groupId = groupMetadata.itemGroupMap[itemId] ?: return null
|
|
43
|
+
val singleSelection = groupMetadata.groupSingleSelection[groupId] ?: return null
|
|
44
|
+
val intId = forwardIdMap[itemId] ?: return null
|
|
45
|
+
val menuItem = toolbar.menu.findItem(intId) ?: return null
|
|
46
|
+
|
|
47
|
+
if (singleSelection && explicitCheckedValue == false) {
|
|
48
|
+
Log.w(
|
|
49
|
+
TAG,
|
|
50
|
+
"[RNScreens] Cannot uncheck item '$itemId' in single-selection group '$groupId'. " +
|
|
51
|
+
"Check a different item instead.",
|
|
52
|
+
)
|
|
53
|
+
return null
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
val newChecked =
|
|
57
|
+
if (singleSelection) {
|
|
58
|
+
true
|
|
59
|
+
} else {
|
|
60
|
+
explicitCheckedValue ?: !menuItem.isChecked
|
|
61
|
+
}
|
|
62
|
+
if (menuItem.isChecked == newChecked) return null
|
|
63
|
+
menuItem.isChecked = newChecked
|
|
64
|
+
|
|
65
|
+
return groupId
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
internal fun collectSelectedIds(
|
|
69
|
+
toolbar: MaterialToolbar,
|
|
70
|
+
groupId: String,
|
|
71
|
+
): List<String> =
|
|
72
|
+
groupMetadata
|
|
73
|
+
.groupMemberItems[groupId]
|
|
74
|
+
.orEmpty()
|
|
75
|
+
.filter { memberId ->
|
|
76
|
+
val intId = forwardIdMap[memberId] ?: return@filter false
|
|
77
|
+
toolbar.menu.findItem(intId)?.isChecked == true
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
companion object {
|
|
81
|
+
private const val TAG = "StackHeaderToolbarMenuSelectionController"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
package com.swmansion.rnscreens.stack.header.toolbar
|
|
1
|
+
package com.swmansion.rnscreens.stack.header.toolbar.model
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Derived group structure for a built menu: item→group, per-group
|
|
5
|
+
* single-selection, and group membership.
|
|
6
|
+
*/
|
|
3
7
|
internal data class StackHeaderToolbarMenuGroupMetadata(
|
|
4
8
|
val itemGroupMap: Map<String, String>,
|
|
5
9
|
val groupSingleSelection: Map<String, Boolean>,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
package com.swmansion.rnscreens.stack.header.toolbar
|
|
1
|
+
package com.swmansion.rnscreens.stack.header.toolbar.update
|
|
2
2
|
|
|
3
3
|
import android.graphics.drawable.Drawable
|
|
4
|
+
import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuItemShowAsAction
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Partial update for a toolbar menu element.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
package com.swmansion.rnscreens.stack.header.toolbar.update
|
|
2
|
+
|
|
3
|
+
import com.swmansion.rnscreens.stack.header.toolbar.model.StackHeaderToolbarMenuItemIconSource
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A single toolbar menu element update carried by an `updateToolbarMenuElements`
|
|
7
|
+
* view command, before its icon (if any) has been resolved.
|
|
8
|
+
*/
|
|
9
|
+
internal data class StackHeaderToolbarMenuElementRawUpdate(
|
|
10
|
+
val id: String,
|
|
11
|
+
val options: StackHeaderToolbarMenuElementOptions,
|
|
12
|
+
val iconSource: StackHeaderToolbarMenuItemIconSource?,
|
|
13
|
+
)
|