@amazon-devices/react-navigation__material-bottom-tabs 2.0.1758683737
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/LICENSE +7 -0
- package/README.md +5 -0
- package/SystemBundles/48b2d0564ba9108d11d2a44e7db78d96e57b1571852ee96e2ae586ec3f92ac7c.bundle +37933 -0
- package/SystemBundles/48b2d0564ba9108d11d2a44e7db78d96e57b1571852ee96e2ae586ec3f92ac7c.map +9186 -0
- package/SystemBundles/dfdc0833a74825464b3c13f4ae466765136f1747e62e61be666c766e2b8fe7c6.bundle +32656 -0
- package/SystemBundles/dfdc0833a74825464b3c13f4ae466765136f1747e62e61be666c766e2b8fe7c6.map +1 -0
- package/SystemModules/amzn__react-navigation__material-bottom-tabs-2.modules.txt +4 -0
- package/SystemModules/amzn__react-navigation__material-bottom-tabs-2.private.modules.txt +250 -0
- package/SystemModules/keplerscript-system-bundle-config.json +7 -0
- package/THIRD_PARTY_NOTICES.txt +24 -0
- package/kepler-compatibility.json +8 -0
- package/kepler-transformed-package-info.json +3 -0
- package/lib/commonjs/index.js +21 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/navigators/createMaterialBottomTabNavigator.js +43 -0
- package/lib/commonjs/navigators/createMaterialBottomTabNavigator.js.map +1 -0
- package/lib/commonjs/types.js +6 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/commonjs/views/MaterialBottomTabView.js +196 -0
- package/lib/commonjs/views/MaterialBottomTabView.js.map +1 -0
- package/lib/module/index.js +14 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/navigators/createMaterialBottomTabNavigator.js +34 -0
- package/lib/module/navigators/createMaterialBottomTabNavigator.js.map +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/views/MaterialBottomTabView.js +188 -0
- package/lib/module/views/MaterialBottomTabView.js.map +1 -0
- package/lib/typescript/src/index.d.ts +13 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/navigators/createMaterialBottomTabNavigator.d.ts +8 -0
- package/lib/typescript/src/navigators/createMaterialBottomTabNavigator.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +56 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/lib/typescript/src/views/MaterialBottomTabView.d.ts +11 -0
- package/lib/typescript/src/views/MaterialBottomTabView.d.ts.map +1 -0
- package/package.json +1 -0
- package/src/index.tsx +19 -0
- package/src/navigators/createMaterialBottomTabNavigator.tsx +71 -0
- package/src/types.tsx +118 -0
- package/src/views/MaterialBottomTabView.tsx +244 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { SafeAreaProviderCompat } from '@amazon-devices/react-navigation__elements';
|
|
2
|
+
import {
|
|
3
|
+
CommonActions,
|
|
4
|
+
Link,
|
|
5
|
+
ParamListBase,
|
|
6
|
+
Route,
|
|
7
|
+
TabNavigationState,
|
|
8
|
+
useLinkBuilder,
|
|
9
|
+
useTheme,
|
|
10
|
+
} from '@amazon-devices/react-navigation__native';
|
|
11
|
+
import * as React from 'react';
|
|
12
|
+
import { Platform, StyleSheet, Text } from 'react-native';
|
|
13
|
+
import {
|
|
14
|
+
BottomNavigation,
|
|
15
|
+
DarkTheme,
|
|
16
|
+
DefaultTheme,
|
|
17
|
+
useTheme as usePaperTheme,
|
|
18
|
+
} from 'react-native-paper';
|
|
19
|
+
import { useSafeAreaInsets } from '@amazon-devices/react-native-safe-area-context';
|
|
20
|
+
|
|
21
|
+
import type {
|
|
22
|
+
MaterialBottomTabDescriptorMap,
|
|
23
|
+
MaterialBottomTabNavigationConfig,
|
|
24
|
+
MaterialBottomTabNavigationHelpers,
|
|
25
|
+
} from '../types';
|
|
26
|
+
|
|
27
|
+
type Props = MaterialBottomTabNavigationConfig & {
|
|
28
|
+
state: TabNavigationState<ParamListBase>;
|
|
29
|
+
navigation: MaterialBottomTabNavigationHelpers;
|
|
30
|
+
descriptors: MaterialBottomTabDescriptorMap;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
type Scene = { route: { key: string } };
|
|
34
|
+
|
|
35
|
+
// Optionally require vector-icons referenced from react-native-paper:
|
|
36
|
+
// https://github.com/callstack/react-native-paper/blob/4b26429c49053eaa4c3e0fae208639e01093fa87/src/components/MaterialCommunityIcon.tsx#L14
|
|
37
|
+
let MaterialCommunityIcons: React.ComponentType<
|
|
38
|
+
React.ComponentProps<
|
|
39
|
+
typeof import('react-native-vector-icons/MaterialCommunityIcons').default
|
|
40
|
+
>
|
|
41
|
+
>;
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
// Optionally require vector-icons
|
|
45
|
+
MaterialCommunityIcons =
|
|
46
|
+
require('react-native-vector-icons/MaterialCommunityIcons').default;
|
|
47
|
+
} catch (e: any) {
|
|
48
|
+
let isErrorLogged = false;
|
|
49
|
+
|
|
50
|
+
// Fallback component for icons
|
|
51
|
+
MaterialCommunityIcons = ({
|
|
52
|
+
name,
|
|
53
|
+
color,
|
|
54
|
+
size,
|
|
55
|
+
selectionColor: _0,
|
|
56
|
+
onLayout: _1,
|
|
57
|
+
...rest
|
|
58
|
+
}) => {
|
|
59
|
+
if (!isErrorLogged) {
|
|
60
|
+
if (
|
|
61
|
+
!/(Cannot find module|Module not found|Cannot resolve module)/.test(
|
|
62
|
+
e.message
|
|
63
|
+
)
|
|
64
|
+
) {
|
|
65
|
+
console.error(e);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
console.warn(
|
|
69
|
+
`Tried to use the icon '${name}' in a component from '@amazon-devices/react-navigation__material-bottom-tabs', but 'react-native-vector-icons/MaterialCommunityIcons' could not be loaded.`,
|
|
70
|
+
`To remove this warning, try installing 'react-native-vector-icons' or use another method to specify icon: https://reactnavigation.org/docs/material-bottom-tab-navigator/#tabbaricon.`
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
isErrorLogged = true;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<Text
|
|
78
|
+
{...rest}
|
|
79
|
+
style={[
|
|
80
|
+
styles.icon,
|
|
81
|
+
{
|
|
82
|
+
color: typeof color !== 'number' ? color : undefined,
|
|
83
|
+
fontSize: size,
|
|
84
|
+
},
|
|
85
|
+
]}
|
|
86
|
+
>
|
|
87
|
+
□
|
|
88
|
+
</Text>
|
|
89
|
+
);
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function MaterialBottomTabViewInner({
|
|
94
|
+
state,
|
|
95
|
+
navigation,
|
|
96
|
+
descriptors,
|
|
97
|
+
safeAreaInsets,
|
|
98
|
+
...rest
|
|
99
|
+
}: Props) {
|
|
100
|
+
const insets = useSafeAreaInsets();
|
|
101
|
+
const { dark, colors } = useTheme();
|
|
102
|
+
const paperTheme = usePaperTheme();
|
|
103
|
+
|
|
104
|
+
const buildLink = useLinkBuilder();
|
|
105
|
+
|
|
106
|
+
const t =
|
|
107
|
+
// If the theme from React Navigation and Paper match, then user the customized theme
|
|
108
|
+
// Otherwise fallback to the matching default theme from Paper
|
|
109
|
+
dark === paperTheme.dark ? paperTheme : dark ? DarkTheme : DefaultTheme;
|
|
110
|
+
|
|
111
|
+
const theme = React.useMemo(() => {
|
|
112
|
+
return {
|
|
113
|
+
...t,
|
|
114
|
+
colors: {
|
|
115
|
+
...t.colors,
|
|
116
|
+
...colors,
|
|
117
|
+
surface: colors.card,
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
}, [colors, t]);
|
|
121
|
+
|
|
122
|
+
return (
|
|
123
|
+
<BottomNavigation
|
|
124
|
+
{...rest}
|
|
125
|
+
theme={theme}
|
|
126
|
+
navigationState={state}
|
|
127
|
+
onIndexChange={(index: number) =>
|
|
128
|
+
navigation.dispatch({
|
|
129
|
+
...CommonActions.navigate({
|
|
130
|
+
name: state.routes[index].name,
|
|
131
|
+
merge: true,
|
|
132
|
+
}),
|
|
133
|
+
target: state.key,
|
|
134
|
+
})
|
|
135
|
+
}
|
|
136
|
+
renderScene={({ route }) => descriptors[route.key].render()}
|
|
137
|
+
renderTouchable={
|
|
138
|
+
Platform.OS === 'web'
|
|
139
|
+
? ({
|
|
140
|
+
onPress,
|
|
141
|
+
route,
|
|
142
|
+
accessibilityRole: _0,
|
|
143
|
+
borderless: _1,
|
|
144
|
+
centered: _2,
|
|
145
|
+
rippleColor: _3,
|
|
146
|
+
style,
|
|
147
|
+
...rest
|
|
148
|
+
}) => {
|
|
149
|
+
return (
|
|
150
|
+
<Link
|
|
151
|
+
{...rest}
|
|
152
|
+
// @ts-expect-error: to could be undefined, but it doesn't affect functionality
|
|
153
|
+
to={buildLink(route.name, route.params)}
|
|
154
|
+
accessibilityRole="link"
|
|
155
|
+
onPress={(e: any) => {
|
|
156
|
+
if (
|
|
157
|
+
!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) && // ignore clicks with modifier keys
|
|
158
|
+
(e.button == null || e.button === 0) // ignore everything but left clicks
|
|
159
|
+
) {
|
|
160
|
+
e.preventDefault();
|
|
161
|
+
onPress?.(e);
|
|
162
|
+
}
|
|
163
|
+
}}
|
|
164
|
+
// TODO: Update @types/react-native to higher version when it will be available and remove ts-ignore
|
|
165
|
+
// @ts-ignore
|
|
166
|
+
style={[styles.touchable, style]}
|
|
167
|
+
/>
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
: undefined
|
|
171
|
+
}
|
|
172
|
+
renderIcon={({ route, focused, color }) => {
|
|
173
|
+
const { options } = descriptors[route.key];
|
|
174
|
+
|
|
175
|
+
if (typeof options.tabBarIcon === 'string') {
|
|
176
|
+
return (
|
|
177
|
+
<MaterialCommunityIcons
|
|
178
|
+
name={options.tabBarIcon}
|
|
179
|
+
color={color}
|
|
180
|
+
size={24}
|
|
181
|
+
style={styles.icon}
|
|
182
|
+
/>
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (typeof options.tabBarIcon === 'function') {
|
|
187
|
+
return options.tabBarIcon({ focused, color });
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return null;
|
|
191
|
+
}}
|
|
192
|
+
getLabelText={({ route }: Scene) => {
|
|
193
|
+
const { options } = descriptors[route.key];
|
|
194
|
+
|
|
195
|
+
return options.tabBarLabel !== undefined
|
|
196
|
+
? options.tabBarLabel
|
|
197
|
+
: options.title !== undefined
|
|
198
|
+
? options.title
|
|
199
|
+
: (route as Route<string>).name;
|
|
200
|
+
}}
|
|
201
|
+
getColor={({ route }) => descriptors[route.key].options.tabBarColor}
|
|
202
|
+
getBadge={({ route }) => descriptors[route.key].options.tabBarBadge}
|
|
203
|
+
getAccessibilityLabel={({ route }) =>
|
|
204
|
+
descriptors[route.key].options.tabBarAccessibilityLabel
|
|
205
|
+
}
|
|
206
|
+
getTestID={({ route }) => descriptors[route.key].options.tabBarTestID}
|
|
207
|
+
onTabPress={({ route, preventDefault }) => {
|
|
208
|
+
const event = navigation.emit({
|
|
209
|
+
type: 'tabPress',
|
|
210
|
+
target: route.key,
|
|
211
|
+
canPreventDefault: true,
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
if (event.defaultPrevented) {
|
|
215
|
+
preventDefault();
|
|
216
|
+
}
|
|
217
|
+
}}
|
|
218
|
+
safeAreaInsets={{
|
|
219
|
+
top: safeAreaInsets?.top ?? insets?.top,
|
|
220
|
+
right: safeAreaInsets?.right ?? insets?.right,
|
|
221
|
+
bottom: safeAreaInsets?.bottom ?? insets?.bottom,
|
|
222
|
+
left: safeAreaInsets?.left ?? insets?.left,
|
|
223
|
+
}}
|
|
224
|
+
/>
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export default function MaterialBottomTabView(props: Props) {
|
|
229
|
+
return (
|
|
230
|
+
<SafeAreaProviderCompat>
|
|
231
|
+
<MaterialBottomTabViewInner {...props} />
|
|
232
|
+
</SafeAreaProviderCompat>
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const styles = StyleSheet.create({
|
|
237
|
+
icon: {
|
|
238
|
+
backgroundColor: 'transparent',
|
|
239
|
+
},
|
|
240
|
+
touchable: {
|
|
241
|
+
display: 'flex',
|
|
242
|
+
justifyContent: 'center',
|
|
243
|
+
},
|
|
244
|
+
});
|