@onekeyfe/react-native-bottom-tabs 0.0.0-stage → 6.7.0-alpha.339

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 (77) hide show
  1. package/LICENSE +46 -0
  2. package/README.md +86 -2
  3. package/android/build.gradle +119 -0
  4. package/android/gradle.properties +4 -0
  5. package/android/src/main/AndroidManifest.xml +3 -0
  6. package/android/src/main/AndroidManifestNew.xml +2 -0
  7. package/android/src/main/java/com/onekey/bottomtabs/BottomTabsPackage.kt +16 -0
  8. package/android/src/main/java/com/onekey/bottomtabs/BottomTabsView.kt +1419 -0
  9. package/android/src/main/java/com/onekey/bottomtabs/BottomTabsViewManager.kt +216 -0
  10. package/android/src/main/java/com/onekey/bottomtabs/FloatingTabBarStyle.kt +50 -0
  11. package/android/src/main/java/com/onekey/bottomtabs/ImageSource.kt +86 -0
  12. package/android/src/main/java/com/onekey/bottomtabs/TabInfo.kt +13 -0
  13. package/android/src/main/java/com/onekey/bottomtabs/Utils.kt +31 -0
  14. package/android/src/main/java/com/onekey/bottomtabs/events/OnNativeLayoutEvent.kt +20 -0
  15. package/android/src/main/java/com/onekey/bottomtabs/events/OnTabBarMeasuredEvent.kt +19 -0
  16. package/android/src/main/java/com/onekey/bottomtabs/events/PageSelectedEvent.kt +21 -0
  17. package/android/src/main/java/com/onekey/bottomtabs/events/TabDoublePressEvent.kt +19 -0
  18. package/common/cpp/react/renderer/components/RNBottomTabs/RNBottomTabsViewComponentDescriptor.h +32 -0
  19. package/common/cpp/react/renderer/components/RNBottomTabs/RNBottomTabsViewShadowNode.cpp +18 -0
  20. package/common/cpp/react/renderer/components/RNBottomTabs/RNBottomTabsViewShadowNode.h +35 -0
  21. package/common/cpp/react/renderer/components/RNBottomTabs/RNBottomTabsViewState.cpp +15 -0
  22. package/common/cpp/react/renderer/components/RNBottomTabs/RNBottomTabsViewState.h +25 -0
  23. package/docs/SPEC.md +101 -0
  24. package/ios/Extensions.swift +46 -0
  25. package/ios/RCTBottomAccessoryComponentView.h +12 -0
  26. package/ios/RCTBottomAccessoryComponentView.mm +67 -0
  27. package/ios/RCTBottomAccessoryContainerView.swift +51 -0
  28. package/ios/RCTBottomTabsComponentView.h +12 -0
  29. package/ios/RCTBottomTabsComponentView.mm +338 -0
  30. package/ios/RCTBottomTabsContainerView.swift +777 -0
  31. package/ios/RCTBottomTabsLog.h +7 -0
  32. package/ios/RCTBottomTabsLog.m +32 -0
  33. package/ios/SVG/CoreSVG.h +13 -0
  34. package/ios/SVG/CoreSVG.mm +177 -0
  35. package/ios/SVG/SvgDecoder.h +10 -0
  36. package/ios/SVG/SvgDecoder.mm +32 -0
  37. package/ios/TabBarFontSize.swift +55 -0
  38. package/lib/module/BottomAccessoryView.js +45 -0
  39. package/lib/module/BottomAccessoryViewNativeComponent.ts +27 -0
  40. package/lib/module/BottomTabs.js +323 -0
  41. package/lib/module/BottomTabsNativeComponent.ts +69 -0
  42. package/lib/module/DelayedFreeze.js +31 -0
  43. package/lib/module/NativeSVGDecoder.js +5 -0
  44. package/lib/module/SceneMap.js +28 -0
  45. package/lib/module/codegen-types.d.js +2 -0
  46. package/lib/module/index.js +20 -0
  47. package/lib/module/package.json +1 -0
  48. package/lib/module/types.js +4 -0
  49. package/lib/module/utils/BottomTabBarHeightContext.js +5 -0
  50. package/lib/module/utils/useBottomTabBarHeight.js +12 -0
  51. package/lib/typescript/package.json +1 -0
  52. package/lib/typescript/src/BottomAccessoryView.d.ts +8 -0
  53. package/lib/typescript/src/BottomAccessoryViewNativeComponent.d.ts +16 -0
  54. package/lib/typescript/src/BottomTabs.d.ts +202 -0
  55. package/lib/typescript/src/BottomTabsNativeComponent.d.ts +58 -0
  56. package/lib/typescript/src/DelayedFreeze.d.ts +9 -0
  57. package/lib/typescript/src/NativeSVGDecoder.d.ts +6 -0
  58. package/lib/typescript/src/SceneMap.d.ts +10 -0
  59. package/lib/typescript/src/index.d.ts +16 -0
  60. package/lib/typescript/src/types.d.ts +29 -0
  61. package/lib/typescript/src/utils/BottomTabBarHeightContext.d.ts +3 -0
  62. package/lib/typescript/src/utils/useBottomTabBarHeight.d.ts +2 -0
  63. package/package.json +117 -4
  64. package/react-native-bottom-tabs.podspec +36 -0
  65. package/react-native.config.js +13 -0
  66. package/src/BottomAccessoryView.tsx +58 -0
  67. package/src/BottomAccessoryViewNativeComponent.ts +27 -0
  68. package/src/BottomTabs.tsx +545 -0
  69. package/src/BottomTabsNativeComponent.ts +69 -0
  70. package/src/DelayedFreeze.tsx +33 -0
  71. package/src/NativeSVGDecoder.ts +5 -0
  72. package/src/SceneMap.tsx +34 -0
  73. package/src/codegen-types.d.ts +28 -0
  74. package/src/index.tsx +18 -0
  75. package/src/types.ts +31 -0
  76. package/src/utils/BottomTabBarHeightContext.ts +5 -0
  77. package/src/utils/useBottomTabBarHeight.ts +15 -0
@@ -0,0 +1,202 @@
1
+ import React from 'react';
2
+ import { type ColorValue, type StyleProp, type ViewStyle } from 'react-native';
3
+ import type { ImageSource } from 'react-native/Libraries/Image/ImageSource';
4
+ import type { AppleIcon, BaseRoute, NavigationState, TabRole } from './types';
5
+ import { type RNBottomTabsAccessoryViewProps } from './BottomAccessoryView';
6
+ interface Props<Route extends BaseRoute> {
7
+ labeled?: boolean;
8
+ /**
9
+ * A tab bar style that adapts to each platform.
10
+ *
11
+ * Tab views using the sidebar adaptable style have an appearance
12
+ * that varies depending on the platform:
13
+ * - iPadOS displays a top tab bar that can adapt into a sidebar.
14
+ * - iOS displays a bottom tab bar.
15
+ * - macOS and tvOS always show a sidebar.
16
+ * - visionOS shows an ornament and also shows a sidebar for secondary tabs within a `TabSection`.
17
+ */
18
+ sidebarAdaptable?: boolean;
19
+ /**
20
+ * Whether to disable page animations between tabs. (iOS only) Defaults to `false`.
21
+ */
22
+ disablePageAnimations?: boolean;
23
+ /**
24
+ * Whether to enable haptic feedback. Defaults to `false`.
25
+ */
26
+ hapticFeedbackEnabled?: boolean;
27
+ /**
28
+ * Describes the appearance attributes for the tabBar to use when an observable scroll view is scrolled to the bottom. (iOS only)
29
+ */
30
+ scrollEdgeAppearance?: 'default' | 'opaque' | 'transparent';
31
+ /**
32
+ * Behavior for minimizing the tab bar. (iOS 26+)
33
+ */
34
+ minimizeBehavior?: 'automatic' | 'onScrollDown' | 'onScrollUp' | 'never';
35
+ /**
36
+ * Active tab color.
37
+ */
38
+ tabBarActiveTintColor?: ColorValue;
39
+ /**
40
+ * Inactive tab color.
41
+ */
42
+ tabBarInactiveTintColor?: ColorValue;
43
+ /**
44
+ * State for the tab view.
45
+ */
46
+ navigationState: NavigationState<Route>;
47
+ /**
48
+ * Function which takes an object with the route and returns a React element.
49
+ */
50
+ renderScene: (props: {
51
+ route: Route;
52
+ jumpTo: (key: string) => void;
53
+ }) => React.ReactNode | null;
54
+ /**
55
+ * Function which takes a route and returns a placeholder for an unloaded lazy scene.
56
+ */
57
+ renderLazyPlaceholder?: (props: {
58
+ route: Route;
59
+ }) => React.ReactNode | null;
60
+ /**
61
+ * Callback which is called on tab change, receives the index of the new tab as argument.
62
+ */
63
+ onIndexChange: (index: number) => boolean | void;
64
+ /**
65
+ * Callback which is called when the same tab is pressed twice within the
66
+ * platform double-tap timeout, receives the index of the tab as argument.
67
+ * Each press still goes through `onIndexChange` / reselection first.
68
+ */
69
+ onTabDoublePress?: (index: number) => void;
70
+ /**
71
+ * Get lazy for the current screen. Uses true by default.
72
+ */
73
+ getLazy?: (props: {
74
+ route: Route;
75
+ }) => boolean | undefined;
76
+ /**
77
+ * Get label text for the tab, uses `route.title` by default.
78
+ */
79
+ getLabelText?: (props: {
80
+ route: Route;
81
+ }) => string | undefined;
82
+ /**
83
+ * Get badge for the tab, uses `route.badge` by default.
84
+ */
85
+ getBadge?: (props: {
86
+ route: Route;
87
+ }) => string | undefined;
88
+ /**
89
+ * Get badge background color for the tab. (Android only)
90
+ */
91
+ getBadgeBackgroundColor?: (props: {
92
+ route: Route;
93
+ }) => ColorValue | undefined;
94
+ /**
95
+ * Get badge text color for the tab. (Android only)
96
+ */
97
+ getBadgeTextColor?: (props: {
98
+ route: Route;
99
+ }) => ColorValue | undefined;
100
+ /**
101
+ * Get active tint color for the tab.
102
+ */
103
+ getActiveTintColor?: (props: {
104
+ route: Route;
105
+ }) => ColorValue | undefined;
106
+ /**
107
+ * Determines whether the tab prevents default action on press.
108
+ */
109
+ getPreventsDefault?: (props: {
110
+ route: Route;
111
+ }) => boolean | undefined;
112
+ /**
113
+ * Get icon for the tab.
114
+ */
115
+ getIcon?: (props: {
116
+ route: Route;
117
+ focused: boolean;
118
+ }) => ImageSource | AppleIcon | undefined | null;
119
+ /**
120
+ * Get hidden for the tab.
121
+ */
122
+ getHidden?: (props: {
123
+ route: Route;
124
+ }) => boolean | undefined;
125
+ /**
126
+ * Get testID for the tab.
127
+ */
128
+ getTestID?: (props: {
129
+ route: Route;
130
+ }) => string | undefined;
131
+ /**
132
+ * Get role for the tab. (iOS only)
133
+ */
134
+ getRole?: (props: {
135
+ route: Route;
136
+ }) => TabRole | undefined;
137
+ /**
138
+ * Custom tab bar to render.
139
+ */
140
+ tabBar?: () => React.ReactNode;
141
+ /**
142
+ * Get freezeOnBlur for the current screen.
143
+ */
144
+ getFreezeOnBlur?: (props: {
145
+ route: Route;
146
+ }) => boolean | undefined;
147
+ /**
148
+ * Get style for the scene.
149
+ */
150
+ getSceneStyle?: (props: {
151
+ route: Route;
152
+ }) => StyleProp<ViewStyle>;
153
+ tabBarStyle?: {
154
+ backgroundColor?: ColorValue;
155
+ };
156
+ /**
157
+ * A Boolean value that indicates whether the tab bar is translucent. (iOS only)
158
+ */
159
+ translucent?: boolean;
160
+ rippleColor?: ColorValue;
161
+ /**
162
+ * Color of tab indicator. (Android only)
163
+ */
164
+ activeIndicatorColor?: ColorValue;
165
+ tabLabelStyle?: {
166
+ fontFamily?: string;
167
+ fontWeight?: string;
168
+ fontSize?: number;
169
+ };
170
+ /**
171
+ * A function that returns a React element to display as bottom accessory view.
172
+ * iOS 26+ only.
173
+ */
174
+ renderBottomAccessoryView?: RNBottomTabsAccessoryViewProps['renderBottomAccessoryView'];
175
+ /**
176
+ * Whether the tab bar is hidden.
177
+ */
178
+ tabBarHidden?: boolean;
179
+ /**
180
+ * Whether to ignore bottom system insets (navigation bar). Android only.
181
+ */
182
+ ignoreBottomInsets?: boolean;
183
+ /**
184
+ * Visual style of the Android tab bar. Android only.
185
+ */
186
+ androidTabBarStyle?: 'default' | 'floating';
187
+ /**
188
+ * Whether the tab bar ignores the soft keyboard. Defaults to true, so the
189
+ * keyboard covers the tab bar as on iOS. Set to false to pad the tab bar by
190
+ * the keyboard height so it rises above the keyboard. Android only.
191
+ */
192
+ ignoreKeyboardInsets?: boolean;
193
+ /**
194
+ * Whether to delay freeze/unfreeze by 200ms on tab switch.
195
+ * Defaults to false (immediate freeze). Set to true to restore the
196
+ * original delayed behavior.
197
+ */
198
+ delayedFreeze?: boolean;
199
+ }
200
+ declare const BottomTabs: <Route extends BaseRoute>({ navigationState, renderScene, renderLazyPlaceholder, onIndexChange, onTabDoublePress, rippleColor, tabBarActiveTintColor: activeTintColor, tabBarInactiveTintColor: inactiveTintColor, getBadge, getBadgeBackgroundColor, getBadgeTextColor, getLazy, getLabelText, getIcon, getHidden, getActiveTintColor, getTestID, getRole, getSceneStyle, getPreventsDefault, hapticFeedbackEnabled, labeled, getFreezeOnBlur, tabBar: renderCustomTabBar, tabBarStyle, tabLabelStyle, renderBottomAccessoryView, activeIndicatorColor, delayedFreeze, ...props }: Props<Route>) => import("react/jsx-runtime").JSX.Element;
201
+ export default BottomTabs;
202
+ //# sourceMappingURL=BottomTabs.d.ts.map
@@ -0,0 +1,58 @@
1
+ import type { ColorValue, ProcessedColorValue, ViewProps } from 'react-native';
2
+ import type { DirectEventHandler, Double, Int32, WithDefault } from 'react-native/Libraries/Types/CodegenTypes';
3
+ import type { ImageSource } from 'react-native/Libraries/Image/ImageSource';
4
+ export type OnPageSelectedEventData = Readonly<{
5
+ key: string;
6
+ }>;
7
+ export type OnTabBarMeasured = Readonly<{
8
+ height: Int32;
9
+ }>;
10
+ export type OnNativeLayout = Readonly<{
11
+ width: Double;
12
+ height: Double;
13
+ }>;
14
+ export type BottomTabsItems = ReadonlyArray<{
15
+ key: string;
16
+ title: string;
17
+ sfSymbol?: string;
18
+ badge?: string;
19
+ badgeBackgroundColor?: ProcessedColorValue | null;
20
+ badgeTextColor?: ProcessedColorValue | null;
21
+ activeTintColor?: ProcessedColorValue | null;
22
+ hidden?: boolean;
23
+ testID?: string;
24
+ role?: string;
25
+ preventsDefault?: boolean;
26
+ }>;
27
+ export interface BottomTabsNativeProps extends ViewProps {
28
+ items: BottomTabsItems;
29
+ selectedPage: string;
30
+ onPageSelected?: DirectEventHandler<OnPageSelectedEventData>;
31
+ onTabDoublePress?: DirectEventHandler<OnPageSelectedEventData>;
32
+ onTabBarMeasured?: DirectEventHandler<OnTabBarMeasured>;
33
+ onNativeLayout?: DirectEventHandler<OnNativeLayout>;
34
+ icons?: ReadonlyArray<ImageSource>;
35
+ selectedIcons?: ReadonlyArray<ImageSource>;
36
+ tabBarHidden?: boolean;
37
+ labeled?: boolean;
38
+ sidebarAdaptable?: boolean;
39
+ scrollEdgeAppearance?: string;
40
+ barTintColor?: ColorValue;
41
+ translucent?: WithDefault<boolean, true>;
42
+ rippleColor?: ColorValue;
43
+ activeTintColor?: ColorValue;
44
+ inactiveTintColor?: ColorValue;
45
+ disablePageAnimations?: boolean;
46
+ activeIndicatorColor?: ColorValue;
47
+ hapticFeedbackEnabled?: boolean;
48
+ minimizeBehavior?: string;
49
+ fontFamily?: string;
50
+ fontWeight?: string;
51
+ fontSize?: Int32;
52
+ ignoreBottomInsets?: boolean;
53
+ androidTabBarStyle?: WithDefault<'default' | 'floating', 'default'>;
54
+ ignoreKeyboardInsets?: WithDefault<boolean, true>;
55
+ }
56
+ declare const _default: import("react-native").HostComponent<BottomTabsNativeProps>;
57
+ export default _default;
58
+ //# sourceMappingURL=BottomTabsNativeComponent.d.ts.map
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ interface FreezeWrapperProps {
3
+ freeze: boolean;
4
+ delayedFreeze?: boolean;
5
+ children: React.ReactNode;
6
+ }
7
+ declare function DelayedFreeze({ freeze, delayedFreeze, children }: FreezeWrapperProps): import("react/jsx-runtime").JSX.Element;
8
+ export default DelayedFreeze;
9
+ //# sourceMappingURL=DelayedFreeze.d.ts.map
@@ -0,0 +1,6 @@
1
+ import { type TurboModule } from 'react-native';
2
+ export interface Spec extends TurboModule {
3
+ }
4
+ declare const _default: Spec;
5
+ export default _default;
6
+ //# sourceMappingURL=NativeSVGDecoder.d.ts.map
@@ -0,0 +1,10 @@
1
+ import * as React from 'react';
2
+ type SceneProps = {
3
+ route: any;
4
+ jumpTo: (key: string) => void;
5
+ };
6
+ export declare function SceneMap<T>(scenes: {
7
+ [key: string]: React.ComponentType<T>;
8
+ }): ({ route, jumpTo }: SceneProps) => import("react/jsx-runtime").JSX.Element | null;
9
+ export {};
10
+ //# sourceMappingURL=SceneMap.d.ts.map
@@ -0,0 +1,16 @@
1
+ import BottomTabs from './BottomTabs';
2
+ /**
3
+ * Views
4
+ */
5
+ export default BottomTabs;
6
+ /**
7
+ * Utilities
8
+ */
9
+ export { SceneMap } from './SceneMap';
10
+ export { useBottomTabBarHeight } from './utils/useBottomTabBarHeight';
11
+ export { BottomTabBarHeightContext } from './utils/BottomTabBarHeightContext';
12
+ /**
13
+ * Types
14
+ */
15
+ export type { AppleIcon, TabRole } from './types';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,29 @@
1
+ import type { ImageSourcePropType, StyleProp, ViewStyle } from 'react-native';
2
+ import type { SFSymbol } from 'sf-symbols-typescript';
3
+ export type IconSource = string | ImageSourcePropType;
4
+ export type AppleIcon = {
5
+ sfSymbol: SFSymbol;
6
+ };
7
+ export type TabRole = 'search';
8
+ export type BaseRoute = {
9
+ key: string;
10
+ title?: string;
11
+ badge?: string;
12
+ badgeBackgroundColor?: string;
13
+ badgeTextColor?: string;
14
+ lazy?: boolean;
15
+ focusedIcon?: ImageSourcePropType | AppleIcon;
16
+ unfocusedIcon?: ImageSourcePropType | AppleIcon;
17
+ activeTintColor?: string;
18
+ hidden?: boolean;
19
+ testID?: string;
20
+ role?: TabRole;
21
+ freezeOnBlur?: boolean;
22
+ style?: StyleProp<ViewStyle>;
23
+ preventsDefault?: boolean;
24
+ };
25
+ export type NavigationState<Route extends BaseRoute> = {
26
+ index: number;
27
+ routes: Route[];
28
+ };
29
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,3 @@
1
+ import * as React from 'react';
2
+ export declare const BottomTabBarHeightContext: React.Context<number | undefined>;
3
+ //# sourceMappingURL=BottomTabBarHeightContext.d.ts.map
@@ -0,0 +1,2 @@
1
+ export declare function useBottomTabBarHeight(): number;
2
+ //# sourceMappingURL=useBottomTabBarHeight.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,119 @@
1
1
  {
2
2
  "name": "@onekeyfe/react-native-bottom-tabs",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "6.7.0-alpha.339",
4
+ "description": "Native bottom tabs (tab bar + scene container) for React Native on iOS and Android",
5
+ "source": "./src/index.tsx",
6
+ "main": "./lib/module/index.js",
7
+ "types": "./lib/typescript/src/index.d.ts",
8
+ "sideEffects": false,
9
+ "exports": {
10
+ ".": {
11
+ "source": "./src/index.tsx",
12
+ "types": "./lib/typescript/src/index.d.ts",
13
+ "default": "./lib/module/index.js"
14
+ },
15
+ "./package.json": "./package.json"
16
+ },
17
+ "files": [
18
+ "src",
19
+ "lib",
20
+ "android",
21
+ "ios",
22
+ "docs",
23
+ "common",
24
+ "react-native.config.js",
25
+ "*.podspec",
26
+ "!ios/build",
27
+ "!android/build",
28
+ "!android/gradle",
29
+ "!android/gradlew",
30
+ "!android/gradlew.bat",
31
+ "!android/local.properties",
32
+ "!**/__tests__",
33
+ "!**/__fixtures__",
34
+ "!**/__mocks__",
35
+ "!**/.*",
36
+ "!**/*.map"
37
+ ],
38
+ "scripts": {
39
+ "clean": "del-cli lib",
40
+ "prepare": "rm -rf lib && bob build",
41
+ "typecheck": "tsc -b",
42
+ "lint": "eslint \"**/*.{js,ts,tsx}\"",
43
+ "test": "jest",
44
+ "release": "yarn prepare && npm whoami && npm publish --access public"
45
+ },
46
+ "keywords": [
47
+ "react-native",
48
+ "ios",
49
+ "android"
50
+ ],
51
+ "repository": {
52
+ "type": "git",
53
+ "url": "git+https://github.com/OneKeyHQ/app-modules.git",
54
+ "directory": "native-views/react-native-bottom-tabs"
55
+ },
56
+ "author": "OneKey",
57
+ "bugs": {
58
+ "url": "https://github.com/OneKeyHQ/app-modules/issues"
59
+ },
60
+ "homepage": "https://github.com/OneKeyHQ/app-modules/tree/main/native-views/react-native-bottom-tabs#readme",
61
+ "license": "MIT",
62
+ "publishConfig": {
63
+ "registry": "https://registry.npmjs.org/",
64
+ "access": "public"
65
+ },
66
+ "devDependencies": {
67
+ "@types/react": "^19.2.0",
68
+ "react": "19.2.3",
69
+ "react-native": "patch:react-native@npm%3A0.86.2#~/.yarn/patches/react-native-npm-0.86.2-c9d546616f.patch",
70
+ "react-native-builder-bob": "^0.40.13",
71
+ "typescript": "^5.9.2"
72
+ },
73
+ "peerDependencies": {
74
+ "react": "*",
75
+ "react-native": "*"
76
+ },
77
+ "react-native-builder-bob": {
78
+ "source": "src",
79
+ "output": "lib",
80
+ "targets": [
81
+ [
82
+ "module",
83
+ {
84
+ "esm": true
85
+ }
86
+ ],
87
+ [
88
+ "typescript",
89
+ {
90
+ "project": "tsconfig.build.json"
91
+ }
92
+ ]
93
+ ]
94
+ },
95
+ "dependencies": {
96
+ "react-freeze": "^1.0.0",
97
+ "sf-symbols-typescript": "^2.0.0",
98
+ "use-latest-callback": "^0.2.1"
99
+ },
100
+ "codegenConfig": {
101
+ "name": "RNBottomTabs",
102
+ "type": "all",
103
+ "jsSrcsDir": "./src",
104
+ "android": {
105
+ "javaPackageName": "com.onekey.bottomtabs"
106
+ },
107
+ "ios": {
108
+ "componentProvider": {
109
+ "RNBottomTabsView": "RCTBottomTabsComponentView",
110
+ "RNBottomTabsAccessoryView": "RCTBottomAccessoryComponentView"
111
+ },
112
+ "modulesConformingToProtocol": {
113
+ "RCTImageDataDecoder": [
114
+ "SvgDecoder"
115
+ ]
116
+ }
117
+ }
118
+ }
119
+ }
@@ -0,0 +1,36 @@
1
+ require "json"
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = "react-native-bottom-tabs"
7
+ s.version = package["version"]
8
+ s.summary = package["description"]
9
+ s.homepage = package["homepage"]
10
+ s.license = package["license"]
11
+ s.authors = package["author"]
12
+
13
+ s.ios.deployment_target = "15.1"
14
+ s.module_name = "BottomTabsModule"
15
+
16
+ s.source = { :git => "https://github.com/nicholasxuu/app-modules.git", :tag => "#{s.version}" }
17
+
18
+ s.source_files = [
19
+ "ios/**/*.{swift}",
20
+ "ios/**/*.{h,m,mm,cpp}",
21
+ ]
22
+
23
+ s.static_framework = true
24
+
25
+ s.subspec "common" do |ss|
26
+ ss.source_files = "common/cpp/**/*.{cpp,h}"
27
+ ss.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/common/cpp\"" }
28
+ end
29
+
30
+ s.pod_target_xcconfig = {
31
+ 'PRODUCT_MODULE_NAME' => 'BottomTabsModule',
32
+ 'DEFINES_MODULE' => 'YES'
33
+ }
34
+
35
+ install_modules_dependencies(s)
36
+ end
@@ -0,0 +1,13 @@
1
+ module.exports = {
2
+ dependency: {
3
+ platforms: {
4
+ android: {
5
+ componentDescriptors: ['RNBottomTabsViewComponentDescriptor'],
6
+ cmakeListsPath: undefined,
7
+ packageImportPath:
8
+ 'import com.onekey.bottomtabs.BottomTabsPackage;',
9
+ packageInstance: 'new BottomTabsPackage()',
10
+ },
11
+ },
12
+ },
13
+ };
@@ -0,0 +1,58 @@
1
+ import React from 'react';
2
+ import type { DimensionValue, NativeSyntheticEvent, ViewStyle } from 'react-native';
3
+ import BottomAccessoryViewNativeComponent from './BottomAccessoryViewNativeComponent';
4
+
5
+ const defaultStyle: ViewStyle = {
6
+ position: 'absolute',
7
+ top: 0,
8
+ left: 0,
9
+ };
10
+
11
+ export interface RNBottomTabsAccessoryViewProps {
12
+ renderBottomAccessoryView: (props: {
13
+ placement: 'inline' | 'expanded' | 'none';
14
+ }) => React.ReactNode;
15
+ }
16
+
17
+ export const BottomAccessoryView = (props: RNBottomTabsAccessoryViewProps) => {
18
+ const { renderBottomAccessoryView } = props;
19
+ const [bottomAccessoryDimensions, setBottomAccessoryDimensions] =
20
+ React.useState<
21
+ { width: DimensionValue; height: DimensionValue } | undefined
22
+ >({ width: '100%', height: '100%' });
23
+ const [placement, setPlacement] = React.useState<
24
+ 'inline' | 'expanded' | 'none'
25
+ >('none');
26
+
27
+ const handleNativeLayout = React.useCallback(
28
+ (event: NativeSyntheticEvent<{ width: number; height: number }>) => {
29
+ const { width, height } = event.nativeEvent;
30
+ setBottomAccessoryDimensions({ width, height });
31
+ },
32
+ [setBottomAccessoryDimensions]
33
+ );
34
+
35
+ const handlePlacementChanged = React.useCallback(
36
+ (event: NativeSyntheticEvent<{ placement: string }>) => {
37
+ const newPlacement = event.nativeEvent.placement;
38
+ if (
39
+ newPlacement === 'inline' ||
40
+ newPlacement === 'expanded' ||
41
+ newPlacement === 'none'
42
+ ) {
43
+ setPlacement(newPlacement);
44
+ }
45
+ },
46
+ [setPlacement]
47
+ );
48
+
49
+ return (
50
+ <BottomAccessoryViewNativeComponent
51
+ style={[defaultStyle, bottomAccessoryDimensions]}
52
+ onNativeLayout={handleNativeLayout}
53
+ onPlacementChanged={handlePlacementChanged}
54
+ >
55
+ {renderBottomAccessoryView({ placement })}
56
+ </BottomAccessoryViewNativeComponent>
57
+ );
58
+ };
@@ -0,0 +1,27 @@
1
+ import { codegenNativeComponent } from 'react-native';
2
+ import type { ViewProps } from 'react-native';
3
+ import type {
4
+ DirectEventHandler,
5
+ Double,
6
+ } from 'react-native/Libraries/Types/CodegenTypes';
7
+
8
+ export type OnNativeLayout = Readonly<{
9
+ width: Double;
10
+ height: Double;
11
+ }>;
12
+
13
+ export type OnPlacementChanged = Readonly<{
14
+ placement: string;
15
+ }>;
16
+
17
+ export interface BottomAccessoryViewNativeProps extends ViewProps {
18
+ onNativeLayout?: DirectEventHandler<OnNativeLayout>;
19
+ onPlacementChanged?: DirectEventHandler<OnPlacementChanged>;
20
+ }
21
+
22
+ export default codegenNativeComponent<BottomAccessoryViewNativeProps>(
23
+ 'RNBottomTabsAccessoryView',
24
+ {
25
+ excludedPlatforms: ['android'],
26
+ }
27
+ );