@onekeyfe/react-native-tab-view 1.1.31
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/android/build.gradle +119 -0
- package/android/gradle.properties +4 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/AndroidManifestNew.xml +2 -0
- package/android/src/main/java/com/rcttabview/ImageSource.kt +86 -0
- package/android/src/main/java/com/rcttabview/RCTTabView.kt +529 -0
- package/android/src/main/java/com/rcttabview/RCTTabViewManager.kt +204 -0
- package/android/src/main/java/com/rcttabview/RCTTabViewPackage.kt +16 -0
- package/android/src/main/java/com/rcttabview/TabInfo.kt +12 -0
- package/android/src/main/java/com/rcttabview/Utils.kt +31 -0
- package/android/src/main/java/com/rcttabview/events/OnNativeLayoutEvent.kt +20 -0
- package/android/src/main/java/com/rcttabview/events/OnTabBarMeasuredEvent.kt +19 -0
- package/android/src/main/java/com/rcttabview/events/PageSelectedEvent.kt +21 -0
- package/android/src/main/java/com/rcttabview/events/TabLongPressedEvent.kt +19 -0
- package/common/cpp/react/renderer/components/RNCTabView/RNCTabViewComponentDescriptor.h +32 -0
- package/common/cpp/react/renderer/components/RNCTabView/RNCTabViewShadowNode.cpp +18 -0
- package/common/cpp/react/renderer/components/RNCTabView/RNCTabViewShadowNode.h +35 -0
- package/common/cpp/react/renderer/components/RNCTabView/RNCTabViewState.cpp +15 -0
- package/common/cpp/react/renderer/components/RNCTabView/RNCTabViewState.h +25 -0
- package/ios/Extensions.swift +46 -0
- package/ios/RCTBottomAccessoryComponentView.h +12 -0
- package/ios/RCTBottomAccessoryComponentView.mm +67 -0
- package/ios/RCTBottomAccessoryContainerView.swift +51 -0
- package/ios/RCTTabViewComponentView.h +12 -0
- package/ios/RCTTabViewComponentView.mm +325 -0
- package/ios/RCTTabViewContainerView.swift +768 -0
- package/ios/RCTTabViewLog.h +7 -0
- package/ios/RCTTabViewLog.m +32 -0
- package/ios/SVG/CoreSVG.h +13 -0
- package/ios/SVG/CoreSVG.mm +177 -0
- package/ios/SVG/SvgDecoder.h +10 -0
- package/ios/SVG/SvgDecoder.mm +32 -0
- package/ios/TabBarFontSize.swift +55 -0
- package/lib/module/BottomAccessoryView.js +45 -0
- package/lib/module/BottomAccessoryView.js.map +1 -0
- package/lib/module/BottomAccessoryViewNativeComponent.ts +27 -0
- package/lib/module/DelayedFreeze.js +26 -0
- package/lib/module/DelayedFreeze.js.map +1 -0
- package/lib/module/NativeSVGDecoder.js +5 -0
- package/lib/module/NativeSVGDecoder.js.map +1 -0
- package/lib/module/SceneMap.js +28 -0
- package/lib/module/SceneMap.js.map +1 -0
- package/lib/module/TabView.js +263 -0
- package/lib/module/TabView.js.map +1 -0
- package/lib/module/TabViewNativeComponent.ts +68 -0
- package/lib/module/codegen-types.d.js +2 -0
- package/lib/module/codegen-types.d.js.map +1 -0
- package/lib/module/index.js +20 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/types.js +4 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/utils/BottomTabBarHeightContext.js +5 -0
- package/lib/module/utils/BottomTabBarHeightContext.js.map +1 -0
- package/lib/module/utils/useBottomTabBarHeight.js +12 -0
- package/lib/module/utils/useBottomTabBarHeight.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/BottomAccessoryView.d.ts +8 -0
- package/lib/typescript/src/BottomAccessoryView.d.ts.map +1 -0
- package/lib/typescript/src/BottomAccessoryViewNativeComponent.d.ts +16 -0
- package/lib/typescript/src/BottomAccessoryViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/DelayedFreeze.d.ts +8 -0
- package/lib/typescript/src/DelayedFreeze.d.ts.map +1 -0
- package/lib/typescript/src/NativeSVGDecoder.d.ts +6 -0
- package/lib/typescript/src/NativeSVGDecoder.d.ts.map +1 -0
- package/lib/typescript/src/SceneMap.d.ts +10 -0
- package/lib/typescript/src/SceneMap.d.ts.map +1 -0
- package/lib/typescript/src/TabView.d.ts +178 -0
- package/lib/typescript/src/TabView.d.ts.map +1 -0
- package/lib/typescript/src/TabViewNativeComponent.d.ts +55 -0
- package/lib/typescript/src/TabViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +16 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +29 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/lib/typescript/src/utils/BottomTabBarHeightContext.d.ts +3 -0
- package/lib/typescript/src/utils/BottomTabBarHeightContext.d.ts.map +1 -0
- package/lib/typescript/src/utils/useBottomTabBarHeight.d.ts +2 -0
- package/lib/typescript/src/utils/useBottomTabBarHeight.d.ts.map +1 -0
- package/package.json +114 -0
- package/react-native-tab-view.podspec +36 -0
- package/react-native.config.js +13 -0
- package/src/BottomAccessoryView.tsx +58 -0
- package/src/BottomAccessoryViewNativeComponent.ts +27 -0
- package/src/DelayedFreeze.tsx +27 -0
- package/src/NativeSVGDecoder.ts +5 -0
- package/src/SceneMap.tsx +34 -0
- package/src/TabView.tsx +466 -0
- package/src/TabViewNativeComponent.ts +68 -0
- package/src/codegen-types.d.ts +28 -0
- package/src/index.tsx +18 -0
- package/src/types.ts +31 -0
- package/src/utils/BottomTabBarHeightContext.ts +5 -0
- package/src/utils/useBottomTabBarHeight.ts +15 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
package com.rcttabview
|
|
2
|
+
|
|
3
|
+
import android.content.res.ColorStateList
|
|
4
|
+
import android.view.View
|
|
5
|
+
import android.view.ViewGroup
|
|
6
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
7
|
+
import com.facebook.react.bridge.ReadableArray
|
|
8
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
9
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
10
|
+
import com.facebook.react.uimanager.UIManagerHelper
|
|
11
|
+
import com.facebook.react.uimanager.ViewGroupManager
|
|
12
|
+
import com.facebook.react.uimanager.ViewManagerDelegate
|
|
13
|
+
import com.facebook.react.viewmanagers.RNCTabViewManagerDelegate
|
|
14
|
+
import com.facebook.react.viewmanagers.RNCTabViewManagerInterface
|
|
15
|
+
import com.rcttabview.events.OnNativeLayoutEvent
|
|
16
|
+
import com.rcttabview.events.OnTabBarMeasuredEvent
|
|
17
|
+
import com.rcttabview.events.PageSelectedEvent
|
|
18
|
+
import com.rcttabview.events.TabLongPressEvent
|
|
19
|
+
|
|
20
|
+
@ReactModule(name = RCTTabViewManager.NAME)
|
|
21
|
+
class RCTTabViewManager(context: ReactApplicationContext) :
|
|
22
|
+
ViewGroupManager<ReactBottomNavigationView>(),
|
|
23
|
+
RNCTabViewManagerInterface<ReactBottomNavigationView> {
|
|
24
|
+
|
|
25
|
+
private val delegate: RNCTabViewManagerDelegate<ReactBottomNavigationView, RCTTabViewManager> =
|
|
26
|
+
RNCTabViewManagerDelegate(this)
|
|
27
|
+
|
|
28
|
+
override fun createViewInstance(context: ThemedReactContext): ReactBottomNavigationView {
|
|
29
|
+
val view = ReactBottomNavigationView(context)
|
|
30
|
+
val eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, view.id)
|
|
31
|
+
val surfaceId = UIManagerHelper.getSurfaceId(context)
|
|
32
|
+
|
|
33
|
+
view.onTabSelectedListener = { key ->
|
|
34
|
+
eventDispatcher?.dispatchEvent(PageSelectedEvent(surfaceId, view.id, key))
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
view.onTabLongPressedListener = { key ->
|
|
38
|
+
eventDispatcher?.dispatchEvent(TabLongPressEvent(surfaceId, view.id, key))
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
view.onNativeLayoutListener = { width, height ->
|
|
42
|
+
eventDispatcher?.dispatchEvent(OnNativeLayoutEvent(surfaceId, view.id, width, height))
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
view.onTabBarMeasuredListener = { height ->
|
|
46
|
+
eventDispatcher?.dispatchEvent(OnTabBarMeasuredEvent(surfaceId, view.id, height))
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return view
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
override fun onDropViewInstance(view: ReactBottomNavigationView) {
|
|
53
|
+
super.onDropViewInstance(view)
|
|
54
|
+
view.onDropViewInstance()
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
override fun getName(): String = NAME
|
|
58
|
+
|
|
59
|
+
override fun getDelegate(): ViewManagerDelegate<ReactBottomNavigationView> = delegate
|
|
60
|
+
|
|
61
|
+
// MARK: - Child view management
|
|
62
|
+
|
|
63
|
+
override fun addView(parent: ReactBottomNavigationView, child: View, index: Int) {
|
|
64
|
+
parent.addView(child, index)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
override fun getChildCount(parent: ReactBottomNavigationView): Int {
|
|
68
|
+
return parent.layoutHolder.childCount
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
override fun getChildAt(parent: ReactBottomNavigationView, index: Int): View? {
|
|
72
|
+
val container = parent.layoutHolder.getChildAt(index) as? ViewGroup
|
|
73
|
+
return container?.getChildAt(0) ?: parent.layoutHolder.getChildAt(index)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
override fun removeView(parent: ReactBottomNavigationView, view: View) {
|
|
77
|
+
for (i in 0 until parent.layoutHolder.childCount) {
|
|
78
|
+
val container = parent.layoutHolder.getChildAt(i) as? ViewGroup
|
|
79
|
+
if (container != null && container.childCount > 0 && container.getChildAt(0) === view) {
|
|
80
|
+
parent.layoutHolder.removeViewAt(i)
|
|
81
|
+
return
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
parent.layoutHolder.removeView(view)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
override fun removeAllViews(parent: ReactBottomNavigationView) {
|
|
88
|
+
parent.layoutHolder.removeAllViews()
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
override fun removeViewAt(parent: ReactBottomNavigationView, index: Int) {
|
|
92
|
+
parent.layoutHolder.removeViewAt(index)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
override fun needsCustomLayoutForChildren(): Boolean = true
|
|
96
|
+
|
|
97
|
+
// MARK: - Props (RNCTabViewManagerInterface)
|
|
98
|
+
|
|
99
|
+
override fun setItems(view: ReactBottomNavigationView?, value: ReadableArray?) {
|
|
100
|
+
if (view != null && value != null) {
|
|
101
|
+
val itemsArray = mutableListOf<TabInfo>()
|
|
102
|
+
for (i in 0 until value.size()) {
|
|
103
|
+
value.getMap(i)?.let { item ->
|
|
104
|
+
itemsArray.add(
|
|
105
|
+
TabInfo(
|
|
106
|
+
key = item.getString("key") ?: "",
|
|
107
|
+
title = item.getString("title") ?: "",
|
|
108
|
+
badge = if (item.hasKey("badge")) item.getString("badge") else null,
|
|
109
|
+
badgeBackgroundColor = if (item.hasKey("badgeBackgroundColor")) item.getInt("badgeBackgroundColor") else null,
|
|
110
|
+
badgeTextColor = if (item.hasKey("badgeTextColor")) item.getInt("badgeTextColor") else null,
|
|
111
|
+
activeTintColor = if (item.hasKey("activeTintColor")) item.getInt("activeTintColor") else null,
|
|
112
|
+
hidden = if (item.hasKey("hidden")) item.getBoolean("hidden") else false,
|
|
113
|
+
testID = item.getString("testID")
|
|
114
|
+
)
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
view.updateItems(itemsArray)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
override fun setSelectedPage(view: ReactBottomNavigationView?, value: String?) {
|
|
123
|
+
if (view != null && value != null)
|
|
124
|
+
view.setSelectedItem(value)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
override fun setIcons(view: ReactBottomNavigationView?, value: ReadableArray?) {
|
|
128
|
+
if (view != null)
|
|
129
|
+
view.setIcons(value)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
override fun setLabeled(view: ReactBottomNavigationView?, value: Boolean) {
|
|
133
|
+
if (view != null)
|
|
134
|
+
view.setLabeled(value)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
override fun setRippleColor(view: ReactBottomNavigationView?, value: Int?) {
|
|
138
|
+
if (view != null && value != null) {
|
|
139
|
+
val color = ColorStateList.valueOf(value)
|
|
140
|
+
view.setRippleColor(color)
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
override fun setBarTintColor(view: ReactBottomNavigationView?, value: Int?) {
|
|
145
|
+
if (view != null && value != null)
|
|
146
|
+
view.setBarTintColor(value)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
override fun setActiveTintColor(view: ReactBottomNavigationView?, value: Int?) {
|
|
150
|
+
if (view != null && value != null)
|
|
151
|
+
view.setActiveTintColor(value)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
override fun setInactiveTintColor(view: ReactBottomNavigationView?, value: Int?) {
|
|
155
|
+
if (view != null && value != null)
|
|
156
|
+
view.setInactiveTintColor(value)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
override fun setActiveIndicatorColor(view: ReactBottomNavigationView?, value: Int?) {
|
|
160
|
+
if (view != null && value != null) {
|
|
161
|
+
val color = ColorStateList.valueOf(value)
|
|
162
|
+
view.setActiveIndicatorColor(color)
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
override fun setHapticFeedbackEnabled(view: ReactBottomNavigationView?, value: Boolean) {
|
|
167
|
+
if (view != null)
|
|
168
|
+
view.isHapticFeedbackEnabled = value
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
override fun setFontFamily(view: ReactBottomNavigationView?, value: String?) {
|
|
172
|
+
view?.setFontFamily(value)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
override fun setFontWeight(view: ReactBottomNavigationView?, value: String?) {
|
|
176
|
+
view?.setFontWeight(value)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
override fun setFontSize(view: ReactBottomNavigationView?, value: Int) {
|
|
180
|
+
view?.setFontSize(value)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
override fun setDisablePageAnimations(view: ReactBottomNavigationView?, value: Boolean) {
|
|
184
|
+
view?.disablePageAnimations = value
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
override fun setTabBarHidden(view: ReactBottomNavigationView?, value: Boolean) {
|
|
188
|
+
view?.setTabBarHidden(value)
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
override fun setIgnoreBottomInsets(view: ReactBottomNavigationView?, value: Boolean) {
|
|
192
|
+
view?.setIgnoreBottomInsets(value)
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// iOS-only props (no-ops on Android)
|
|
196
|
+
override fun setTranslucent(view: ReactBottomNavigationView?, value: Boolean) {}
|
|
197
|
+
override fun setSidebarAdaptable(view: ReactBottomNavigationView?, value: Boolean) {}
|
|
198
|
+
override fun setScrollEdgeAppearance(view: ReactBottomNavigationView?, value: String?) {}
|
|
199
|
+
override fun setMinimizeBehavior(view: ReactBottomNavigationView?, value: String?) {}
|
|
200
|
+
|
|
201
|
+
companion object {
|
|
202
|
+
const val NAME = "RNCTabView"
|
|
203
|
+
}
|
|
204
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
package com.rcttabview
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.ReactPackage
|
|
4
|
+
import com.facebook.react.bridge.NativeModule
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.uimanager.ViewManager
|
|
7
|
+
|
|
8
|
+
class RCTTabViewPackage : ReactPackage {
|
|
9
|
+
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
|
|
10
|
+
return listOf(RCTTabViewManager(reactContext))
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
|
14
|
+
return emptyList()
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
package com.rcttabview
|
|
2
|
+
|
|
3
|
+
data class TabInfo(
|
|
4
|
+
val key: String,
|
|
5
|
+
val title: String,
|
|
6
|
+
val badge: String? = null,
|
|
7
|
+
val badgeBackgroundColor: Int? = null,
|
|
8
|
+
val badgeTextColor: Int? = null,
|
|
9
|
+
val activeTintColor: Int? = null,
|
|
10
|
+
val hidden: Boolean = false,
|
|
11
|
+
val testID: String? = null
|
|
12
|
+
)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
package com.rcttabview
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.graphics.Typeface
|
|
5
|
+
import android.util.TypedValue
|
|
6
|
+
import androidx.appcompat.content.res.AppCompatResources
|
|
7
|
+
|
|
8
|
+
class Utils {
|
|
9
|
+
companion object {
|
|
10
|
+
fun convertPixelsToDp(context: Context, value: Int): Double {
|
|
11
|
+
val displayDensity = context.resources.displayMetrics.density
|
|
12
|
+
return (value / displayDensity).toDouble()
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
fun getTypefaceStyle(weight: Int?) = when (weight) {
|
|
16
|
+
700 -> Typeface.BOLD
|
|
17
|
+
else -> Typeface.NORMAL
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
fun getDefaultColorFor(context: Context, baseColorThemeAttr: Int): Int? {
|
|
21
|
+
val value = TypedValue()
|
|
22
|
+
if (!context.theme.resolveAttribute(baseColorThemeAttr, value, true)) {
|
|
23
|
+
return null
|
|
24
|
+
}
|
|
25
|
+
val baseColor = AppCompatResources.getColorStateList(
|
|
26
|
+
context, value.resourceId
|
|
27
|
+
)
|
|
28
|
+
return baseColor.defaultColor
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
package com.rcttabview.events
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments
|
|
4
|
+
import com.facebook.react.bridge.WritableMap
|
|
5
|
+
import com.facebook.react.uimanager.events.Event
|
|
6
|
+
|
|
7
|
+
class OnNativeLayoutEvent(surfaceId: Int, viewTag: Int, private val width: Double, private val height: Double) : Event<OnNativeLayoutEvent>(surfaceId, viewTag) {
|
|
8
|
+
override fun getEventName(): String = EVENT_NAME
|
|
9
|
+
|
|
10
|
+
override fun getEventData(): WritableMap {
|
|
11
|
+
return Arguments.createMap().apply {
|
|
12
|
+
putDouble("width", width)
|
|
13
|
+
putDouble("height", height)
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
companion object {
|
|
18
|
+
const val EVENT_NAME = "onNativeLayout"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
package com.rcttabview.events
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments
|
|
4
|
+
import com.facebook.react.bridge.WritableMap
|
|
5
|
+
import com.facebook.react.uimanager.events.Event
|
|
6
|
+
|
|
7
|
+
class OnTabBarMeasuredEvent(surfaceId: Int, viewTag: Int, private val height: Int) : Event<OnTabBarMeasuredEvent>(surfaceId, viewTag) {
|
|
8
|
+
override fun getEventName(): String = EVENT_NAME
|
|
9
|
+
|
|
10
|
+
override fun getEventData(): WritableMap {
|
|
11
|
+
return Arguments.createMap().apply {
|
|
12
|
+
putInt("height", height)
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
companion object {
|
|
17
|
+
const val EVENT_NAME = "onTabBarMeasured"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
package com.rcttabview.events
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments
|
|
4
|
+
import com.facebook.react.bridge.WritableMap
|
|
5
|
+
import com.facebook.react.uimanager.events.Event
|
|
6
|
+
|
|
7
|
+
class PageSelectedEvent(surfaceId: Int, viewTag: Int, private val key: String) : Event<PageSelectedEvent>(surfaceId, viewTag) {
|
|
8
|
+
override fun getEventName(): String = EVENT_NAME
|
|
9
|
+
|
|
10
|
+
override fun canCoalesce(): Boolean = false
|
|
11
|
+
|
|
12
|
+
override fun getEventData(): WritableMap {
|
|
13
|
+
return Arguments.createMap().apply {
|
|
14
|
+
putString("key", key)
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
companion object {
|
|
19
|
+
const val EVENT_NAME = "topPageSelected"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
package com.rcttabview.events
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments
|
|
4
|
+
import com.facebook.react.bridge.WritableMap
|
|
5
|
+
import com.facebook.react.uimanager.events.Event
|
|
6
|
+
|
|
7
|
+
class TabLongPressEvent(surfaceId: Int, viewTag: Int, private val key: String) : Event<TabLongPressEvent>(surfaceId, viewTag) {
|
|
8
|
+
override fun getEventName(): String = EVENT_NAME
|
|
9
|
+
|
|
10
|
+
override fun getEventData(): WritableMap {
|
|
11
|
+
return Arguments.createMap().apply {
|
|
12
|
+
putString("key", key)
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
companion object {
|
|
17
|
+
const val EVENT_NAME = "onTabLongPress"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#ifdef __cplusplus
|
|
2
|
+
|
|
3
|
+
#pragma once
|
|
4
|
+
|
|
5
|
+
#include <react/renderer/components/RNCTabView/RNCTabViewShadowNode.h>
|
|
6
|
+
#include <react/renderer/core/ConcreteComponentDescriptor.h>
|
|
7
|
+
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
|
|
8
|
+
|
|
9
|
+
namespace facebook::react {
|
|
10
|
+
|
|
11
|
+
class RNCTabViewComponentDescriptor final
|
|
12
|
+
: public ConcreteComponentDescriptor<RNCTabViewShadowNode> {
|
|
13
|
+
public:
|
|
14
|
+
using ConcreteComponentDescriptor::ConcreteComponentDescriptor;
|
|
15
|
+
|
|
16
|
+
void adopt(ShadowNode& shadowNode) const override {
|
|
17
|
+
ConcreteComponentDescriptor::adopt(shadowNode);
|
|
18
|
+
|
|
19
|
+
#if !defined(ANDROID)
|
|
20
|
+
auto &tabViewShadowNode =
|
|
21
|
+
static_cast<RNCTabViewShadowNode&>(shadowNode);
|
|
22
|
+
|
|
23
|
+
std::weak_ptr<void> imageLoader =
|
|
24
|
+
contextContainer_->at<std::shared_ptr<void>>("RCTImageLoader");
|
|
25
|
+
tabViewShadowNode.setImageLoader(imageLoader);
|
|
26
|
+
#endif
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
} // namespace facebook::react
|
|
31
|
+
|
|
32
|
+
#endif
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#include <react/renderer/components/RNCTabView/RNCTabViewShadowNode.h>
|
|
2
|
+
|
|
3
|
+
namespace facebook::react {
|
|
4
|
+
|
|
5
|
+
extern const char RNCTabViewComponentName[] = "RNCTabView";
|
|
6
|
+
|
|
7
|
+
void RNCTabViewShadowNode::setImageLoader(
|
|
8
|
+
std::weak_ptr<void> imageLoader) {
|
|
9
|
+
getStateDataMutable().setImageLoader(imageLoader);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
RNCTabViewShadowNode::StateData &
|
|
13
|
+
RNCTabViewShadowNode::getStateDataMutable() {
|
|
14
|
+
ensureUnsealed();
|
|
15
|
+
return const_cast<RNCTabViewShadowNode::StateData &>(getStateData());
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
} // namespace facebook::react
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#ifdef __cplusplus
|
|
2
|
+
|
|
3
|
+
#pragma once
|
|
4
|
+
|
|
5
|
+
#include <react/renderer/components/RNCTabView/EventEmitters.h>
|
|
6
|
+
#include <react/renderer/components/RNCTabView/Props.h>
|
|
7
|
+
#include <react/renderer/components/RNCTabView/RNCTabViewState.h>
|
|
8
|
+
#include <react/renderer/components/view/ConcreteViewShadowNode.h>
|
|
9
|
+
#include <jsi/jsi.h>
|
|
10
|
+
|
|
11
|
+
namespace facebook::react {
|
|
12
|
+
|
|
13
|
+
JSI_EXPORT extern const char RNCTabViewComponentName[];
|
|
14
|
+
|
|
15
|
+
/*
|
|
16
|
+
* `ShadowNode` for <RNCTabView> component.
|
|
17
|
+
*/
|
|
18
|
+
class JSI_EXPORT RNCTabViewShadowNode final: public ConcreteViewShadowNode<
|
|
19
|
+
RNCTabViewComponentName,
|
|
20
|
+
RNCTabViewProps,
|
|
21
|
+
RNCTabViewEventEmitter,
|
|
22
|
+
RNCTabViewState> {
|
|
23
|
+
|
|
24
|
+
public:
|
|
25
|
+
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
26
|
+
using StateData = ConcreteViewShadowNode::ConcreteStateData;
|
|
27
|
+
|
|
28
|
+
void setImageLoader(std::weak_ptr<void> imageLoader);
|
|
29
|
+
|
|
30
|
+
StateData &getStateDataMutable();
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
#endif
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#include <react/renderer/components/RNCTabView/RNCTabViewState.h>
|
|
2
|
+
|
|
3
|
+
namespace facebook::react {
|
|
4
|
+
|
|
5
|
+
void RNCTabViewState::setImageLoader(
|
|
6
|
+
std::weak_ptr<void> imageLoader) {
|
|
7
|
+
imageLoader_ = imageLoader;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
std::weak_ptr<void> RNCTabViewState::getImageLoader()
|
|
11
|
+
const noexcept {
|
|
12
|
+
return imageLoader_;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
} // namespace facebook::react
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#ifdef __cplusplus
|
|
2
|
+
|
|
3
|
+
#pragma once
|
|
4
|
+
|
|
5
|
+
#include <react/renderer/core/StateData.h>
|
|
6
|
+
#ifdef RN_SERIALIZABLE_STATE
|
|
7
|
+
#include <folly/dynamic.h>
|
|
8
|
+
#endif
|
|
9
|
+
|
|
10
|
+
namespace facebook::react {
|
|
11
|
+
|
|
12
|
+
class RNCTabViewState final {
|
|
13
|
+
public:
|
|
14
|
+
RNCTabViewState() = default;
|
|
15
|
+
|
|
16
|
+
void setImageLoader(std::weak_ptr<void> imageLoader);
|
|
17
|
+
std::weak_ptr<void> getImageLoader() const noexcept;
|
|
18
|
+
|
|
19
|
+
private:
|
|
20
|
+
std::weak_ptr<void> imageLoader_;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
} // namespace facebook::react
|
|
24
|
+
|
|
25
|
+
#endif
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import UIKit
|
|
2
|
+
|
|
3
|
+
extension Collection {
|
|
4
|
+
subscript(safe index: Index) -> Element? {
|
|
5
|
+
indices.contains(index) ? self[index] : nil
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
extension Collection where Element == TabItem {
|
|
10
|
+
func findByKey(_ key: String?) -> Element? {
|
|
11
|
+
guard let key else { return nil }
|
|
12
|
+
guard !isEmpty else { return nil }
|
|
13
|
+
return first { $0.key == key }
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
extension UIView {
|
|
18
|
+
func pinEdges(to other: UIView) {
|
|
19
|
+
NSLayoutConstraint.activate([
|
|
20
|
+
leadingAnchor.constraint(equalTo: other.leadingAnchor),
|
|
21
|
+
trailingAnchor.constraint(equalTo: other.trailingAnchor),
|
|
22
|
+
topAnchor.constraint(equalTo: other.topAnchor),
|
|
23
|
+
bottomAnchor.constraint(equalTo: other.bottomAnchor)
|
|
24
|
+
])
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
extension UIImage {
|
|
29
|
+
func resizeImageTo(size: CGSize) -> UIImage? {
|
|
30
|
+
let renderer = UIGraphicsImageRenderer(size: size)
|
|
31
|
+
return renderer.image { _ in
|
|
32
|
+
self.draw(in: CGRect(origin: .zero, size: size))
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
extension UIColor {
|
|
38
|
+
convenience init(rgb: Int) {
|
|
39
|
+
self.init(
|
|
40
|
+
red: CGFloat((rgb >> 16) & 0xFF) / 255.0,
|
|
41
|
+
green: CGFloat((rgb >> 8) & 0xFF) / 255.0,
|
|
42
|
+
blue: CGFloat(rgb & 0xFF) / 255.0,
|
|
43
|
+
alpha: CGFloat((rgb >> 24) & 0xFF) / 255.0
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
2
|
+
#import <React/RCTViewComponentView.h>
|
|
3
|
+
#import <UIKit/UIKit.h>
|
|
4
|
+
|
|
5
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
6
|
+
|
|
7
|
+
@interface RCTBottomAccessoryComponentView: RCTViewComponentView
|
|
8
|
+
@end
|
|
9
|
+
|
|
10
|
+
NS_ASSUME_NONNULL_END
|
|
11
|
+
|
|
12
|
+
#endif /* RCT_NEW_ARCH_ENABLED */
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#import "RCTBottomAccessoryComponentView.h"
|
|
2
|
+
|
|
3
|
+
#import <react/renderer/components/RNCTabView/ComponentDescriptors.h>
|
|
4
|
+
#import <react/renderer/components/RNCTabView/EventEmitters.h>
|
|
5
|
+
#import <react/renderer/components/RNCTabView/Props.h>
|
|
6
|
+
#import <react/renderer/components/RNCTabView/RCTComponentViewHelpers.h>
|
|
7
|
+
|
|
8
|
+
#import <React/RCTFabricComponentsPlugins.h>
|
|
9
|
+
|
|
10
|
+
#if __has_include(<TabViewModule/TabViewModule-Swift.h>)
|
|
11
|
+
#import <TabViewModule/TabViewModule-Swift.h>
|
|
12
|
+
#elif __has_include("TabViewModule/TabViewModule-Swift.h")
|
|
13
|
+
#import "TabViewModule/TabViewModule-Swift.h"
|
|
14
|
+
#elif __has_include("TabViewModule-Swift.h")
|
|
15
|
+
#import "TabViewModule-Swift.h"
|
|
16
|
+
#else
|
|
17
|
+
#import "react_native_tab_view-Swift.h"
|
|
18
|
+
#endif
|
|
19
|
+
|
|
20
|
+
using namespace facebook::react;
|
|
21
|
+
|
|
22
|
+
@implementation RCTBottomAccessoryComponentView {
|
|
23
|
+
UIView *_accessoryView;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
+ (ComponentDescriptorProvider)componentDescriptorProvider
|
|
27
|
+
{
|
|
28
|
+
return concreteComponentDescriptorProvider<BottomAccessoryViewComponentDescriptor>();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
- (instancetype)initWithFrame:(CGRect)frame
|
|
32
|
+
{
|
|
33
|
+
if (self = [super initWithFrame:frame]) {
|
|
34
|
+
static const auto defaultProps = std::make_shared<const BottomAccessoryViewProps>();
|
|
35
|
+
_props = defaultProps;
|
|
36
|
+
|
|
37
|
+
Class containerClass = NSClassFromString(@"TabViewModule.RCTBottomAccessoryContainerView");
|
|
38
|
+
if (!containerClass) {
|
|
39
|
+
containerClass = NSClassFromString(@"RCTBottomAccessoryContainerView");
|
|
40
|
+
}
|
|
41
|
+
_accessoryView = [[containerClass alloc] init];
|
|
42
|
+
self.contentView = _accessoryView;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return self;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
- (void)setFrame:(CGRect)frame
|
|
49
|
+
{
|
|
50
|
+
[super setFrame:frame];
|
|
51
|
+
if (frame.size.width > 0 && frame.size.height > 0) {
|
|
52
|
+
auto eventEmitter = std::static_pointer_cast<const BottomAccessoryViewEventEmitter>(_eventEmitter);
|
|
53
|
+
if (eventEmitter) {
|
|
54
|
+
eventEmitter->onNativeLayout(BottomAccessoryViewEventEmitter::OnNativeLayout {
|
|
55
|
+
.width = frame.size.width,
|
|
56
|
+
.height = frame.size.height
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@end
|
|
63
|
+
|
|
64
|
+
Class<RCTComponentViewProtocol> BottomAccessoryViewCls(void)
|
|
65
|
+
{
|
|
66
|
+
return RCTBottomAccessoryComponentView.class;
|
|
67
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import UIKit
|
|
3
|
+
import React
|
|
4
|
+
|
|
5
|
+
extension Notification.Name {
|
|
6
|
+
static let bottomAccessoryPlacementChanged = Notification.Name("bottomAccessoryPlacementChanged")
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
class RCTBottomAccessoryContainerView: UIView {
|
|
10
|
+
|
|
11
|
+
// MARK: - Events
|
|
12
|
+
@objc var onNativeLayout: RCTDirectEventBlock?
|
|
13
|
+
@objc var onPlacementChanged: RCTDirectEventBlock?
|
|
14
|
+
|
|
15
|
+
// MARK: - Init
|
|
16
|
+
|
|
17
|
+
override init(frame: CGRect) {
|
|
18
|
+
super.init(frame: frame)
|
|
19
|
+
|
|
20
|
+
NotificationCenter.default.addObserver(
|
|
21
|
+
self,
|
|
22
|
+
selector: #selector(handlePlacementNotification(_:)),
|
|
23
|
+
name: .bottomAccessoryPlacementChanged,
|
|
24
|
+
object: nil
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
required init?(coder: NSCoder) {
|
|
29
|
+
fatalError("init(coder:) has not been implemented")
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
deinit {
|
|
33
|
+
NotificationCenter.default.removeObserver(self)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// MARK: - Layout
|
|
37
|
+
|
|
38
|
+
override func layoutSubviews() {
|
|
39
|
+
super.layoutSubviews()
|
|
40
|
+
let bounds = self.bounds
|
|
41
|
+
guard bounds.width > 0 && bounds.height > 0 else { return }
|
|
42
|
+
onNativeLayout?(["width": Double(bounds.width), "height": Double(bounds.height)])
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// MARK: - Placement
|
|
46
|
+
|
|
47
|
+
@objc private func handlePlacementNotification(_ notification: Notification) {
|
|
48
|
+
guard let placement = notification.userInfo?["placement"] as? String else { return }
|
|
49
|
+
onPlacementChanged?(["placement": placement])
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
2
|
+
#import <React/RCTViewComponentView.h>
|
|
3
|
+
#import <UIKit/UIKit.h>
|
|
4
|
+
|
|
5
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
6
|
+
|
|
7
|
+
@interface RCTTabViewComponentView: RCTViewComponentView
|
|
8
|
+
@end
|
|
9
|
+
|
|
10
|
+
NS_ASSUME_NONNULL_END
|
|
11
|
+
|
|
12
|
+
#endif /* RCT_NEW_ARCH_ENABLED */
|