@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.
Files changed (94) hide show
  1. package/android/build.gradle +119 -0
  2. package/android/gradle.properties +4 -0
  3. package/android/src/main/AndroidManifest.xml +3 -0
  4. package/android/src/main/AndroidManifestNew.xml +2 -0
  5. package/android/src/main/java/com/rcttabview/ImageSource.kt +86 -0
  6. package/android/src/main/java/com/rcttabview/RCTTabView.kt +529 -0
  7. package/android/src/main/java/com/rcttabview/RCTTabViewManager.kt +204 -0
  8. package/android/src/main/java/com/rcttabview/RCTTabViewPackage.kt +16 -0
  9. package/android/src/main/java/com/rcttabview/TabInfo.kt +12 -0
  10. package/android/src/main/java/com/rcttabview/Utils.kt +31 -0
  11. package/android/src/main/java/com/rcttabview/events/OnNativeLayoutEvent.kt +20 -0
  12. package/android/src/main/java/com/rcttabview/events/OnTabBarMeasuredEvent.kt +19 -0
  13. package/android/src/main/java/com/rcttabview/events/PageSelectedEvent.kt +21 -0
  14. package/android/src/main/java/com/rcttabview/events/TabLongPressedEvent.kt +19 -0
  15. package/common/cpp/react/renderer/components/RNCTabView/RNCTabViewComponentDescriptor.h +32 -0
  16. package/common/cpp/react/renderer/components/RNCTabView/RNCTabViewShadowNode.cpp +18 -0
  17. package/common/cpp/react/renderer/components/RNCTabView/RNCTabViewShadowNode.h +35 -0
  18. package/common/cpp/react/renderer/components/RNCTabView/RNCTabViewState.cpp +15 -0
  19. package/common/cpp/react/renderer/components/RNCTabView/RNCTabViewState.h +25 -0
  20. package/ios/Extensions.swift +46 -0
  21. package/ios/RCTBottomAccessoryComponentView.h +12 -0
  22. package/ios/RCTBottomAccessoryComponentView.mm +67 -0
  23. package/ios/RCTBottomAccessoryContainerView.swift +51 -0
  24. package/ios/RCTTabViewComponentView.h +12 -0
  25. package/ios/RCTTabViewComponentView.mm +325 -0
  26. package/ios/RCTTabViewContainerView.swift +768 -0
  27. package/ios/RCTTabViewLog.h +7 -0
  28. package/ios/RCTTabViewLog.m +32 -0
  29. package/ios/SVG/CoreSVG.h +13 -0
  30. package/ios/SVG/CoreSVG.mm +177 -0
  31. package/ios/SVG/SvgDecoder.h +10 -0
  32. package/ios/SVG/SvgDecoder.mm +32 -0
  33. package/ios/TabBarFontSize.swift +55 -0
  34. package/lib/module/BottomAccessoryView.js +45 -0
  35. package/lib/module/BottomAccessoryView.js.map +1 -0
  36. package/lib/module/BottomAccessoryViewNativeComponent.ts +27 -0
  37. package/lib/module/DelayedFreeze.js +26 -0
  38. package/lib/module/DelayedFreeze.js.map +1 -0
  39. package/lib/module/NativeSVGDecoder.js +5 -0
  40. package/lib/module/NativeSVGDecoder.js.map +1 -0
  41. package/lib/module/SceneMap.js +28 -0
  42. package/lib/module/SceneMap.js.map +1 -0
  43. package/lib/module/TabView.js +263 -0
  44. package/lib/module/TabView.js.map +1 -0
  45. package/lib/module/TabViewNativeComponent.ts +68 -0
  46. package/lib/module/codegen-types.d.js +2 -0
  47. package/lib/module/codegen-types.d.js.map +1 -0
  48. package/lib/module/index.js +20 -0
  49. package/lib/module/index.js.map +1 -0
  50. package/lib/module/package.json +1 -0
  51. package/lib/module/types.js +4 -0
  52. package/lib/module/types.js.map +1 -0
  53. package/lib/module/utils/BottomTabBarHeightContext.js +5 -0
  54. package/lib/module/utils/BottomTabBarHeightContext.js.map +1 -0
  55. package/lib/module/utils/useBottomTabBarHeight.js +12 -0
  56. package/lib/module/utils/useBottomTabBarHeight.js.map +1 -0
  57. package/lib/typescript/package.json +1 -0
  58. package/lib/typescript/src/BottomAccessoryView.d.ts +8 -0
  59. package/lib/typescript/src/BottomAccessoryView.d.ts.map +1 -0
  60. package/lib/typescript/src/BottomAccessoryViewNativeComponent.d.ts +16 -0
  61. package/lib/typescript/src/BottomAccessoryViewNativeComponent.d.ts.map +1 -0
  62. package/lib/typescript/src/DelayedFreeze.d.ts +8 -0
  63. package/lib/typescript/src/DelayedFreeze.d.ts.map +1 -0
  64. package/lib/typescript/src/NativeSVGDecoder.d.ts +6 -0
  65. package/lib/typescript/src/NativeSVGDecoder.d.ts.map +1 -0
  66. package/lib/typescript/src/SceneMap.d.ts +10 -0
  67. package/lib/typescript/src/SceneMap.d.ts.map +1 -0
  68. package/lib/typescript/src/TabView.d.ts +178 -0
  69. package/lib/typescript/src/TabView.d.ts.map +1 -0
  70. package/lib/typescript/src/TabViewNativeComponent.d.ts +55 -0
  71. package/lib/typescript/src/TabViewNativeComponent.d.ts.map +1 -0
  72. package/lib/typescript/src/index.d.ts +16 -0
  73. package/lib/typescript/src/index.d.ts.map +1 -0
  74. package/lib/typescript/src/types.d.ts +29 -0
  75. package/lib/typescript/src/types.d.ts.map +1 -0
  76. package/lib/typescript/src/utils/BottomTabBarHeightContext.d.ts +3 -0
  77. package/lib/typescript/src/utils/BottomTabBarHeightContext.d.ts.map +1 -0
  78. package/lib/typescript/src/utils/useBottomTabBarHeight.d.ts +2 -0
  79. package/lib/typescript/src/utils/useBottomTabBarHeight.d.ts.map +1 -0
  80. package/package.json +114 -0
  81. package/react-native-tab-view.podspec +36 -0
  82. package/react-native.config.js +13 -0
  83. package/src/BottomAccessoryView.tsx +58 -0
  84. package/src/BottomAccessoryViewNativeComponent.ts +27 -0
  85. package/src/DelayedFreeze.tsx +27 -0
  86. package/src/NativeSVGDecoder.ts +5 -0
  87. package/src/SceneMap.tsx +34 -0
  88. package/src/TabView.tsx +466 -0
  89. package/src/TabViewNativeComponent.ts +68 -0
  90. package/src/codegen-types.d.ts +28 -0
  91. package/src/index.tsx +18 -0
  92. package/src/types.ts +31 -0
  93. package/src/utils/BottomTabBarHeightContext.ts +5 -0
  94. 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 */