react-native-screens 4.12.0 → 4.13.0
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/RNScreens.podspec +29 -2
- package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +4 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.kt +9 -1
- package/android/src/main/java/com/swmansion/rnscreens/ScreenFragmentWrapper.kt +0 -1
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +4 -4
- package/android/src/main/java/com/swmansion/rnscreens/ScreensModule.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/DimmingView.kt +4 -4
- package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/DimmingViewManager.kt +8 -2
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenAnimationDelegate.kt +1 -2
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenEventEmitter.kt +16 -13
- package/android/src/main/java/com/swmansion/rnscreens/gamma/common/BaseEventEmitter.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/gamma/common/FragmentProviding.kt +11 -0
- package/android/src/main/java/com/swmansion/rnscreens/gamma/common/NamingAwareEventType.kt +13 -0
- package/android/src/main/java/com/swmansion/rnscreens/gamma/helpers/EventHelpers.kt +6 -0
- package/android/src/main/java/com/swmansion/rnscreens/gamma/helpers/FragmentManagerHelper.kt +76 -0
- package/android/src/main/java/com/swmansion/rnscreens/gamma/helpers/SystemDrawable.kt +33 -0
- package/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/TabScreen.kt +101 -0
- package/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/TabScreenDelegate.kt +17 -0
- package/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/TabScreenEventEmitter.kt +46 -0
- package/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/TabScreenFragment.kt +37 -0
- package/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/TabScreenViewManager.kt +178 -0
- package/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/TabsHost.kt +433 -0
- package/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/TabsHostEventEmitter.kt +14 -0
- package/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/TabsHostViewManager.kt +177 -0
- package/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/event/TabScreenDidAppearEvent.kt +30 -0
- package/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/event/TabScreenDidDisappearEvent.kt +30 -0
- package/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/event/TabScreenWillAppearEvent.kt +30 -0
- package/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/event/TabScreenWillDisappearEvent.kt +30 -0
- package/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/event/TabsHostNativeFocusChangeEvent.kt +36 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/views/ChildDrawingOrderStrategyImpl.kt +0 -1
- package/android/src/main/java/com/swmansion/rnscreens/transition/ExternalBoundaryValuesEvaluator.kt +9 -2
- package/android/src/main/java/com/swmansion/rnscreens/utils/FragmentTransactionKt.kt +4 -1
- package/android/src/main/jni/rnscreens.h +1 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSBottomTabsManagerDelegate.java +76 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSBottomTabsManagerInterface.java +33 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSBottomTabsScreenManagerDelegate.java +97 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSBottomTabsScreenManagerInterface.java +40 -0
- package/android/src/paper/java/com/swmansion/rnscreens/FabricEnabledHeaderConfigViewGroup.kt +2 -2
- package/android/src/versioned/backgroundcolor/76/ViewBackgroundUtils.kt +0 -1
- package/android/src/versioned/backgroundcolor/latest/ViewBackgroundUtils.kt +0 -3
- package/android/src/versioned/pointerevents/77/com/swmansion/rnscreens/PointerEventsBoxNoneImpl.kt +1 -1
- package/android/src/versioned/pointerevents/latest/com/swmansion/rnscreens/PointerEventsBoxNoneImpl.kt +1 -1
- package/common/cpp/react/renderer/components/rnscreens/RNSBottomTabsComponentDescriptor.h +31 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSBottomTabsShadowNode.cpp +20 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSBottomTabsShadowNode.h +32 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSBottomTabsState.cpp +22 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSBottomTabsState.h +44 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.cpp +8 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSSplitViewScreenComponentDescriptor.h +40 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSSplitViewScreenShadowNode.cpp +13 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSSplitViewScreenShadowNode.h +36 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSSplitViewScreenState.h +32 -0
- package/cpp/RNScreensTurboModule.h +5 -0
- package/ios/RNSEnums.h +6 -0
- package/ios/RNSScreen.h +2 -1
- package/ios/RNSScreen.mm +48 -1
- package/ios/RNSScreenContainer.mm +6 -0
- package/ios/RNSScreenStack.h +3 -1
- package/ios/RNSScreenStack.mm +39 -2
- package/ios/RNSScreenStackHeaderConfig.mm +1 -1
- package/ios/RNSScrollViewBehaviorOverriding.h +24 -0
- package/ios/RNSScrollViewFinder.h +13 -0
- package/ios/RNSScrollViewFinder.mm +22 -0
- package/ios/RNSScrollViewHelper.h +10 -0
- package/ios/RNSScrollViewHelper.mm +15 -0
- package/ios/RNScreens-Bridging-Header.h +4 -0
- package/ios/UIScrollView+RNScreens.h +14 -0
- package/ios/UIScrollView+RNScreens.mm +15 -0
- package/ios/bottom-tabs/RCTConvert+RNSBottomTabs.h +18 -0
- package/ios/bottom-tabs/RCTConvert+RNSBottomTabs.mm +25 -0
- package/ios/bottom-tabs/RNSBottomTabsHostComponentView.h +80 -0
- package/ios/bottom-tabs/RNSBottomTabsHostComponentView.mm +486 -0
- package/ios/bottom-tabs/RNSBottomTabsHostComponentViewManager.h +11 -0
- package/ios/bottom-tabs/RNSBottomTabsHostComponentViewManager.mm +48 -0
- package/ios/bottom-tabs/RNSBottomTabsHostEventEmitter.h +53 -0
- package/ios/bottom-tabs/RNSBottomTabsHostEventEmitter.mm +57 -0
- package/ios/bottom-tabs/RNSBottomTabsScreenComponentView.h +95 -0
- package/ios/bottom-tabs/RNSBottomTabsScreenComponentView.mm +492 -0
- package/ios/bottom-tabs/RNSBottomTabsScreenComponentViewManager.h +9 -0
- package/ios/bottom-tabs/RNSBottomTabsScreenComponentViewManager.mm +55 -0
- package/ios/bottom-tabs/RNSBottomTabsScreenEventEmitter.h +53 -0
- package/ios/bottom-tabs/RNSBottomTabsScreenEventEmitter.mm +106 -0
- package/ios/bottom-tabs/RNSBottomTabsSpecialEffectsSupporting.h +17 -0
- package/ios/bottom-tabs/RNSTabBarAppearanceCoordinator.h +34 -0
- package/ios/bottom-tabs/RNSTabBarAppearanceCoordinator.mm +243 -0
- package/ios/bottom-tabs/RNSTabBarAppearanceProvider.h +23 -0
- package/ios/bottom-tabs/RNSTabBarController.h +132 -0
- package/ios/bottom-tabs/RNSTabBarController.mm +206 -0
- package/ios/bottom-tabs/RNSTabBarControllerDelegate.h +9 -0
- package/ios/bottom-tabs/RNSTabBarControllerDelegate.mm +63 -0
- package/ios/bottom-tabs/RNSTabsScreenViewController.h +42 -0
- package/ios/bottom-tabs/RNSTabsScreenViewController.mm +105 -0
- package/ios/bottom-tabs/extensions/RNSBottomTabsHostComponentView+RNSImageLoader.h +21 -0
- package/ios/bottom-tabs/extensions/RNSBottomTabsHostComponentView+RNSImageLoader.mm +22 -0
- package/ios/bridging/RNSReactBaseView.h +31 -0
- package/ios/bridging/RNSReactBaseView.mm +5 -0
- package/ios/bridging/Swift-Bridging.h +7 -0
- package/ios/conversion/RNSConversions-BottomTabs.mm +216 -0
- package/ios/conversion/RNSConversions-SplitView.mm +63 -0
- package/ios/conversion/RNSConversions.h +53 -0
- package/ios/gamma/ReactMountingTransactionObserving.swift +7 -0
- package/ios/gamma/split-view/RNSSplitViewHostComponentView.h +29 -0
- package/ios/gamma/split-view/RNSSplitViewHostComponentView.mm +209 -0
- package/ios/gamma/split-view/RNSSplitViewHostComponentViewManager.h +11 -0
- package/ios/gamma/split-view/RNSSplitViewHostComponentViewManager.mm +7 -0
- package/ios/gamma/split-view/RNSSplitViewHostController.swift +98 -0
- package/ios/gamma/split-view/RNSSplitViewNavigationController.swift +31 -0
- package/ios/gamma/split-view/RNSSplitViewScreenComponentView.h +24 -0
- package/ios/gamma/split-view/RNSSplitViewScreenComponentView.mm +106 -0
- package/ios/gamma/split-view/RNSSplitViewScreenComponentViewManager.h +11 -0
- package/ios/gamma/split-view/RNSSplitViewScreenComponentViewManager.mm +7 -0
- package/ios/gamma/split-view/RNSSplitViewScreenController.swift +86 -0
- package/ios/gamma/split-view/RNSSplitViewScreenShadowStateProxy.h +35 -0
- package/ios/gamma/split-view/RNSSplitViewScreenShadowStateProxy.mm +56 -0
- package/ios/gamma/stack/RNSScreenStackHostComponentView.h +16 -0
- package/ios/gamma/stack/RNSScreenStackHostComponentView.mm +143 -0
- package/ios/gamma/stack/RNSScreenStackHostComponentViewManager.h +11 -0
- package/ios/gamma/stack/RNSScreenStackHostComponentViewManager.mm +7 -0
- package/ios/gamma/stack/RNSStackController.swift +65 -0
- package/ios/gamma/stack/RNSStackScreenComponentEventEmitter.h +37 -0
- package/ios/gamma/stack/RNSStackScreenComponentEventEmitter.mm +60 -0
- package/ios/gamma/stack/RNSStackScreenComponentView.h +36 -0
- package/ios/gamma/stack/RNSStackScreenComponentView.mm +124 -0
- package/ios/gamma/stack/RNSStackScreenComponentViewManager.h +11 -0
- package/ios/gamma/stack/RNSStackScreenComponentViewManager.mm +7 -0
- package/ios/gamma/stack/RNSStackScreenController.swift +56 -0
- package/ios/utils/NSString+RNSUtility.h +17 -0
- package/ios/utils/NSString+RNSUtility.mm +37 -0
- package/lib/commonjs/components/BottomTabs.js +54 -0
- package/lib/commonjs/components/BottomTabs.js.map +1 -0
- package/lib/commonjs/components/BottomTabsScreen.js +149 -0
- package/lib/commonjs/components/BottomTabsScreen.js.map +1 -0
- package/lib/commonjs/components/gamma/ScreenStackHost.js +27 -0
- package/lib/commonjs/components/gamma/ScreenStackHost.js.map +1 -0
- package/lib/commonjs/components/gamma/SplitViewHost.js +57 -0
- package/lib/commonjs/components/gamma/SplitViewHost.js.map +1 -0
- package/lib/commonjs/components/gamma/SplitViewScreen.js +22 -0
- package/lib/commonjs/components/gamma/SplitViewScreen.js.map +1 -0
- package/lib/commonjs/components/gamma/StackScreen.js +51 -0
- package/lib/commonjs/components/gamma/StackScreen.js.map +1 -0
- package/lib/commonjs/fabric/BottomTabsNativeComponent.js +19 -0
- package/lib/commonjs/fabric/BottomTabsNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/BottomTabsScreenNativeComponent.js +14 -0
- package/lib/commonjs/fabric/BottomTabsScreenNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/gamma/ScreenStackHostNativeComponent.js +11 -0
- package/lib/commonjs/fabric/gamma/ScreenStackHostNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/gamma/SplitViewHostNativeComponent.js +11 -0
- package/lib/commonjs/fabric/gamma/SplitViewHostNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/gamma/SplitViewScreenNativeComponent.js +13 -0
- package/lib/commonjs/fabric/gamma/SplitViewScreenNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/gamma/StackScreenNativeComponent.js +12 -0
- package/lib/commonjs/fabric/gamma/StackScreenNativeComponent.js.map +1 -0
- package/lib/commonjs/flags.js +70 -0
- package/lib/commonjs/flags.js.map +1 -0
- package/lib/commonjs/index.js +66 -3
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/utils.js +0 -28
- package/lib/commonjs/utils.js.map +1 -1
- package/lib/module/components/BottomTabs.js +48 -0
- package/lib/module/components/BottomTabs.js.map +1 -0
- package/lib/module/components/BottomTabsScreen.js +144 -0
- package/lib/module/components/BottomTabsScreen.js.map +1 -0
- package/lib/module/components/gamma/ScreenStackHost.js +20 -0
- package/lib/module/components/gamma/ScreenStackHost.js.map +1 -0
- package/lib/module/components/gamma/SplitViewHost.js +50 -0
- package/lib/module/components/gamma/SplitViewHost.js.map +1 -0
- package/lib/module/components/gamma/SplitViewScreen.js +15 -0
- package/lib/module/components/gamma/SplitViewScreen.js.map +1 -0
- package/lib/module/components/gamma/StackScreen.js +44 -0
- package/lib/module/components/gamma/StackScreen.js.map +1 -0
- package/lib/module/fabric/BottomTabsNativeComponent.js +15 -0
- package/lib/module/fabric/BottomTabsNativeComponent.js.map +1 -0
- package/lib/module/fabric/BottomTabsScreenNativeComponent.js +12 -0
- package/lib/module/fabric/BottomTabsScreenNativeComponent.js.map +1 -0
- package/lib/module/fabric/gamma/ScreenStackHostNativeComponent.js +5 -0
- package/lib/module/fabric/gamma/ScreenStackHostNativeComponent.js.map +1 -0
- package/lib/module/fabric/gamma/SplitViewHostNativeComponent.js +5 -0
- package/lib/module/fabric/gamma/SplitViewHostNativeComponent.js.map +1 -0
- package/lib/module/fabric/gamma/SplitViewScreenNativeComponent.js +7 -0
- package/lib/module/fabric/gamma/SplitViewScreenNativeComponent.js.map +1 -0
- package/lib/module/fabric/gamma/StackScreenNativeComponent.js +8 -0
- package/lib/module/fabric/gamma/StackScreenNativeComponent.js.map +1 -0
- package/lib/module/flags.js +64 -0
- package/lib/module/flags.js.map +1 -0
- package/lib/module/index.js +16 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/utils.js +0 -27
- package/lib/module/utils.js.map +1 -1
- package/lib/typescript/components/BottomTabs.d.ts +30 -0
- package/lib/typescript/components/BottomTabs.d.ts.map +1 -0
- package/lib/typescript/components/BottomTabsScreen.d.ts +56 -0
- package/lib/typescript/components/BottomTabsScreen.d.ts.map +1 -0
- package/lib/typescript/components/gamma/ScreenStackHost.d.ts +13 -0
- package/lib/typescript/components/gamma/ScreenStackHost.d.ts.map +1 -0
- package/lib/typescript/components/gamma/SplitViewHost.d.ts +13 -0
- package/lib/typescript/components/gamma/SplitViewHost.d.ts.map +1 -0
- package/lib/typescript/components/gamma/SplitViewScreen.d.ts +13 -0
- package/lib/typescript/components/gamma/SplitViewScreen.d.ts.map +1 -0
- package/lib/typescript/components/gamma/StackScreen.d.ts +21 -0
- package/lib/typescript/components/gamma/StackScreen.d.ts.map +1 -0
- package/lib/typescript/fabric/BottomTabsNativeComponent.d.ts +31 -0
- package/lib/typescript/fabric/BottomTabsNativeComponent.d.ts.map +1 -0
- package/lib/typescript/fabric/BottomTabsScreenNativeComponent.d.ts +51 -0
- package/lib/typescript/fabric/BottomTabsScreenNativeComponent.d.ts.map +1 -0
- package/lib/typescript/fabric/gamma/ScreenStackHostNativeComponent.d.ts +7 -0
- package/lib/typescript/fabric/gamma/ScreenStackHostNativeComponent.d.ts.map +1 -0
- package/lib/typescript/fabric/gamma/SplitViewHostNativeComponent.d.ts +16 -0
- package/lib/typescript/fabric/gamma/SplitViewHostNativeComponent.d.ts.map +1 -0
- package/lib/typescript/fabric/gamma/SplitViewScreenNativeComponent.d.ts +7 -0
- package/lib/typescript/fabric/gamma/SplitViewScreenNativeComponent.d.ts.map +1 -0
- package/lib/typescript/fabric/gamma/StackScreenNativeComponent.d.ts +15 -0
- package/lib/typescript/fabric/gamma/StackScreenNativeComponent.d.ts.map +1 -0
- package/lib/typescript/flags.d.ts +45 -0
- package/lib/typescript/flags.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +14 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/utils.d.ts +0 -26
- package/lib/typescript/utils.d.ts.map +1 -1
- package/package.json +34 -6
- package/react-native.config.js +2 -1
- package/src/components/BottomTabs.tsx +115 -0
- package/src/components/BottomTabsScreen.tsx +291 -0
- package/src/components/gamma/ScreenStackHost.tsx +32 -0
- package/src/components/gamma/SplitViewHost.tsx +84 -0
- package/src/components/gamma/SplitViewScreen.tsx +26 -0
- package/src/components/gamma/StackScreen.tsx +64 -0
- package/src/fabric/BottomTabsNativeComponent.ts +82 -0
- package/src/fabric/BottomTabsScreenNativeComponent.ts +107 -0
- package/src/fabric/gamma/ScreenStackHostNativeComponent.ts +8 -0
- package/src/fabric/gamma/SplitViewHostNativeComponent.ts +39 -0
- package/src/fabric/gamma/SplitViewScreenNativeComponent.ts +10 -0
- package/src/fabric/gamma/StackScreenNativeComponent.ts +25 -0
- package/src/flags.ts +72 -0
- package/src/index.tsx +18 -1
- package/src/utils.ts +0 -28
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
package com.swmansion.rnscreens.gamma.tabs
|
|
2
|
+
|
|
3
|
+
import android.util.Log
|
|
4
|
+
import com.facebook.react.bridge.ReadableMap
|
|
5
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
6
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
7
|
+
import com.facebook.react.uimanager.ViewGroupManager
|
|
8
|
+
import com.facebook.react.uimanager.ViewManagerDelegate
|
|
9
|
+
import com.facebook.react.uimanager.annotations.ReactProp
|
|
10
|
+
import com.facebook.react.viewmanagers.RNSBottomTabsScreenManagerDelegate
|
|
11
|
+
import com.facebook.react.viewmanagers.RNSBottomTabsScreenManagerInterface
|
|
12
|
+
import com.swmansion.rnscreens.gamma.helpers.makeEventRegistrationInfo
|
|
13
|
+
import com.swmansion.rnscreens.gamma.tabs.event.TabScreenDidAppearEvent
|
|
14
|
+
import com.swmansion.rnscreens.gamma.tabs.event.TabScreenDidDisappearEvent
|
|
15
|
+
import com.swmansion.rnscreens.gamma.tabs.event.TabScreenWillAppearEvent
|
|
16
|
+
import com.swmansion.rnscreens.gamma.tabs.event.TabScreenWillDisappearEvent
|
|
17
|
+
|
|
18
|
+
@ReactModule(name = TabScreenViewManager.REACT_CLASS)
|
|
19
|
+
class TabScreenViewManager :
|
|
20
|
+
ViewGroupManager<TabScreen>(),
|
|
21
|
+
RNSBottomTabsScreenManagerInterface<TabScreen> {
|
|
22
|
+
private val delegate: ViewManagerDelegate<TabScreen> = RNSBottomTabsScreenManagerDelegate<TabScreen, TabScreenViewManager>(this)
|
|
23
|
+
|
|
24
|
+
override fun getName() = REACT_CLASS
|
|
25
|
+
|
|
26
|
+
override fun createViewInstance(reactContext: ThemedReactContext): TabScreen {
|
|
27
|
+
Log.d(REACT_CLASS, "createViewInstance")
|
|
28
|
+
return TabScreen(reactContext)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
override fun getDelegate() = delegate
|
|
32
|
+
|
|
33
|
+
override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> =
|
|
34
|
+
mutableMapOf(
|
|
35
|
+
makeEventRegistrationInfo(TabScreenWillAppearEvent),
|
|
36
|
+
makeEventRegistrationInfo(TabScreenDidAppearEvent),
|
|
37
|
+
makeEventRegistrationInfo(TabScreenWillDisappearEvent),
|
|
38
|
+
makeEventRegistrationInfo(TabScreenDidDisappearEvent),
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
override fun addEventEmitters(
|
|
42
|
+
reactContext: ThemedReactContext,
|
|
43
|
+
view: TabScreen,
|
|
44
|
+
) {
|
|
45
|
+
super.addEventEmitters(reactContext, view)
|
|
46
|
+
view.onViewManagerAddEventEmitters()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// These should be ignored or another component, dedicated for Android should be used
|
|
50
|
+
|
|
51
|
+
override fun setTabBarBackgroundColor(
|
|
52
|
+
view: TabScreen,
|
|
53
|
+
value: Int?,
|
|
54
|
+
) = Unit
|
|
55
|
+
|
|
56
|
+
override fun setTabBarBlurEffect(
|
|
57
|
+
view: TabScreen,
|
|
58
|
+
value: String?,
|
|
59
|
+
) = Unit
|
|
60
|
+
|
|
61
|
+
override fun setTabBarItemTitleFontFamily(
|
|
62
|
+
view: TabScreen,
|
|
63
|
+
value: String?,
|
|
64
|
+
) = Unit
|
|
65
|
+
|
|
66
|
+
override fun setTabBarItemTitleFontSize(
|
|
67
|
+
view: TabScreen,
|
|
68
|
+
value: Float,
|
|
69
|
+
) = Unit
|
|
70
|
+
|
|
71
|
+
override fun setTabBarItemTitleFontWeight(
|
|
72
|
+
view: TabScreen,
|
|
73
|
+
value: String?,
|
|
74
|
+
) = Unit
|
|
75
|
+
|
|
76
|
+
override fun setTabBarItemTitleFontStyle(
|
|
77
|
+
view: TabScreen,
|
|
78
|
+
value: String?,
|
|
79
|
+
) = Unit
|
|
80
|
+
|
|
81
|
+
override fun setTabBarItemTitleFontColor(
|
|
82
|
+
view: TabScreen,
|
|
83
|
+
value: Int?,
|
|
84
|
+
) = Unit
|
|
85
|
+
|
|
86
|
+
override fun setTabBarItemBadgeBackgroundColor(
|
|
87
|
+
view: TabScreen,
|
|
88
|
+
value: Int?,
|
|
89
|
+
) = Unit
|
|
90
|
+
|
|
91
|
+
override fun setTabBarItemTitlePositionAdjustment(
|
|
92
|
+
view: TabScreen?,
|
|
93
|
+
value: ReadableMap?,
|
|
94
|
+
) = Unit
|
|
95
|
+
|
|
96
|
+
override fun setTabBarItemIconColor(
|
|
97
|
+
view: TabScreen?,
|
|
98
|
+
value: Int?,
|
|
99
|
+
) = Unit
|
|
100
|
+
|
|
101
|
+
override fun setIconType(
|
|
102
|
+
view: TabScreen?,
|
|
103
|
+
value: String?,
|
|
104
|
+
) = Unit
|
|
105
|
+
|
|
106
|
+
override fun setIconImageSource(
|
|
107
|
+
view: TabScreen?,
|
|
108
|
+
value: ReadableMap?,
|
|
109
|
+
) = Unit
|
|
110
|
+
|
|
111
|
+
override fun setIconSfSymbolName(
|
|
112
|
+
view: TabScreen?,
|
|
113
|
+
value: String?,
|
|
114
|
+
) = Unit
|
|
115
|
+
|
|
116
|
+
override fun setSelectedIconImageSource(
|
|
117
|
+
view: TabScreen?,
|
|
118
|
+
value: ReadableMap?
|
|
119
|
+
) = Unit
|
|
120
|
+
|
|
121
|
+
override fun setSelectedIconSfSymbolName(
|
|
122
|
+
view: TabScreen?,
|
|
123
|
+
value: String?
|
|
124
|
+
) = Unit
|
|
125
|
+
|
|
126
|
+
// Annotation is Paper only
|
|
127
|
+
@ReactProp(name = "isFocused")
|
|
128
|
+
override fun setIsFocused(
|
|
129
|
+
view: TabScreen,
|
|
130
|
+
value: Boolean,
|
|
131
|
+
) {
|
|
132
|
+
Log.d(REACT_CLASS, "TabScreen [${view.id}] setIsFocused $value")
|
|
133
|
+
view.isFocusedTab = value
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
@ReactProp(name = "tabKey")
|
|
137
|
+
override fun setTabKey(
|
|
138
|
+
view: TabScreen,
|
|
139
|
+
value: String?,
|
|
140
|
+
) {
|
|
141
|
+
view.tabKey = value
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
override fun setBadgeValue(
|
|
145
|
+
view: TabScreen?,
|
|
146
|
+
value: String?,
|
|
147
|
+
) = Unit
|
|
148
|
+
|
|
149
|
+
@ReactProp(name = "title")
|
|
150
|
+
override fun setTitle(
|
|
151
|
+
view: TabScreen,
|
|
152
|
+
value: String?,
|
|
153
|
+
) {
|
|
154
|
+
view.tabTitle = value
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
@ReactProp(name = "iconResourceName")
|
|
158
|
+
override fun setIconResourceName(
|
|
159
|
+
view: TabScreen,
|
|
160
|
+
value: String?,
|
|
161
|
+
) {
|
|
162
|
+
view.iconResourceName = value
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
override fun setSpecialEffects(
|
|
166
|
+
view: TabScreen,
|
|
167
|
+
value: ReadableMap?,
|
|
168
|
+
) = Unit
|
|
169
|
+
|
|
170
|
+
override fun setOverrideScrollViewContentInsetAdjustmentBehavior(
|
|
171
|
+
view: TabScreen,
|
|
172
|
+
value: Boolean
|
|
173
|
+
) = Unit
|
|
174
|
+
|
|
175
|
+
companion object {
|
|
176
|
+
const val REACT_CLASS = "RNSBottomTabsScreen"
|
|
177
|
+
}
|
|
178
|
+
}
|
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
package com.swmansion.rnscreens.gamma.tabs
|
|
2
|
+
|
|
3
|
+
import android.R
|
|
4
|
+
import android.content.res.ColorStateList
|
|
5
|
+
import android.util.Log
|
|
6
|
+
import android.view.Menu
|
|
7
|
+
import android.view.MenuItem
|
|
8
|
+
import android.view.ViewGroup
|
|
9
|
+
import android.widget.FrameLayout
|
|
10
|
+
import android.widget.LinearLayout
|
|
11
|
+
import android.widget.TextView
|
|
12
|
+
import androidx.core.view.children
|
|
13
|
+
import androidx.core.view.isVisible
|
|
14
|
+
import androidx.fragment.app.FragmentManager
|
|
15
|
+
import com.facebook.react.common.assets.ReactFontManager
|
|
16
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
17
|
+
import com.google.android.material.bottomnavigation.BottomNavigationView
|
|
18
|
+
import com.google.android.material.navigation.NavigationBarView
|
|
19
|
+
import com.swmansion.rnscreens.BuildConfig
|
|
20
|
+
import com.swmansion.rnscreens.gamma.helpers.FragmentManagerHelper
|
|
21
|
+
import kotlin.properties.Delegates
|
|
22
|
+
|
|
23
|
+
class TabsHost(
|
|
24
|
+
val reactContext: ThemedReactContext,
|
|
25
|
+
) : LinearLayout(reactContext),
|
|
26
|
+
TabScreenDelegate {
|
|
27
|
+
/**
|
|
28
|
+
* All container updates should go through instance of this class.
|
|
29
|
+
* The semantics are as follows:
|
|
30
|
+
*
|
|
31
|
+
* * `invalidateXXX` methods do mark that some update is required, however **they do not schedule the update**!
|
|
32
|
+
* * `postXXX` methods schedule an update
|
|
33
|
+
* * `runXXX` methods execute update synchronously
|
|
34
|
+
*
|
|
35
|
+
* If there is a posted update & before it is executed updates are flushed synchronously, then
|
|
36
|
+
* the posted update becomes a noop.
|
|
37
|
+
*/
|
|
38
|
+
private inner class ContainerUpdateCoordinator {
|
|
39
|
+
private var isUpdatePending: Boolean = false
|
|
40
|
+
|
|
41
|
+
private var isSelectedTabInvalidated: Boolean = false
|
|
42
|
+
private var isBottomNavigationMenuInvalidated: Boolean = false
|
|
43
|
+
|
|
44
|
+
fun invalidateSelectedTab() {
|
|
45
|
+
isSelectedTabInvalidated = true
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
fun invalidateNavigationMenu() {
|
|
49
|
+
isBottomNavigationMenuInvalidated = true
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
fun invalidateAll() {
|
|
53
|
+
invalidateSelectedTab()
|
|
54
|
+
invalidateNavigationMenu()
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
fun postContainerUpdateIfNeeded() {
|
|
58
|
+
if (isUpdatePending) {
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
postContainerUpdate()
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
fun postContainerUpdate() {
|
|
65
|
+
isUpdatePending = true
|
|
66
|
+
post {
|
|
67
|
+
runContainerUpdateIfNeeded()
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private fun runContainerUpdateIfNeeded() {
|
|
72
|
+
if (isUpdatePending) {
|
|
73
|
+
runContainerUpdate()
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
fun runContainerUpdate() {
|
|
78
|
+
isUpdatePending = false
|
|
79
|
+
if (isSelectedTabInvalidated) {
|
|
80
|
+
isSelectedTabInvalidated = false
|
|
81
|
+
this@TabsHost.updateSelectedTab()
|
|
82
|
+
}
|
|
83
|
+
if (isBottomNavigationMenuInvalidated) {
|
|
84
|
+
isBottomNavigationMenuInvalidated = false
|
|
85
|
+
this@TabsHost.updateBottomNavigationViewAppearance()
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
private val containerUpdateCoordinator = ContainerUpdateCoordinator()
|
|
91
|
+
|
|
92
|
+
private val bottomNavigationView: BottomNavigationView =
|
|
93
|
+
BottomNavigationView(reactContext).apply {
|
|
94
|
+
layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private val contentView: FrameLayout =
|
|
98
|
+
FrameLayout(reactContext).apply {
|
|
99
|
+
layoutParams =
|
|
100
|
+
LinearLayout
|
|
101
|
+
.LayoutParams(
|
|
102
|
+
LayoutParams.MATCH_PARENT,
|
|
103
|
+
LayoutParams.WRAP_CONTENT,
|
|
104
|
+
).apply {
|
|
105
|
+
weight = 1f
|
|
106
|
+
}
|
|
107
|
+
id = generateViewId()
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
internal lateinit var eventEmitter: TabsHostEventEmitter
|
|
111
|
+
|
|
112
|
+
private var fragmentManager: FragmentManager? = null
|
|
113
|
+
private val requireFragmentManager
|
|
114
|
+
get() = checkNotNull(fragmentManager) { "[RNScreens] Nullish fragment manager" }
|
|
115
|
+
|
|
116
|
+
private val tabScreenFragments: MutableList<TabScreenFragment> = arrayListOf()
|
|
117
|
+
|
|
118
|
+
private var isLayoutInvalidated: Boolean = false
|
|
119
|
+
|
|
120
|
+
var tabBarBackgroundColor: Int? by Delegates.observable<Int?>(null) { _, oldValue, newValue ->
|
|
121
|
+
updateNavigationMenuIfNeeded(oldValue, newValue)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
var tabBarItemIconColor: Int? by Delegates.observable<Int?>(null) { _, oldValue, newValue ->
|
|
125
|
+
updateNavigationMenuIfNeeded(oldValue, newValue)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
var tabBarItemTitleFontFamily: String? by Delegates.observable<String?>(null) { _, oldValue, newValue ->
|
|
129
|
+
updateNavigationMenuIfNeeded(oldValue, newValue)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
var tabBarItemIconColorActive: Int? by Delegates.observable<Int?>(null) { _, oldValue, newValue ->
|
|
133
|
+
updateNavigationMenuIfNeeded(oldValue, newValue)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
var tabBarItemTitleFontColor: Int? by Delegates.observable<Int?>(null) { _, oldValue, newValue ->
|
|
137
|
+
updateNavigationMenuIfNeeded(oldValue, newValue)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
var tabBarItemTitleFontColorActive: Int? by Delegates.observable<Int?>(null) { _, oldValue, newValue ->
|
|
141
|
+
updateNavigationMenuIfNeeded(oldValue, newValue)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
var tabBarItemTitleFontSize: Float? by Delegates.observable(null) { _, oldValue, newValue ->
|
|
145
|
+
updateNavigationMenuIfNeeded(oldValue, newValue)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
var tabBarItemTitleFontSizeActive: Float? by Delegates.observable(null) { _, oldValue, newValue ->
|
|
149
|
+
updateNavigationMenuIfNeeded(oldValue, newValue)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
var tabBarItemTitleFontWeight: String? by Delegates.observable(null) { _, oldValue, newValue ->
|
|
153
|
+
updateNavigationMenuIfNeeded(oldValue, newValue)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
var tabBarItemTitleFontStyle: String? by Delegates.observable(null) { _, oldValue, newValue ->
|
|
157
|
+
updateNavigationMenuIfNeeded(oldValue, newValue)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
private fun <T> updateNavigationMenuIfNeeded(
|
|
161
|
+
oldValue: T,
|
|
162
|
+
newValue: T,
|
|
163
|
+
) {
|
|
164
|
+
if (newValue != oldValue) {
|
|
165
|
+
containerUpdateCoordinator.let {
|
|
166
|
+
it.invalidateNavigationMenu()
|
|
167
|
+
it.postContainerUpdateIfNeeded()
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
init {
|
|
173
|
+
orientation = VERTICAL
|
|
174
|
+
bottomNavigationView.labelVisibilityMode = NavigationBarView.LABEL_VISIBILITY_LABELED
|
|
175
|
+
addView(contentView)
|
|
176
|
+
addView(bottomNavigationView)
|
|
177
|
+
|
|
178
|
+
bottomNavigationView.addOnLayoutChangeListener { view, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom ->
|
|
179
|
+
Log.d(
|
|
180
|
+
TAG,
|
|
181
|
+
"BottomNavigationView layout changed {$left, $top} {${right - left}, ${bottom - top}}",
|
|
182
|
+
)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
bottomNavigationView.setOnItemSelectedListener { item ->
|
|
186
|
+
Log.d(TAG, "Item selected $item")
|
|
187
|
+
val fragment = getFragmentForMenuItemId(item.itemId)
|
|
188
|
+
val tabKey = fragment?.tabScreen?.tabKey ?: "undefined"
|
|
189
|
+
eventEmitter.emitOnNativeFocusChange(tabKey)
|
|
190
|
+
true
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
override fun onAttachedToWindow() {
|
|
195
|
+
Log.d(TAG, "TabsHost [$id] attached to window")
|
|
196
|
+
super.onAttachedToWindow()
|
|
197
|
+
fragmentManager =
|
|
198
|
+
checkNotNull(FragmentManagerHelper.findFragmentManagerForView(this)) {
|
|
199
|
+
"[RNScreens] Nullish fragment manager - can't run container operations"
|
|
200
|
+
}
|
|
201
|
+
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
|
202
|
+
// On Paper the children are not yet attached here.
|
|
203
|
+
containerUpdateCoordinator.let {
|
|
204
|
+
it.invalidateAll()
|
|
205
|
+
it.runContainerUpdate()
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
internal fun mountReactSubviewAt(
|
|
211
|
+
tabScreen: TabScreen,
|
|
212
|
+
index: Int,
|
|
213
|
+
) {
|
|
214
|
+
require(index < bottomNavigationView.maxItemCount) {
|
|
215
|
+
"[RNScreens] Attempt to insert TabScreen at index $index; BottomNavigationView supports at most ${bottomNavigationView.maxItemCount} items"
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
val tabScreenFragment = TabScreenFragment(tabScreen)
|
|
219
|
+
tabScreenFragments.add(index, tabScreenFragment)
|
|
220
|
+
tabScreen.setTabScreenDelegate(this)
|
|
221
|
+
containerUpdateCoordinator.let {
|
|
222
|
+
it.invalidateAll()
|
|
223
|
+
it.postContainerUpdateIfNeeded()
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
internal fun unmountReactSubviewAt(index: Int) {
|
|
228
|
+
tabScreenFragments.removeAt(index).also {
|
|
229
|
+
it.tabScreen.setTabScreenDelegate(null)
|
|
230
|
+
containerUpdateCoordinator.let {
|
|
231
|
+
it.invalidateAll()
|
|
232
|
+
it.postContainerUpdateIfNeeded()
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
internal fun unmountReactSubview(reactSubview: TabScreen) {
|
|
238
|
+
tabScreenFragments.removeIf { it.tabScreen === reactSubview }.takeIf { it }?.let {
|
|
239
|
+
reactSubview.setTabScreenDelegate(null)
|
|
240
|
+
containerUpdateCoordinator.let {
|
|
241
|
+
it.invalidateAll()
|
|
242
|
+
it.postContainerUpdateIfNeeded()
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
internal fun unmountAllReactSubviews() {
|
|
248
|
+
tabScreenFragments.forEach { it.tabScreen.setTabScreenDelegate(null) }
|
|
249
|
+
tabScreenFragments.clear()
|
|
250
|
+
containerUpdateCoordinator.let {
|
|
251
|
+
it.invalidateAll()
|
|
252
|
+
it.postContainerUpdateIfNeeded()
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
override fun onTabFocusChangedFromJS(
|
|
257
|
+
tabScreen: TabScreen,
|
|
258
|
+
isFocused: Boolean,
|
|
259
|
+
) {
|
|
260
|
+
containerUpdateCoordinator.let {
|
|
261
|
+
it.invalidateSelectedTab()
|
|
262
|
+
it.postContainerUpdateIfNeeded()
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
override fun onMenuItemAttributesChange(tabScreen: TabScreen) {
|
|
267
|
+
getMenuItemForTabScreen(tabScreen)?.let { menuItem ->
|
|
268
|
+
updateMenuItemOfTabScreen(menuItem, tabScreen)
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
override fun getFragmentForTabScreen(tabScreen: TabScreen): TabScreenFragment? = tabScreenFragments.find { it.tabScreen === tabScreen }
|
|
273
|
+
|
|
274
|
+
private fun updateBottomNavigationViewAppearance() {
|
|
275
|
+
Log.w(TAG, "updateBottomNavigationViewAppearance")
|
|
276
|
+
|
|
277
|
+
bottomNavigationView.isVisible = true
|
|
278
|
+
bottomNavigationView.setBackgroundColor(
|
|
279
|
+
tabBarBackgroundColor ?: com.google.android.material.R.color.m3_sys_color_light_surface_container,
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
val states = arrayOf(intArrayOf(-R.attr.state_checked), intArrayOf(R.attr.state_checked))
|
|
283
|
+
|
|
284
|
+
// Font color
|
|
285
|
+
val fontInactiveColor = tabBarItemTitleFontColor ?: com.google.android.material.R.color.m3_tabs_text_color_secondary
|
|
286
|
+
val fontActiveColor =
|
|
287
|
+
tabBarItemTitleFontColorActive ?: tabBarItemTitleFontColor ?: com.google.android.material.R.color.m3_tabs_text_color
|
|
288
|
+
val fontColors = intArrayOf(fontInactiveColor, fontActiveColor)
|
|
289
|
+
bottomNavigationView.itemTextColor = ColorStateList(states, fontColors)
|
|
290
|
+
|
|
291
|
+
// Icon color
|
|
292
|
+
val iconInactiveColor = tabBarItemIconColor ?: com.google.android.material.R.color.m3_tabs_icon_color_secondary
|
|
293
|
+
val iconActiveColor = tabBarItemIconColorActive ?: tabBarItemIconColor ?: com.google.android.material.R.color.m3_tabs_icon_color
|
|
294
|
+
val iconColors = intArrayOf(iconInactiveColor, iconActiveColor)
|
|
295
|
+
bottomNavigationView.itemIconTintList = ColorStateList(states, iconColors)
|
|
296
|
+
|
|
297
|
+
// First clean the menu, then populate it
|
|
298
|
+
bottomNavigationView.menu.clear()
|
|
299
|
+
|
|
300
|
+
tabScreenFragments.forEachIndexed { index, fragment ->
|
|
301
|
+
Log.d(TAG, "Add menu item: $index")
|
|
302
|
+
val item =
|
|
303
|
+
bottomNavigationView.menu.add(
|
|
304
|
+
Menu.NONE,
|
|
305
|
+
index,
|
|
306
|
+
Menu.NONE,
|
|
307
|
+
fragment.tabScreen.tabTitle,
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
item.icon = fragment.tabScreen.icon
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Update font styles
|
|
314
|
+
updateFontStyles()
|
|
315
|
+
|
|
316
|
+
bottomNavigationView.selectedItemId =
|
|
317
|
+
checkNotNull(getSelectedTabScreenFragmentId()) { "[RNScreens] A single selected tab must be present" }
|
|
318
|
+
|
|
319
|
+
post {
|
|
320
|
+
forceSubtreeMeasureAndLayoutPass()
|
|
321
|
+
Log.d(TAG, "BottomNavigationView request layout")
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
private fun updateFontStyles() {
|
|
326
|
+
val bottomNavigationMenuView = bottomNavigationView.getChildAt(0) as ViewGroup
|
|
327
|
+
|
|
328
|
+
for (menuItem in bottomNavigationMenuView.children) {
|
|
329
|
+
val largeLabel =
|
|
330
|
+
menuItem.findViewById<TextView>(com.google.android.material.R.id.navigation_bar_item_large_label_view)
|
|
331
|
+
val smallLabel =
|
|
332
|
+
menuItem.findViewById<TextView>(com.google.android.material.R.id.navigation_bar_item_small_label_view)
|
|
333
|
+
|
|
334
|
+
val isFontStyleItalic = tabBarItemTitleFontStyle == "italic"
|
|
335
|
+
|
|
336
|
+
// Bold is 700, normal is 400 -> https://github.com/facebook/react-native/blob/e0efd3eb5b637bd00fb7528ab4d129f6b3e13d03/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/assets/ReactFontManager.kt#L150
|
|
337
|
+
// It can be any other int -> https://reactnative.dev/docs/text-style-props#fontweight
|
|
338
|
+
// Default is 400 -> https://github.com/facebook/react-native/blob/e0efd3eb5b637bd00fb7528ab4d129f6b3e13d03/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/assets/ReactFontManager.kt#L117
|
|
339
|
+
val fontWeight = if (tabBarItemTitleFontWeight == "bold") 700 else tabBarItemTitleFontWeight?.toIntOrNull() ?: 400
|
|
340
|
+
|
|
341
|
+
val fontFamily =
|
|
342
|
+
ReactFontManager.getInstance().getTypeface(
|
|
343
|
+
tabBarItemTitleFontFamily ?: "",
|
|
344
|
+
fontWeight,
|
|
345
|
+
isFontStyleItalic,
|
|
346
|
+
reactContext.assets,
|
|
347
|
+
)
|
|
348
|
+
|
|
349
|
+
val smallFontSize = tabBarItemTitleFontSize?.takeIf { it > 0 } ?: 12f
|
|
350
|
+
val largeFontSize = tabBarItemTitleFontSizeActive?.takeIf { it > 0 } ?: 14f
|
|
351
|
+
|
|
352
|
+
// Inactive
|
|
353
|
+
smallLabel.textSize = smallFontSize
|
|
354
|
+
smallLabel.typeface = fontFamily
|
|
355
|
+
|
|
356
|
+
// Active
|
|
357
|
+
largeLabel.textSize = largeFontSize
|
|
358
|
+
largeLabel.typeface = fontFamily
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
private fun updateSelectedTab() {
|
|
363
|
+
val newFocusedTab =
|
|
364
|
+
checkNotNull(tabScreenFragments.find { it.tabScreen.isFocusedTab }) { "[RNScreens] No focused tab present" }
|
|
365
|
+
|
|
366
|
+
check(requireFragmentManager.fragments.size <= 1) { "[RNScreens] There can be only a single focused tab" }
|
|
367
|
+
val oldFocusedTab = requireFragmentManager.fragments.firstOrNull()
|
|
368
|
+
|
|
369
|
+
if (newFocusedTab === oldFocusedTab) {
|
|
370
|
+
return
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
if (oldFocusedTab == null) {
|
|
374
|
+
requireFragmentManager
|
|
375
|
+
.beginTransaction()
|
|
376
|
+
.setReorderingAllowed(true)
|
|
377
|
+
.apply {
|
|
378
|
+
this.add(contentView.id, newFocusedTab)
|
|
379
|
+
}.commitNowAllowingStateLoss()
|
|
380
|
+
} else {
|
|
381
|
+
requireFragmentManager
|
|
382
|
+
.beginTransaction()
|
|
383
|
+
.setReorderingAllowed(true)
|
|
384
|
+
.apply {
|
|
385
|
+
this.remove(oldFocusedTab)
|
|
386
|
+
this.add(contentView.id, newFocusedTab)
|
|
387
|
+
}.commitNowAllowingStateLoss()
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
private fun forceSubtreeMeasureAndLayoutPass() {
|
|
392
|
+
isLayoutInvalidated = false
|
|
393
|
+
|
|
394
|
+
measure(
|
|
395
|
+
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
|
|
396
|
+
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY),
|
|
397
|
+
)
|
|
398
|
+
|
|
399
|
+
layout(left, top, right, bottom)
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
private fun getFragmentForMenuItemId(itemId: Int): TabScreenFragment? = tabScreenFragments.getOrNull(itemId)
|
|
403
|
+
|
|
404
|
+
private fun getSelectedTabScreenFragmentId(): Int? {
|
|
405
|
+
if (tabScreenFragments.isEmpty()) {
|
|
406
|
+
return null
|
|
407
|
+
}
|
|
408
|
+
return checkNotNull(tabScreenFragments.indexOfFirst { it.tabScreen.isFocusedTab }) { "[RNScreens] There must be a focused tab" }
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
private fun getMenuItemForTabScreen(tabScreen: TabScreen): MenuItem? =
|
|
412
|
+
tabScreenFragments.indexOfFirst { it.tabScreen === tabScreen }.takeIf { it != -1 }?.let { index ->
|
|
413
|
+
bottomNavigationView.menu.findItem(index)
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
private fun updateMenuItemOfTabScreen(
|
|
417
|
+
menuItem: MenuItem,
|
|
418
|
+
tabScreen: TabScreen,
|
|
419
|
+
) {
|
|
420
|
+
menuItem.title = tabScreen.tabTitle
|
|
421
|
+
menuItem.icon = tabScreen.icon
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
internal fun onViewManagerAddEventEmitters() {
|
|
425
|
+
// When this is called from View Manager the view tag is already set
|
|
426
|
+
check(id != NO_ID) { "[RNScreens] TabsHost must have its tag set when registering event emitters" }
|
|
427
|
+
eventEmitter = TabsHostEventEmitter(reactContext, id)
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
companion object {
|
|
431
|
+
const val TAG = "TabsHost"
|
|
432
|
+
}
|
|
433
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
package com.swmansion.rnscreens.gamma.tabs
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReactContext
|
|
4
|
+
import com.swmansion.rnscreens.gamma.common.BaseEventEmitter
|
|
5
|
+
import com.swmansion.rnscreens.gamma.tabs.event.TabsHostNativeFocusChangeEvent
|
|
6
|
+
|
|
7
|
+
internal class TabsHostEventEmitter(
|
|
8
|
+
reactContext: ReactContext,
|
|
9
|
+
viewTag: Int,
|
|
10
|
+
) : BaseEventEmitter(reactContext, viewTag) {
|
|
11
|
+
fun emitOnNativeFocusChange(tabKey: String) {
|
|
12
|
+
reactEventDispatcher.dispatchEvent(TabsHostNativeFocusChangeEvent(surfaceId, viewTag, tabKey))
|
|
13
|
+
}
|
|
14
|
+
}
|